笔记日期: 2026-08-23 作者: Zhongzhu Zhou 阅读论文: FreeToken: Efficient Edge-Native MoE Serving with Bandwidth-Adaptive Execution 论文作者: Shuo Yang, Xiaoze Fan, Melissa Pan, Haocheng Xi, Zhe Wang, Shanlin Sun, Kurt Keutzer, Song Han, Matei Zaharia, Chenfeng Xu, Ion Stoica(UC Berkeley、MIT、UT Austin 及合作团队) arXiv: 2608.16157 会议/状态: 预印本(cs.DC),2026 年 8 月
1. 一句话讲清楚这篇论文在做什么
FreeToken 是一套推理引擎,让一台普通的个人电脑——笔记本、游戏台式机,或者单卡工作站——也能跑起远超自己显存容量的、前沿级别的开源 MoE(Mixture-of-Experts,混合专家)大模型,而且是真正意义上的「交互式速度」,不是那种”能跑但要等半天”的勉强能用。做到这一点的核心思路是:不要把 GPU、CPU、内存、PCIe 链路当成互相独立、各自优化的资源,而是把它们当成同一个可以持续重新调配的统一推理平台。论文里的几个数字放在一起看确实有点离谱:单张工作站 GPU 上跑 7530 亿参数的 GLM-5.2;32GB 显存的游戏台式机上交互式地跑 2840 亿参数的模型;8GB 显存的笔记本上跑 350 亿参数模型,解码速度还比 Codex 生产环境的中位数更快。

真正让这篇论文成为一个”系统贡献”而不是”堆更多 offloading 技巧”的,是解码阶段里一个很具体的洞察:当 MoE 层里被路由选中的专家权重不在 GPU 缓存里(即缓存未命中,cache miss)时,有两种办法把它填上——把专家权重通过 PCIe 传到 GPU 上执行,或者直接在专家权重已经躺在的主机内存里就地执行——而这两种办法没有哪个是普遍更优的,因为它们其实在抢同一份主机内存带宽。FreeToken 由此推导出一个闭式解(closed-form),用一个标量 来决定这两条路径之间该怎么分配,而这个标量只需要在部署的那台真实机器上测量两个数:PCIe 传输带宽,以及 CPU 端专家执行带宽。这就把一个看起来需要”针对每台硬件精细调参”的问题,变成了一条能自动适配任意消费级 GPU、任意内存代际、任意 PCIe 代际的两行公式。
这篇笔记假设读者已经了解 transformer 推理和 KV cache 的基本概念,但未必仔细想过边缘端(edge)MoE 推理这个具体问题——这里的约束不是”怎么让一张 GPU 跑得更快”,而是”怎么让一张 GPU、一个 CPU、一条慢速互联链路配合得像一张更大、更奇怪的 GPU”。第二节从头搭建前置知识(MoE 稀疏性、专家 offloading、为什么 prefill 和 decode 是两个不同的问题)。第三节逐条拆解 FreeToken 的三段式设计,包括 策略的完整推导和语义感知缓存机制。第四节讲一个容易被忽视但很关键的实现细节——怎么让这个动态策略真正跑得快。第五节走完论文里的每一个实验,不只是标题数字。第六节是局限性,第七节是独立的批判性分析小节。
2. 前置知识
2.1 为什么 MoE 同时是边缘推理的机会,也是它的难题
一个 参数的稠密(dense)transformer,处理每一个 token 大致都需要花费 参数量级的计算——不管硬件多强,你都没法让一个 7000 亿参数的稠密模型,用少于 7000 亿参数量的矩阵乘法去处理一个 token。Mixture-of-Experts(MoE)架构打破了这个耦合关系:一个 MoE 层里包含 个专家子网络(常常是几百个),但一个轻量的路由器(router)每次只为每个 token 挑选其中 个。以 DeepSeek-V4-Flash 为例,它在 43 层里每层激活 256 个专家中的 6 个,所以处理任意一个 token 时,实际参与计算的只有全部 2840 亿参数中的 130 亿。这是论文里”机会”的那一半:稀疏激活意味着每个 token 需要的计算量足够小,消费级硬件理论上是有可能跟上的,即便参数总量十分庞大。
“难题”的那一半在于:稀疏性降低了每个 token 的计算量,却没有按比例降低存储完整专家池所需要的内存——你依然需要把全部 256 个专家都放在某个地方,因为你事先不知道某个 token 会被路由到哪 6 个。如果完整专家池装不进 GPU 显存(而对于一个 2840 亿或 7530 亿参数的模型、在一块 24–96GB 的消费级/工作站级 GPU 上,答案显然是装不进去),那些非活跃专家就必须放在主机内存或磁盘上,并按需拉到 GPU 上执行。这就是专家 offloading,它正是边缘 MoE 推理要解决的核心系统问题:稀疏激活让计算变得可行,但完整专家池让服务变得困难,因为现在每个 token 的前向传播,都可能需要经过一条相对缓慢的 PCIe 链路,去取那些还没在 GPU 上驻留的权重。
2.2 Prefill 和 decode 是两个不同的瓶颈,不是同一个问题在不同规模下的表现
很容易把”高效服务一个 MoE 模型”想成一个统一的问题,但论文第二节的诊断性拆解(以及本文这里的复述)把它清晰地分成了两个体制(regime),各自有截然不同的失效方式:
- Prefill(处理最初的 prompt,可能长达几千个 token)会激活每一层几乎全部的专家集合,即便单个 token 只路由到 个专家——因为只要 prompt 里的 token 足够多,它们各自路由决策的并集就会覆盖掉大部分专家池。因此一次 prefill 至少要把接近完整的专家池通过 CPU–GPU 互联通道流式传输一遍,这纯粹是个带宽问题:对于 FP4 精度部署的 DeepSeek-V4-Flash 来说,大约是 140GB 的专家权重,在快速的 PCIe 5.0 链路上大约要 2 秒,在笔记本常见的更窄的 ×8 链路上则要 10 秒以上。一个纯粹按需拉取专家的引擎,会把这整个几秒钟的窗口暴露成 GPU 空闲时间——对于一个理应快速响应的交互式 agent 来说,这是不可接受的。
- Decode(生成阶段,一次生成一个 token)则是相反的体制:每一步只激活真正稀疏的一小撮专家,但具体是哪几个会随每个 token 变化,所以任何一次性(在加载时或 prefill 后)选定的放置方案很快就会过时,而每一次 cache miss 都要么触发一次新的 PCIe 传输,要么触发一次 CPU 执行。这里的问题不是”总共要搬多少字节”,而是”要反反复复地、以低延迟地服务大量微小且不可预测的 miss”,而 CPU 的内存带宽只是 GPU 片上内存带宽的一个很小的分数(消费级双通道 DDR4/DDR5 大约是 50–90 GB/s,而一张 RTX 4090/5090 的显存带宽是 1–1.8 TB/s)。
这两个问题还被第三个在数据中心里根本不存在的因素进一步放大:边缘硬件不是专用的。用户的浏览器、游戏和其他应用会随时抢占同一份显存,可能瞬间占用掉数 GB;推理引擎能用的”预算”不是启动时定下的常量,而是整个会话过程中一直在变化的目标。任何假设内存预算固定不变(只在启动时决定一次)的边缘推理设计,本质上都是在解一个错误的问题。
2.3 现有引擎各自只解决了一部分,不是整体
llama.cpp 在加载模型时就把 MoE 张量静态分配到设备上。KTransformers 把一个固定的”热”专家子集常驻在 GPU 上,用 AMX 优化的内核在 CPU 上执行剩下的部分,只在 prefill 边界更新一次。MoE-Infinity 追踪请求级别的激活模式来指导预取。这些系统里没有一个会在每一步 decode都动态地重新推导”该怎么把剩余的 cache miss 分配给’传到 GPU’和’就地在 CPU 上执行’这两条路径”,而且这个分配依据的是部署机器上实测的带宽平衡——而这恰恰是 FreeToken 核心算法贡献(见下文第 3.2 节)填补的空白。
3. FreeToken 的设计拆解
FreeToken 把 GPU 内存组织成一个两级层级结构(见图 1,复现了论文自己的架构图):CPU 常驻的专家池保存完整的路由专家权重集合,永远是数据的”事实来源”(source of truth);非专家权重(注意力投影、层归一化、embedding)永久驻留在 GPU 上。剩下的 GPU 内存被组织成一个所有 MoE 层共享的单一弹性专家缓存(expert cache),每个缓存槽保存评估一个 (layer, expert) 对所需的全部张量——也就是说,驻留和查找都是基于逻辑标识符操作的,不是基于张量分片。

