SMELT:把预算砍到和对手一样,循环Transformer还是先到终点

号称白嫖深度,这笔账真的白嫖了吗

把同一段代码调用两次,和把代码复制两份、各自修改,算力上几乎没差别,差别全在参数量:前者只有一份代码,后者有两份。循环 Transformer 赌的就是"前者够了"。它把同一组网络层反复执行两次,深度凭空多了一轮,参数却只付一份。这个算盘 2018 年的 Universal Transformer 打过,2025 年复兴循环语言模型的 Huginn 又打了一次。但这些年几乎所有对比都钉死"模型大小"再分胜负,循环模型却暗中把每个 token 多算了一遍。赢,到底是架构赢的,还是额外算力买来的?SMELT Huginn

要回答循环是否真的白嫖,先看它声称白嫖的那份"深度"到底是什么。循环 Transformer 把"层数"和"参数量"这两件原本绑死的事解开了:普通 Transformer 每一层一套独立参数,层数意味着几份参数;循环版本反复复用同一组层,物理上还是那几层,实际走过的深度却多了一倍。这个"实际走过的深度"叫有效深度(effective depth),它与参数份数脱钩,概念的最初定义来自 Universal Transformer。UT 标准 Transformer 的深度被层数钉死,共享层块的出现把它变成了可以单独调节的旋钮,这正是 SMELT 打算审计的那份资产。一张图就能看清这个结构。

图注:Universal Transformer 结构图:自注意力子块与过渡子块组成一个层块,配合位置与步数嵌入,同一组参数沿底部串行复用多次。层数在这里与参数份数脱钩,"有效深度"概念由此发端。UT

要回答循环是否真的白嫖,再看这笔账为什么难算。图里量不出的是成本:同一个块跑两遍,每个 token 的浮点运算量就上去了,参数却一分不多花。固定大小的模型比较里,循环方等于偷偷多干了一份活。也有人尝试把账算清:有人钉死有效深度再比,发现循环的深度红利要打折扣;有人从参数侧对齐,发现循环次数得和数据量一起涨。这两条路都只对了一本账,还差得远,SMELT 要补的正是这份缺口。

要回答循环是否真的白嫖,最后看 SMELT 打算怎么审。它的立场很直接:要问循环值不值,就把三本账同时摆上台面,一本对不齐,比较里就混进了别的变量。这笔账为什么现在非算不可?因为 2025 年后循环语言模型密集回归,Huginn 用 latent depth 在推理时做题,MoR 给每个 token 动态分配循环次数,2026 年春天 Schwethelm 和 Parcae 又前后脚把"循环值多少"写成了缩放定律,各家都搭了自己的擂台,却没有一个能同时回答"训练时到底省不省算力"。而这个问题的答案还关系到一堆实在的好处:同样的深度只花一份参数,训练省显存、推理省存储,Parcae 甚至报过 770M 的循环模型在部分下游任务上与 1.3B 的普通 Transformer 打平。如果循环真的划算,等于给整个参数效率的账本翻了一页。SMELT 挑的正是这块空白。

想审判循环,先得把三本账对平:算力、参数、缓存

三本账各有各的名字,付的也是三种不同的钱。第一本,每 token FLOPs:处理一个 token 平均要做的浮点运算量,它决定训练和推理烧掉多少算力,账单走 GPU 时长。第二本,总非嵌入参数:embedding 之外的全部参数,它决定模型的容量上限,账单走显存。第三本,KV cache:推理时缓存历史键值所需的内存,它决定模型能服务多长的上下文,账单走推理时的带宽。任何一本对不齐,循环和普通模型的比较就失去了意义。

难的是同时对齐。缩窄隐藏宽度能压低第一本账,参数却跟着缩水;多塞参数会把第二本账撑大;KV cache 还得另外找补。凭什么能同时做到?答案藏在底座里:SMELT 选了稀疏 MoE(Mixture of Experts,专家混合)当基座。MoE 把总参数和每 token 算力解耦:总参数随专家数量增长,但每个 token 只激活少数几个专家。Switch

解码器前馈层换成稀疏 Switch 层后,每个 token 的路由是独立进行的。

图注:Switch Transformer 编码块示意:原稠密前馈层替换为稀疏 Switch 层,两个 token 各自被路由器分到四个专家之一,只有被选中的专家输出并乘上门控值返回。总参数随专家数增长,每个 token 的算力却只取决于被激活的少数专家。Switch

