19.5 GB 的模型装进 24 GB 的机器,为什么论文实测反而快了五倍:Edge0 把 MoE 专家权重放回 SSD,用「预测即路由」抢出一个 token 的时间
论文实测(arXiv:2609.18063,Mac mini M4 Pro 24 GB,单流解码、短上下文)报告了一组反直觉的数字:一个 35B 级 MoE(基座 Qwen3.6-35B-A3B,发布档路由宽度 K=4)的 4-bit 权重文件是 19.5 GB——这是磁盘上的 int4 checkpoint,不是内存占用;把这 19.5 GB 全驻留内存时解码 3.9 tok/s、全驻留权重内存 18.2 GiB;而 Edge0 让专家权重留在 SSD 上按需流入,解码 20.4 tok/s,峰值活跃内存(MLX 分配器峰值,不等于进程 RSS)2.9 GiB。它用的不是纯搬运:预测路由与恢复适配器把模型的计算路径也换掉了。代价是每步都要等磁盘,它靠「预测即路由」抢出一个 token——部分层设置预测头,用第 N 层在 token t 的隐藏态预测第 N+1 层在 token t+1 的专家集合。本文把参数账、时间账、量化账和它没解决的三件事逐项算清:论文实测值可追溯,本文推导值列出假设与中间值。
除另行标注外,本文引用的外部事实与页面核验均以 2026-10-26(北京时间)为时点。论文里的实验数字一律标「论文实测」,本文自己按公式算出来的数字一律标「本文自行推导」并写清假设与中间值。本文没有做端到端实测:所有 tok/s 与耗时都是论文报告值或按其报告的常量复算的结果,不是我在本机跑出来的。论文实测值只能追溯、不能由文内公式复算;凡标「本文自行推导」的才是可照着按一遍的。
一、先把三个数字摆在一起
2026 年 9 月 16 日挂到 arXiv 的这篇论文(arXiv:2609.18063 v1,AutoArk,五位作者,CC BY 4.0;v2 于 2026-09-17 更新)只有一件事要说,但它把这件事说得非常具体。一台机器、两种方案、三组关键指标:
- 一台 24 GB 的 Mac mini M4 Pro,跑一个 35B 级的 MoE(基座 Qwen3.6-35B-A3B,论文发布档路由宽度 )。权重文件本身 19.5 GB——这是磁盘上的 int4 checkpoint,不是内存占用。
- 用最直白的办法——全部权重常驻内存(现成的 mlx-lm 服务)——解码 3.9 tok/s,全驻留权重内存 18.2 GiB。
- 用论文的引擎 Edge0——权重留在 SSD 上按需流入——解码 20.4 tok/s,峰值活跃内存 2.9 GiB(MLX 分配器峰值,不等于进程 RSS,见 §十二)。
同一台机器、同一套解码协议、同一份基座 int4 权重,后者快了约 5.2 倍——但注意基座权重相同,不代表计算路径相同:Edge0 还换了路由(预测即路由)并加了一个恢复适配器(见 §六、§九),这两件事本身会掉质量,所以「快」不能理解成免费。(本文自行推导:),同时把内存占用压到前者的六分之一左右()。
这件事的反直觉之处在于:变快的那一版,每一步都要去读硬盘。 常驻内存的版本一个字节都不用读盘,却被「装不下」这件事拖住了——18.2 GiB 不可回收的权重放在 24 GB 的机器上,KV 缓存和操作系统几乎无处安放,系统只能不停换页。于是问题从「怎么算得快」变成了「怎么让权重不住在内存里,还不在读盘上卡死」。
先把单位钉死,不然后面每个数都会打架:GB 是 10 亿字节、GiB 是 2 的 30 次方字节,19.5 GB 约合 18.2 GiB。本文里 19.5 GB 一律指「磁盘上的 checkpoint 文件大小」,18.2 GiB 指「全部权重常驻内存时的占用」,2.9 GiB 指「Edge0 的峰值活跃内存」——三个不同对象、三次不同测量。
这篇论文把全部力气花在第二个问题上,而它的答案不是工程技巧,是一个可训练的小模型:用预测出来的路由,直接当路由用。
二、术语与符号表(先把记号约定好)
先统一符号,后文所有公式都用这套。
| 符号 | 含义 | 在这篇论文里的取值 |
|---|---|---|
| 解码器层数 | 35B 档 40 层,8B 档 24 层 | |
| 每层专家数 | 35B 档 256,8B 档 128 | |
| 每 token 每层选中的专家数(路由宽度) | 基座 ,发布档 35B 用 ,8B 用 | |
| 单个专家在 int4 下的字节数 | 35B 档 1.77 MB | |
| 单层全部专家的字节数 | 453 MB | |
| 单个 token 必须就位的专家字节数 | 本文自行推导,见 §三 | |
| 页缓存命中率 | 论文未单独报告,本文只按「1 − 冷页占比」间接引用,不当作独立测量 | |
| cold | cold 的分母与采集方法:论文按「一次加载里有多少字节是冷页」统计,不是按加载次数;该统计定义未独立核实 | 按需臂 17%–20%,预取臂 84%–98% |
| 单次加载的耗时 | 论文拟合 毫秒 | |
| 预测头 / prerouter | 用上一层在上一 token 的隐藏态预测下一层本轮路由的小网络 | 35B 档 33 个,8B 档 16 个 |
| 学生路径 / student path | 解码时按「预测出的路由」而不是原路由器走一遍前向 | 部署形态 |
| 教师 / teacher | 原始 fp16 基座,只用来蒸馏与打分 | 不参与部署 |
| recovery LoRA | 修复 int4 量化 + 路由替换两处损失的适配器 | 秩 16、、42 MB |
| 冷读 cold | 该次加载读到的页不在页缓存里,必须等 SSD | 论文按每次加载统计 |
表里几个高负担的系统词,先就地给一句话释义(不然后面要回论文找定义):臂(arm) = A/B 实验里的一条对照分支,本文的「按需臂」与「预取臂」是同一 session 里交替跑的两条;flush = 触发一次待求值计算(MLX 是惰性求值,图建好不等于算过);sticky-slot = 常驻槽位的张量原地更新,配合 incr_stack 只重写变化的那几个专家;feature drift = 预测头输入里「上一层实际选了哪些专家」这一项,在训练时来自真路由器、在解码时来自预测本身,两边分布不同;尾部项 = 蒸馏时把 top- 之外的 token 概率质量用一个附加项承载,而不是直接丢掉。
三个容易混的口径先分清,不然后面会一直打架:
- 19.5 GB 是磁盘上的 int4 checkpoint;18.2 GiB 是全驻留时的内存占用;2.9 GiB 是流式方案的峰值活跃内存。这三个数指的不是同一件事,前两个单位也不同(GB 与 GiB)。
- 稀疏性省的是算力,不是字节。 论文原文说得很直:一个 35B MoE 每 token 大约激活 3B 参数,这缩小的是「要算多少」,不是「要存多少」。
- 磁盘读得少不等于不需要那些字节。 论文实测里每次解码步只从磁盘读了几十 MiB,而每步「必须就位」的专家字节是几百 MiB 量级——差的那部分是页缓存兜住的(§五会把这笔账算清)。
三、第一本账:稀疏为什么救不了内存
把一个 40 层、每层 256 个专家的 MoE 拆开看。int4 量化(affine、group size 64)之后,单个专家的三个投影(gate、up、down)连同分组缩放一起是 1.77 MB。于是单层的专家权重是:
(本文自行推导,与论文 §3.1 报告值一致。)
40 层加起来:
论文写的是「18 GB(16.9 GiB)的路由专家,装在一个 19.5 GB 的 checkpoint 里」,剩下的部分给注意力、词表嵌入、共享专家和 int4 的分组缩放。也就是说,专家占了整个模型的九成以上,而且一个都不能少——路由器可能在任何一步选中任何一个专家。
这里是最容易被误读的一步。有人看到「每 token 只激活 3B 参数」,就以为「那是不是只需要 3B × 0.5 字节 ≈ 1.5 GB」。不对。那 3B 是这一 token 用到的参数,模型必须有能力在下一个 token 用到另外 3B。要从「稀疏激活」里拿到「字节变少」,唯一的路是这些字节不在内存里也在别处——这正是 Edge0 把专家权重放回 SSD 的全部动机。
那么一个 token 到底要就位多少专家字节?答案并不小:
(本文自行推导,按发布档 计。)
如果这 283 MB 每一步都得从 SSD 拿,20 tok/s 需要的持续读带宽是:
(本文自行推导。 为解码速度。)
5.8 GB/s 已经吃满一条消费级 NVMe 的顺序读带宽了。
但这里必须加一道闸:283 MB 是「专家访问量」,不等于本步新增的 SSD 读取量。 40 层里只有 32 层按预测流式执行(§五),暂存槽的 sticky 复用还会省掉一部分重复读(§十四),同一份字节也可能已经在页缓存里。论文实测的每步读盘量是另一个量级: 时 58.9 MiB、 时 125.1 MiB(§十 的表,注意那是另一台机器上的测量)。两组数不能互相代入,也不能拿差值直接当成命中率。这也是为什么论文里「几十到一百余 MiB/步」的读数不是因为需求小,而是因为页缓存把大部分字节变成了命中:热专家留在内存里,只有冷的那一小部分真的落到盘上。论文给出的实测冷页占比在 17%–98% 之间,变化跟路由宽度无关、跟是哪条臂有关:按需臂 17%–20%,预取臂 84%–98%(论文 Table 4,本文 §十 的表;口径是「一次加载里的冷页字节占比」)。也就是说,是「预取」这个动作本身把读变冷了——提前发出的读,等不到被谁顺手带热。
一句话记住这一节:MoE 的稀疏性缩小的是每 token 的计算量,不是每 token 必须可达的权重集合;只要路由可以选到任意一个专家,那部分字节就必须「存在」,问题只是「存在哪、怎么搬」。
四、第二本账:串行的罚金
把权重放到 SSD 上,第一版实现一定很慢,而且慢得很有节奏——每层停一次。
原因是一条硬依赖:第 层选哪些专家,取决于第 层的输出。而第 层的专家权重,要在这个选择出来之后才知道该去读哪几块。读盘必须等选择,选择必须等算完。 于是每一步解码变成一串「算一层 → 停 → 读专家 → 算一层 → 停 → ……」的锯齿:
sequenceDiagram
autonumber
participant G as GPU(层 N 计算)
participant S as SSD / 页缓存
participant R as 路由器
Note over G,R: 按需流式加载(on-demand):读盘串在关键路径上
G->>R: 层 N 输出完成
R->>R: 选出层 N+1 的 K 个专家
R->>S: 请求这 K 个专家的字节
S-->>R: 冷读等待(ms 级,每层一次)
R->>G: 权重就位,层 N+1 才能开算
Note over G,S: 40 层乘一个 token,就是 40 次串行等待这张图说明什么:慢的不是总字节数,是等待的次数。每一次等待都把一层计算和一次磁盘往返串成一条链,40 层就是 40 次。论文在 16 GB 的 MacBook M2 上(checkpoint 18.4 GiB,装不下,每步都得把专家换进来)实测了这条链的代价:主线程花在等专家加载上的时间, 时是每步 154.9 ms, 时 244.0 ms, 时 575.0 ms。
注意最后那个数: 的 575.0 ms 比它所在的那一整步(559.1 ms)还长——这两个数口径不同:575.0 ms 是把各层等待相加得到的和(跨层求和),559.1 ms 是那一步的墙钟时间;和能超过墙钟,正因为不同层的加载彼此重叠。原因是「每步阻塞时间」是把各层的等待相加得到的,而不同层的加载彼此有重叠,所以相加之和可以超过墙钟时间。这个细节只能说明等待存在、且层间有重叠,不能反过来当「串行度」的判据(§十 会专门说清)。它的用处是:既然层间加载能重叠,把读盘再往前挪就有希望收回一部分罚金。
收回它的钥匙,是一个关于「谁能预知未来」的工程妥协。
五、把「预知」做成一个可以训练的小网络
问题可以写成一句话:在第 层的专家还没被选出来之前,能不能先知道它们是谁?
已有工作里最接近的答案是 Pre-gated MoE(arXiv:2308.12066,2023 年 8 月):它在同一个 token 内、在第 层注意力算完之后,立刻预测第 层的专家,然后用这个预测去提前取权重。这个设计的「提前量」是一层。
Edge0 说这条路在流式引擎里走不通,并给了两条理由:
- 一层的时间窗太窄。 论文实测:在同一 token 内做逐层预测,需要一次逐层的同步与预测头求值,会把 GPU 流水线排空,代价是每步 30–100 ms——比它能隐藏的加载时间还长。他们试过的每一个「同 token」变体,最终都跑不过一个朴素的 LRU 缓存基线。
- 下一层的注意力还没算。 预测第 层专家时,第 层的注意力输出根本不存在,输入特征先天不足。
Edge0 的答案是把提前量从一层改成一整个 token:第 层挂在 token 上,用它自己的后注意力归一化输出,去预测第 层在 token 的路由。于是有两个效果同时发生:
- 一个 token 的提前量把预测头的求值搬出了逐层关键路径。每步只需要一次统一的冲刷(flush),一次性把全部待流式加载的层都预测出来(35B 档 32 层,8B 档 16 层)。
- 这个窗口里的磁盘读取,正好与当前这一步的计算重叠。论文的 16 GB 机器上, 时一层专家大约 7 MB,而预测版每步仍要花 101.9 ms 等冷加载——它没有消灭等待:部分加载等待被重叠,仍有未隐藏等待(101.9 ms 是主线程等待的跨层求和,不是墙钟罚金)。
预测头的形状很朴素,值得抄下来(下文 是预测出的路由 logits, 是线性残差路径,注意它与路由器输出 logits 的符号 不是同一个东西):
(论文 §3.2。 是该层后注意力的归一化隐藏态,、 是本层本 token 与上一 token 实际选中的专家集合, 是一条线性残差路径,训练脚本用「下一层的路由器权重」热启动它,默认值为零——等于让训练从「直接把下一层路由器套在当前的隐藏态上」这个起点开始,MLP 只学修正量。)
输入维度可以当场核对:
(35B 档;预测头 MLP 中间宽度 512——别和模型隐藏维度 2048 混成一个数;fp16。8B 档是 。)
这里的 不是论文自说自话——我去拉了基座模型 Qwen/Qwen3.6-35B-A3B 的 config.json(2026-10-26 读取),text_config.hidden_size 就是 2048,且 layer_types 是线性注意力与全注意力交错的混合结构(full_attention_interval: 4)。这个数对得上,是本文少数能独立核验的常量之一。
先说层编号:本文与论文一致,解码层从 0 开始编号。层数账也对得上:35B 档有 33 个预测头(所属层 6–38),预测被消费在 7–38 层,所以 40 层里有 32 层是从预测而不是从自己的路由器取路由的;第 38 层那个头预测的是第 39 层,而第 39 层不做流式加载,于是这个头出厂却不带消费者。8B 档 16 个头(所属层 7–22),消费在 8–23 层,24 层里 16 层走预测。
六、「预测即路由」:这一步决定了整套设计的性质
有了预测还不够。真正让 Edge0 与众不同的是它怎么用这个预测:解码时,MoE 层直接用预测头的 logits 当路由,而不是拿预测去当提示、再回退到真路由器。
这一句话把系统的性质换掉了:
- 暂存的专家集合与被路由的专家集合,按构造完全相同。 不丢专家、不需要在推理时补加载、不需要回退。
- Pre-gated MoE 那类方案在推理时要处理「预测偏了怎么办」——补加载要时间,丢掉会掉质量,于是变成一个「覆盖率 vs 质量」的运行时权衡。Edge0 把这个权衡整个搬到了训练阶段,一次性付掉。
- 代价是模型确实在「换过的路由」下工作。这不是免费的:预测头能看到的信息有限(上一层、上一个 token 的隐藏态),不可能恢复到原路由器的全部信息。
论文把这个现象叫 feature drift,而且很诚实地指出它没有专门去修:预测头的输入里包含了「本层实际执行的专家集合」,训练时那是基座路由器的选择,解码时却变成「前一层所拥有的预测头在上一 token 给本层的预测」(因为预测已经取代了路由器),而这些头并没有为这种位移重新训练。他们靠 recovery LoRA 在「学生路径」(即带着预测路由跑)上训练来吸收这个位移,并用最终的质量测量把 int4、路由近似、位移三者的损失一起定价。
这一节想让你记住的一件事:在这套设计里,「预测得准不准」不是目标函数,「在预测路由下还能不能写出好文本」才是。 论文原话是:追更高的路由器一致率是错误的目标,跨 token 预测从上一个 token 的隐藏态出发,本身就是信息受限的。
七、路由数学:两种主流家族,三条不能弄错的顺序
预测头输出的不是「专家编号」,而是 logits;把它变成专家集合要走和原路由器同一套函数。论文实现两种主流家族,且直接把它们从模型实现里抽出来共用(resident、streaming、prerouter 三条路径共用同一份,并用对齐测试钉死一致性)。
softmax-top-k(Qwen 系):
sigmoid-group(DeepSeek 系、Ling 系):
关键差别在顺序,共有三条不能弄错:① 选择分数:DeepSeek 系给每个专家一个可学习的偏置 ,选择用带偏置的分数 ,而权重仍用原始 (偏置只影响选谁,不影响权重,这是 DeepSeek 风格路由的惯例);② 分组保留:按组内 top-2 之和排名、保留 个组,其余组整体掩到 ,然后才在存活组里取 top-;③ 归一化:softmax-top-k 要重新归一化到和 1,sigmoid-group 用原始 sigmoid 乘以缩放 再归一化。8B 档用的是 组、保留 组、缩放 、。
把这三步的顺序对齐不是洁癖。这两段公式是示意写法(论文附录附录 A 亦为简写),落地时要按上面三条补全偏置与分组细节;本文不宣称给出了可逐位复现的实现。预测即路由意味着路由函数本身就是推理路径的一部分:这里差一个 、那里把 top-k 放在分组掩码之前还是之后,出来的是不同的专家集合,而专家集合一不同,权重就要重新读盘——错误会被放大成性能与质量的双重偏差。
八、训练三阶段:顺序不是可调项
这套方案的全部赌注在下半句:近似的路由可以靠训练补回来。 论文的配方有三个阶段,全部在「4-bit 部署 checkpoint 的反量化 bf16 重建」上训练(即训练它将要服务的东西),基座全程冻结。
- 阶段一:把预测头蒸馏出来。 唯一被训练的参数就是这些头。损失函数去模仿下一层真实路由器的输出,所以头学到的是「预测路由」,不是「拟合文本」。
- 阶段二:在学生路径上做 SFT。 LoRA 挂在注意力、线性注意力和共享专家的投影上,不挂路由专家(那些权重要流式替换,必须保持可替换)。训练时整个前向都带着预测路由跑,数据是约两百万行教师生成的文本。论文说这一步才是让近似可用的关键:只做蒸馏、没有 SFT 的 checkpoint 在预测路由下会输出重复、坍缩的文本;同一批头加上 SFT 之后,在同样的速度和内存下输出连贯。
- 阶段三:on-policy 蒸馏。 阶段二用的是教师写的文本;阶段三用学生自己生成的文本,让原始 fp16 基座当教师打分,梯度仍然只走学生路径上那层可训练参数。目标函数是反向 KL(mode-seeking,不要求学生覆盖教师的全部支撑集),作用在教师的 top- token 上,top- 之外的 mass 用一个尾部项承载而不是直接丢掉。阶段三只用 SFT 语料的十分之一(约 20 万行 vs 200 万行)就收敛。
论文明确说这个顺序在那几轮里不可谈判:先头后 SFT(否则 SFT 的信号会把极小的头梯度淹掉),最后 on-policy。
这一节想让你记住的一件事:「预测即路由」不是一个推理技巧,它是一个训练契约。 想让推理时不回退、不补加载,就得在训练时把模型按部署形态再教一遍——这也是为什么这套方案不能直接套到「别人的权重 + 一个外挂脚本」上。
九、LoRA 为什么必须「不合并」
这是全文我觉得最值得单独拎出来讲的一段,因为它推翻了一个很常见的直觉:把适配器合并进 4-bit 基座,再重新量化回 4-bit,行不行? 论文的回答是:算术上不行。
部署形态是:
(int4 基座冻死,LoRA 作为并行 delta 参与计算,基座的 4-bit 字节一个都不动。)
而「合并再量化」这条路是这样塌掉的:LoRA 的 delta 量级(RMS )落在 4-bit 分组量化的台阶以下,重新量化会把权重层面的 delta 大部分抹平。论文给了三个保留率数字(以未合并版为 1):
- 注意力投影上,保留 34%;
- 一个稠密投影上,保留 2%;
- 在 logits 层面,保留 18%。
logits 层面的保留率定义是:
其中 是未合并模型的 logits、 是合并后重新量化模型的 logits、 是基座 logits,都取固定 prompt 的首 token;论文报告该值为 0.18。权重层面的保留率按目标分别算:
代价一侧:不合并要多花 42 MB 适配器权重,解码时间无可测量的增加。于是在该论文所测的适配器与重新量化配置下它更优——一个只读基座可以服务所有代的适配器,给某个档位换路由宽度只需要换两个文件。
顺带一句量级感,但要说清它的边界:BF16 没有固定绝对单位,它的相对精度随指数变化;int4 affine 的台阶也要看组内范围与量化定义。所以不能只用「delta 的 RMS 小于台阶」推出普遍的不可能性。能说的是:在这篇论文所测的这组适配器与这套重新量化配置下,重新量化把 delta 的大部分抹掉了(34% / 2% / 18%),换基座或换重量化方案必须重测。
这一节想让你记住的一件事:低比特基座 + 适配器时,「合并」是能力损失而不是打包便利;如果你的部署链路默认合并,那你可能一直在白扔适配器的大部分效果。
十、实验账:收益主要来自「把读盘挪出关键路径」
论文的实验设计有一处值得学:它不跟你比「谁更快」的绝对值,而是同一个 session 内交替 A/B、每轮换顺序、两条腿在同一份采样 token 序列上重放、两边缓存预算对齐,报的是多轮中位数。它甚至明说了理由——这台硬件上单次基准的轮间波动有 ±40%,跨 session 可达 2.3 倍,所以「跨 session 的数字不当作证据」。
下面这张是它的核心结果(论文 Table 3,16 GB MacBook M2,18.4 GiB checkpoint 装不下,所有臂都在真实地从 SSD 换入专家):
| 路由宽度 | 按需流式(tok/s) | 预测预取(tok/s) | 增益 |
|---|---|---|---|
| 2 | 4.8 | 8.6 | +80% |
| 4 | 3.5 | 6.4 | +82% |
| 8 | 1.8 | 3.3 | +84% |
增益几乎与路由宽度无关(+80% 到 +84%),而绝对速度随宽度急剧下降。这组数字本身就是论点:预测带来的不是「更聪明的缓存」,而是「同样的读盘,早一步发出」。
再看代价(论文 Table 4,同一 session、同一对臂):
| 方案 | 加载次数/步 | MiB/步 | MiB/次 | 冷读比例 | ms/次 | |
|---|---|---|---|---|---|---|
| 2 | 按需 | 99.3 | 30.4 | 0.31 | 20% | 1.56 |
| 2 | 预测 | 19.3 | 29.5 | 1.53 | 98% | 2.41 |
| 4 | 按需 | 189.4 | 50.9 | 0.27 | 17% | 1.29 |
| 4 | 预测 | 44.7 | 58.9 | 1.32 | 84% | 2.28 |
| 8 | 按需 | 398.6 | 126.9 | 0.32 | 20% | 1.44 |
| 8 | 预测 | 89.5 | 125.1 | 1.40 | 90% | 2.36 |
(列名沿用论文口径:MiB/步 是每解码步从存储层实际读出的字节数,MiB/次 是平均每次加载的大小,冷读比例是这些字节里必须等 SSD 的那部分占比。)
三件事在这张表里同时出现:
- 字节数几乎不变(:125.1 vs 126.9 MiB;:29.5 vs 30.4 MiB),只有 时预测臂多读了 16%(58.9 vs 50.9 MiB)。论文的定性是「守恒,不是预测得更准」——它把读盘提前,但不能让读盘消失。
- 次数缩到约四分之一(189.4 → 44.7 次/步,4.2 倍),每次大到约五倍(0.27 → 1.32 MiB,4.9 倍;其余两臂是 4.4–5.1 倍,都不到一个数量级)。这是预取的自然形态:把许多小的、随机的读,合并成更少的、更大的读。
- 每次变贵了(1.29 → 2.28 ms),因为冷读比例从 17% 涨到 84%。论文拟合了单次加载成本:
(论文 Figure 3 拟合式,拟合于 那一对臂,对全部实测单次成本复现误差在 0.13 ms 内,预取点内 0.07 ms。本文自行代入: 预测臂 cold 0.84 → ms,与表中 2.28 ms 一致;按需臂 cold 0.17 → ms,与 1.29 ms 差 0.11 ms。)
于是真正的收益可以直接读出来——主线程等加载的阻塞时间:
- :154.9 → 46.5 ms/步
- :244.0 → 101.9 ms/步
- :575.0 → 211.6 ms/步
(论文 §5.3 实测。)
想自己核一遍量级的话,可以拿 那行做粗算:按需臂每步 189.4 次加载、每次 1.29 ms,乘积约 244 ms,与实测等待之和 244.0 ms 等同量级;预测臂 44.7 × 2.28 ≈ 102 ms,对上 101.9 ms。这两组相等只说明统计相容(乘积与和是同一量级),不能据此断定没有重叠——论文明确说不同层的加载会重叠, 那组「等待之和 575.0 ms > 墙钟 559.1 ms」就是反例;判串行度要靠时间线或关键路径测量。能下的结论是窄的:同样的总字节、同样的单次成本表,仅仅因为「发出时机」不同,等待之和从 244 掉到 102;剩下的 102 ms 是仍未隐藏的等待(论文口径:主线程等待加载的跨层求和),预测把它压到零。
同一步里,三个资源都没被吃满:磁盘读最多占整步的 12%,进程只用约 1 个核(共 8 个),GPU 占用 35–41%。瓶颈不是任何一个资源,而是等待的顺序。 这句话是整篇论文最值钱的一句工程判断。
十一、质量账:损失集中在长链推理
质量用 OpenCompass 在算力服务器上跑,Edge0(int4 + 适配器 + 预测路由)与原始 fp16 基座同设置对比,不涉计时(论文 Table 2):
| 基准 | edge0-35b (int4) | Qwen3.6 (fp16) | edge0-8b (int4) | Ling 3.0 tiny (fp16) |
|---|---|---|---|---|
| AIME 2026 | 86.6 | 92.7 | 63.3 | 73.3 |
| HumanEval | 90.9 | 95.1 | 91.5 | 92.7 |
| GPQA-Diamond | 79.8 | 81.8 | 70.7 | 71.2 |
| MMLU-Pro | 81.0 | 84.6 | 70.1 | 65.8 |
| IFBench | 57.9 | 61.7 | 53.9 | 60.6 |
| 平均 | 79.2 | 83.2 | 69.9 | 72.7 |
(每格满分 100。)
两个档位的平均值差是 35B 档 4.0 分(论文报「逐基准平均偏差 3.9」)、8B 档 2.8 分。但这个平均掩盖了一个非均匀结构,论文自己在局限一节里点了出来:损失集中在长链推理——35B 档 AIME 掉 6.1 分,8B 档掉 10.0 分,而 8B 档其他基准都在 6.7 分以内,MMLU-Pro 甚至比基座高 4.3 分。
这个结构值得工程读者停下来想一想:它不是「整体稍微差一点」,而是「在需要长链条、每步都不能错的任务上差得多」。如果你的场景是单轮检索问答或格式抽取,3–4 分的平均差可能感觉不到——但这只是推测,五个基准的均分并不能证明某类任务无感,要到你自己的任务上测;如果是数学推理、多步工具调用、长程代码修复,就该按最差的那个分项(而不是平均值)来评估能不能用。
十二、内存账:2.9 GiB 到底买了什么
回到开头那三个数字。为什么「装不下」的版本反而快?论文的解释很直接:全驻留时那 18.2 GiB 是不可回收的权重,24 GB 里几乎什么都没给 KV 缓存和操作系统留,于是系统只能换页;Edge0 的峰值活跃内存是 2.9 GiB,其余字节留在磁盘上。但要注意:磁盘上有文件 ≠ 那些字节不在内存——页缓存与暂存槽都在真实占用内存,只是页缓存可回收、暂存槽已计入分配峰值。
| 口径 | 全驻留(mlx-lm) | Edge0 流式(35B 档) |
|---|---|---|
| 解码 | 3.9 tok/s | 20.4 tok/s |
| 全量路由专家是否常驻内存 | 是(含在 18.2 GiB 里) | 否(字节在磁盘,按需流入) |
| 全驻留权重内存 | 18.2 GiB | 不计(改由页缓存与暂存槽承担,二者都占真实内存) |
| 峰值活跃内存 | 18.2 GiB | 2.9 GiB |
| checkpoint 在盘上 | 19.5 GB | 19.5 GB |
预取的价钱也在这里付出:预测需要那些专家在被用到之前就在内存里,而 MLX 的已分配内存不可回收。论文实测(16 GB 机器):
- 不可回收分配:按需 1.72 / 1.73 / 1.79 GiB()→ 预测 2.33 / 2.60 / 3.22 GiB;
- 进程 RSS(含文件页):按需 5.29 / 6.12 / 6.18 GiB → 预测 4.91 / 5.61 / 6.39 GiB;
- 代价的来处: 时预测臂多占 1.43 GiB 不可回收内存,页缓存相应少了 1.15 GiB——约五分之四的驻留成本是从页缓存里抢来的。
注意 RSS 那三个数的方向并不一致:(5.29 → 4.91)与 (6.12 → 5.61)预测臂更低,而 (6.18 → 6.39)预测臂反而更高。原因大概是预取把「分散的小冷读」变成「集中的大冷读」,文件页的驻留形态跟着变,在驻留成本最高的那一档翻了向。结论不变、但口径要收紧:判断一个流式方案好不好,不能只看 RSS,要看不可回收分配和页缓存的差额——RSS 的变化方向可能随档位翻转。
一个 24 GB 机器的分配先验,可以用本文的算式自己摆开:
(本文自行推导的记账式;论文没有给这个式子,它给的是各分项实测:解码器图与执行器分配、每层暂存槽、KV 缓存、适配器与预测头 0.2 GB。)按论文的 35B 档数字,等号左边是实测的 2.9 GiB,右边各分项的具体拆分论文没有逐项列出,这里不替它编。
prefill 是镜像的另一半:35B 档冷启动首次 prefill 113 tok/s、热 prefill 140 tok/s(3.1k token 的 prompt),8B 档 500 / 1102;prefill 走的是「整层加载」路径(一层所有专家一次性读进来,因为 prefill 会命中一层里的全部专家),此时没有预测可做,页缓存热起来之后 prefill 变成算力受限。这套机制的全部靶子是 decode,不是 prefill。
十三、它与你可能已见过的四种「专家卸载」有什么不同
专家卸载不是新题目。论文的相关工作把已有的四条路摆得挺清楚,但真正有价值的区分不在「谁把权重放哪」,而在谁知道下一步需要哪些专家:
| 方案 | 权重放在哪 | 谁决定下一批专家 | 预测偏了怎么办 |
|---|---|---|---|
llama.cpp 的 --cpu-moe | MoE 专家留在 CPU/系统内存,注意力在 GPU | 不预测:按当步真实路由从系统内存取 | 不存在「偏」,但每条 token 都要过一遍内存带宽 |
| PowerInfer | 神经元分热/冷,热驻 GPU、冷留 CPU | 部署前离线 profiling 定热/冷放置,运行时用 adaptive predictor 预测本层激活;不做跨层/跨 token 的提前取数 | 冷神经元按原样回落到 CPU 路径 |
| Mixtral-offloading / MoE-Infinity | 专家按热度或复用距离做缓存 | 历史统计(热度 / 复用距离),没有跨 token 的可训练预测头 | 未命中就从上一级取,等待暴露在关键路径上 |
| FlexGen | 权重与 KV 一起做 GPU/CPU/磁盘三级 | 不做跨层预测,按调度策略批量搬 | 未命中即等待 |
| Edge0 | 专家权重留在 SSD,按需 mmap 流入 | 部分层设置预测头(35B 档 33 个头、32 层消费),提前一个 token | 不存在「偏」:预测就是路由,暂存集恒等于路由集 |
这张表想让你注意一件事:前四行都在移动同一个字节集合,它们的差别只是在哪一级、缓存策略多聪明;只有最后一行改变了这个集合的性质——它让「需要的集合」由预测决定,于是「加载的集合」不可能错配。代价是模型的输出被永久地换了一条路由,而不只是搬运方式变了。
这也解释了论文里那句略带挑衅的话:「预测选择,暂存加载」——暂存(staging)本身不是可部署的配置,没有正确的集合来源,它要么丢专家导致输出退化,要么钉住一个热集合来回抖动。
十四、系统怎么搭:一张图看懂数据流
flowchart LR
subgraph DISK["SSD:19.5 GB int4 checkpoint(按层堆叠的 safetensors)"]
L1["层 N 专家<br/>256 × 1.77 MB"]
L2["层 N+1 专家<br/>256 × 1.77 MB"]
end
subgraph MEM["内存:可回收页缓存 + 有限暂存槽"]
PC["OS page cache<br/>(LRU,可回收)"]
SLOT["暂存槽<br/>sticky slot 双缓冲"]
end
subgraph GPU["GPU:解码前向(跨两个 token)"]
ATTN["注意力 + 归一化<br/>token t"]
PR["预测头(层 N 拥有)<br/>在 token t 预测层 N+1 在 token t+1 的路由"]
MOE["MoE 层 N+1<br/>token t+1,按预测集合执行"]
end
L1 --> PC
L2 --> PC
PC --> SLOT
SLOT --> MOE
ATTN --> PR
PR -- "预测即路由:直接决定要预取的专家" --> PC
PR -- "跨步消费:t+1 用 t 做出的预测" --> MOE
MOE --> ATTN
LORA["recovery LoRA(42 MB,永不合并)<br/>只挂注意力与共享专家投影,不作用于路由专家"] --> ATTN这张图说明什么:预测头不在推理的关键路径上做决策,它只是提前把「该搬哪些字节」告诉装载器。 真正的路由决定由预测直接给出(图中从预测头到 MoE 层的那条线),装载器则靠页缓存与暂存槽把字节提前放好。LoRA 是一条常年挂着的并行支路,永远不并进 4-bit 基座。
论文的引擎还有四个执行器路径,按用途切换、但共用同一个量化 gather 内核,且每条路径都要与反量化参考实现做逐元素比对(相对 L2 误差只到内核自身的 bf16 内部精度):
- exact:去重后按需构建、堆叠、量化 gather。其他三条路径的正确性基线。
- staged:固定槽位双缓冲,解码的主力。路由索引通过槽表映射,索引不出 GPU;专家集合重复时复用已建的图节点;用常驻的 sticky-slot 张量原地更新(
incr_stack),一步只重写变化的那几个专家,而不是重建一层的九个堆叠张量(gate/up/down 各自带缩放与偏置)。 - hot:每层一组 LRU 常驻的热专家,命中走堆叠 gather,未命中回落 exact——和 PowerInfer、Mixtral-offloading、MoE-Infinity 的热/冷切分是同一个思路。
- whole-layer:prefill 时一次把一层全部专家读进来。因为 checkpoint 是「按层堆叠」布局,这一次读是九个直接读(三个量化投影),而不是 次构建;CPU 侧的加载与前一层 GPU 执行重叠。
「exact 作为正确性基线、其他路径与之逐元素对齐」这个契约,是它能按层、按阶段自由切换路径而不改变输出的前提。工程上这是个便宜但经常被忽略的纪律:任何加速路径都要有一个可以随时回退的参考实现,否则「快」和「对」就只能二选一。
十五、论文没解决的三件事(也是你抄之前要知道的三件事)
论文在局限一节里自己交代了四条,我认为其中三条对「我要不要用」影响最大:
- 一次只服务一个请求,FIFO 串行。 并发属于服务层,不属于这个引擎;而批处理会改变专家的活跃集合,论文的按请求 profile 并没有建模这件事。这意味着这套数字是单流交互场景的数字,不能直接拿来推吞吐型服务的成本。
- 44 ms/步的图构建地板。 论文说得很直:流式引擎的解码瓶颈是 CPU 侧而不是存储侧,40 层前向里 44 ms/步的图构建是下限,任何存储侧优化都推不动它;要关掉这个差距需要内核级的图摊薄,或者换更小的模型。K=8 时主线程上同步做的填充就要 62.5 ms/步,把它挪到别的线程是论文列出的「还没拉的第二个杠杆」。
- 收益被复用率限制住。 相邻 token 在一层上只有约四分之一的专家集合重合,所以大部分预取来的专家在后续 token 里未再次复用(注意:这不是「预测白读」——预测集合就是当步路由集合,当步一定被消费,浪费的是后续 token 的命中)。论文归因得很干脆:存储层决定「有多少可赢」,复用率决定「预测能收到多少」。
另外两条值得知道:实现范围要带日期:论文 v1(2026-09-16)里只有 MLX 一条实现路径,CUDA 那一格是架构不是代码;但按官方模型卡,Edge0 已在 2026-09-30 放出 iOS·macOS·Android·Windows 四个平台的原生引擎(2026-10-26 读取)——所以「只有 MLX」是论文当时的实现状态,不是今天的事实;质量的损失集中在长链推理(§十一)。
一个不那么显眼但很关键的点:这套设计的收益会随硬件变薄。 论文自己说,预取收益来自「它移除的等待」——页缓存热、存储快的时候收益自然缩小。换句话说,如果你的机器是 128 GB 内存 + 能把 19.5 GB 全放下,那这套方案最大的卖点(内存)消失,剩下的是「省内存」而不是「更快」;如果你的盘是 PCIe 5.0 且冷读便宜,那么每次加载的成本项 变小,预取的价值也跟着缩水。它更适合「内存紧、存储慢」这个区间;论文没有把它与全部替代方案做对比,所以不能说它是该区间的全局最优。
十五·补:仓库口径「约 2.5 GB」与论文实测 2.9 GiB 的关系
读这篇论文最容易撞上的第二个口径矛盾在这里。论文仓库的自我介绍写的是「在约 2.5 GB 内存里跑 35B MoE」,而论文正文实测的 35B 档峰值活跃内存是 2.9 GiB。两个数来自不同来源、覆盖的测量对象未必相同:
- 约 2.5 GB 是仓库 About 的约数(它是否对应某一组具体分项,本轮没有核到)。它到底对应哪几个内存分项,本轮没有核到定义(README 里另有一组带 MLX allocator 说明的数字,也不是同一个口径)——所以这里只能说「两个数是不同来源的不同口径」,不能替仓库补一个测量定义;
- 2.9 GiB 是论文 §5.4 报告的实验口径,MLX 分配器峰值、短上下文、按发布档 配置实测。
本文一律引用 2.9 GiB,并在 §十二 的内存表里注明这是「峰值活跃内存」而不是「进程 RSS」或「磁盘占用」。同类数字并置时,先出现的那个位置就必须把口径写清楚——否则读者会把 19.5 GB(磁盘)、18.2 GiB(全驻留)、2.9 GiB(流式峰值)三个数当成同一件事的不同说法。
15.1 如果换成 32 路并发,这套账会变成什么样(本文自行推导)
论文的局限一节承认它一次只服务一个请求、FIFO 串行,而批处理会改变专家的活跃集合。这一步值得自己推,因为它是「这套方案能不能上生产」的分水岭。
单请求 时,每层只碰 4 个专家, MB;40 层约 283 MB(前文 §三 的 )。
如果 32 个请求一起做一步解码,最坏情况下每层被选中的不同专家数是:
对应每层字节数 MB,40 层约 GB——在这个「无缓存命中、无跨步复用、所需专家均从 SSD 读取」的示意上界下,一步的访问量约 9.1 GB,按 5 GB/s 的盘算约 1.8 秒一步。实际 I/O 会小得多(页缓存、批内共享、跨步复用都未建模)。
但注意这一步同时产出了 32 个 token,所以摊到每个 token 的字节仍是 283 MB,单请求与批处理一样。批处理改变的不是总字节效率,而是三件事:每步延迟从几十毫秒涨到秒级、交互体验(首 token 延迟、打字机感)直接崩掉、以及「预测预取」要覆盖的窗口从几十毫秒变成一个秒级区间(能不能藏住要看时间线,不能默认窗口变宽就更划算)。
结论要说得克制:流式 + 预取在单流交互下是正收益,在吞吐型批处理下必须先重算延迟预算(首 token 延迟与每步解码延迟要分开算),而论文没有测这一格(它的 profile 是单请求的)。这也解释了为什么它把并发明确划给「服务层」:那是另一套账。
15.2 冷启动那一次特别难看,稳态才是这套方案的主场
论文分别报了 prefill 的冷、热两个数(3.1k token 的 prompt):35B 档冷 113 tok/s、热 140 tok/s;8B 档冷 500 tok/s、热 1102 tok/s。
本文自行推导:热的/冷的比值,35B 档是 ,8B 档是 。小模型在冷启动时被 IO 拖得更狠,一个自然的解释是它的每层专家更少、每步算力更小,加载时间在整步里的占比更高(本文推断,论文未给这项归因)。
这条对验收方式有直接影响,也是很多「端侧大模型 demo」翻车的地方:你不能用第一次跑的感受评价这类方案,也不能只看稳态曲线。 但要分清这里的举证是冷热 prefill(同一阶段、缓存状态不同),而稳定 decode 是另一项测量(§十 那组),两者机制不同、不能互相解释。验收指标应按三段分开列:模型加载时间、首次 prefill / 首 token 延迟、稳定 decode 的 tok/s。要评它,就得分两个数报:冷启动的首次可用时间,与稳态的 tok/s。
15.3 预测头本身有多大:一笔可以自己核的账
论文说 35B 档的「适配器 + 预测头」一共多占 0.2 GB。这句话可以自己验一遍。
单个头按 §五 的形状算(35B 档:输入 2560、隐藏 512、输出 256,另加一条 2048→256 的线性残差):
33 个头合计 参数,fp16 存储约 130 MB;加上论文报告的 42 MB LoRA 适配器,合计约 172 MB——与「0.2 GB」这个口径对得上(本文自行推导)。
算力侧同样可以估:每 token 每头约 MFLOPs,33 个头约 0.13 GFLOPs;而一个每 token 激活 3B 参数的 MoE 本身约 6 GFLOPs(,本文按乘加两次运算估算)。也就是说预测头只占约 2% 的计算量——它便宜的真正原因不是「小」,而是它把几十毫秒的磁盘等待换成了几毫秒的计算。
十六、给工程读者的六条可迁移结论
这六条我认为即使你一辈子不部署 Edge0 也用得上。
- 先分清你卡的是「字节」还是「等待」。 判断方法很土但有效:看每步的阻塞时间之和是否近似等于「加载次数 × 单次耗时」。论文的 那行是 189.4 × 1.29 ≈ 244 ms,与实测 244.0 ms 对得上——这说明它是串行的。如果对不上(显著小于),说明已经在重叠,你该去挖别的地方。
- 把「次数」和「字节」分开做优化。 同一份字节,189 次小读和 45 次大读在论文那台机器上差了约四到五倍(Table 4);别的硬件上要实测,不能默认同倍数。合并读的收益通常比减少总字节来得快。
- 低比特基座上的适配器不要合并。 保留率 34%/2%/18% 这三个数字说明:合并后再量化会把 delta 抹到 4-bit 台阶以下。要合并就得先提高基座精度,等于把省下来的内存还回去——是否值得取决于你的基座与重量化配置,需要实测(论文只测了它自己那一组)。
- 「预测即路由」是一条设计取舍,不是唯一解。 保留「预测失败就回退真路由」的路径也完全可行,代价是每次回退都在关键路径上等一次加载——论文实测同 token 的预门控变体跑不过 LRU 基线,这是它选「不回退」的理由,而不是「回退不可用」的证明。
- 估算任何「卸载」方案的收益,先算每 token 必须就位的字节数(),再乘上你的目标解码速度,得到所需的持续带宽。这个数字如果超过你的存储层,就必须依赖缓存命中率;而命中率是可测的、不是可以假设的。
- 别用 RSS 判断内存方案。 用「不可回收分配」和「页缓存被挤掉多少」。论文的 那组里,预测臂多占 1.43 GiB 不可回收内存、页缓存少了 1.15 GiB,而 RSS 只从 6.18 涨到 6.39 GiB(约 3%)——只看 RSS 会严重低估代价,而且它在低档位还会反过来下降,方向都不可靠。
十七、四步自测:你的场景到底吃不吃得到这套收益
- 量「每 token 必须就位字节」与你的盘带宽的比值。 用 算出 (本文 §三 的算式),再除以你实测的顺序读带宽,得到一个「理论最低每步秒数」。如果这个值已经高于你的目标每步时间,那说明你必须依赖缓存命中,预测预取只控制「这一批要读哪些字节」,并不控制 OS 页缓存命中率(预取臂的冷页占比反而更高)。
- 量等待暴露度。 「加载次数 × 单次耗时」与实测等待之和相等只说明统计相容,不能判串行;要判必须做时间线或关键路径测量(论文自己就有「等待之和 575.0 ms > 墙钟 559.1 ms」的反例)。先拿到「主线程实际被阻塞多久 / 一步总时长」,再决定要不要上预取。
- 量复用率。 统计相邻 token 的专家集合重合比例。论文在自己的 traces 上只有约 1/4;如果你的场景更低(例如高熵采样、多轮短对话),预取来的专家未再次复用的比例会更高,收益上限也就更低(这仍不是「当步浪费」)。
- 量一下你的「不可回收分配」与页缓存的此消彼长。 把预取打开前后各采一次 MLX/CUDA 的分配峰值与
MemAvailable,看预取多占的内存里有多少是从页缓存抢来的。论文的比例是「多占 1.43 GiB、页缓存少 1.15 GiB」,约五分之四;如果你的机器上这个比例接近 1,说明预取几乎全在跟页缓存抢,收益会打折。
十八、小结:四句可以带走的话
- MoE 的稀疏性省算力不省字节。 35B 级 MoE 的 19.5 GB 4-bit 权重里,18 GB 是路由专家,一个都少不了——问题只是它们存在哪。
- 流式加载的瓶颈是等待的次序,不是总字节。 同样的 125 MiB/步,按需读是 1.8 tok/s,提前一个 token 发出去就是 3.3 tok/s。
- 「预测即路由」把运行时的权衡换成训练时的一次性成本。 不丢专家、不回退、不补加载,代价是模型真的活在一条被替换过的路由上,且需要三阶段训练把它教回来。
- 收益是区间性的,且随硬件退坡。 它在「内存紧、存储慢、单流交互」这个区间里把 3.9 tok/s 变成 20.4 tok/s、把 18.2 GiB 变成 2.9 GiB;离开这个区间,卖点会迅速变薄。
这套方案还顺便示范了一件事:论文把自己的基线(全驻留 3.9 tok/s)也一起报出来了,而不是只报自己最好的格子——这让读者能判断收益来自哪里。
论文最后那句话说得挺漂亮,也确实是这件事的形状:「你桌上的机器早就够大了,权重只是需要一个容身之处。」
📋 来源与核验记录
以下 URL 均于 2026-10-26(北京时间)本轮实际打开并核验(HTTP 200,标题与内容一致):
- Yu Lin, Yiming Wang, Runyuan Cai, Hanze Liu, Xiaodong Zeng,《The Other Half of the Memory Wall: Serving 35B MoEs from SSD with Trained Routing Prediction》,arXiv:2609.18063v1,2026-09-16 提交(v2:2026-09-17;本文逐节比对的是 v1 的 HTML 全文),CC BY 4.0。本文所有论文内数字(19.5 GB / 2.9 GiB / 20.4 与 3.9 tok/s / 453 MB 与 1.77 MB / Table 1–4 / 质量表 / 拟合式 / 局限)均出自此文的 HTML 全文:https://arxiv.org/html/2609.18063v1 (摘要页:https://arxiv.org/abs/2609.18063 单列)
- 论文仓库(Apache-2.0):https://github.com/Edge0-AI/Edge0 —— 页面描述明确写「Run 35B MoE models in ~2.5 GB of RAM. Weights stream from SSD; a trained router predicts loads a step ahead」,与论文口径一致(注意「约 2.5 GB」是仓库自己的宣传口径,论文实测 35B 档峰值活跃内存是 2.9 GiB,本文按论文的数字引用)。
- 发布模型(Apache-2.0):https://huggingface.co/Edge0/Edge0-35B-A3B-preview
- 基座模型 config 核验:https://huggingface.co/Qwen/Qwen3.6-35B-A3B 的
config.json(/raw/main/config.json,本轮实际下载),text_config.hidden_size = 2048、full_attention_interval = 4、layer_types为 linear_attention 与 full_attention 交错——用于核对论文预测头输入维度 。模型页:https://huggingface.co/Qwen/Qwen3.6-35B-A3B - Pre-gated MoE(被本文用来对照「提前一层 vs 提前一个 token」):Ranggi Hwang 等,《Pre-gated MoE: An Algorithm-System Co-Design for Fast and Scalable Mixture-of-Expert Inference》,arXiv:2308.12066 —— https://arxiv.org/abs/2308.12066
- 专家卸载的代表工作(用于 §十三 对照表):Artyom Eliseev, Denis Mazur,《Fast Inference of Mixture-of-Experts Language Models with Offloading》,arXiv:2312.17238 —— https://arxiv.org/abs/2312.17238
- 热/冷切分的代表工作:Yixin Song 等,《PowerInfer: Fast Large Language Model Serving with a Consumer-grade GPU》,arXiv:2312.12456 —— https://arxiv.org/abs/2312.12456
论文内的百分比数字(单次加载成本式中冷读比例的拟合、Table 4 的冷读比例 17%/20%/84%/90%/98%、Table 3 的增益 +80%/+82%/+84%、磁盘读占整步最多 12%、GPU 占用 35–41%、 时预测臂多读 16%、LoRA 保留率 34%/2%/18%(logits 层 0.18)、异步填充 62.5 ms、「相邻 token 约 1/4 专家重合」、单次基准 ±40% 轮间波动)均出自来源 1(arXiv:2609.18063)的正文、Table 1–4 与§5.3–5.4,未做二次换算。
本文自行推导的数字(与论文数字分列,不混用):
- 倍、(§一)。
- 与所需持续带宽 (§三,按发布档 、20.4 tok/s 计,假设专家字节全不命中页缓存)。
- 「RSS 6.18 → 6.39 GiB 约 3%」的涨幅换算(§十二)。
- 拟合式在两个臂上的复现值(§十:2.29 vs 2.28 ms;1.40 vs 1.29 ms)。
- 「189.4 × 1.29 ≈ 244 ms 对上实测 244.0 ms」的串行度校验(§十、§十六)。
- §十二 的内存记账式 是本文为讲清结构写的,论文并未给出该式,也没有公开各分项的拆分,故不填数。
- 实体独立转引(不等于实验复现):AI Weekly 2026-09-17 的 alert《AutoArk’s Edge0 Serves 35B MoE From SSD at 20 tok/s on 24GB Mac》https://aiweekly.co/alerts/autoarks-edge0-serves-35b-moe-from-ssd-at-20-toks-on-24gb-mac ;Artificial Analysis 的 Qwen3.6 35B A3B 独立模型记录 https://artificialanalysis.ai/models/qwen3-6-35b-a3b ;论文所引 8B 基座对应页 https://huggingface.co/inclusionAI/Ling-3.0-tiny-base 。这三条只能证明「实体与第三方转引存在」,不能证明 tok/s、训练过程或质量结果被第三方复现过;不存在任何独立复现的证据。
未核实项(如实列出):
- 论文的 8B 档基座写作「Ling 3.0 tiny」,其参考文献指向 inclusionAI/Ling-3.0-tiny-base(本轮核到该页存在),但实际部署用的是哪个 checkpoint 本文未确认;35B 档「Qwen3.6-35B-A3B」同样没有下载权重文件核对,只核到了后者 config.json 的隐藏维度与层类型;论文报告的 40 层 × 256 专家、8B 档 24 层 × 128 专家按其 Table 1 引用。
- Edge0 仓库/HF 页面的实际文件大小、是否与论文的 19.5 GB 完全一致,本轮未逐字节核对(HF 页面为模型卡,未下载权重);仓库 About 里的「约 2.5 GB」也只当宣传口径引用,未核明它对应哪些内存分项。
- 论文的 tok/s 与 ms 数字均为其本机实测(Mac mini M4 Pro 24 GB / MacBook M2 16 GB),本文未在任何机器上复测;本文所有「更快/更省」的表述都是相对论文自己的基线,而不是相对你手上的硬件。