这套设计直接对应第 2.2 节指出的两个瓶颈:prefill 需要把传输隐藏在计算背后,并避免上下文编辑导致的重复计算(第 3.1 节);decode 需要在两条执行路径之间智能地分配剩余的 cache miss(第 3.2 节);而这两个阶段都需要底层 GPU 内存预算本身在运行时可调整,而不是在启动时就固定死(第 3.3 节)。
3.1 Prefill:全层双缓冲 + 语义感知状态检查点
全层双缓冲把传输隐藏在计算背后。 因为 prefill 阶段几乎会激活每一层的全部专家(第 2.2 节),按需拉取(on-demand fetching)在这里是错误的策略——你已经知道几乎整层专家都要用上了,为什么还要等着看具体哪部分 miss 了才去拉?FreeToken 的做法是从共享槎位池里分配两个完整层大小的缓冲区。当 GPU 正在从其中一个缓冲区计算第 层被路由到的专家时,一条专用的传输流会同时把第 层完整的专家集合流式加载到另一个缓冲区里——第 层的传输甚至可以在它自己的路由决策出来之前就开始,因为反正几乎全部都要拉取。两个缓冲区随后交换角色,进入下一层。这样一来,原本”等传输 → 算 → 再等下一次传输”的串行模式,就变成了一条完全流水线化的过程,PCIe 带宽利用率能逼近物理上限。当共享槎位池腾不出两个完整层的空间时(比如显存非常紧张的笔记本),引擎会优雅地退化回按需 prefill 加载,而不是冒着 OOM 的风险去超额占用 GPU 内存。
语义感知状态检查点让循环状态能在上下文编辑之后存活,而不必从头重新推导。 许多前沿模型会把全注意力层和线性/循环层混在一起(Qwen3.6 里的 gated DeltaNet,Kimi-K3 里的 Kimi Delta Attention),正是因为全注意力的 KV cache 会随上下文长度线性增长。这些循环层把整个过去的上下文压缩进一个持续演化的单一状态里,这对内存很友好,却带来一个更微妙的问题:和 KV cache 不同(如果只是上下文的后缀发生了变化,KV cache 的前缀部分还能被部分复用),循环层这个被压缩过的单一状态要么恰好匹配当前上下文,要么就完全没用——一旦所有信息都折叠进同一个状态里,就不存在”只复用前一半”这种选项。因为保存这样一个完整状态的检查点,代价相当于几百个 token 的普通 KV cache,所以能保留的检查点数量非常有限,放在哪里这件事就变得极其重要。
Agent 框架在编辑上下文时,往往会在非常特定、可预测的位置动手:OpenClaw 会从除最新一轮之外的每一轮助手回复里剥离掉旧的思考(thinking)片段;OpenCode 会把最近窗口之外的旧工具输出替换成一个固定占位符;SWE-agent 只保留最后 条观察结果,其余全部省略。无论哪种情况,这种编辑都是删除或替换掉一整个由特殊 token(</think>、</tool_call>、</tool_output>)界定的完整区块,而这个边界之前的前缀是原样保留的。FreeToken 正是利用了这一点:把宝贵的循环状态检查点专门锚定在这些语义边界上,而不是随意的 token 位置上。当一个新请求在上下文被编辑之后到达时,系统会从最深的、依然存活的检查点恢复,只需要重新 prefill 真正新增的后缀部分——全注意力层像普通推理系统一样,复用基于 radix 树索引的 KV cache 一直到编辑点为止,而循环层则从锚定的检查点继续,而不是从对话最开始重新计算整个压缩状态。检查点槎位以 LRU 的方式独立于普通 KV 池进行淘汰。
3.2 Decode:一步一步推导 带宽自适应执行策略
这是全篇论文最核心的机制,值得完整推导一遍,而不是只抄最终公式。
设定。 在 decode 阶段的每一个 MoE 层里,一个 GPU 内核会判断当前 token 被路由到的专家里,有哪些已经驻留在共享 LRU 缓存中(命中,集合 ),哪些不在(未命中/miss,集合 ,记 )。命中的部分直接在 GPU 上执行,不需要额外决策。真正有意思的问题完全在于:该怎么服务这 个 miss。
为什么不能永远把 miss 都传到 GPU 上? 因为一个 miss 掉的专家不是非得走 PCIe——它也可以直接在 CPU 上就地执行,因为它本来就驻留在主机 DRAM 里。朴素的做法(类似 KTransformers 那种静态 CPU offloading)永远把 CPU 常驻的专家放在 CPU 上执行;朴素的另一个极端(纯预取加传输的设计)永远把 miss 传到 GPU 上。FreeToken 的洞察是这两个极端都在浪费某种资源:纯 CPU 执行会让 PCIe 链路和 GPU 计算闲着,即便 PCIe 明明还有余量可以拿来做一次传输;纯”传输再执行”会让 CPU 核心闲着,并且放弃了一次传输将来能带来的缓存命中收益——而且它还会跟 CPU 执行抢同一份主机内存带宽,因为无论是 DMA 传输还是 CPU 计算内核,最终都要从主机 DRAM 里把专家的权重字节读出来。
剩余带宽论证。 设 为实测的 PCIe 专家传输带宽, 为实测的主机端(CPU)专家执行带宽——两者都在实际部署的机器上实测得到,而不是查规格表得来,因为正如论文所说,“这个最优比例是没法从规格表里读出来的”。由于 PCIe 传输和 CPU 执行最终都要读取同一个主机内存子系统,一旦 PCIe 传输被跑满,留给 CPU 的剩余带宽就是:
这份剩余带宽正是 CPU 能够与正在进行的 PCIe 传输并发地拿去做直接专家执行的部分。FreeToken 把 个 miss 拆成两个集合:缓存填充集 (传到 GPU、在 GPU 上执行、并保留下来供未来复用)和 CPU 执行集 (就地执行,不改变 GPU 驻留状态),满足 ,记 。设 为一个完整专家的字节大小,两条分支的执行时间分别是:
这两条分支是并发执行的——CPU 分支不需要等 GPU 分支跑完——所以处理这一步 miss 所暴露出来的延迟,是两者中较慢的那一个,即 。在 固定的约束下,让这个最大值最小化,恰好发生在两条分支耗时相等,也就是系统在两者之间达到完美负载均衡的时候。令 并求解:
在两个极端情况下检验公式的合理性。 当 (主机带宽只是勉强超过传输带宽——一台”饥饿”的主机)时,:所有 miss 都应该走 GPU,因为 CPU 已经几乎没有超出 PCIe 已占用部分的余量可以贡献了,公式会自动退化成纯缓存填充,不需要单独写一个特例来处理。当 (主机带宽远远超过 PCIe——比如那台 PCIe ×8 的 8GB 笔记本)时, 会缩小,更多的 miss 处理工作会转移到 CPU 上,这也符合直觉:如果 PCIe 才是真正的瓶颈资源,就不该把它浪费在每一个 miss 上,而 CPU 明明还有带宽富余。
在实践中, 会被四舍五入成整数,并且至少保留一次填充(这样即便 CPU 承担了大部分 miss,缓存也依然在持续预热),而具体哪些专家被分进 还是 ,是交给 LRU 缓存本身正常的淘汰逻辑来决定的,不是由带宽公式直接指定——公式只决定多少个,不决定哪几个。
一个结合论文实测硬件带宽的实际数值例子。 值得把真实数字代入公式 3,看看 在论文六台测试机器(表 1 的带宽数据)上究竟能有多大差异——这恰恰能解释第 5.4 节个几个跨硬件结果背后的机制:
| 测试机器 | (GB/s) | (GB/s) | 实际含义 | |
|---|---|---|---|---|
| RTX 4060 笔记本 | 11.8 | 47.5 | 0.25 | 只有大约 4 分之 1 的 miss 会走 GPU;CPU 凭借这台机器狭窄 PCIe ×8 链路 4 倍以上的主机带宽,吸收了大部分剩余 miss。 |
| RTX 3090(服务器限流) | 25.3 | 56.7 | 0.45 | 大致均分,略偏向 CPU。 |
| RTX 4090(服务器限流) | 25.1 | 63.2 | 0.40 | 与 3090 相似——PCIe 4.0 的上限明显低于这台机器的主机带宽。 |
| RTX 5090(服务器限流) | 52.7 | 77.3 | 0.68 | PCIe 5.0 缩小了差距,现在大部分 miss 走 GPU 了。 |
| RTX 5090 台式机 | 49.0 | 53.8 | 0.91 | 主机带宽和链路带宽几乎相当——几乎每个 miss 都走 GPU,因为一旦把这条几乎同样快的 PCIe 链路算进去,CPU 剩下的”余量带宽”就几乎没有了。 |
| RTX PRO 6000 工作站 | 51.5 | 178.0 | 0.29 | 8 通道 DDR5 带来的巨大主机带宽优势,把分配比例又拉回偏向 CPU 执行——尽管这是测试中 PCIe 链路最快的一台机器。 |
这里呈现的规律不是孤立地”链路越快就该往 GPU 卸载更多”——真正起决定作用的是两个带宽的比值,这正是为什么一个基于规格表的启发式规则(比如”永远往 CPU 卸载 X%“)会在这六台机器里,朝着六个不同的方向全部踩错。这也直接解释了第 5.4 节的跨硬件发现:RTX 5090 台式机偏弱(双通道、消费级)的主机内存并没有拖累 FreeToken 太多,恰恰因为这台机器上 本来就已经把几乎所有 miss 都路由到了 GPU 路径,所以偏弱的 CPU 执行路径压根没怎么被用上——而 llama.cpp 那种静态、偏重 CPU 的放置策略没有这样的自适应退路,只能全额承受这份偏弱主机带宽的代价。
执行顺序与精确正确性。 FreeToken 会先启动 CPU 分支(因为它要从 DRAM 里读权重,相对于同样要经过这条 DRAM 读取路径的 PCIe 传输,给它一个头部优势),然后再跑 GPU 的 miss 处理路径(更新缓存、批量拷贝 、对合并后的 GPU 执行集合 做分组计算),CPU 工作线程与此同时并发处理 。CPU 和 GPU 各自算出的部分结果会被精确合并——没有任何算法层面的近似,没有丢弃任何专家,也没有精度损失;模型的输出与一个完全显存驻留的部署所计算出的结果是逐位相同(bit-identical)的。这一点值得特别强调,因为第 6 节相关工作里的一些竞争方案,是用牺牲精确性来换取速度的(拉取低精度的专家副本、跳过得分低的专家);而 FreeToken 的加速完全来自如何调度这个(未被修改的)计算过程在 CPU 和 GPU 之间的分配,而不是去算一个”稍微不一样”的东西。(因为它要从 DRAM 里读权重,相对于同样要经过这条 DRAM 读取路径的 PCIe 传输,给它一个头部优势),然后再跑 GPU 的 miss 处理路径(更新缓存、批量拷贝 、对合并后的 GPU 执行集合 做分组计算),CPU 工作线程与此同时并发处理 。CPU 和 GPU 各自算出的部分结果会被精确合并——没有任何算法层面的近似,没有丢弃任何专家,也没有精度损失;模型的输出与一个完全显存驻留的部署所计算出的结果是逐位相同(bit-identical)的。这一点值得特别强调,因为第 6 节相关工作里的一些竞争方案,是用牺牲精确性来换取速度的(拉取低精度的专家副本、跳过得分低的专家);而 FreeToken 的加速完全来自如何调度这个(未被修改的)计算过程在 CPU 和 GPU 之间的分配,而不是去算一个”稍微不一样”的东西。
3.3 语义感知专家缓存:为什么这个 LRU 缓存值得存在
策略只处理确实发生的 miss; 本身有多大,取决于 GPU 常驻缓存有多善于预判路由器接下来会挑哪些专家。FreeToken 观察到,decode 阶段的路由展现出很强的时间局部性(temporal locality)——在连续的解码步之间,同一个 MoE 层往往会路由到重叠或者最近用过的专家(这一现象在此前跨多个模型家族的”路由一致性”研究里已经被独立测量证实过)。这就支持了一个朴素但有效的策略:一个在所有层之间共享的 LRU 缓存,命中会刷新该专家的最近使用时间,填充会接纳新选中的专家,淘汰则会移除最久未被使用的专家。这里没有针对特定工作负载的预测模型,也没有学习出来的预取器——只是把经典的时间局部性假设,应用在 (layer, expert) 这个粒度上,而不是一个朴素实现可能会用的 (layer, tensor-shard) 粒度上。
论文后面的消融实验(见下文第 5.3 节)直接量化了这个机制到底带来了多少收益——相对于两种竞争性的放置策略(静态分割、prefill 时更新)——差距足够大(在同等缓存大小下,miss 率低 2–5 倍),说明这个简单机制确实在做实事,不只是边际上的锦上添花。
3.4 弹性内存管理:让 GPU 预算变成运行时变量,而不是启动时的常量
因为主机常驻的专家池永远是数据的事实来源,GPU 缓存容量纯粹是一个性能杠杆,从来不是正确性杠杆——缩小缓存只会让事情变慢,永远不会算错。正是这个特性,让 FreeToken 能做一件大多数推理引擎做不到的事:在调度器的安全点上运行时调整 GPU 专家缓存大小,而不需要重启引擎,也不需要重新从磁盘加载主机常驻专家池。这一点之所以重要,是因为一次真实会话里有两件事在持续漂移:引擎能用的显存预算(要和浏览器、游戏、桌面合成器共享),以及这份预算在 KV cache 和专家缓存之间的分配比例(agentic 会话会随着多轮对话不断累积上下文,所以 KV cache 的需求会在整个会话过程中持续增长,而专家工作集大致保持不变——第 1 轮时正确的分配比例,到第 20 轮就已经不对了)。
论文还处理了第二个不那么显眼、但同样很实际的边缘部署成本:启动延迟。从一块 7GB/s 的 NVMe 盘上加载一个约 140GB 的专家池,在任何请求能够开始之前就要花掉大约 20 秒——而在个人机器上,引擎启动是经常发生的事(用户会关掉引擎释放机器、切换模型、崩溃后重启),不像数据中心部署那样启动一次然后连续跑上数周。FreeToken 通过把专家权重从磁盘直接读进它们最终的主机内存布局、并且只在填充完毕之后才做内存锁定(pinning)来缩短这一过程——如果先锁定空缓冲区,会导致这些页面被立即换入并清零,而这些字节马上就要被覆盖掉,纯属浪费。它更进一步,彻底取消了 GPU 预热:第一个请求就用一个冷缓存来服务,它的 miss 走第 3.2 节描述的普通 decode 路径来处理,缓存会在正常服务过程中自然升温,而不是经过一个专门的(而且对用户可见的)预热阶段。
3.5 把 decode 一步的控制流串起来看
上面的文字推导最好用一张图来内化:每一步 decode 中、每一个 MoE 层上,按顺序发生的事情如下:
flowchart TD
A["路由器为当前 token 选出 top-k 个专家"] --> B["GPU 内核把它们和驻留表比对分类"]
B --> C{"在 GPU 缓存里吗?"}
C -- "命中(集合 H)" --> D["直接在 GPU 上执行,刷新 LRU 时间"]
C -- "未命中(集合 M,|M|=m)" --> E["计算 q* = m * B_P / B_H(式3)"]
E --> F["将 M 拆分为缓存填充集 F(大小 q)和 CPU 执行集 C(大小 m-q)"]
F --> G["CPU 分支:从主机常驻专家池里就地执行 C"]
F --> H["GPU 分支:通过 PCIe 传输 F,更新缓存,对 G = H_命中 并 F 做评估"]
G --> I["精确合并 CPU 和 GPU 的部分输出(无任何近似)"]
H --> I
D --> I
I --> J["得到层输出,与完全显存驻留部署逐位相同"]
图 A(自绘,汇总了第 3.2 节 decode 阶段的控制流):每一层的 miss 集合,都会按闭式解 比例拆成 GPU 缓存填充路径和 CPU 就地执行路径两部分,二者并发执行并精确合并。 正是这个机制,把一个本来很依赖具体硬件的调参问题,变成了一个只需两个实测数字、每一层每一步都重新计算一次的闭式解运行时决定。
3.6 弹性内存管理和快速引擎引擎开机是怎么拼在一起的
第 3.4 节的两个机制——运行时缓存重配置和快速引擎启动——最好理解为同一个生命周期里的两个阶段,一个在启动时,一个在服务过程中持续发生:
flowchart TD
subgraph startup["引擎启动(第 3.4 节)"]
A["直接从磁盘读取专家权重到最终的主机 bank 布局(FTW 格式)"] --> B["只在 bank 填充完成后才锁定主机内存"]
B --> C["用一个冷缓存服务第一个请求——没有专门的预热阶段"]
C --> D["缓存通过普通的 decode 路径(第 3.2 节)自然升温"]
end
subgraph runtime["在调度器安全点上持续进行的运行时适配"]
E["VRAM 预算在漂移:其他应用占用/释放显存;KV cache 需求随着 agent 轮数增加"] --> F["针对修订后的预算重建 GPU 专家缓存"]
F --> G["不重启引擎;不重新加载主机常驻专家池"]
G --> E
end
D --> E
**图 B(自绘,汇总了第 3.4 节):快速引擎启动让引擎能很快开始服务,不需要专门的预热阶段;而同样的”主机池永远是正确的,GPU 缓存只是一个性能杠杆
一个再聪明的带宽分配公式,如果计算和应用它本身又引入了它想要消除的那份延迟,那就毫无意义。FreeToken 的实现部分正是在解决这个具体风险,理解为什么这不是一个 trivial 的问题,是理解这个修复方案的前提。
问题所在:朴素实现里,依赖路由结果的控制逻辑每一层都需要一次主机同步。 哪些专家 miss 了、miss 了多少个、要淘汰哪些缓存槎位——这些在每一个 MoE 层、每一步 decode都会变化,这本质上就是动态的、依赖数据的控制流。一个朴素的实现会需要:GPU 先算完路由决策,把结果拷回主机 CPU,让主机端代码决定 并选择淘汰对象,然后再发起下一批内核启动——这在每一层都是一次昂贵的设备同步,会吃掉这整套方案本来想要节省下来的大部分延迟收益。
修复方案:把所有依赖路由结果的控制逻辑都留在 GPU 上,作为静态捕获的 CUDA Graph 里的数据来处理。 对每一个 MoE 层,一个单一的 GPU 内核会完成:去重被路由到的专家、把它们和驻留表做比对分类、计算带宽推导出的拉取数量 、选出淘汰对象、把逻辑专家 ID 重写成物理槎位 ID(或者一个 CPU 分配标志)——全部过程都不离开设备。淘汰对象的选择特别避开了经典 LRU 的一个陷阱,即每淘汰一个槎位就要扫一遍整个缓存:一个单遍(single-pass)内核一次性识别出 个最久未使用的候选槎位,miss 处理路径只需要消费其中前 个——这样一来,发现淘汰对象的开销永远是常数,和某一步实际发生了多少个 miss 无关。因为每个专家 bank 都共享同一套逻辑 (layer, expert) 到槎位的映射,一份设备常驻的索引列表就能驱动跨所有 bank 的一次融合传输,用一次固定形状的内核启动完成,再用一个有效计数字段来屏蔽掉没用上的那部分工作——这带来了很少的内核启动次数、很高的持续 PCIe 利用率,以及在关键路径上零主机端决策延迟。
CPU 分支也被捕获进同一个图里:对每一个支持的 decode batch size,FreeToken 会准备稳定的锁页 I/O 缓冲区和持久化的任务描述符,所以设备到主机的拷贝、一个提交主机函数的节点、并发的 GPU 路径、一个同步节点、以及主机到设备的结果拷贝,全都被一起捕获,作为一个整体重放——这意味着重放会重新执行整个异构步骤(GPU 和 CPU 分支一起),不需要任何逐 token 级别的 Python 调度开销。CPU 端的工作线程池是一个持久化、绑定到具体物理核心的 C++ 线程池,其内核使用架构专属的 SIMD 指令和内核内反量化(in-kernel dequantization),让整条路径始终受带宽而不是算力限制(这一点很重要,因为整个 公式的前提就是假设 CPU 执行受限于内存带宽,而不是 CPU 算力吞吐)。
在存储层面,FreeToken 引入了FTW(FreeToken Weight)格式,它把模型特定的 checkpoint 布局预先合并成一小组用扁平化的 标识符索引的”专家 bank”,这样 GPU 内核和 CPU 执行器就能通过同一个共享的逻辑标识来访问专家,不管原始 checkpoint 的物理张量布局是什么样。这让引擎启动时可以完全跳过张量发现和重打包的过程,通过并行的直接 I/O 把对齐的数据块直接读进精确大小的主机 bank 里。当完整专家池无法被锁页或注册为 DMA(某些操作系统/驱动配置下的限制)时,引擎会退化成一个纯 CPU 的 MoE 后端,专家权重保留在普通的可分页内存里,所有被路由到的专家都在 CPU 上执行——用峰值带宽换取部署上的保底可用性,这是一条明确且合理的降级路径,而不是直接失败。
5. 实验拆解
5.1 实验设置
六台独立 GPU 系统覆盖了消费级和工作站级硬件的实际范围(见原论文表 1):一台 RTX 4060 笔记本(8GB 显存,PCIe ×8,实测传输带宽 11.8 GB/s)、一台 RTX 5090 台式机和三台租用的双路服务器(3090/4090/5090,被限制在 6 个 CPU 线程并绑定到 GPU 所在的 NUMA 节点上,以此模拟消费级主机带宽,尽管用的是服务器级 CPU),以及一台单卡 RTX PRO 6000 Blackwell 工作站 GPU(96GB 显存)用于前沿规模的展示。论文表格里所有的带宽数字都是在实际部署的张量形状上实测得到的,不是从厂商规格表抄来的——考虑到整套 公式完全依赖于带宽测量的准确性,这个方法论细节很重要。
两个主要模型:DeepSeek-V4-Flash(2840 亿总参数,130 亿激活参数,路由专家原生就是 MXFP4 量化的)和 Qwen3.6-35B-A3B(BF16 精度,只有 8GB 那台笔记本出于内存原因用的是官方 NVFP4 版本)。一个跨硬件的扩展实验加入了 GLM-5.2(7530 亿总参数,400 亿激活参数,NVFP4 精度,一个 433GB 的 checkpoint)作为在 RTX PRO 6000 上的前沿规模展示层。四个真实的 agentic 工作负载覆盖了不同的服务体制:W1(AIME 数学推理,单轮,decode 主导,不涉及工具调用),W2(通过 OpenCode 框架、经过三轮脚本化用户交互解决的一个 SWE-bench 代码仓库问题,涉及真实的工具执行),W3(同一个代码问题,通过 Claude Code 的原生协议驱动,会派生出并发请求的子 agent,会话增长到 56–65k token),以及W4(通过 OpenClaw 完成的 13 轮邮件/日程 agent,携带约 24.5k token 的系统上下文底座)。基线包括 llama.cpp、Ollama、KTransformers 和 MoE-Infinity,各自跑在它们所支持的配置上,并且各引擎之间的权重格式被精确对齐,以保证公平性。
5.2 主要结果:解码吞吐量与尾部延迟的故事

