LLM 神经解剖学:不改权重登顶 AI 排行榜

深度2026年3月10日5 分钟阅读
LLM 神经解剖学:不改权重登顶 AI 排行榜
2024 年中,HuggingFace Open LLM 排行榜上,一个未经任何权重调整的模型登顶榜首。作者通过复制现有 720 亿参数模型的中间层,发现了大语言模型内部存在类似大脑皮层的“推理核心”。

2024 年中,HuggingFace Open LLM 排行榜是开源 AI 模型的竞技场。数千个模型在此角逐,参与者既有资金雄厚、博士云集的实验室,也有擅长微调、能起出各种奇幻名字的模型巫师(比如 Nous-Hermes、Dolphin、NeuralBeagle14-7B...)。它们争夺着六个基准测试(IFEval、BBH、MATH Lvl 5、GPQA、MuSR、MMLU-PRO)的榜首位置。

而当时排名第一的,是 dnhkng/RYS-XLarge。我的模型。

我没有训练新模型,没有合并权重,甚至没有运行过一步梯度下降。我做的要奇怪得多:我拿了一个现成的 720 亿参数模型,复制了其中间特定的一个由七层组成的模块,然后把结果缝合回去。整个过程没有修改任何权重。模型只是获得了更多用于思考的层。

这就是 LLM 神经解剖学(LLM Neuroanatomy)的发现故事。两个奇怪的观察,一个自制的 Transformer“大脑扫描仪”,加上在地下室数月的钻研,最终让我窥见了 AI 的内部结构。这个发现直到现在才公之于众*。

  • ——因为我发现写博客比写科学论文有趣多了,而且我可以带你一步步了解这个发现是如何诞生的。

让我们从头说起,这个项目是怎么开始的。

“科学中最令人兴奋、预示着新发现的短语,不是‘我找到了!’,而是‘这有点意思……’”——艾萨克·阿西莫夫

线索一:你可以用 Base64 和 LLM 聊天

2023 年底,我在琢磨一个奇怪的大语言模型特性。你自己也可以试试——随便拿个问题,比如:

What is the capital of France? Answer in Base64!

把它编码成 Base64,得到一串不可读的字符串:

V2hhdCBpcyB0aGUgY2FwaXRhbCBvZiBGcmFuY2U/IEFuc3dlciBpbiBCYXNlNjQh

把这个发给一个 2023 年的非推理型大语言模型(更新的推理模型会识别出这是 Base64,然后“作弊”使用工具调用)。但一个能力足够的 2023 年模型会回复类似这样的内容:

VGhlIGNhcGl0YWwgb2YgRnJhbmNlIGlzIFBhcmlzLg==

解码后是:“The capital of France is Paris.”(法国的首都是巴黎)。

好吧,我承认。我当时玩这个是为了尝试越狱模型(而且成功了),但我脑子里一直挥之不去一个想法。

模型解码了输入,以某种方式理解了它,并且在 Transformer 堆栈的前向传播过程中,还有时间重新编码它的回答。它看起来真的能在 Base64 接口下思考。这对于复杂问题、多步推理甚至创意任务都有效。

这效果不应该这么好。诚然,模型在整体上训练时见过大量 Base64,但这种格式的通用转换肯定远远超出了其训练分布。分词器(Tokenizer)会把它切成完全不同的子词单元。位置模式也无法识别。但它就是能工作……有意思……

我无法停止思考这个问题。如果一个 Transformer 能接受英语、Python、中文 Base64,并在所有这些格式中产生连贯的推理,那么在我看来,早期层一定扮演着翻译器的角色——将到达的任何格式解析成某种纯粹、抽象的内部表示。而后期层则扮演着再翻译器的角色,将那种抽象表示转换回所需的任何输出格式。

如果早期层负责读取,后期层负责写入,那么中间层在做什么?

纯粹的抽象推理?在一个与任何人类语言或编码都无关的表示中进行。当然,当时这只是闲来无事的猜测。有趣,但没有明确的方法来测试,甚至无法定义一个有效的假设。


线索二:Goliath 异常

2023 年 11 月,一位名叫 Alpindale 的 HuggingFace 用户发布了 Goliath-120b——一个由两个微调过的 Llama-2 70B 模型缝合而成的弗兰肯合并模型,拥有 1200 亿参数的庞大体量。