正因为每 token 算力与总参数脱钩,循环多走一遍多出来的算力,才能靠"缩窄宽度、补足专家数"摊回去。摊回去的账目长什么样,200M 规模的配置单写得清清楚楚。基线是一个 12 层 Transformer,隐藏宽度 1280,每层 192 个专家;循环版把它改成 12 层中中间 6 层循环两次,有效深度变成 18,宽度缩到 1056 省算力,专家加到 288 个补参数,head size 和 GQA(分组查询注意力)比例再调一调稳住 KV cache。最终三本账:每 token FLOPs 只差 2.9%(1.37e9),总参数差 0.4%(3.89e9),KV cache 偏差在 4% 以内。SMELT

账本对平手段200M 配置示例剩余偏差
每 token FLOPs缩窄隐藏宽度 H1280 → 1056+2.9%
总非嵌入参数增加每层专家数192 → 288+0.4%
KV cache调 head size 与 GQA 比例论文未逐档列出小于 4%

第三本账为什么值得单独列?因为循环不只是多烧算力。多执行一遍共享层,就多一层要缓存的键值,上下文一长,KV cache 也会跟着膨胀。算力和参数都对平了,循环方还可能在这一本账上领先,所以它必须被单独按住。

为什么非 MoE 不可?稠密模型里,把宽度砍半给循环腾算力,容量立刻跟着腰斩,循环多走一遍也补不回来;想让参数变多而算力不涨,只有稀疏激活做得到。MoE 把"参数量"和"每 token 算力"拆成两根独立的轴,循环才可能在不亏容量的前提下把多走一遍的算力摊掉。这不是锦上添花,是整个对账协议成立的前提。

当代 MoE 也沿着同一思路演化:DeepSeekMoE 把专家切得更细、并留几个始终激活的共享专家负责共性知识,同样是参数与算力解耦的延伸。DeepSeekMoE 擂台搭好了,循环这一方该怎么打?循环哪里、循环几次才最划算?

循环哪里、循环几次才最赚?三组消融逼出配方

循环的枪口可以对着任意一段层,也可以循环任意多次。SMELT 在 200M 规模上做了三组消融,把答案一步步逼出来。第一组扫"循环跨度":固定循环两次,扫描循环哪一段,中间 50% 处验证损失取最小,约 95% 稀疏度下为 1.8517,约 85% 稀疏度下为 1.9257。第二组比"有效深宽比":同样物理 12 层,循环后有效深度 18 层,验证损失、DCLM Core、DCLM Completion 三项指标全部胜过基线。第三组扫"循环次数":1 到 4 次都试过,两次最优,验证损失 1.9257;三次回退到 1.9385,四次也只有 1.9360。有意思的是,DCLM Core 在约 95% 稀疏度下的峰值落在 67% 跨度处,与验证损失的排序相反;论文以验证损失为选择依据,把下游指标当作一致性检查。

为什么循环不是越多越好?这个反直觉点恰恰来自对账本身:FLOPs 被钉死,循环次数每加一,模型宽度就得再缩一截,容量损失迟早吃掉多走一遍的收益。循环两次正好踩在收益与损失的平衡点上。三组消融拼出的配方就叫 SMELT(Sparse MoE Transformer,middle layers Loop Twice):稀疏 MoE 底座,中间一半层循环两次,循环内残差按 1/r 缩放,这里的 r 是循环次数,本例中就是 1/2,防止共享权重在重复访问中把残差流越放越大。整套配方可以画成一张图。

残差按 1/r 缩放在防什么?Transformer 每一层的输出都等于输入加上一层更新,共享层被执行两次,等于同一份更新被叠加两次。如果不缩放,残差流里的更新幅度会因重复访问而失控,训练跟着不稳定。把两次访问的更新各按 1/2 缩放,残差流的量级才压得住。这是让"多走一遍"在数值上成立的小机关,也是配方里最容易被略过的一笔。

图注:SMELT 全景图。panel (a) 是配方:循环中间 50% 的层两次,缩窄隐藏宽度、提高专家数补回总参数,循环内残差按 1/2 缩放,配更小的 head size 与更高的 GQA 比例稳住 KV cache;panel (b) 是算力对齐下的计算最优损失,panel (c) 是 1.6B 规模的下游准确率。SMELT