在 RTX 5090 上,FreeToken 在 Qwen3.6-35B-A3B 上维持 77–83 tok/s,在 DeepSeek-V4-Flash 上维持 22–25 tok/s——分别是各工作负载下最强基线的 1.8–2.3 倍和 1.5–1.9 倍。比原始数字更值得注意的是在 agentic 负载下的稳定性:在三个真正意义上的 agentic 工作负载(W2–W4)里,FreeToken 的解码速率始终保持在其单轮 W1 值的 12% 范围以内,而对上下文最敏感的基线——KTransformers 在 DSV4-Flash 上——到 W2 时就已经丢失了它 W1 速率的 31%。这一点很重要,因为单流微基准测试系统性地夸大了基线在真实场景下的表现——一个在孤立单轮基准测试上看起来还有竞争力的推理引擎,一旦上下文增长、工具调用开始触发重复 prefill,性能可能急剧下滑,而这恰恰是真实的编码或邮件 agent 所处的场景。MoE-Infinity 值得一提的是它只能跑起 W1(8.8 tok/s):它按专家分级的 prefill 分阶段上限,在更长 prompt 的工作负载上直接中止,而且它自带的服务器不会在多个请求之间保留 KV cache,这让它很难适配任何多轮场景。
Time-to-first-token(首 token 延迟)讲述了一个关于可用性而不只是速度的更尖锐的故事。FreeToken 在六个多轮场景里的五个里都拿到了最低的平均 TTFT(只有在 Qwen3.6×W3 上输给了 KTransformers 专门的 GPU-prefill 分支,在 W1 那些短小、孤立的 prompt 上输给了 llama.cpp——毕竟这种场景下没什么好用流水线去隐藏的)。尾部数据比均值更能把各引擎区分开:FreeToken 在每一个测试场景里,最差的那一轮也不会超过 44 秒,而每个基线都在某个场景下超过了 150 秒——llama.cpp 达到 232 秒,Ollama 达到 179 秒,KTransformers 更是达到了惊人的 946 秒。这些不只是”慢”的数字,它们越过了真实客户端会直接放弃请求的阈值:OpenClaw 内置了 120 秒的空闲看门狗(watchdog),Claude Code 的默认请求超时大约是十分钟。一个偶尔超过这些阈值的基线,不只是”更慢”,从用户的角度看,它是在悄无声息地让请求彻底失败。这正是论文最有力的论点之一:尾部 TTFT 应该被当成一个可用性边界,而不是一个可以被平均掉的延迟统计量。
5.3 收益归因:流水线化 prefill 与专家缓存的局部性