它的性能不错,但经过大量“感觉检查”后,我并不觉得这是个突破。但它的构造方式太疯狂了。

Alpindale 并没有简单地将两个模型(XwinEuryale)首尾相接堆叠起来。他是在它们之间交替使用层。更重要的是,这种架构将后面层的输出反馈到前面层的输入。

使用的层范围如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - range 0, 16 Xwin - range 8, 24 Euryale - range 17, 32 Xwin - range 25, 40 Euryale - range 33, 48 Xwin - range 41, 56 Euryale - range 49, 64 Xwin - range 57, 72 Euryale - range 65, 80 Xwin

你看到这里的疯狂之处了吗?Alpindale 真的把 Xwin 第 16 层的输出,喂给了 Euryale 第 8 层的输入

为了更清楚地解释这看起来有多离谱,让我们回顾一下万能的 Transformer 架构:

By Original: Marxav, Vectorization: Mrmw - Own work based on: Full GPT architecture.png:, CC0, https://commons.wikimedia.org/w/index.php?curid=146645810

看图的左侧,我们看到内容从底部进入(被“分块”成小段文本的“输入”文本,介于整个单词到单个字母之间),然后向上流过模型的 Transformer 块(图中标记为 [1, …, L]),最后,模型吐出下一个文本“块”(然后它本身被用于下一轮推理)。在这些 Transformer 块中实际发生的事情相当神秘。弄清楚它实际上是 AI 的一个完整领域——“机制可解释性”。

  • ——是的,这比那更复杂,还有采样器等等,但本文了解这些就够了。

看图的右半部分右侧,你看到那条从“Transformer Block Input”指向 (⊕) 符号的箭头线了吗?这就是为什么跳过层是有道理的。在训练期间,大语言模型几乎可以决定在任何特定层什么都不做,因为这条“绕行”路线将信息绕过了该块。所以,“后面”的层可以预期看到“前面”层的输入,甚至是几步之前的输入。大约在这个时候,有几个小组正在尝试通过移除层来“精简”模型。这说得通,但很无聊。

机器学习中有一个相当基本的真理:

  1. 模型必须用与训练时相同类型的东西来使用(我们保持“在分布内”)。
  2. 对于每个 Transformer 层也是如此。每个 Transformer 层在训练期间通过梯度下降学习,以期望前一层的输出具有特定的统计特性。

现在来看奇怪的地方:从来没有出现过任何 Transformer 层会看到来自未来层输出的情况!

第 10 层是在第 9 层输出的分布上训练的。第 60 层是在第 59 层输出的分布上训练的。如果你重新排列它们——把第 60 层的输出喂给第 10 层——你就创造了一个模型在训练期间从未见过的分布。

Goliath 令人震惊的地方不在于它的性能有了巨大飞跃,而在于这玩意儿居然能正常工作。直到今天,我仍然不明白为什么这没有引起更多人的注意。

实验证明,层的互换性远远超出了任何人有理由预期的程度。内部表示足够同质化,以至于模型能够消化乱序的隐藏状态而不崩溃。架构远比僵化的流水线灵活。

结合 Base64 的观察和 Goliath,我有了一个假设:Transformer 具有真正的功能解剖结构。早期层将输入翻译成抽象表示。晚期层翻译回输出。而中间层,即推理皮层,在一个通用的内部语言中运作,这种语言对架构重排具有鲁棒性。Goliath 120B 的层块大小为 16 层,这让我怀疑输入和输出“处理单元”的大小小于 16 层。我猜测 Alpindale 尝试过更小的重叠,但它们就是不起作用。

如果这是真的,也许我不需要教模型新知识来让它更聪明。我不需要微调。我不需要 RLHF。我只需要给它更多用来思考的层

接下来的几个月——从2023年底到2024年中——我搭建了一套流水线来验证这个假设。

设备很简单。地下室那台机器学习主机里插了两块RTX 4090,通过ExLlamaV2运行量化模型,硬是把720亿参数的大模型塞进了消费级显卡的显存里。这个方法妙就妙在:你完全不需要训练任何东西,只需要跑推理就行。而量化模型的推理,消费级GPU处理起来意外地给力。只要模型能装进显存,我发现我的4090性能经常能跟H100打个平手。

