阶段 8 · 前沿范式

自适应计算:1+1 和证明定理
不该花一样多的算力

接着上一章《神经符号与可验证推理》:「想多久」能按题目难度分配, 「走多少层」为什么不能?
标准前馈网络是固定计算量的——不管输入是「这是猫还是狗」还是 「用黎曼猜想推一下这个」,层数、矩阵一模一样。这在工程上简单,在道理上荒唐。

1

算力花在了不需要的地方

一个 70B 模型回答「1+1 等于几」,消耗的 FLOPs 和回答 「分析这段代码的时间复杂度」是一模一样的。

现实情况固定计算量的做法本该怎么做
很多输入其实很简单 照样跑满全部层数 中间层就有把握了 → 提前收工
一小部分输入特别难 跑到最后也没想清楚,也只能给答案 再想想 —— 多花算力反复推敲
MoE 已经做了一半 每次只激活一部分专家(参数维度上省) 但它层数还是固定的——该走的层一层不少

动态分配算力有三个地方可动手:网络的深度(中间层够确定就不往下走)、 每层用多少参数(只激活一部分,即 MoE,阶段 5 讲过)、 推几步(难就多想几轮,阶段 5 的 reasoning 那章)。 这一章只讲最直接的那一个——深度,因为它是唯一能在推理时动态改变的。

🎯 类比

认知科学里有个很贴切的划分:系统 1(快、直觉、省力)和 系统 2(慢、费力、准确)。
人不会对每个问题都启动深思熟虑模式。「今天几号」用系统 1, 「这个合同有什么法律风险」才切到系统 2。
固定计算量的神经网络,等于对所有问题都强制用系统 2 的全部流程。 这个类比管到「该不该多花力气」为止:人自己判断用哪种思考,网络只认一个阈值和一个概率数。

2

中间层各自挂一个出口

标准网络只有最后一个出口。早退架构在中间几层各自挂一个小的分类头, 每个出口都能给出预测和置信度。

结构示意

💡 关键的训练改动只有一处

损失函数(L,越小越好)从「最后一个出口的损失」变成「所有出口损失之和」:
L = L出口1 + L出口2 + L出口3

这样逼着中间层也得学好。不然中间出口乱猜, 置信度不可信,早退就成了随机提前收工。 辅助出口要在训练时一起学,所以早退不是给训好的模型加几个头就能用——通常要重训。

真算 · 每个出口各自有多大把握(240 个测试样本)

3

每层的置信度是从哪来的

下面这个网络有 3 个出口。每个置信度都是当前样本一路走到那一层之后, 经过该出口 softmax 得到的输出;阈值 τ 就是「把握到多少才允许退出」。

核心大图 · 逐层置信度决定在第几层退出

💡 核心大图:点三个按钮,看它退在哪一层

点「容易的样本」「随机的样本」「难的样本」,各试几次:
· 容易的样本(离边界很远的点)——第一层出口的置信度就很高, 这时只跑 1 层,省掉约 2/3 的算力(这个演示共 3 层)
· 难的样本(正好落在两个类中间的点)——它一路走到最后, 置信度都不高。这种样本必须跑满,早退对它没有意义
早退的价值不来自「所有输入都更快」,而来自「大部分输入其实很简单」。

真算 · 它说自己有多准,和它实际有多准

4

整批一起看:省下多少算力

要算的账是:把置信度阈值调高调低,能省多少算力、掉多少准确率。 下面是 240 个测试样本的真实统计,准确率算的是它实际退出的那个出口给出的答案。 阈值没有标准答案,按你能接受的准确率在验证集上选。

互动 · 阈值 vs 省下的算力 vs 准确率

平均用了几层
—
省下的算力
—
准确率
—
相比跑满的变化(+ = 更好)
—

⚠️ 注意「省下的算力」不等于「更快的墙钟时间」

这里算的是理论 FLOPs(模型要做的乘法次数)。真实 GPU 上,早退的收益会大打折扣—— 原因见第 6 节。所以看到论文里写「省 60% 算力」, 别直接理解成「快 2.5 倍」(墙钟时间 = 从开始到结束实际花的时间)。

5

其他路子:有的省,有的反着来

三种省法,动的是哪一刀