流水线化 prefill。 开启双缓冲重叠后,每一个 8192-token 的 prefill 数据块在 1.19–1.22 秒内完成——这恰好是把模型完整的 64.4GB 专家池,以实测的 52.7 GB/s PCIe 上限速率完整流过一遍所需要的时间。换句话说,专家计算被完全隐藏在传输背后;prefill 变成纯粹受传输限制的过程,吞吐量在 16k-token prompt 时爬升到 6.7k tok/s。如果关闭第二个缓冲区(让传输和计算串行执行),在 4k token 时会损失 19% 的吞吐量,8k 时损失 25%,16k 时损失 26%——这个代价会随 prompt 长度增长,因为更长的 prompt 有成比例更多的计算量可以隐藏在传输背后,失去这个重叠机制会浪费掉其中越来越大的一部分。
专家缓存的局部性。 在 RTX 5090 实际的服务缓存容量下(Qwen3.6 专家池的 37%,DSV4-Flash 专家池的 11%——相对于完整模型来说,这是一个真实意义上偏小的缓存,恰好是边缘场景的实际情况),把来自四个工作负载的相同 decode 阶段路由轨迹,分别重放在三个引擎的放置策略上,FreeToken 的全局 LRU 在两个模型上分别只 miss 掉 16% 和 39% 的 decode 阶段专家读取,而 KTransformers 的 prefill 时更新放置策略是 41%/59%,llama.cpp 那种对路由完全无感的静态分割则高达 62%/89%。这个排序——LRU 优于周期性更新,周期性更新优于完全静态——在几乎覆盖完整专家池之前的每一种缓存容量、每一个工作负载下都保持一致,这相当干净地证实了 MoE 路由中的时间局部性是真实存在且可利用的,不是某一个特定工作负载或模型的偶然产物。
5.4 跨硬件泛化性与前沿规模的展示