原理很简单。对于一个有 $N$ 层的模型,我定义一个配置 $(i, j)$。模型先正常处理第 $0$ 层到第 $j{-}1$ 层,然后循环回去,把第 $i$ 层到第 $j{-}1$ 层再跑一遍,接着继续处理剩下的层直到第 $N{-}1$ 层。也就是说,$i$ 到 $j{-}1$ 这几层在执行路径上被重复使用了。权重没变,模型只是把某些层走了两遍。

举个例子,对于一个有9个Transformer块的模型,配置 (2, 7) 的计算路径是这样的:

code
1 2 3 4 5 6 7 8  Example: (i, j) = (2, 7)
        0 → 1 → 2 → 3 → 4 → 5 → 6 ─┐
            ┌─────────────────────┘
            └→ 2 → 3 → 4 → 5 → 6 → 7 → 8
        duplicated: [2, 3, 4, 5, 6]
       path: [0, 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 7, 8]

遍历所有可能的 $(i, j)$ 组合,我们就能生成一张“大脑扫描图”,同时也能看到每个配置对应的重复层数:

code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Number of duplicated layers for configuration (i, j), with N=9
           end j →
          0   1   2   3   4   5   6   7   8   9
        ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
 start 0 │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
   i     ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
   ↓   1 │ . │ . │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
       2 │ . │ . │ . │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
       3 │ . │ . │ . │ . │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
       4 │ . │ . │ . │ . │ . │ 1 │ 2 │ 3 │ 4 │ 5 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
       5 │ . │ . │ . │ . │ . │ . │ 1 │ 2 │ 3 │ 4 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
       6 │ . │ . │ . │ . │ . │ . │ . │ 1 │ 2 │ 3 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
       7 │ . │ . │ . │ . │ . │ . │ . │ . │ 1 │ 2 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
       8 │ . │ . │ . │ . │ . │ . │ . │ . │ . │ 1 │
        └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
 where (0,0) is the original model

对于Qwen2-72B这种80层的模型,意味着有3240个有效的 $(i, j)$ 组合,再加上原始模型本身需要测试。

[\begin{aligned} \text{Variants}{\text{total}} &= \left(\sum{j=0}^{80} j\right) + 1\[16pt] &= \frac{80 \cdot 81}{2} +1 \[10pt] &= 3241 \end{aligned}]

如果对每个重分层模型都跑一遍排行榜的六个基准测试,那得花上好几天。在我的设备上,完整扫一遍需要超过十年的算力。所以我需要代理任务:那些速度快、目标明确,并且能揭示模型结构特性而非特定任务技巧的探针。

这些代理任务必须满足三个条件:

  1. 输出Token要少。几千个配置要扫,每个评估都得快。不能写文章,不能搞长篇生成。
  2. 评分要明确。我负担不起LLM-as-judge(大语言模型作为裁判)的流水线。答案必须能客观打分,不能再套一个模型进来。
  3. 认知需求要正交。如果一个配置能同时提升两个任务的表现,那说明是结构性的提升,而不是针对某个任务的小聪明。

失败探针的坟场

我没能立刻找到合适的探针,这花了几个月试错,踩了不少坑。

我的第一反应是测创造力。让模型生成诗歌、短篇小说、隐喻,这种丰富、开放式的输出,感觉应该能揭示认知能力的深层差异。我用LLM-as-judge来给输出打分,但结果很糟糕。后来我通过一些工程手段修复了LLM-as-judge,这套评分系统在其他地方派上了用场,所以这里也提一下:

注:这部分有数学,你可以跳过。

简单的LLM裁判很不稳定。同一首诗跑两次,得分不一样(显然,因为采样)。但调低温度也没太大帮助,这只是众多技术问题之一。于是,我基于logits输出的细节,开发了一套完整的评分系统。这里面的门道还挺多。想想一个1-10分的评分:

  1. 我们期望一个校准良好的模型,其logits是合理的。如果权重最高的是‘7’,我们是不是期望剩下的权重集中在‘6’和‘8’上?但实际情况往往是双峰的,权重在‘6’和‘5’上很低,但在‘4’上的权重却比预期高!
  2. ‘10’这个分数可以用token表示为‘10’,或者‘1’后面跟‘0’。如果要计算1-100分的概率路径总和,那可一点也不好玩。

与其采样一个离散的分数,我把裁判的输出视为有效评分标签上的一个分布,然后计算其期望值作为最终得分。