除了"循环中间这一刀",配方里每个动作都在补第 2 章那三本账的差值:宽度缩了省算力,专家补回来保住参数,head size 和 GQA 调完 KV cache 不变。"中间循环最好"也不是 SMELT 一家之言。Mixture-of-Recursions(MoR)在 135M 和 360M 的稠密递归 Transformer 上把共享策略分成四类,其中 Middle-Cycle 保留首末层独立、只复用中间层。它在 360M、循环两次时拿到四策略最低的验证损失,NLL 为 2.8295。全栈循环是另一种摆法,把首末层也一起共享,可在 MoR 的四策略对比里,首末保持独立的 Middle-Cycle 在多数设置(含 360M 全部两档)上优于全共享的 Cycle,仅 135M、循环两次时 Cycle 略胜,SMELT 的跨度扫描也把 100% 全栈排除在外。MoR 只对齐了参数侧的预算,没碰 FLOPs 和 KV cache,这份独立旁证恰好反衬出 SMELT 的三本账更严。MoR

但这套配方只在 200M 上验证过。上了规模还赢吗?这需要用缩放定律来说话。

上了规模还赢吗:四档模型、96 对对手,省下 6.8% 到 18% 算力

先补一把尺子。验证损失可以粗略拆成三块:数据本身的不可约下限、容量不足的惩罚,也就是模型太小;数据不足的惩罚,也就是喂得太少。给定算力预算,就存在一个最优的规模与数据量组合;把不同预算下的最优点连起来,就是计算最优前沿(compute-optimal frontier)。Chinchilla 用下面的形式拟合稠密 Transformer:

$$L(N,D)=E+A/N^{\alpha}+B/D^{\beta}$$

三种独立拟合方法都收敛到指数约 0.5 对 0.5,结论是"每翻一倍参数,训练数据也应翻倍"。前人还沿这条前沿读出过一张最优配置表,400M 的参数配上 8B token、67B 配上 1.5T token,训练预算每翻十倍,配置沿着曲线换一套。但这条经验只对稠密模型成立:循环架构里参数与深度已经脱钩,必须自己重拟合自己的前沿。Chinchilla

SMELT 的规模实验拉了四档,每 token 激活参数从 100M、200M、600M 一直到 1.6B,其中 1.6B active 对应约 54B 总非嵌入参数。再横扫四档稀疏度,0% 是稠密参考,其余约 85%、95%、97%。一共 32 次训练,得到 96 对逐项匹配的 Baseline 与 SMELT 端点。每一对端点都来自同一个规模与稀疏度配置,预算在配置层面就配好了对,Baseline 和 SMELT 只在架构上不同。两个架构各自拟合独立的缩放表面:

$$L(F,S,D)=E+A(1-S)^{b}/F^{a}+K/D^{c}$$

其中 F 是每 token FLOPs、S 是稀疏度、D 是训练 token 数,六个系数互不共享,两个表面的拟合残差都很小(RMSE 约 0.006 与 0.010 nats)。拟合出的关键指数说明循环确实把曲线拖陡了:SMELT 的 a=0.3892 高于基线的 0.3703,c=0.7011 高于 0.6594,容量项和数据项随算力下降都快一截;前沿指数 $\gamma=ac/(a+c)$ 从 0.237 提到 0.250,快了约 5.5%。至于循环为什么能把曲线拖陡,拟合本身给不出机制解释,论文要靠第 6 章的注意力分析来凑上这块拼图。两套系数必须各自拟合,不能合成一个表面:如果假设循环不改变损失随算力下降的速度、硬把两个架构塞进同一套系数,那等于先把要证明的东西当成了前提。为什么必须拉到四档规模?因为 200M 上的胜负可能是小模型特例,而缩放定律给的是整条曲线上的承诺:只要前沿拟合得干净,节省就对拟合窗口内所有预算成立。

拟合之前,先看原始数据建立起直觉。

图注:验证损失对累计训练 FLOPs 的曲线,按三档稀疏度分面、按规模着色。每个规模与稀疏度的格子里,空心圆是 Baseline、实心方块是 SMELT;相同算力下,SMELT 的方块总在基线的圆点下方。SMELT

