Anthropic J-Space:大语言模型内部全局工作空间的发现、可干预与可解释性突破

发布时间:2026/7/17 12:32:01

Anthropic J-Space:大语言模型内部全局工作空间的发现、可干预与可解释性突破 一、引言:窥见AI的"内心独白"2026年7月6日,Anthropic研究团队发表了一篇引发广泛讨论的论文——《A Global Workspace in Language Models》(语言模型中的全局工作空间),并开源了配套工具J-lens(雅可比透镜)。研究团队在Claude模型内部识别出一个仅占模型活动6%-10%的稀疏子空间——J-Space,这个空间中的神经表征可以被观测、被干预,且具有因果效力。这一发现的重要意义在于:研究者首次得以窥见模型推理过程中的"内心独白"——那些在模型输出中从未出现、但实实在在参与推理的中间概念。当Claude回答"会织网的动物有几条腿"时,它只输出"8",但J-lens能在中间层读到"蜘蛛"这个从未说出口的推理步骤。本文将从J-Space的技术原理、J-lens工具的实现机制、实验验证、与神经科学全局工作空间理论的类比,以及其在AI安全领域的应用前景等维度,深入剖析这一可解释性突破的技术内涵,并辅以完整的Python/Go代码实现。二、J-Space的核心技术原理2.1 什么是J-Space?J-Space(Jacobian Space)是语言模型内部一个特殊的神经活动子空间,其名称来源于用于探测它的数学工具——雅可比矩阵(Jacobian Matrix)。""" J-Space 核心概念的形式化定义 """importtorchimporttorch.nnasnnimportnumpyasnpfromtypingimportList,Tuple,Optional,CallableclassJSpaceDefinition:""" J-Space 的形式化定义 J-Space 是模型内部激活空间中一个低维子空间,满足: 1. 可读性(Verbalizable):其中的表征可以映射为自然语言概念 2. 因果性(Causal):对其中的表征进行干预会改变模型输出 3. 稀疏性(Sparse):仅占模型内部激活方差的6%-10% 4. 广播性(Broadcast):其中的信息可以被多个下游模块访问 """def__init__(self,model:nn.Module,layer_idx:int):self.model=model self.layer_idx=layer_idx self.jacobian:Optional[torch.Tensor]=Noneself.j_space_directions:Optional[torch.Tensor]=Nonedefcompute_jacobian(self,input_ids:torch.Tensor,target_token_ids:torch.Tensor)-torch.Tensor:""" 计算雅可比矩阵:输出对中间层激活的偏导数 J = ∂output / ∂h_layer 其中 h_layer 是第 layer_idx 层的隐藏状态 """# 注册前向钩子获取中间层激活intermediate_activation=Nonedefhook_fn(module,input,output):nonlocalintermediate_activation intermediate_activation=output hook=self.model.layers[self.layer_idx].register_forward_hook(hook_fn)# 前向传播output=self.model(input_ids)# 选择目标token的logitstarget_logits=output.logits[0,-1,target_token_ids]# 计算雅可比矩阵self.jacobian=torch.autograd.functional.jacobian(lambdah:self._compute_logits_from_hidden(h,target_token_ids),intermediate_activation)hook.remove()returnself.jacobiandef_compute_logits_from_hidden(self,hidden_state:torch.Tensor,target_token_ids:torch.Tensor)-torch.Tensor:"""从隐藏状态计算目标token的logits"""# 简化版:假设从隐藏状态到logits的映射returnself.model.lm_head(hidden_state)[:,target_token_ids]defextract_j_space(self,activation:torch.Tensor,threshold:float=0.01)-torch.Tensor:""" 从激活中提取J-Space方向 通过SVD分解雅可比矩阵,保留贡献最大的奇异向量 """ifself.jacobianisNone:raiseValueError("请先调用 compute_jacobian()")# SVD分解U,S,Vh=torch.linalg.svd(self.jacobian,full_matrices=False)# 保留超过阈值的奇异值对应的方向significant_dirs=(Sthreshold*S.max()).sum().item()self.j_space_directions=Vh[:significant_dirs,:]# 将激活投影到J-Spacej_space_activation=self.j_space_directions @ activationreturnj_space_activationdefverbalize_activation(self,activation_projection:torch.Tensor,tokenizer:Callable)-List[str]:""" 将J-Space中的激活解码为可读的概念 通过查找与投影方向最接近的词嵌入来实现 """# 获取模型词嵌入矩阵embedding_matrix=self.model.get_input_embeddings().weight# 对每个J-Space方向,找到最接近的词concepts=[]foriinrange(activation_projection.shape[0]):direction=self.j_space_directions[i]similarities=embedding_matrix @ direction top_k=torch.topk(similarities,k=5).indices concepts.append([tokenizer.decode(idx)foridxintop_k])returnconcepts2.2 J-lens 工具的实现J-lens(Jacobian Lens)是Anthropic开发的核心工具,它通过计算雅可比矩阵来"读取"模型内部激活中蕴含的概念信息:""" J-lens (Jacobian Lens) 的完整实现 """classJacobianLens:""" 雅可比透镜:一种无需额外训练的模型内部状态读取工具 核心思想:不是看模型"下一步最可能输出什么词", 而是看"某一层某个内部激活,平均来看会让模型在未来更容易说出哪些词" """def__init__(self,model,tokenizer,layers:List[int]):self.model=model self.tokenizer=tokenizer self.layers=layers self.activations:dict={}self._register_hooks()def_register_hooks(self):"""注册钩子以捕获中间层激活"""defmake_hook_fn(layer_idx):defhook_fn(module,input,output):self.activations[layer_idx]=output[0].detach()ifisinstance(output,tuple)elseoutput.detach()returnhook_fnforlayer_idxinself.layers:self.model.model.layers[layer_idx].register_forward_hook(make_hook_fn(layer_idx))defcompute_jacobian_at_layer(self,layer_idx:int,input_ids:torch.Tensor,target_positions:List[int])-torch.Tensor:""" 计算指定层的雅可比矩阵 对于输入序列中的每个位置,计算: J_{i,j} = ∂logit_j / ∂h_i 其中 h_i 是第i个位置的隐藏状态 logit_j 是第j个位置的logit """batch_size,seq_len=input_ids.shape hidden_dim=self.model.config.hidden_size# 确保模型处于评估模式self.model.eval()# 清空之前的激活self.activations.clear()# 前向传播(带钩子)withtorch.no_grad():outputs=self.model(input_ids)hidden_states=self.activations[layer_idx]# [batch, seq_len, hidden_dim]logits=outputs.logits# [batch, seq_len, vocab_size]# 初始化雅可比矩阵jacobian=torch.zeros(seq_len,hidden_dim,len(target_positions))# 对每个目标位置计算雅可比fort_idx,posinenumerate(target_positions):target_logit=logits[0,pos,:]# 使用自动微分计算雅可比foriinrange(seq_len):forjinrange(hidden_dim):# 近似:∂logit_pos / ∂hidden[i,j]epsilon=1e-5hidden_orig=hidden_states[0,i,j].clone()# 正向扰动hidden_states[0,i,j]=hidden_orig+epsilonwithtorch.no_grad():output_plus=self.model(input_ids).logits[0,pos,:]# 负向扰动hidden_states[0,i,j]=hidden_orig-

相关新闻