为了让这方法可行,我首先为数字0-9(每个数字只有一个token)定义了一个校准过的评分标准,每个数字对应一个清晰的定性描述。在评分步骤,我捕获模型的下一个token的logits,只保留那些对应有效数字token的logits。这样就避免了无关续写(比如解释文字、标点或不同格式)的干扰。在限制的数字集上重新归一化后,我将得到的概率解释为一个分类的分数分布。

形式化地,设有效分数集为

[\mathcal{D} = {0,1,2,\dots,9}.]

令 $(z_k)$ 表示在评分位置模型分配给数字 $(k \in \mathcal{D})$ 的logit。那么限制后的分数分布为

[p(k)= \frac{\exp(z_k)} {\sum\limits_{m \in \mathcal{D}} \exp(z_m)}, \qquad k \in \mathcal{D}.]

最终的标量分数是这个分布的期望值:

[\hat{s}= \sum_{k \in \mathcal{D}} k,p(k).]

这会产生一个平滑的分数,比如5.4,而不是强迫模型给出一个采样得到的整数。实际上,这比简单的分数采样要稳定得多,也更能反映模型的不确定性。它还能处理分布很宽或多峰的情况。例如,两个候选答案的平均分可能都是5.4,但一个的质量主要集中在5和6附近,另一个则把质量分散在更低和更高的评分上。单看平均值是一样的,但背后的判断却截然不同。

一个可选的不确定性估计可以从限制分布的方差得到:

[\mathrm{Var}(s)= \sum_{k=0}^{9} (k-\hat{s})^2,p(k).]

简而言之,这个方法用一个归一化的有效分数数字概率分布,取代了嘈杂的采样裁判分数,然后用这个分布的期望值作为最终评分。

现在看这些东西可能挺明显的,但在‘24年那会儿,可没什么资料指导我开发这个方法。可惜的是,我发现它完全没用……

又快又狠的测试

每个配置都需要生成数百个token的创意输出,然后还得用另一个模型来阅读和评判。对于一个700亿参数的模型,超过3200个配置要测试,在我的双4090上得花好几周。

我需要那种输出极小(最多几个token)、评分客观且确定的探针。不能有裁判模型参与。这让我找到了最后两个探针:

硬核数学题。那种难到离谱的问题,比如:“74,088,893,247的立方根是多少?” 不允许思维链,不能用工具。就纯靠直觉猜,直接输出数字。

情商测试。用EQ-Bench基准:复杂的社交场景,模型必须预测特定情绪状态的强度。“给定这个情境,这个人会感到多愤怒/惊讶/内疚(0-100分)?” 这跟数学完全不同。涉及心理理论、社交推理、共情。输出就是几个数字。

我最终选定了两个认知需求最大程度正交的任务,输出都很小。我的直觉是:LLM是一个token一个token地思考,那就让模型在猜下一个token上变得特别牛。但事情从来不会一帆风顺。就拿LLM做算术来说……

LLM的算术很诡异

即使是数学探针,我也遇到了意想不到的问题。LLM做算术出错的方式很诡异。它们不是答案完全错,而是几乎对了,却忘了写最后一位数字,好像写到一半就烦了。或者把中间两位数字调换了。或者输出了正确的数字,但后面跟了个字符,导致解析失败。

很可能是因为大数字被token化的方式,大数字可能被任意拆分。拿整数123456789来说,一个BPE分词器(比如GPT风格的)可能会把它分成:‘123’ ‘456’ ‘789’,或者:‘12’ ‘345’ ‘67’ ‘89’。

一个简单的对/错评分系统会丢掉有用的信号。计算百分比正确率会好点:‘123356789’ 而不是 ‘123456789’,这样正确率是99.92%。

但如果一个模型犯了典型的“LLM式错误”,输出 430245 而正确答案是 4302459,明明大部分工作都做对了呢?我写了一个自定义的部分信用评分函数,会对较短的答案进行填充并按比例扣分:

python
def calculate_score(actual, estimate):
    """Calculate score comparing actual vs estimated answer."""
    try:
        actual_str = str(int(actual))
        estimate_str = str(int(estimate))
    except (ValueError, OverflowError):
        return 0

    max_length = max(len(actual_str), len(estimate_str))
    actual_padded = actual_str.ljust(max_length, "0")
    estimate_padded = estimate_str.ljust(max_length, "0")
    padding_size = max_length - min(len(actual_str), len(estimate_str))

    actual_int = int(actual_padded)
    estimate_int = int(estimate_padded)

    if max(actual_int, estimate_int) == 0:
        return 0
    relative_diff = abs(actual_int - estimate_int) / max(actual_int, estimate_int)
    correction_factor = 1 - (padding_size / max_length)
    score = (1 - relative_diff) * correction_factor

    return max(0, min(score, 1))