方法在哪一维省机制
Early Exit
2016 起
深度 每层挂辅助分类头,置信度够高就返回。最直接,也最容易实现
ACT
Adaptive Computation Time
深度 让模型自己学「该想几步」——用一个额外的输出预测「还要不要再算」, 用「思考成本」惩罚它多想。理论上优雅,实际用起来要小心调参
PonderNet深度 ACT 的概率化版本。把「停在第几步」变成一个可微的概率分布(能对它求导、 能端到端训练),再给每一步一个固定概率继续往下想(几何分布),训练稳定得多
CALM
2022
深度 把早退用在大语言模型上:用当前层的隐状态和前一层的隐状态做对比, 够接近就跳过。不需要额外的分类头
MoE
阶段 5
参数 每层只激活一部分专家。层数不变,但每层只用一部分参数
测试时计算
阶段 5
推理步数 让模型「想久一点」——生成更长的思维链、采样多个候选再投票。 和早退方向相反:这个是往多了花
级联 Cascade模型大小 先用小模型答,置信度低再升级到大模型。 工业界最实用的自适应计算形式,因为它不需要改模型结构
投机解码
阶段 6
验证成本 小模型猜、大模型验。本质也是一种「大部分情况走便宜路径」

三者的区别一句话:早退省深度、MoE 省宽度、测试时计算花步数。 前两个省钱,第三个花钱,但目标一致——把算力从不需要的地方挪到需要的地方。

M

数学 · 退出决定是一道不等式

前面说「置信度够高就从这一层返回」。整件事只有一道不等式, 但读起来最容易空——拿哪个数去比?比出来的「第一个」又是什么意思? 第一个达标的出口记作 l*(读作「L 星」),一张图看完整件事。

互动 · 拉高虚线,看出口一个个掉下去

第一个越过 τ 的出口
—
它在那一层的置信度
—
算力(跑满 = 100%)
—

互动 · 每个符号管图上的哪一块

卡片下面那条横条是期望算力:每个出口都能拦住一部分样本, 它贡献的算力 = (用掉的层数 l) × (停在该层的样本比例 P)。全批平均要跑几层 = Σ l·P(停在第 l 层),图里那条横条的三个格子就是这么来的。这里默认每层开销一样,所以算力直接用层数记; 真实网络每层的计算量不同,账要按 FLOPs 各自加权。

🎬 自己验一遍

把虚线往上拖:出口 1 先掉下去,出口 2 掉下去……最后只剩一个出口够得着。 虚线越高,走的路越长。那个「第一个够得着的出口」,就是公式里的 l*。

6

GPU 为什么不喜欢它

代价说明什么时候真的会痛 → 换什么
动态控制流 vs GPU 并行 这是最根本的矛盾。GPU 快的唯一原因是同一个指令同时作用在成千上万个数据上。 但如果 batch 里第 7 个样本在第 2 层就退出了、第 13 个要跑到第 3 层—— 它们没法再放在同一个矩阵乘法里。
结果是:省了 FLOPs,却没省时间。
输入难度参差、又要求低延迟 → 别用早退,改用不改结构的级联 / 投机解码
置信度不等于正确率 神经网络普遍偏自信——它会在错误答案上给出 0.95 的概率。 早退正好放大了这个问题的危害:你是在模型最自信的时候相信它。 所以早退必须配置信度校准(拿验证样本拟合一个温度,把概率调到可信) 模型偏自信、或输入是训练时没见过的分布 → 先校准;校准后仍不可信就别用早退
辅助出口本身有开销 每个出口都是一个小的分类头。虽然参数量不大,但它们要参与训练、 要占显存、而且会干扰主干(网络的主体层)的表示学习—— 网络被迫让中间层也具备分类能力,而不是纯粹地为后续层服务 层很窄、显存紧 → 少挂几个出口,或只在中间少数几层挂
大 batch 下收益被摊薄 批量推理时,即使 80% 的样本早退了,剩下的 20% 仍然要跑满。 而 GPU 是按最长的那条路径计时的—— 除非你批内分组(把已退出的样本从 batch 里换出去,空出槽位接新样本)。 这就是连续批处理要解决的问题(阶段 6) 吞吐优先的在线服务 → 批内分组 / 连续批处理;否则早退只省纸面算力
训练更麻烦 多出口联合训练需要调各出口的损失权重。ACT 这类「自己学该想几步」的方法 尤其难训——它有个退化解:永远只算一步,然后在训练集上碰运气。 必须用正则项专门惩罚这种偷懒 想直接拿现成模型改 → 得重训;ACT 类还要加正则,防「永远只算一步」的退化解

真算 · 省下来的 FLOPs,为什么换不成墙钟时间

省下的算力
—
省下的时间
—

真算 · 辅助出口本身要占多少参数

⚠️ 所以工业界实际在用的是哪个

