深度解析塑造未来的技术文章。

权重空间编程:LLM 的第三根杠杆

权重空间编程让 LLM 直接读取并编辑神经网络权重。何时直接改权重胜过微调,以及它为何脆弱。

一个发光的节点网格,单根线束被光束精细地重新布线。
手动编辑神经网络:在数十亿根“线”中改动一根,改动是出于明确意图,而不是由梯度压力驱动。

梯度下降从来都不是什么神圣的东西。它只是脚手架,是我们手头唯一能塑造数十亿个没人读得懂的数字的通用工具,于是整个深度学习的信仰体系都围绕它搭了起来。MIT CSAIL 的一个团队刚刚把这套脚手架踢开了。他们把训练好的神经网络的原始权重交给一个前沿模型,用自然语言让它解释、调试并改写这些权重,不允许训练循环,不用梯度,也不做前向传播。结果居然成了。权重空间编程,即直接对参数进行推理,而不是沿着梯度往下推,已经从思想实验变成了演示。我认为它悄悄地把微调从“我们适配模型的方式”降级为三个选项之一。

这个核心结果确实值得这番热议。研究者让 Qwen3.5-0.8B 在完全不做梯度更新的情况下提升数学能力,模型 GPT-6 Astra 追溯出一个病态的推理循环,它被写入两个 MLP 层中的某个单一方向。随后它从 0.016% 的权重中减去了这个方向,MATH-500 准确率从 7.9% 提升到 48.1%。采样设置相同,其他条件也全部相同。这个修复甚至迁移到了指令遵循上,让 IFEval 翻了三倍。这不是超参数微调,这是手术。不过在我们急着埋葬梯度下降之前,有必要精确说明究竟证明了什么,它在哪些地方能泛化,又在哪些地方已经失效。

什么是权重空间编程

多年来,我们只有两种方式改变模型的行为。提示词改变输入,权重保持冻结。微调改变权重,但方式比较盲目:你给损失函数曲面看一批样本,让梯度把参数推向任何能降低误差的方向,对于途中哪些内部机制被重新布线几乎无法控制。权重空间编程提出了第三根杠杆:完全抛开损失函数,让一个推理系统读取权重,推断它们在计算什么,然后按照自然语言规范编辑这些权重。

最诡异的部分是读取结果。研究者用 PPO 训练了四个微型策略,分别去玩网格世界版的 Breakout、Pong、吃豆人和 Freeway。它们架构相同、输入通道相同、动作空间相同,所以只有权重能区分它们。Astra 在没有被告知候选列表的情况下,正确说出了全部四个游戏的名字。对于训练来生成圆形、方形和三角形的扩散模型,它也做到了。更难的版本是:只给它中间层,去掉嵌入层和输出层,所有维度都没有标签,它要判断三个字符级 Transformer 分别是在 Python、英语还是罗马化日语上训练的,它也判断对了。在这个过程中,它还通过把权重矩阵相乘,定位到了每一个归纳头,也就是让模型能够重复前文内容的复制电路。这是可解释性文献中的一项已知技术,但没人告诉过它。如果你一直关注机制可解释性那些缓慢而艰苦的工作,看到一个通用模型原生地完成这些事情,还是会让人有点眩晕。

接着它开始写权重。给定一个卡在局部极小值里的 PPO 训练赛车控制器,策略直接朝斜坡冲去,而不是先倒车积累速度。Astra 只凭权重加上一条录制的回合,就诊断出了失败原因。它的编辑在改动 3.5% 的参数后,让赛车在全部 1,024 个评估回合中都能成功。当要求它从零开始编写游戏网络、且没有任何环境反馈时,它产出的策略竟然打败了用 PPO 训练一亿步的网络。请再读一遍:没有交互,没有奖励信号,只有对一个游戏的自然语言描述,经由语言模型的推理被编译成了可以正常工作的权重。

直接编辑权重在真实模型上如何运作

对实践者来说,Qwen 的修复才是真正重要的结果,因为 8 亿参数是一个真实的模型,正是团队真正会微调和上线的那种规模。这种失败有大量文档记录:小型推理模型会陷入循环,不停重复同样的文字,直到耗尽 token 上限也给不出答案。Qwen 自己的模型卡就对此发出了警告,而在研究者的实际测试中,前 96 个回答里有 85 个以这种方式耗尽了完整的 32,768 token 上下文。Astra 的诊断是:第 15 层和第 19 层的 MLP 正在向残差流中写入一个方向,这个方向不断把模型拉回同一条生成轨迹。它的修复方法是从这两个 MLP 各自的 64 个输出列中减去该方向,总共 131,072 个权重,占模型的 0.016%。