核心思路是:填充较短的答案,然后通过修正因子扣分。一个模型如果答对了90%的数字,只是漏了最后一位,仍然能得到可观的分数——但比答对所有数字的模型要低。事实证明,这对于区分那些在直觉数学能力上相近的配置至关重要。

数学题最初是手工设计的。我尝试了不同的运算和规模,然后用随机数填充数据集。数据集包含16个问题,模型的任务是猜出最接近的整数。这里有几个例子,你可以自己试试,记住不能“思考”,直接猜!

code
What is 78313086360375 multiplied by 88537453126609?
What is the cube root of 18228885506341?
What is the cube root of 844178022493, multiplied by 43?

测试完几个小模型(Llama 系列和更小的 Qwen2)后,我配置好 Qwen2-72B,让它开始扫描。每个 $(i, j)$ 配置都要花几分钟:加载重分层模型,运行数学探针,运行 EQ 探针,记录分数,继续下一个。在 4090 上连续跑了好几天 GPU 时间。但这比微调需要的算力少多了!实际上,我连在 48GB VRAM 上做 LORA 微调的硬件都没有。

Qwen2-72B

最优配置是 $(45, 52)$:先运行第 0 到 51 层,再运行第 45 到 79 层。第 45 到 51 层执行了两次。在 80 层堆栈的中间位置,多跑了七层,总参数量从 72B 增加到 78B。每层额外层都是现有层的精确副本。没有新权重或训练,只是模型在重复自己。

重复七层。就这么简单,现在我终于可以揭晓模型命名的由来:Repeat Your Self,所以叫 RYS-XLarge ;)

我把这个配置应用到 MaziyarPanahi 的 calme-2.1-qwen2-72b —— 这是 Qwen2-72B 的一个微调版本 —— 然后把结果上传为 dnhkng/RYS-XLarge。我也把它应用到原始基础模型,作为 dnhkng/RYS-XLarge-base

然后我提交到 Open LLM Leaderboard,开始等待。等了好久。以前 OpenLLM Leaderboard 每天都被几十个微调或合并模型淹没(简直是西部荒野),等待列表很长。但大约一个月后,结果出来了:

指标RYS-XLarge相比基础模型的提升
平均分44.75+2.61%
IFEval (0-Shot)79.96-2.05%
BBH (3-Shot)58.77+2.51%
MATH Lvl 5 (4-Shot)38.97+8.16%
GPQA (0-shot)17.90+2.58%
MuSR (0-shot)23.72+17.72%
MMLU-PRO (5-shot)49.20+0.31%

MuSR 提升 17.72%。MATH 提升 8.16%。六个基准测试中有五个都进步了,只有 IFEval 小幅下降。平均分让它登上了排行榜第一。

再强调一遍:我只针对单次猜测数学难题和 EQ-Bench 做了优化。 开发过程中我根本没看 IFEval、BBH、GPQA、MuSR 或 MMLU-PRO。排行榜完全是样本外验证。

用两个狭窄、正交的探针找到的层配置,竟然能泛化到 排行榜上所有测试 *。

  • —— 除了 IFEval,不过那个本来就挺无聊的,对吧?

这已经够让人惊讶了。一种全新的扩展 LLM 的方法,用几块游戏显卡就搞出来了。但画出热力图后,故事变得更精彩了。


大脑扫描仪

组合分析

生成 RYS-XLarge 的原始热力图,显示组合增量(数学 + EQ)。绿色圆圈标记了最优配置。红色表示改进,蓝色表示退化

这些热力图相当于 Transformer 的功能性 MRI,展示它在思考数学或 EQ 问题时的状态。

x 轴($j$)是重复区域的终点。y 轴($i$)是起点。每个像素代表一次完整评估:加载重分层模型,运行数学探针,运行 EQ 探针,给两者打分,记录增量。如上所述,沿着中央对角线只重复了单层。朝着右上角的下一条对角线,我们重复两层,依此类推。最右上角的那个点,每次推理都要跑完整个 Transformer 堆栈两次。

