SpecForge v0.3.0 发布:统一解耦与共置投机解码栈,新增开放 SpecBundle 草稿模型
Blog SpecForge v0.3.0: a Unified Disaggregated and Colocated Speculative Decoding Stack, and New Open SpecBundle Draft Models When we first released SpecForge, a training job owned both the frozen target model and the draft model being optimized. This made EAGLE3 draft-model training practical and directly compatible with SG... The SpecForge Team
SpecForge v0.3.0 将目标模型推理与草稿模型训练分离,支持 EAGLE3、EAGLE3.1、P-EAGLE、DFlash、Domino、DSpark 等多种投机解码算法,并统一在线、离线与解耦工作流。
将目标模型推理与草稿模型训练分离,让两种工作负载可独立扩缩,改变了投机解码训练中资源配比必须硬编码的旧模式,资源规划可按模型和序列长度灵活调整。
当我们首次发布 SpecForge 时,一个训练任务同时拥有冻结的目标模型和正在优化的草稿模型。这使得 EAGLE3 草稿模型的训练变得切实可行,并能直接兼容 SGLang,但它也将两种截然不同的工作负载绑定到了同一个进程生命周期和资源拓扑上。
今天,我们为 SpecForge 带来了一次重大更新。新的运行时将目标模型推理与草稿模型训练分离,支持更广泛的投机解码算法家族,并将在线、离线和分离式工作流统一在一个类型化的训练入口之下。伴随此次发布,我们还公开了更多草稿模型,覆盖不同的投机解码方法和不同的目标模型。
新特性
- 在线训练现已完全分离。经过补丁的 SGLang 服务器捕获目标模型特征,Mooncake 传输张量,训练器工作进程通过独立的控制平面消费轻量级引用。
- 推理和训练可以独立扩展。在我们的 8xH20 测试平台上,3 个 SGLang 服务器和 5 个训练器工作进程的拓扑相比我们之前的共置实现,将端到端训练吞吐量提升了约 10%。
- 现在同一个运行时支持多个草稿模型系列: EAGLE3、EAGLE3.1、P-EAGLE、DFlash、Domino 和 DSpark,以及 DFlash 可选的 D-PACE 目标函数。
- 更多草稿模型正在陆续发布,其中大部分由社区贡献。 合作伙伴和个人贡献者已使用该运行时,针对不同的投机解码方法和不同的目标模型训练并发布了草稿模型,且全部仅使用开放数据训练。
本次发布还附带了一个训练-服务一致性门禁,它会在一个受控样例上验证采集、训练、导出和 SGLang 服务的结果一致——这是在投入完整训练运行之前的一次快速正确性检查。
从耦合训练器到训练流水线
在线草稿模型训练包含两种不同的工作负载:
- 目标侧在训练对话上运行一个大型的冻结模型,以采集隐藏状态。它推理负载很重,通常使用张量并行,并且受益于生产级推理引擎。
- 草稿侧通过前向和反向传播训练一个规模小得多的模型。它通过数据并行或序列并行来扩展,并且具有不同的内存和计算特征。
在此前的共置设计中,两侧共享同一个生命周期和同一套固定资源布局。这带来了三个实际限制:
- 固定的推理与训练比例。扩展训练器 worker 也会影响目标模型的放置,即使只有一侧是瓶颈。
- 资源干扰。目标捕获和草稿优化在同一个紧耦合作业内部相互竞争。
- 共享的故障边界。特征生成缓慢或失败可能导致训练停滞,而过量生产则可能造成无限制的内存压力。
关键观察很简单:训练器不需要拥有目标模型。它们只需要所选训练目标所需的 token 序列、掩码和目标特征。将这一边界显式化,使 SpecForge 从一个包含目标模型的训练器进程转变为一个协调式训练流水线。
一个边界,三重契约
新的在线运行时包含一个生产者池和一个消费者池。生产者将提示词调度到已打补丁的 SGLang 捕获服务器上。SGLang 将特征张量写入 Mooncake,而 SpecForge 仅通过控制平面发送轻量级的 SampleRef 元数据。训练器 rank 在准备构建批次时解析这些引用。
图 1. 在线解耦训练流程。大张量保留在数据平面中;引用和生命周期状态通过控制平面传递。
1. 捕获契约
deployment.disaggregated.server_urls 中的每个 URL 都会创建一个连接到已打补丁的 SGLang 服务器的 rollout worker。Worker 从共享控制器租用互不相交的提示词,因此捕获容量可以在不改变训练器拓扑的情况下发生变化。
捕获支持是在固定版本的 sglang==0.5.14 之上打的一个小补丁:patches/sglang/v0.5.14/spec-capture.patch 添加了一个 --enable-spec-capture 标志以及一个服务端 sink,该 sink 使用特征存储的键布局将捕获的张量直接写入 Mooncake。捕获服务器就是应用了此补丁的现成 SGLang 服务器。
这建立了一条清晰的归属边界:SGLang 负责目标模型的并行和特征捕获,而 SpecForge 负责提示词调度、引用发布和草稿模型优化。
2. 交付契约
捕获的隐藏状态可能很大,因此通过 Python 队列或控制数据库转发它们会很快成为瓶颈。SpecForge 将张量存储与样本协调分离:
- SGLang 将特征张量写入 Mooncake。
- 生产者发布不含张量的
SampleRef记录。 FeatureDataLoader将引用解析为携带张量的训练批次。- 训练器在收到优化器步确认后释放特征对象。
训练循环依赖于 FeatureStore 契约,而非特定的传输方式。因此,同一条消费者路径可以使用本地特征、共享目录或由 Mooncake 支持的在线捕获。
3. 生命周期契约
分布式 rank 必须同步推进。消费者以完整的优化器步为量子单位释放引用,因此每个 rank 都能收到一次同步更新所需的样本。高水位和低水位在途标记会暂停和恢复捕获,防止生产者过度领先于训练进度。
在优化器边界处,消费者 rank 0 会在确认信息减少在途深度并释放特征对象之前,将已训练的样本 ID 记录到一个持久化的 SQLite 账本中。中断之后,消费者可以利用该账本跳过已完成的样本 ID,并重放剩余的引用。
在生产者一侧,失败同样是显式的。一个失败的采集 worker 会将其租用的提示词归还给共享控制器,从而让健康的 worker 继续运行。如果所有采集服务器都不可用,或者某个提示词耗尽了其重试预算,整个运行会以显式方式失败。
这些契约共同使训练器与特征传输保持独立,同时不削弱分布式步对齐、有界缓冲或恢复语义。
这种分离解锁了什么
新的边界带来了两个用户可见的收益:基础设施可以围绕工作负载进行均衡,算法实现可以共享同一个训练运行时。
独立的推理池与训练池
目标模型的张量并行与专家并行现在归属于 SGLang;草稿模型的数据与序列并行归属于 SpecForge。这两个池可以在同一个本地 supervisor 下运行,也可以作为由调度器管理的独立作业运行。
当两个池共享固定的 GPU 预算时,它们之间的比例仍然是一种资源权衡。区别在于,这种权衡现在是显式且可调的,而不是硬编码在训练器中。当有更多资源可用时,任一池都可以扩展,而无需迫使另一个池采用相同的拓扑。
初步系统结果:3 台采集服务器 + 5 个训练器
在 8×H20 测试平台上,我们以 3K token 的上下文长度评估了 Qwen3-8B Domino 训练。将工作负载重新分配到三台 SGLang 采集服务器和五个训练器 worker 上,相比此前共置部署的实现,实测端到端训练吞吐量提升了约 10%。
| 运行时 | 目标采集 | 草稿训练 | 相对端到端训练吞吐量 |
|---|---|---|---|
| 此前的共置版本 | 与训练任务耦合 | 固定共置布局 | 1.00× |
| 新的解耦运行时 | 3 台 SGLang 服务器 | 5 个训练器 worker | 1.10× |
下面的性能剖析图展示了两种运行时拓扑下具有代表性的训练窗口。
(a) 共置基线