这个运算简单得几乎令人难堪,而这正是关键。一旦你知道激活空间中哪个方向对应“永远循环”,删除它就只是一次投影:对每个受影响的权重向量,减去它在那个坏方向上的分量。任何人用十几行代码就能写出来。

import numpy as np
def subtract_direction(W, v, columns):
"""Remove the component of each chosen column that lies along v."""
v = v / np.linalg.norm(v)
W[:, columns] -= np.outer(v, v @ W[:, columns])
return W
# The Qwen repair, schematically: for the MLP output projections of
# layers 15 and 19, subtract the "loop" direction from 64 columns each.
# 2 layers x 64 columns x 1024 rows = 131,072 edited weights.
W_down[15] = subtract_direction(W_down[15], loop_dir[15], cols[15])
W_down[19] = subtract_direction(W_down[19], loop_dir[19], cols[19])

真正困难的从来不是减法本身,而是要知道是哪个方向、在哪一层,而且是在一个宽达数千维的残差流中找出来。这正是我们过去需要梯度下降的部分,因为梯度本质上是在权重空间里做搜索,它完全不需要任何理解。Astra 用诊断取代了搜索。这就像两种电工:一种靠反复试错去接线,直到故障消失;另一种读懂电路图,然后剪断正确的那根线。模型通过组合权重矩阵找到归纳头,也是同样的道理。它应用了一个从未被展示过的、已发表的可解释性方法,这说明它迁移的是真正的推理能力,而不是背下来的套路。

一根发光的线从致密的发光织物中被干净地抽出。
从网络的权重中减去单一方向:只要抽对了那根线,整张织物依然完好。

直接编辑权重何时胜过微调

我的看法是这样,而且我愿意为它辩护:对于中小型模型中范围狭窄、可定位的故障,直接编辑权重已经是更好的工具,而且差距很大。不妨看看针对那个循环 bug 的微调方案。你得先整理一个不循环的推理轨迹数据集,再跑 SFT 或 RL,然后寄希望于损失压力能去掉这个行为,同时不损害模型已经掌握的其他一切。你会耗费 GPU 小时去朝一个代理目标爬坡,比如更多的数学数据,而不是朝真正的意图去努力,那个意图其实就是“别再重复自己”。权重空间编程允许你直接说明意图。这次编辑只动了模型的万分之一左右;而微调会动到全部参数,附带损伤之后会以奇怪的回归形式浮现出来,而且没人能把它们和那次训练联系起来。

微调是朝着你意图的代理指标爬坡。权重空间编程让你直接说明意图。

第二种情况是跳出梯度方法在结构上无法逃脱的局部极小值。PPO 之所以让赛车卡在斜坡上,是因为强化学习是通过对当前策略做抖动来探索的,而对“直行”这一策略做任何小扰动,都发现不了“先倒车两秒”。推理不做抖动。它可以跳到一个性质完全不同的解,因为它是在问题的模型上操作,而不是对当前答案做扰动。十亿步的 PPO 找不到的东西,一次推理就找到了。这不是效率上的差距,而是类别上的差异。

第三,迭代循环被压缩了。微调有一条长长的后勤尾巴,包括数据整理、训练运行、评估扫描和回归检查,它把“一个小的行为改动”变成了一个要花好几天的项目。任何在自己硬件上运行过大模型的人都知道,其中大部分工作是管道工程而非建模。权重编辑更像一次代码热修复:诊断、打补丁、跑评估,如果不对就回滚。当诊断是正确的时候,你就能跳过整个训练流程。明显的优势集中在四种情况:

  • 故障已经诊断清楚,但没有能表达这个修复的训练数据
  • 你需要精确的作用范围,只改一个行为而不影响其他部分
  • 模型卡在随机探索无法逃脱的局部极小值里
  • 你承担不起训练流程的成本,无论是 GPU 还是日程时间

为什么权重空间编程很脆弱

现在说点泼冷水的话,因为确实有不少。我见过的最有用的数据点不是来自论文,而是来自一位从业者,他在一个小型的自然语言转 bash 模型上尝试了同样的技巧,结果净收益为零。编辑 1,920 个权重修好了一些 grep 错误,却弄坏了其他命令。这正是预期中的结果,也揭示了深层问题:训练好的网络中的行为是相互纠缠的。Qwen 的编辑之所以奏效,是因为循环行为恰好存在于一个紧凑、可移除的方向中。很多行为并非如此。它们以叠加态散布开来,同一批列承载着多个互不相关的特征,所以减去一个“方向”就像试图从一个和弦里去掉一个音符,你一定会误伤其他音符。没人有理论能预先判断哪些故障在几何上是紧凑的,哪些是弥散的。在这之前,每一次权重编辑都是一场赌博。