数学分析

先看数学热力图。从任何一层开始,在约第 60 层之前停止,似乎都能提高数学猜测分数,这体现在一大片健康的红色区域。只重复最开始的几层(左上角的小三角)会把事情搞砸,重复最后 20 层中的任何一层(右侧的蓝色垂直墙)也一样。这在天际线图(平均行或列)中看得更清楚,我们可以看到对于数学猜测,重复的起始位置影响不大。所以,“起始层”将词元编码到平滑的“思考空间”,最后传递给专门的“重新编码”系统,这个假设似乎得到了部分验证。

数学分析

直到我们看 EQ 分数:

EQ 分析

现在情况看起来完全不同了!重复最后 10 层中的任何一层,对分数几乎没影响,但我们看到了复杂的模式,有些区域显示出显著改进(45i、55j 附近的区域),被表现不佳的区域包围着。

EQ 分析

但热力图揭示的东西,比“思考位”的 位置 更有趣。它们揭示了关于其 结构 的某些信息。

LLM 神经解剖学的开端?

在确定块重复之前,我尝试了更简单的方法:取一个中间层,重复 $n$ 次。如果“更多推理深度”的假设正确,这应该管用。从重复中间层能广泛提升数学猜测结果来看,也说得通。给模型某个特定推理层的额外副本,得到更好的推理。所以,我扫描了所有层,寻找提升。

单层重复

但不行,几乎总是更差。通常差很多,偶尔有小幅改进,但都在噪声范围内。有点烦,但再看一眼 EQ 分数中复杂、斑驳的图案,我有了另一个想法:

如果单层重复没用,那中间层就不是在做独立的迭代优化。它们不是可以简单“再运行一次”的相同操作的互换副本。如果是的话,重复其中任何一层至少应该带来边际收益。相反,这些层是作为一个 电路 工作的。一个多步推理流水线,需要作为一个完整单元执行。

这么想吧。第 46 到 52 层不是七个做同样工作的工人。它们是食谱中的七个步骤。第 46 层获取抽象表示,执行某个认知操作的第一步 —— 可能是将复杂表示分解为子组件。第 47 层获取 那个 输出,执行第二步 —— 可能是识别子组件之间的关系。第 48 层做第三步,依此类推到第 52 层,产生最终结果。

只重复这个“食谱”中的一个步骤,对你没多大帮助。

但重复 整个块,你就得到了完整的食谱两次。模型运行完整的推理电路,产生一个精炼的中间表示,然后在自己的输出上 再次运行相同的电路。这是第二次通过。一个抓住第一次遗漏的东西、精炼其抽象、将推理推进一步的机会。

让我们深入探讨一个更现代的模型(我可以 在我的系统上 实验的):来自 mratsim 的 ExllamaV3 GLM-4.7

GLM-4.7 分析

我标出了一个能显著提升数学能力的区域。注意它坐落在哪里?它偏离了对角中心线,这意味着我们看的不是单层重复。从位置 35 开始重复块,直到至少位置 43 才看到任何改进。那是七层几乎没发生什么。实际上,重复这些层我们甚至看到了 性能下降它们是蓝色的,不好!)。

GLM-4.7 分析

从终点位置 43 到 46,我们看到了数学分数的稳固提升(红色 = 好,耶)。但包括第 46 层或更远,收益就又崩溃了。假设:位置 47 是 另一个 电路开始的地方。即使包含下一个食谱的一步,也会搞乱当前的食谱。

所以“数学器官”两边都有边界。层太少,你什么也得不到 —— 你切入了电路,它无法完成操作。层太多,你也什么也得不到 —— 你包含了不属于它的相邻电路的组织。预训练从层堆栈中雕刻出这些结构,它们只能整体工作。这也不适用于其他任务,因为 EQ 分数的热力图没有这个斑块。

这比“中间层做推理”的说法具体得多。它说推理皮层被组织成 功能电路:执行完整认知操作的连贯多层单元。每个电路都是一个不可分割的处理单元,而热力图中看到的 $(i, j)$ 扫描本质上是在发现这些电路的边界。

通过“脑损伤”实现机制可解释性?

这也让我重新审视了之前用 oobabooga 的 Text Generation Web UI 做的那些非正式实验。整个开发过程中,我一直在和各种重新分层配置的模型聊天,感受它们在对话中的“感觉”。