这张图只能建立"同等算力下损失更低"的直觉,"到底省多少算力"必须从拟合前沿换算。把前沿上的损失差换成算力差:在 10^20 FLOPs 的训练预算上省 6.8% 到 10.0%,在 10^21 上省 14.7% 到 18.0%,都是论文用 cell-bootstrap 给出的 95% 置信区间,做法是把端点按格子分组重采样。10^22 的外推还有 19.6% 到 23.5% 的区间,论文明确标注它落在拟合窗口之外,不属于主结论。论文的整体表述是:在计算最优前沿上省下 6.8% 到 18% 的训练 FLOPs。SMELT 另一个体检指标同样重要:两架构的"每等效参数 token 数"几乎一致,这个指标衡量同样多的等效参数能吃下多少训练数据,两者读数几乎一致(点估计互差在 6% 以内,95% 置信区间几乎完全重叠),说明节省来自同一算力分配下损失更低,而不是换了一种算力分配。省 18% 是算术 FLOPs 口径的节省;论文明确未对齐 wall-clock 机时成本,串行块重执行可能带来硬件效率差距。

不过,答案绑在协议上。Schwethelm 等人的 iso-depth 协议把有效深度钉死,拟合出循环等价值 φ=0.46:循环 r 次的贡献只相当于 r^0.46 个独特层,r=4 时约 1.89 层,等于一次循环大约只值半个独特层,共享参数的代价被单独拎出来秤,该协议下循环前沿反而落后,而且循环越深、r 越大,前沿越靠上,落得越远。Iso-Depth Parcae 把参数与数据预算钉死,拟合出最优循环次数随算力按幂律增长,μrec∝C^0.40,循环量要和数据量一起长大。Parcae 三种协议,三种答案。

公平协议钉死什么结论
iso-depth(Schwethelm 等)有效深度一次循环约值 0.46 个独特层,循环前沿落后
iso-params(Parcae)参数与数据预算最优循环次数与数据量同向增长,μrec∝C^0.40
三预算对齐(SMELT)FLOPs、参数、KV 同时计算最优前沿上省 6.8% 到 18% 训练 FLOPs

方向反过来的原因很简单:两版协议问的不是同一个问题。iso-depth 问的是"同样的有效深度下,一次循环等价于几个独特层",于是共享参数的代价被单独拎出来秤;SMELT 问的是"同样烧这些算力,循环结构本身有没有净贡献"。所以"循环好不好"取决于你允许哪一版公平。SMELT 的贡献不是给出唯一答案,而是把三本账同时对齐的那一版摆上了桌面。但验证损失降得快,下游真的跟着涨吗?

验证损失没讲完的赢面:代码、长序列、例子给得越多越赢

预训练曲线的胜利,最终要落到下游任务上。96 对端点上逐个比:DCLM Completion 类任务 96/96 全胜,DCLM Core 类 83/96,MMLU 上 29/30——MMLU 的胜负计数限定在基线得分高于随机 10 个百分点以上的 30 对可比端点(原 96 对中仅 30 对满足),其余两类均按全部 96 对统计。96/96 的意思是,在全部 96 对匹配端点(16 个规模×稀疏度组合、每组合沿 6 个 WSD 衰减分支的检查点)上,循环模型无一例外赢过基线。这不是靠几个大模型的运气,而是每个配置都赢。不过胜负是压倒性的,这还只是"水涨船高"级别的证据:损失低本来就该赢。

更强的证据是"超出验证损失预测的增益"。做法是先用一个四参数单调 sigmoid 把验证损失校准到三项指标上,拟合优度 R² 高达 0.997、0.974、0.911,说明验证损失能解释下游九成以上的变化。校准曲线的意思是:给定一个验证损失,下游分数大概该是多少。然后看 SMELT 的端点落在曲线哪里。落点是正的残差,而且随规模放大。如果循环只是把损失压低,它应该恰好躺在曲线上;它躺在曲线之上,说明优势里有验证损失看不到的部分,同样的损失换到了更多的下游分数。翻译成算力的话:省下来的预算,在真实任务上比预训练曲线显示的更值钱。SMELT

拆开领域看,这部分隐藏的赢面集中在哪?按 39 个验证源类别拆分的 CE Gain 分析中,Code 类收益最大(20.4%),Finance 16.8%、Math/STEM 16.6% 随后。而且优势随样本长度和上下文内示例数 k 单调放大:同样的 few-shot 例子加进来,例子给得越多,循环方赢得越多。这个趋势和 Huginn 在 latent reasoning 上的观察一致:任务越难、few-shot 上下文越丰富,模型越需要也越受益于更多轮迭代;循环多走的那一遍,正是在长代码、多示例这些真实使用场景里兑现价值。论文自己也说明,Code 收益最大目前是描述性结论,机制层面的因果论证还没有做。Huginn