(b) 分离式:3 个 SGLang 服务器 + 5 个训练器 worker

图 2. 在 3K token 上下文长度下具有代表性的 Qwen3-8B Domino 训练窗口。吞吐量表报告了端到端对比;轨迹图则提供了两种执行模式的定性视图。
在此工作负载中,性能分析表明收益来自更好地将特征生产供给与训练器需求相匹配。更广泛的优势在于可配置性:不同的目标规模、序列长度和草稿算法可以使用不同的采集与训练比例,而无需另做一套训练器实现。
一个运行时支持多种草稿家族
SpecForge 最初以 EAGLE3 为强重点。新的运行时将通用的系统关注点与策略特定的建模代码分离。
每个策略都复用提示词调度、特征传输、分布式执行、检查点和进程监管。策略只定义它所需的目标特征、这些特征如何变成训练批次、其草稿模型架构以及其目标函数。
| 方法 | 策略特定思路 | SpecForge 支持 |
|---|---|---|
| EAGLE3 | 直接 token 预测,配合训练时测试与多层目标特征融合 | 在线解耦、本地离线与解耦离线;可选的 LK 损失目标 |
| P-EAGLE | 通过共享隐藏状态进行并行多 token 预测 | 在线解耦 |
| EAGLE3.1 | 一种 EAGLE3 配置变体,带有逐层归一化和注意力漂移设置 | 通过 eagle3 策略实现在线解耦 |
| DFlash | 块扩散草稿,可并行预测一个 token 块 | 在线解耦、本地离线与解耦离线;可选的 D-PACE目标 |
| Domino | 一个并行草稿主干,后接一个轻量级因果校正头 | 在线分离式、本地离线式与分离式离线 |
| DSpark | 带置信度建模的半自回归起草,用于自适应验证 | 在线分离式、本地离线式与分离式离线 |
在这里,统一指的是同一套配置 schema、启动器、数据流契约、训练器生命周期和 checkpoint 接口。它并不意味着每一种策略都支持所有的数据源与拓扑组合。
数据源与部署方式是彼此独立的选择
在线与离线描述的是目标特征来自何处。本地与分离式描述的是训练工作流如何部署。将这两个概念区分开来,可以更容易理解所支持的组合:
| 特征来源 | 本地/数据流部署 | 生产者/消费者部署 |
|---|---|---|
| 在线 SGLang 采集 | 否 | 是,配合 Mooncake |
| 离线特征检查点 | 是 | 是,使用共享特征存储 |
每次在线运行都使用生产者/消费者拓扑;训练器从不初始化同址部署的目标模型。离线 EAGLE3、DFlash、Domino 和 DSpark 训练可以在本地运行,也可以使用独立的摄取池和消费者池。P-EAGLE 目前仅支持在线训练。
特征来源不等于数据策略
在实践中还有一个区别很重要。捕获服务器对你提供的对话执行完整的预填充,并且从不生成训练响应,因此在线捕获并不决定草稿模型学习谁的文本——决定这一点的是数据集。这个选择比任何拓扑决策都更重要:当数据集响应由人类或由另一个模型撰写时,草稿模型会学习续写目标模型本身很少产生的文本,其接受率会远低于同一草稿模型在目标模型生成数据上所达到的水平。在我们的训练运行中,用目标模型重新生成数据集响应——以贪心方式、在将要服务的推理模式下——一直是影响最终接受率的最大杠杆。我们建议每种策略都使用目标模型生成的数据。下面描述的一致性门控依赖于同一特性:只有当训练样本是目标模型在温度 0 下能够复现的文本时,其服务阶段才能通过。
完整的策略矩阵请参阅训练指南,部署细节请参阅分离式训练指南。
一份配置,一个入口点
拓扑结构与模型、数据、算法和优化器设置位于同一个带类型的 YAML 文档中。以下摘录展示了上文所用的三服务器/五训练器形态:
training:
strategy: domino
deployment:
mode: disaggregated
trainer:
nnodes: 1
nproc_per_node: 5
disaggregated:
control_dir: outputs/qwen3-8b-domino/control
consumer_state_dir: outputs/qwen3-8b-domino/consumer-state
backend: mooncake
server_urls:
- http://capture-0:30000
- http://capture-1:30000
- http://capture-2:30000
同一条命令即可解析并启动所选的拓扑结构:
specforge train --config run.yaml
在单节点上,启动器可以同时监管两个 SpecForge 角色。在外部调度器下,各资源池可以使用相同的配置独立启动:
specforge train --config run.yaml --role producer
specforge train --config run.yaml --role consumer
不存在针对特定方法的 Python 训练入口点。完整、可运行的配置可在 examples/configs 下获取。
训练示例:Qwen3.6-27B
使用单条命令在单节点上启动训练和推理:
specforge train --config examples/configs/qwen3.6-27b-dspark-disaggregated.yaml
训练示例:Kimi-K3
训练配方列于 docs/recipes/kimi-k3-dspark-disaggregated.md。
草稿模型服务性能
训练系统吞吐量与草稿模型服务加速回答的是不同的问题。上文的 H20 结果衡量的是训练流水线的效率。以下评估衡量的是用 SpecForge 训练出的草稿检查点的端到端服务加速;它不作为 10% 训练运行时结果的证据。
我们在 2×A100 GPU 上评估了 Qwen3.6-27B-Domino。所有数值均相对于仅目标模型的自回归解码(AR = 1.00×)。B8 和 B16 分别表示草稿块大小为 8 和 16。
并发数 = 1
| 数据集 | AR | MTP-S3 | MTP-S7 | DFlash-B8 | DFlash-B16 | Domino-B8 | Domino-B16 |
|---|---|---|---|---|---|---|---|
| GSM8K | 1.00× | 2.68× | 3.22× | 3.79× | 4.25× | 4.36× | 5.25× |
| MATH500 | 1.00× | 2.80× | 3.55× | 4.29× | 5.07× | 4.60× | 5.72× |
| HumanEval | 1.00× | 2.65× | 3.18× | 3.98× | 4.47× | 4.20× | 4.98× |
| MBPP | 1.00× | 2.57× | 2.98× | 3.73× | 3.91× | 3.97× | 4.49× |
| MT-Bench | 1.00× | 2.44× | 2.65× | 3.00× | 3.05× | 3.31× | 3.44× |
| Alpaca | 1.00× | 2.38× | 2.54× | 2.87× | 2.84× | 3.18× | 3.34× |
在并发数为 1 时,Domino-B16 在全部六个数据集上都提供了最高的加速比,从 Alpaca 上的 3.34× 到 MATH500 上的 5.72× 不等。
跨方法与目标模型的更多草稿模型
一套训练工具栈,只有能产出人们真正可以部署的 checkpoint 才有用。投机解码提供了强有力的理论保证,并在 token 接受率和端到端速度上带来了一致的提升,但开源社区对其的采用一直受限,原因在于缺乏生产就绪的训练工具、高质量草稿 checkpoint 稀缺,以及这些草稿模型训练所用数据的规模偏小。
因此,除了运行时之外,现在还提供了规模大得多的一组开放草稿模型——而引人注目的是,其中我们自己训练的少之又少。在生产环境中运行 SpecForge 的团队,为他们实际服务的目标模型训练了草稿模型,并把权重回馈了出来,而且全部仅使用开放数据训练。下面列出的十一个 checkpoint 中有九个是这样来的,分别来自蚂蚁集团 AQ、RadixArk、招商银行、Domino 的作者们,以及社区中的个人成员。
正是这股流入,从两个维度拓宽了这份目录:
- 更广的目标覆盖范围,涵盖社区实际部署的开源模型,从指令微调模型扩展到推理模型以及当前开放权重发布的前沿。
- 更广的方法覆盖范围。按照上一节所述的算法,发布的检查点现在涵盖 EAGLE3、DFlash、Domino 和 DSpark。范围内的若干目标还自带 原生 MTP 头,让社区有机会在同一目标上将这些草稿模型与原生 MTP 进行对比。
如果你使用 SpecForge 训练了草稿模型,我们希望将其与这些模型一同托管——欢迎贡献新的目标和新的算法。
已发布模型与性能
所有检查点均已发布在 Hugging Face 上的 SpecBundle 集合中:
| 目标模型 | 草稿模型 | 算法 | 提供方 |
|---|---|---|---|
| GLM-5.1 | 🤗 | EAGLE3 | 蚂蚁集团 AQ |
| Kimi-K2.5 | 🤗 | EAGLE3 | 蚂蚁集团 AQ |
| Kimi-K2.6 | 🤗 | EAGLE3 | 蚂蚁集团 AQ |
| Kimi-K2.7-Code | 🤗 | EAGLE3 | 蚂蚁集团 AQ |
| Qwen3-32B | 🤗 | EAGLE3 | 招商银行 |
| Qwen3.5-35B-A3B | 🤗 | EAGLE3 | SpecForge |
| Step-3.5-Flash | 🤗 | EAGLE3 | RadixArk |
| Qwen3.5-397B-A17B | 🤗 | DFlash | LMSYS |
| Qwen3.6-27B | 🤗 | Domino | Domino 团队 |
| Inkling-Small | 🤗 | DSpark | RadixArk |
| Kimi-K3 | 🤗 | DSpark | RadixArk |
这些模型中一部分的结果如下所示,按算法分组。
EAGLE3
图 3. 三个采用相同草稿配置(3 步、top-k 1、4 个草稿 token)的 EAGLE3 草稿模型:相对于自回归基线的输出吞吐量,每个柱子上方标注了加速比。Step-3.5-Flash 和 Qwen3-32B 在 4 × H200、并发 16 下测量;Kimi-K2.7-Code 的数字是其 模型卡上发布的 8 × H200、并发 8 的结果。
DFlash
图 4. Qwen3.5-397B-A17B 在 8 × B200 上(TP8、bfloat16、启用思考、贪心解码、最大输出 4096 token):块大小为 8 的 DFlash 相对于自回归基线的输出吞吐量。块大小 16 在并发 1 时更高——在 HumanEval 上最高达 4.31×——而块大小 8 在高负载下是更强的选择。完整数字,包括与 MTP 的对比,见 模型卡。
Domino
图 5. Qwen3.6-27B 在 2 × A100(TP2、BF16、启用 thinking、贪心解码)上:Domino 在块大小 8 时的输出吞吐量与自回归基线对比,加速比标注在每个柱状图上方。并发数为 1 时增益最大——在 MATH500 上最高达 4.60×——在并发数为 32 时收窄至 1.48–2.11×,此时目标模型已被更好地利用。
完整的各工作负载数据,包括其他块大小以及 MTP 和 DFlash 的对比,都在模型卡上。
DSpark
图 6. Kimi-K3 在 8 × B300 上:DSpark 在五个工作负载上的输出吞吐量与自回归基线对比,加速比标注在每个柱状图上方。并发数为 1 时增益最大——在 GSM8K 上最高达 3.14×——在并发数为 16 时收窄至 1.37–2.36×,此时目标模型已被更好地利用。MT-Bench 是这五个中最开放式的,在每一并发级别上获益都最少。完整数据在模型卡上。
验证训练-服务一致性
模型质量基准和正确性门禁服务于不同的目的。基准衡量泛化能力;门禁检查训练、导出和服务是否实现了相同的算法契约。
SpecForge 为 DFlash 系列模型(包括 Domino)提供了端到端的训练与服务门禁。它执行三个阶段:
- 选择一个有效样本。 该门控会检查目标对话模板、推理模式、tokenizer 行为、序列长度以及最小可训练后缀,然后生成可审计的提示词产物。
- 通过公开训练路径进行过拟合。 它会通过
specforge train启动一个有界运行,对该样本重复训练,然后要求达到配置的损失和 token 准确率阈值,并得到精确的最终 checkpoint。 - 导出并服务该 checkpoint。 它通过
specforge export导出,使用 DFlash 投机解码启动 SGLang,并验证每请求的接受元数据以及与目标 token 前缀的一致性。
该门控有意设计得严格且范围狭窄。通过它表明捕获、训练、导出和服务在一个受控样本上保持一致;它不能替代留出集上的模型质量评估或服务性能评估。
下一步
本次发布改变了 SpecForge 中的扩展单元。一次运行不再是一个恰好包含目标模型的训练器进程;它是一条协调流水线,其推理容量、存储和优化容量可以独立配置规模。
我们的下一步是完成发布上述剩余目标模型对应的草稿模型,并继续扩展算法和模型目录。我们还将跨不同模态进行测试和适配,例如 VLM 以及其他硬件平台,包括但不限于 AMD 和昇腾。
致谢
我们感谢 SGLang 和 SpecForge 社区、所支持的投机解码方法的作者们,以及所有帮助测试新运行时和算法集成的贡献者。
SpecForge 团队:Jiaping Wang、Shenggui Li、Xiaoming Dong、Chao Wang 和 Ji Li
RadixArk 团队:Cheng Mao、Yi Sun 和 Kan Wu
Domino 团队:Jianuo Huang
蚂蚁集团 AQ 团队:Yefei Chen、Yuan Wang
招商银行团队:Peixiang Tan
Meta/Pytorch:Richard Zou
Modal 团队
来源:LMSYS:Blog(Chatbot Arena 团队) · lmsys.org