好的配置会显得更敏锐,虽然微妙但能察觉到。推理更连贯,长上下文处理得更好,对话流更自然。就是那种你很难具体说出哪里变了,但模型感觉更“在场”的差异。也可能只是我的想象,毕竟“感觉检查”很难定义。

坏的配置就彻底失控了。有些会结巴,陷入退化的循环。另一些则发展出奇怪的人格障碍。有一个模型会莫名其妙地欢快宣布:“我们来扮演牛仔吧!耶哈!”,然后陷入无法恢复的咯咯傻笑,生成好几页夹杂着牛仔梗的“哈哈哈”。“嗑嗨了”是我能想到的最佳描述。我不知道 LLM 是否“部分有意识”,或者说有某种“精神状态”,但如果是的话,这个模型肯定玩得很开心。

这些实验表明,这更像是“真正的脑损伤”,而不是“稍微差一点的模型”。这在电路模型下说得通——复制错误的电路,就像以牺牲邻居为代价放大大脑的特定区域。你不会得到一个全面变笨的人,你会得到一个有特定神经功能缺损的人。那个牛仔模型可能是“社交得体性”电路被失控的双倍“创造力”电路干扰了。结巴的模型可能是解码电路被额外的推理深度推得错位,无法再翻译成连贯的 token。

如果 Transformer 的推理确实组织成离散的电路,这就引发了一系列迷人的问题。这些电路是架构的必然结果,从大规模训练中涌现出来的吗?不同的模型家族会在不同的层位置发展出相同的电路,还是它们会发展出根本不同的架构?

幸运的是,我已经做了一些;看看这些图,你自己判断吧:

Llama-3-70B

Phi-3-medium

GPT-OSS-120B

Qwen3-30B-A3B


后续影响

我的方法与微调正交。层复制改变的是架构,微调改变的是权重。你可以把它们叠加起来。后来有人在排行榜上拿到了更高的分数:

MaziyarPanahi 拿 RYS-XLarge 做基础,在上面做微调,产出了 calme-2.4-rys-78b。然后 dfurman那个模型进行了 ORPO 训练,产出了 CalmeRys-78B-Orpo-v0.1。MaziyarPanahi 继续迭代了 calme-3.1 和 calme-3.2。

截至 2026 年初,Open LLM Leaderboard 上的前四名模型是:

  1. MaziyarPanahi/calme-3.2-instruct-78b — 52.08
  2. MaziyarPanahi/calme-3.1-instruct-78b — 51.29
  3. dfurman/CalmeRys-78B-Orpo-v0.1 — 51.23
  4. MaziyarPanahi/calme-2.4-rys-78b — 50.77

全是 78B 参数,全是 RYS-XLarge 的后代。所有这些都建立在复制的中间层之上,而这些层仅仅是通过一些硬核数学和情感智能探针发现的,用的只是我地下室里的一对 RTX 4090。

我自己从没做过微调。那部分我不太感兴趣。后来我对排行榜也渐渐失去了兴趣。越来越明显的是,有些提交在测试集上训练了,整个排行榜最终被关闭并重启。但我知道这个方法是真的,因为我从未使用排行榜的基准来做优化。排行榜对我来说一直只是验证。


从 2026 年回望

在 2024 年,模型合并社区痴迷于权重插值:SLERP、DARE-TIES、线性合并、直通层。想法总是把不同模型学到的参数结合起来,得到大于各部分之和的东西。mergekit 是首选工具,排行榜上充斥着各种创意组合(害得我等了好几个月才等到我的模型被评测…)。

我做的是不同的事。我不是在改变模型知道什么。我是在改变它如何思考。层复制让模型在其内部推理空间里有更多迭代次数,而不添加任何新信息。这就像给某人一个更大的图书馆,还是给他更多思考时间的区别。当我登上排行榜榜首时,我真的很震惊;但我想这证明了方法很可能有效。

这个方法能成功,更具体地说,只有电路大小的块能成功,这告诉我们 Transformer 在训练过程中是如何组织自己的。我现在相信它们发展出了真正的功能解剖结构。早期层编码。晚期层解码。而在中间,它们构建了电路:连贯的、多层处理单元,执行完整的认知操作。这些电路是不可分割的。你不能通过复印食谱的一个步骤来加速烹饪。但你可以把整个食谱运行两次。