游戏网络的读取演示也要打些折扣。Astra 对游戏网络的推理依赖于表层统计,比如第一层权重集中在哪里、哪些输出 logits 能够区分开。而语言识别实际上是一个三选一的选择题,其中罗马化日语这个选项的字母分布异常显眼,没有 q、l、v 或 x。它的模式匹配确实令人印象深刻,但这算不算对权重空间的深层原生理解?就不那么清楚了。扩散模型的结果则是双刃剑:Astra 把每个形状都画成了轮廓,而模型实际生成的是填充的图形。这个错误证明它读取的是几何结构,而不是在模拟网络,但同时也说明它的“理解”可能在结构上是错的,却仍然能通过测试。

然后是规模和来源的问题。所有干净的结果都集中在 1.7 万到 700 万个权重之间,Qwen 的 0.8B 是个例外;而即便是中间层读取实验,也需要多达一百次 Python 分析运行才能得出结果。没有人展示过它在 70B 模型上有效,更不用说前沿模型了,而那种朴素的做法,即把权重直接塞进上下文窗口,远在此之前就会失败。还有一个令人不安的问题笼罩着整件事:这种能力从哪里来?那些在国际象棋上异常强的 LLM,通常最后都会发现训练中吃进了大量棋谱。如果 Astra 是被刻意用权重数据训练过的,那么这些结果与其说说明了涌现的理解,不如说说明了一套非常好的课程设计。我们确实不知道。

最后,MATH-500 的提升需要加一个星号。这个基准多年来已经被训练数据饱和,一个得分 7.9% 的基础模型,几乎肯定是在循环和格式问题上失败,而不是在数学能力上失败。这意味着这次编辑解锁的是潜在能力,而不是创造了技能。这依然很有价值,解锁本身就是真正的收获。但这与“编辑让模型数学能力变得更强”是不同的主张,而且它符合一个熟悉的模式:基准测试遗漏了真实工作中的大部分内容。

工作台上一把手术刀和一把大锤并排放在一块裸露的电路板旁边。
改变模型的两种哲学:权重编辑的手术刀,与梯度训练的大锤。

生产环境中的权重编辑:当作热修复对待

如果你想尝试这件事(在小模型上你确实应该试试),那就用你对待运行中数据库热补丁的那种纪律来对待权重编辑。所有改动都要做 diff,精确记录哪些张量被改动了、改了多少,因为 0.016% 小到足以让编辑脚本里的一个静默 bug 永远隐藏起来。要做广泛评估,而不仅仅看目标行为。Qwen 的修复恰好改善了指令遵循,但这种副作用的方向纯属运气,下次它可能会朝反方向走。保持基础检查点不可篡改,并把每次编辑作为可回滚的补丁进行版本管理。至于野心,要收敛:目前已被证明的最佳适用范围是小型、理解充分的故障,而且是在你能够完整评估的模型上。如果你的本能是通过“移除坏方向”去修复一个 70B 模型上模糊的“感觉不对”问题,那你很快就会用最艰难的方式领教什么叫叠加态。

  • 固定基础检查点;将编辑存为 diff,绝不原地覆盖
  • 在修改前后都运行广泛评估,而不仅限于目标基准
  • 优先选择有清晰、可复现特征的故障,而不是模糊的感觉
  • 预留回滚预算,假设一部分编辑会弄坏点什么

我的诚实立场是:目前这更像是一种可解释性工具和调试手术刀,还不是部署流水线。最先从中获益的团队,不会是那些把权重编辑推上生产环境的团队,而是那些用前沿模型来解释自家小模型学到了什么的团队。他们像我们早已习惯阅读推理轨迹那样去读取检查点,然后用普通、朴素、可靠的工具去采取行动。

梯度没有死,只是被降级了

这里是我开篇论点站不住脚的地方,我想坦率地说明。梯度下降能做到权重空间编程做不到的一件事:它能在规模上从数据中学习。Astra 用来完成这些编辑的每一种能力,本身都是由梯度在庞大的训练语料上安装进去的。推理可以对网络所知道的内容做手术,但它无法教会网络人类文本的全部总和。现实的未来不是梯度被取代,而是分工。梯度负责浇筑混凝土,权重空间编程负责精装修。四十年来,我们把训练好的权重当作一个不透明的产物,一个只能从外部去引导的黑箱。这里真正新颖的想法是:这个黑箱正在变得可读,而读它的东西已经不是我们了。这究竟是令人安心还是令人不安,大概取决于你有多信任梯度。