不是早退。是级联(cascade)和投机解码。
原因很实际:它们不需要改模型结构。
· 级联:训一个小模型和一个大模型,先用小的答,置信度低再升级。 换人时大模型拿到的是原问题、从头算一遍——小模型已经说出口的中间状态不会传过去。
· 投机解码:小模型猜、大模型验,验证通过就一次接受多个 token。
两者都把「自适应」放在了模型外面的调度层,而不是塞进网络内部。 这样 GPU 仍然能高效并行,工程上也容易部署。
这是「算法上更优雅」和「工程上更可行」之间的一次典型妥协。

🎯 类比

早退像让每个员工自己决定几点下班——理论上最高效,但你要给他们排班、 统计工时、还得处理协作问题。
级联像设两个岗位:初级客服先接,搞不定转高级——流程固定、好管理, 虽然不如前者精细,但落地成本低得多。
大公司几乎总是选后者。

7

小结

它对应哪条线 ② 没有免费午餐 → 必须有归纳偏置——想省算力, 就必须先对「输入长什么样」下注。早退赌的是输入难度的分布严重不均: 大部分输入其实很简单
一句话 它把「算力」从一个固定常数改成一个跟着输入难度走的变量: 简单的输入走浅一点,难的输入走深一点,用推理时的动态决策 代替「所有输入一视同仁」的固定前向。
它牺牲了什么 牺牲了整齐的形状,而形状是 GPU 效率的全部来源。 一旦每个样本在第几层退出各不相同,它们就再也放不进同一个矩阵乘法里 (第 6 节第一行)——省下来的 FLOPs 换不成墙钟时间。 代价还包括:辅助出口要占显存、训练要调权重, 而且网络被迫让中间层也学会分类,不再纯粹为后面的层服务
🎬 自己验一遍

回到第 3 节那张核心大图。先点「容易的样本」,阈值拖到 0.90—— 第一层出口就过了线,后面两层直接不跑。再点「难的样本」——它一路走到底,每一层都不够自信。 这两个按钮之间的差别,就是这一章的全部赌注:你得先相信「大部分样本长得像前者」, 早退才划得来;如果所有样本都像后者,早退一分钱都省不下。

再往下挖一层:这条赌注什么时候会输?

它假设什么时候不成立
大部分输入其实很简单(难度分布很偏) 任务本身就很难且均匀(每一个输入都要想很久)。 这时平均退出层数会贴着最深层走,辅助出口纯属白烧显存
置信度高 ≈ 答对 神经网络普遍偏自信——它会在错答案上给 0.95(第 6 节第二行), 早退等于把「自信的错误」提前固化成最终答案
省下的算力能换成时间 在 GPU 上不成立。GPU 快的原因是一条指令同时作用在成千上万个数据上, 按最长的那条路径计时。80% 的样本早退了,那 20% 仍然要跑满,整批就得陪着等

它在暗线里站在哪

暗线这一章的回答
A 信息流动 输入输出的形状没变,变的是「这一批数据走完的是不是一块矩形」: 固定计算量时是整齐的矩形,早退后变成参差不齐的长条,同一时刻大家不再做同一件事。 完整的硬件账写在《硬件与算力账本》里
E 它假设了什么 两条缺一不可:① 输入的难度分布严重不均;② 置信度高的地方通常就是答对的地方。 第一条错了早退省不下任何算力,第二条错了它会把「自信的错误」留下来
F 违背了哪个直觉 「省了 60% 算力」≠「快一倍多」——GPU 按最长的那条路径计时。 更反直觉的是:算法上更优雅的早退,输给了工程上更土的级联和投机解码
🎯 前后钩子

它接住了上一章的什么:《神经符号与可验证推理》刚问过 「想多久」能不能按题目难度分配,这一章接着问「走多少层」。 更早的《MoE 混合专家》只是旁证。

它给下一章留了什么:既然「算多少」可以跟着输入变, 那「记住什么、忘记什么」是不是也可以?《持续学习与遗忘》要问的就是这个问题。

一句话带进自适应计算

固定计算量假设所有输入一样难,而事实不是:早退给中间层挂出口,用「所有出口损失之和」训练, 让容易的输入走浅、难的走深。
但省下的 FLOPs 换不成墙钟时间——动态控制流打散了 GPU 的批, 所以真正落地的是把自适应放在模型外面的级联和投机解码。

9

拓展阅读

上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。

📄 这一章的说法从哪来

💻 工业界怎么写

第 6 节的结论是:真正上线的是投机解码,不是早退。 它在代码里长什么样?

∑ 更严格的形式