假设厨房只能摆下少量食材,完整仓库却有几十倍大。厨师每做一步菜,都要等人从仓库取回下一批原料。此时再快的刀工也没用,真正拖慢出餐的是搬运。
在一张 8 GB 的 RTX 3070 上运行 Qwen3-235B-A22B,情况大致如此。这个模型采用 MoE——混合专家架构,内部有许多“专家”子网络,每个 Token(模型处理文字的基本单位)只调用其中一小部分。它共有 2350 亿参数,每个 Token 激活约 220 亿参数。经过 Q4_K_M 量化——用较少比特保存参数——模型仍有 134 GB,远远装不进显存。
所以,标题里的“塞进”并不是把 134 GB 权重完整放入 8 GB 显存,而是把少量参数留在显存和内存,其余放在 SSD,需要时再读。论文测得,预热后的生成速度只有 0.441 tok/s。它确实能运行,但说不上实用。
以下数据均来自这篇论文及同一团队公开材料,尚无独立复现。
芯片没在算,它在等参数
作者把问题称为“内存带宽墙”:瓶颈不是芯片算不动,而是参数从 SSD、内存搬到显存的速度太慢。就像厨师一直在等仓库送货。
论文所用机器有 8 GB 显存、32 GB 系统内存和一块消费级 NVMe SSD。显存带宽为 448 GB/s,内存为 50 GB/s,SSD只有 2.4 GB/s。约 70% 的模型权重落在最慢的 SSD 上。每生成一个 Token,需要读取约 12 GB 的专家权重。实测速度与“每个 Token 要搬多少字节,再除以存储带宽”的简单模型基本吻合。
作者还测试了一个直观办法:同时处理许多请求,让一次磁盘扫描服务多个生成流。低并发时预测与测量相符,但 batch 32——一次并行处理 32 路请求——出现分页抖动。大量页面换入换出使有效吞吐反而跌到 0.087 tok/s。问题不在批处理思路本身,而在现有 llama.cpp 无法稳定表达这种大规模顺序扫描;论文认为,这需要专门设计的执行引擎。
与其加快搬运,不如少去仓库
MoE 里有一个“路由器”,负责为每个 Token 挑选专家。常规训练关注它是否选对专家,作者则多问了一句:能否让相邻 Token 尽量重复使用同一批专家?如果答案是肯定的,缓存就能保留刚用过的权重,减少从 SSD 重新读取。
团队先开发了 llama-moe-trace,在不修改权重的情况下记录路由选择。他们分析的是 Qwen3-30B-A3B,而不是前面测速的 235B 模型。结果显示,相邻 Token 的专家复用率是随机水平的 2.0 倍;95% 的流量集中在 52.5% 的专家上。代码文本使用的专家集合,与散文、数学和医疗文本也明显不同。
这些偏好已经足以帮助缓存。模拟中,一个只能容纳全部专家 13.4% 的 LRU 缓存——LRU 会优先淘汰最久没用的内容——可以服务 65.9% 的专家请求。相比之下,固定钉住最常用专家的命中率是 59.2%。这说明有价值的不只是“哪些专家总体最热门”,还有“刚才用过的专家很可能很快再用”。
作者据此提出 Path-Mapped Serving:热专家留在快速存储,冷专家从磁盘读取。按论文模型推算,它可把 235B 模型的单路速度提高到约 0.9 tok/s,并保持所服务模型的权重不变。但这仍不接近交互速度。若要达到 10 tok/s,缓存命中率需要约 95%,相当于让约 70 GB 专家权重常驻快速存储,已经超出这台机器的容量。
让路由器养成“就近取货”的习惯
论文真正想改变的是模型本身。作者在训练时加入辅助损失,奖励路由器连续选择相近的专家;另一组实验则按文本领域划分专家,希望某一领域的请求集中落入可预先固定的一组专家。
这里的关键不是事后猜下一次会用谁,而是让模型从训练阶段就形成更容易缓存的访问模式。作者事先登记了判断成功的门槛:不仅缓存未命中要明显下降,困惑度也不能显著上升。困惑度是衡量语言模型预测能力的指标,通常越低越好。
在 1.37 亿参数的多领域 MoE 上,机制确实改变了路由。较强的局部性约束让缓存未命中下降 59%—60%,但困惑度增加 2.1%—3.1%,超过预先设定的 1% 上限。较弱约束把困惑度增幅控制在 0.3%,未命中却只下降 15%,达不到 30% 的目标。中间设置则两道门槛都没过。
领域路由也出现同样的取舍:固定专家的命中率达到 99.1%,超过 90% 目标,但困惑度增加 3.1%,高于预设的 2%。换句话说,路由器学会了更规整地取货,却失去了一部分自由选择最合适专家的能力。
这是一项预注册的负面结果。训练没有失败,缓存指标甚至改善得很明显;失败的是“几乎不损失质量”这个更严格的承诺。
两种不完美方法,叠起来反而更好
作者随后加入免训练的 cache-aware rerouting:如果首选专家不在缓存,而缓存中的另一个专家得分足够接近,就临时改用后者。单独把它强行用在普通模型上,质量会迅速下降;但路由器先接受过局部性训练后,替换专家的额外代价变小。
两种方法叠加,在 1.37 亿和 3.4 亿参数实验中都把缓存未命中减少约 80%,困惑度增幅不超过 3.4%。这不等于吞吐提高 80%,也不是无损结果,但它提示了一个更实际的方向:训练负责让相近专家更可替换,推理时的缓存策略再利用这种余地。
相反,按领域提前把专家装入缓存没有改善。论文观察到,LRU 缓存在领域切换后很快就能重新变热,预取带来的收益不足以改变整体结果。
为什么值得关注
边缘设备运行超大 MoE,通常被当作系统调度问题:怎样缓存、预取和搬运参数。这项工作把问题向前推到了模型设计阶段。既然路由决定每次要搬哪些权重,模型能否在学会语言的同时,也学会一种更适合硬件的访问习惯?
论文给出的回答很克制:可以训练出局部性,但目前不能证明它免费。这个结论仍有价值。它把“让路由更好缓存”从一个听起来合理的想法,变成了可以同时检查缓存收益与质量代价的问题。作者也公开了 llama-moe-trace、代码、路由轨迹和预注册材料,便于后续检验。
局限与未知
- 235B 模型只用于带宽测量;路由统计来自 Qwen3-30B,局部性训练则只在 137M 和 340M 小模型上完成。不能把后两者的效果直接套到 235B。
- 340M 实验没有显示质量代价随规模扩大而缩小,反而略有上升;但两个规模都训练不足,只有两档规模,因此仍不能判断更大模型的走势。
- 论文只测试一套消费级硬件。Path-Mapped Serving 的速度来自实测 IO 与缓存率推算,并非完整部署后的端到端成绩;硬件细节与测量条件也不足以支持更广泛外推。