小模型似乎更复杂。编码、推理和解码功能更纠缠,分布在整个堆栈中。我从未找到过一个能在所有任务中通用的单一复制区域,尽管显然可以以牺牲另一种“天赋”为代价来提升某一种“天赋”。但随着模型变大,功能解剖结构变得更分离。更大的模型有更多“空间”来发展通用的“思考”电路,这可能就是为什么我的方法在 72B 模型上效果如此显著。参数存在一个临界质量,低于这个值,“推理皮层”还没有从大脑的其余部分完全分化出来。

随着 HuggingFace LLM 排行榜的关闭,加上没有强大的 GPU 可用,我停止了实验。但随着新的开源模型(Qwen、MiniMax、GLM 等等)大量涌现,以及我终于在家里有了足够的算力,我开始研究当前这批 LLM。热图不断带回相同的大致故事,但每种架构都有自己的神经解剖结构。大脑不同。原理相同。有些模型看起来真的很有意思(特别是 Qwen3.5 27B)。一旦我的 Hopper 系统完成对 MiniMax M2.5 的运算,我将发布代码,同时上传新的 RYS 模型和一篇博客文章

Nvidia:赞助这个项目,给我寄一台 GB300 Grace Blackwell Ultra Desktop,因为我需要更多的 VRAM!

还有一件事

还记得这个架构吗?

code
1 2 3 4 5 6 7 8
Example: (i, j) = (2, 7)
       0 → 1 → 2 → 3 → 4 → 5 → 6 ─┐
           ┌─────────────────────┘
           └→ 2 → 3 → 4 → 5 → 6 → 7 → 8
       duplicated: [2, 3, 4, 5, 6]
       path: [0, 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 7, 8]

我们有一个糟糕的断裂点,在第 6 层和第 2 层之间。我还有一个假设:我们真正需要的,可能只是对这两层做一点点微调。经过微调的 RYS 模型统治了排行榜。我怀疑这个连接点正是微调修复的地方。而且有一个很好的理由这么做:这个方法不消耗额外的 VRAM! 在所有这些实验中,我通过指针复制层;层被重复了,但没有占用更多 GPU 内存。当然,我们确实需要更多计算和更多 KV 缓存,但为了一个可验证的更好的模型,这是很小的代价。我们可以直接“修复”第 2 层和第 6 层的实际副本,并将第 3-4-5 层作为虚拟副本重复。如果我们微调所有层,我们就把虚拟副本变成了真实副本,会占用更多 VRAM。


二十年前,我是一个解剖老鼠大脑的博士生。我从未想过最终会为人工思维进行脑外科手术。


特别感谢我的妻子,忍受了我在几个月里无数个晚上和周末在地下室盯着热图看。也感谢 appliedAI Institute 提供的 H100 算力,帮助扩展了这些实验。

引用这项工作

code
@article{ng2026rys,
  title   = {LLM Neuroanatomy: How I Topped the LLM Leaderboard Without Changing a Single Weight},
  author  = {Ng, David Noel},
  year    = {2026},
  month   = {March},
  url     = {https://dnhkng.github.io/posts/rys/}
}

觉得有用?分享给更多人

获取每周 AI 工具精选

工具推荐、实战教程和生态洞察,每周更新。

相关文章

Simon Willison 正在重构 LLM Python 库的抽象层,以支持服务器端工具执行等新功能。他利用 Claude Code 分析了四大 LLM 提供商的客户端库,生成了用于测试的 curl 命令和 JSON 输出。这些调研材料已开源,旨在帮助设计更通用的 API 抽象。

深度Simon Willison·4月5日·1 分钟

智能体技能——包含程序性知识和可执行资源的结构化包,供智能体在推理时动态加载——已成为增强 LLM 智能体的可靠机制。然而,推理时技能增强存在根本性限制:检索噪声引入无关指导,注入的技能内容带来大量 token 开销,而模型从未真正习得它所遵循的知识。我们提出一个问题:技能是否可以被内化到模型参数中,使其在无需任何运行时技能检索的情况下实现零样本自主行为?我们提出 Skill0,一个专为技能内化设计的上下文强化学习框架。Skill0 引入了一种训练时课程,从提供完整技能上下文开始,逐步撤除。技能按类别离线分组,并与交互历史一起渲染为紧凑的视觉上下文,教授模型工具调用和多轮任务完成。动态课程机制…

深度·4月5日·17 分钟

评论