那为什么多走一遍,恰恰赢在内容相关的注意力上?这就要翻开注意力本身。

第二次循环在修什么:注意力从首字的泄洪区回到内容

先看一个所有 Transformer 共有的毛病。softmax 强制每个 attention head 的注意力权重加起来等于 1,当 query 在上下文里找不到像样的匹配时,这份概率质量也必须花在某个地方。而自回归模型里,后面的 token 都能看到第一个 token,第一个 token 却看不到后面的任何一个,初始位置于是成了最便宜的下水口:几乎所有 head 都把多余的注意力倒向首 token。Llama-2-7B 的注意力统计里,从第 2 层起几乎所有 head 都这么做。这个现象叫 attention sink(注意力泄洪区),它是稠密 softmax 注意力训练出来的固有惯性,不是某个部署技巧,StreamingLLM 第一次把它讲清楚。工程上还有一个反证:StreamingLLM 发现推理时只要在缓存里保留开头四个 token 的键值,长文本困惑度就不会崩,说明首 token 在注意力分布里承担着某种结构性角色。StreamingLLM

SMELT 观察到的是:第二次循环把这个泄洪区修掉了一大截。论文把第一次执行共享层块叫 visit 1,第二次执行叫 visit 2。普通 Transformer 的 sink 随层数加深而增大,这是此前就被观察到的趋势;SMELT 的 visit 2 逆着这条趋势走。

图注:1M-token 留出样本(held-out)上的段首注意力质量(S≈85%)。左半是 1.6B 模型逐 head 的段首注意力热图,visit 1 有一条集中的亮带,visit 2 几乎全体冷却;右半是匹配物理深度下 sink 质量随层数的变化,Baseline 随层数上升,SMELT 的 visit 2 始终压在 visit 1 下方。SMELT

token 级的量化来自论文的另一个实验。在 Dyck 括号匹配任务上,设置约为 85% 稀疏度、1.6B 规模、4-shot,研究者先定位出对括号结构最敏感的那个 head:第一次循环时它把 0.60 的注意力质量放在段首的 BOS(序列起始符)token 上,第二次循环后降到 0.02;演示答案 token 上的质量从 0.24 涨到 0.85。sink 失去的质量几乎全部转移到了演示答案 token 上。SMELT 注意:这是相关性证据,不是因果分解。作者明说,具体哪个子层贡献最大、修好 sink 是不是损失更低的原因,都还没有被证明。一种说得通的机制叙事是:sink 里的注意力质量是死重,它不指向任何内容;第二次循环把这份质量腾出来转向演示答案,等于把每次注意力的预算花到了更值钱的地方。但这是论文给出的机制叙事,证据仍然是相关性的。

把全文的账审一遍,SMELT 的边界画得很清楚。配方消融只在 200M(约 3.9B 非嵌入参数)规模上做过,更大规模是否仍是"中间 50% 循环两次"最优没有验证;只研究了最简单的循环形式,连续块加完全共享权重,per-visit 低秩适配器、token 级自适应深度、动态终止这些变体都不在范围内;三本账对齐的是算术 FLOPs,不是墙钟时间,串行重执行与稀疏路由在真实硬件上的效率差被留在账外。论文把这些问题都列为待验证的开放项,其中两件最值得盯:更大规模下中间 50% 还是不是最优切割,以及墙钟时间对齐后循环的真实成本。后者尤其现实,因为算术算力对齐和硬件效率是两回事。但作为工程指引,三条启示足够干净:算力对齐下优先循环中间层而非全栈循环;代码密集的管道收益最大;给循环架构单独拟合缩放面,别把稠密模型的 Chinchilla 前沿直接套上去。

回到开头那笔"白嫖"的账。循环 Transformer 没有变成必胜魔法,SMELT 做的是把口号变成一本可核对的账本:同样的预算、同样的参数、同样的缓存,循环先到终点,省下 6.8% 到 18% 的训练算力。下次再有人说某种架构白嫖了什么,先把三本账递过去。

想深入可以读原文:SMELT: Scaling Laws for Compute-Matched MoE Looped Transformers arXiv:2609.01343

参考文献

SMELT:把预算砍到和对手一样,循环Transformer还是先到终点