这个优势泛化到了整个消费级硬件范围,不只是主要拆解实验用的那台 RTX 5090:FreeToken 在 RTX 3090 和 RTX 4090 上都领先最强可用基线 1.3 倍,在(服务器模拟的)RTX 5090 上领先 1.9 倍,在真实的 RTX 5090 台式机上领先 2.1 倍,在 RTX 4060 笔记本上领先 1.8 倍——其中 NVFP4 版本在这台 8GB、PCIe ×8 的机器上维持 39.3 tok/s,是 RTX 4090 速率的 92%,尽管硬件明显弱得多,而且这个速度还超过了实测的生产环境 Codex 流量 33 tok/s 的中位数解码速度。有一个特别干净的自然实验藏在两个”5090”那一列里:服务器绑定的 RTX 5090 和真实的 RTX 5090 台式机用的是完全相同的 GPU 芯片,唯一的差别在主机系统。从多通道服务器主机切换到真正的双通道消费级台式机,FreeToken 只损失了 4% 的解码速率——但 llama.cpp 却损失了 20% 的速率,因为 llama.cpp 那些 CPU 常驻的专家会被更弱的主机内存子系统”饿死”,而 FreeToken 的带宽自适应分配却不会。这是一个直接证据,证明 策略确实做到了它所声称的事情:自动吸收更弱的主机内存子系统,而不是被它打个措手不及。
在前沿规模这一档,FreeToken 在单张 RTX PRO 6000 上以 14.9 tok/s 的速度服务 GLM-5.2,而 llama.cpp 只有 7.3 tok/s(2.0 倍),两者用的是逐位相同的专家权重,平均 TTFT 也相当(7.5 秒对 7.8 秒)。值得一提的是,KTransformers 在这台硬件上完全没有可行的服务路径:它的方法需要 753GB–1.5TB 的主机常驻专家,而测试机只有 512GiB 可用主机内存,而且它的 CPU 内核压根不支持 GLM-5.2 的 NVFP4 布局——这是一个真正的能力缺口,不只是速度上的差距。
6. 相关工作简述
论文把自己精心地定位在三条相邻的研究线之间。专家 offloading 与缓存(EdgeMoE、Mixtral-offloading、MoE-Infinity、ProMoE、ExpertFlow、FineMoE)都收敛到了 FreeToken 所采用的同一种”主机专家池 + GPU 缓存”架构,但它们之间的差别仅仅在于预测质量——这些系统里的每一次 miss,最终都还是要靠一次 PCIe 传输来服务,所以 decode 延迟始终受限于这条链路,不管预测器有多准,主机的计算能力全程闲置。另一条互补的研究线(HOBBIT、SiDA、SMoE、Pre-gated MoE)则是通过放松精确性来减少传输量——低精度的专家副本、跳过得分低的专家,或者重新构建并微调路由器本身——用一定的精度损失来换取带宽。混合 CPU-GPU 执行方向的工作(FlexGen、PowerInfer、Fiddler、KTransformers、HybriMoE)把 CPU 当成真正的计算资源,而不只是被动的权重存储,但 CPU 和 GPU 之间的工作分配,通常要么在启动时就固定下来,要么由主机端的启发式逻辑重新计算,而这种逻辑每一步的调度和同步开销都没法被捕获进 CUDA Graph——这正是第 4 节实现部分所填补的那个空白。分层内存管理系统(SGLang HiCache、WiSP、eLLM、FluxMoE)会把 KV cache 或专家分页分层存放在 GPU/主机/远程存储之间,但它们移动的只是被动的字节:当某个东西不在了,能做的只有去取它,永远无法在别处把它算出来。FreeToken 声称的贡献,是把这两种手段结合起来:一个统一 prefill/decode 驻留的弹性完整专家缓存,再加上当专家 miss 时,可以选择就地计算而不是只能去取它的这个额外选项——由一个单一的、足够轻量、能塞进被捕获的 CUDA Graph 里的实测带宽模型来协调。
7. 局限性
论文在这几处边界的说明相当直接,值得原样复述一下:
- 质量上没有问题,但从”没有问题”这个角度看,这本身也是一种局限。 因为 FreeToken 只改变了(未被修改的)模型的执行和调度方式——从不做近似、不在 checkpoint 本身已经量化的基础上进一步量化、也不改变路由——所以不存在质量和速度之间的权衡需要评估,论文相应地也没有报告任何精度/困惑度数字。对一篇系统论文来说这是一个真正的优点,但这也意味着 FreeToken 天生就不可能捕获那些愿意牺牲一点精确性来换取更多加速的方法(第 6 节里 SiDA/SMoE/HOBBIT 那一类)所能拿到的额外加速空间——而论文没有量化这个天花板到底有多高。
- 带宽测量是每次部署时静态测一次,不是持续重新测量的。 和 在部署机器上测一次,拿来推导 ;论文没有讨论如果有一个并发应用(会话过程中突然启动的游戏,一次占用大量带宽的浏览器下载)暂时性地抢走了 PCIe 或 DRAM 带宽,会发生什么——这会让”最优” 策略在那段争抢期间,一直基于一个已经过时的带宽比例在算分配。
- 对 CPU 能力差异的探索相对较轻。 所有测试系统的 CPU 都相当能打(Core i9、Ryzen 9,或者被限制到消费级线程数的服务器级 Xeon);论文没有测试一个真正孱弱或老旧的 CPU,在那种情况下 可能低到 CPU 执行几乎不值得去做,这本来是一个能测试 公式鲁棒性的有趣边界情况。
- 前沿规模(7530 亿参数)的展示只是一个数据点。 GLM-5.2 在 RTX PRO 6000 上只在一个工作负载(根据图 6 的图注,是数学 agent)上被评估,而不是像主要的 RTX 5090 拆解实验那样跑遍全部四个 agentic 工作负载,所以它在不同工作负载类型上的泛化性,论证得没有主要结果那么充分。
- 没有多 GPU 或多机的讨论。 论文里的一切都是单 GPU、单机的场景。如果配置变成(这其实是一种相当常见的”游戏主机插两张卡”配置)一台主机共享两张消费级 GPU,带宽自适应执行模型需要怎么调整,论文完全没有讨论。
8. 批判性分析
(a) 这篇论文本身的具体缺陷。 首先, 的推导(第 3.2 节 / 公式 3)是一个干净的闭式结果,但它隐含地假设 CPU 执行分支和 PCIe 传输分支对主机内存带宽的消耗是可加且无损的——也就是说,(大概是在 CPU 分支单独运行时测得的)和 (大概是在传输分支单独运行时测得的)可以简单地相减,得到两者并发运行时的剩余带宽 。但实际上,两个独立的消费者(一个 DMA 引擎和 CPU 核心)并发访问 DRAM,可能会遇到额外的争抢效应(页/bank 冲突、NUMA 局部性不匹配、内存控制器排队),这会让真实可达到的并发带宽,比这个朴素的线性相减模型预测的更低。论文强有力的实验结果说明,这个近似误差在被测硬件上小到不会造成实际影响,但论文并没有直接分离或量化这个具体的近似误差——如果能在几个不同的 值上,直接比较” 预测的最优延迟”和”实测延迟”,本可以更有说服力地证明这个公式在实践中的紧致程度,而不是仅仅从端到端吞吐量数字里间接推断出来。
第二,语义感知状态检查点机制(第 3.1 节)是用三个具体的 agent 框架(OpenClaw、OpenCode、SWE-agent)来动机化的,这三个框架编辑上下文的方式恰好都和特殊 token 边界对齐——但论文没有测试如果换成一个不尊重这些边界的框架会怎么样(比如一种朴素的滑动窗口截断,直接从区块中间切开,而不是在区块边界处切)。既然语义锚定机制的全部收益,在那种情况下都会退化成”没有检查点能存活,回退到完整重新 prefill”,如果论文能刻画一下退化得有多优雅,而不是只展示有利的那种情况,本可以让论证更扎实。
(b) 作者低估或省略的局限。 论文在引言和摘要里都提到”FreeToken 支持超过 20 个 MoE 模型”,但详细的评估实验只覆盖了三个模型家族(DeepSeek-V4-Flash、Qwen3.6-35B-A3B、GLM-5.2)——另外那 17 个以上被声称支持的模型,在论文任何地方都没有给出吞吐量、TTFT 或 miss 率数字。这在系统论文里是一种常见且总体上可以理解的取舍(穷尽性地给 20 多个模型都做基准测试成本很高),但摘要里”支持 20 多个模型”的措辞,会给人一种论文覆盖范围很广的印象,而实际的评估深度并不能支撑这种印象;读者应该把定量结论理解为”在这三个被测试的模型家族上得到验证”,而不是对全部支持模型都成立。类似地,论文没有讨论引擎自身的内存开销,也没有量化 CUDA Graph 捕获所需的那些缓冲区(锁页 I/O 缓冲区、固定形状的工作缓冲区、任务描述符)本身占用了多少显存——在被测设备中最受内存约束的那台(8GB 笔记本)上,这部分记账开销在比例上可能比在 96GB 工作站 GPU 上更重要,但论文任何地方都没有给出量化数字。
(c) 具体的改进建议。 (1) 增加一个直接的微基准测试,专门隔离出剩余带宽模型的预测准确性——在预测出的 附近取几个不同的 值,实测并发 PCIe 传输加 CPU 执行的实际吞吐量,和公式的预测值做对比,以此直接验证(或者界定误差范围)公式 1–3 背后”带宽可以线性相减”这个假设。(2) 为摘要里提到的另外那 17 个以上”被支持”的模型,报告至少一份简化版的吞吐量/TTFT/miss 率数字,让”覆盖范围广”这个说法和评估的实际深度更加匹配。(3) 至少针对一个上下文编辑方式不跟特殊 token 边界对齐的 agent 框架,测试一下语义锚定检查点机制的表现,以此刻画它的优雅退化行为(是悄无声息地回退到完整重新 prefill,还是会发生更糟的事情),而不是完全不去讨论这种失效模式。
8.5 常见误读辨析
在向别人转述这篇论文时,有几个地方很容易被误解,值得单独救出来讨论一下:
- 误读一:“FreeToken 是又一个专家预测器”。 不对。前文提到的 ProMoE、ExpertFlow、FineMoE 都在做”预测下一步路由会选中哪些专家,提前预取”;FreeToken 根本没有预测机制,它的 LRU 缓存只是在被动地跟踪已经发生过的访问模式,正确性上不依赖任何预测准确度。真正新颖的部分是 公式——它处理的是预测失败之后(即 miss 已经发生)怎么最优地分派剩余工作,而不是怎么避免 miss 发生。
- 误读二:“CPU 执行只是备用方案,真正快的还是 GPU。” 从表 5.4 的数据看,在那台 8GB 笔记本上 仅为 0.25,也就是说大部分 miss 实际上是由 CPU 就地执行的,而不是传到 GPU 上。在这类带宽失衡的边缘机器上,CPU 执行不是备用,而是主力。论文标题里的”bandwidth-adaptive”正是在强调这个自适应方向可以往任何一侧倾斜,不存在预设的主要路径。
- 误读三:“这是个量化/剪枝方案,换了精度换速度。” 不对。如第 3.2 节反复强调的,CPU 和 GPU 分支的输出是精确合并的,没有任何信息损失,与完全显存驻留的部署逐位相同。这一点把它与第 6 节里那些“拉低精度换带宽”的方案清楚地区分开来。
- 误读四:” 是个学习出来的超参数,需要为每个部署环境单独调。” 也不容易破临时——它不是学习出来的,而是由两个实测带宽值代入公式 3 直接计算得到的。只要换一台机器,重新测一下 和 , 就自己变了——这正是论文强调“这个最优比例从规格表里读不出来”背后真正的工程含义。
8.6 如果自己部署,需要注意什么:一份简单清单
如果看完这篇论文之后真想在自己机器上试一试类似的思路(或者直接去试 FreeToken 的 GitHub 代码),下面这个清单值得先过一遍:
- 先测实两个带宽数,别相信规格表。 (PCIe 传输带宽)和 (CPU 专家执行带宽)必须在实际部署机器上、对实际部署的张量形状实测。表 1 里那些数字只能给你个大致区间,自家机器的实际值可能差很多(同样是 RTX 5090,服务器上 ,台式机上只有 )。
- 确认完整专家池能被 pin 住。 若操作系统/驱动不允许锁页(pin)或 DMA 注册对应大小的内存块,引擎会退化到纯 CPU 后端,性能会掉得很厉害。部署前先确认目标机器的锁页额度设置(比如 Linux 上的
ulimit -l或memlockcgroup 限制)足够容下完整专家池。 - KV cache 和专家缓存的分配比例,不要开局就固定。 因为 agentic 会话会随轮次积绷上下文,建议利用第 3.4 节提到的运行时重配置机制,定期(或在检测到显存压力变化时)重新校准这个分割,而不是启动时选一个固定比例一路用到底。
- 别把 GQA 模型上的收益预期得和 MHA 一样大。 第 5.8 节的附录数据显示 GQA 下的推理加速只有 7–8% 左右,远低于 MHA 下 1.2–2.8 倍的提升——因为 GQA 本身已经拿走了一部分 KV 压缩的收益,别拿前者的预期套到后者上。
- 边缘机器上不要假设带宽是常数。 如本篇第 8 节指出的,论文本身也没有处理并发应用(浏览器、游戏)临时占用带宽导致 变得不准的情况。如果要自己实现类似机制,值得先加一个周期性重新校准带宽的安全机制,而不是只在启动时测一次。
8.7 与其他相关方案的定位对照表
为了把 FreeToken 放到边缘 MoE 推理的整个地图里,下面这张表把它与第 6 节提到的几条主要经运线放在一起对比,重点看“专家放在哪”、“计划机制”和“是否改变模型输出”三个维度:
| 方案 | 专家放在哪 | 分派/预取机制 | 是否修改输出 | 适用场景 |
|---|---|---|---|---|
| llama.cpp | 加载时静态分配到设备 | 无(固定放置) | 不修改 | 通用、易部署,但对 agentic 上下文变化适应很差 |
| KTransformers | 预热层面固定“热”子集在 GPU,其余 CPU AMX 执行 | prefill 时每轮更新一次 | 不修改 | 早期固定工作负载,对长会话退化明显 |
| MoE-Infinity | 请求级激活模式追踪 | 预测式预取 | 不修改 | 单轮、短 prompt 场景,无多轮保持 |
| HOBBIT / SiDA / SMoE | 拉低精度副本或跳过低分专家 | 预测+降精度 | 修改(牺牲保真) | 对精度容忍度高、对带宽极度敏感的场景 |
| WiSP / eLLM / FluxMoE | KV cache 与专家页分层管理 | 被动取回(不能就地计算) | 不修改 | 侧重内存分配而不是计算路径选择 |
| FreeToken | 共享 LRU 缓存,动态跟踪实时路由 | 无预测, 公式根据实测带宽分派 miss | 不修改(精确合并) | 异构、非专用的边缘硬件,尤其是多轮 agentic 负载 |
从这张表里可以看出一个比较清晰的分化:右侧两栏(“是否修改输出”、“适用场景”)把现有方案大致分成两派:一派用精度换带宽(HOBBIT 类),一派用预测准确度换带宽(ProMoE 类)。FreeToken 的位置比较特别:它既不牺牲精度,也不依赖预测准确度,而是把“如何分派已发生的 miss”本身当成一个可以用实测带宽直接求解的优化问题。这也是为什么它能同时拿下“不牺牲精度”和“不需要预测器”两个好处的根本原因。
9. 可复现性说明
论文精确地列出了硬件配置(表 1 里六种带实测 PCIe 和主机带宽的 GPU/CPU/DRAM 组合)、使用的具体模型 checkpoint(包括量化格式——DeepSeek-V4-Flash 用的 MXFP4,笔记本上的 Qwen3.6 版本和 GLM-5.2 用的 NVFP4),以及四个 agentic 工作负载(框架名称、轮数、大致 token 数量)的足够细节,理论上足以重建出类似的评估轨迹。作者在 https://github.com/FlashML-org/FreeToken 开源了系统代码,并在 flashml.ai 提供了可下载的构建版本,相对于一篇描述闭源或纯内部系统的论文,这大大提高了可复现性的门槛——读者原则上可以在自己的硬件上验证核心的吞吐量结论,而不需要单纯信任论文报告的数字。核心算法贡献( 公式,对应本文的公式 1–4)是完整给出的,只需要两个可以实测的数字(、)就能在新硬件上复现,相比那些需要学习出的预测器或大量工作负载特定调参的方法,这是一个相当低的独立验证门槛。
10. 结语
FreeToken 的贡献,最好理解为它接受了一个真正具有边缘特性的系统问题——异构、非专用、极度多变的消费级硬件要服务一个专家池明显超出可用显存的模型——并拒绝用单一固定的策略去解决它。相反,它从”这台机器现在实际测出来的两个数字”里,推导出一个闭式的答案,来回答”这个具体的 miss 现在应该怎么被服务”,而且这个答案能在一台 8GB 的笔记本和一台 96GB 的工作站 GPU 上同样自动适配。全层双缓冲的 prefill 流水线、让 agentic 上下文编辑不必整体重新 prefill 的语义锚定检查点,以及可运行时调整大小的弹性缓存,每一项都是各自讲得通的工程决策,但这篇论文最值得引用的系统洞察其实是那个剩余带宽论证本身:一旦你注意到 PCIe 传输和 CPU 执行争抢的是同一份底层主机内存带宽,“该往哪条路径 offload 多少”这个问题就不再是一个需要手动调的参数,而变成了一条两行公式。那些诚实的边界说明——尽管声称支持 20 多个模型,却只深入评估了三个模型家族;没有直接分离带宽可加性假设的误差;没有讨论当 agent 框架编辑上下文的方式不尊重语义边界时会发生什么——让它没有成为边缘 MoE 推理的万能答案,但这些限制并没有削弱它的核心结论:一台被当成统一弹性平台、而不是”一张小 GPU 外加一些额外内存”的个人电脑,真的能够服务那些看起来完全不该由它来服务的模型。