AngelSpec 全链路开源:从 Drafter 训练到投机解码部署

2026-07-30 28 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

大模型推理优化不只是在算子层面压缩几毫秒。对于自回归生成,模型通常需要逐个 token 完成前向计算,显存带宽、调度开销和并发压力会共同限制吞吐。投机解码的思路,是让一个成本更低的 drafter 先提出多个候选 token,再由目标模型批量验证,从而减少昂贵的串行解码步骤。

腾讯混元团队此次开源 AngelSpec,覆盖 drafter 训练、架构设计和线上部署,并同步发布训练工具、Hy3-A21B 的 MTP / DFly drafter 权重及训练代码。公告披露,新一代 DFly drafter 在六个 benchmark、4 至 64 并发档位上取得更高吞吐,相比自回归(AR)基线平均加速 1.98 至 2.40 倍。对工程团队而言,重点不只是这个数字,而是投机解码从单点算法走向了可以训练、评测和部署的完整链路。

投机解码真正优化的是什么

普通自回归解码可以简化为以下循环:

  1. 目标模型根据已有上下文预测下一个 token。
  2. 将新 token 追加到上下文。
  3. 再次执行目标模型前向计算。
  4. 重复以上过程,直到生成结束。

投机解码增加了一个 drafter。它先连续预测若干候选 token,目标模型随后在一次验证过程中检查这些候选。候选被接受得越多,每次目标模型调用所推进的生成步数就越多。

因此,端到端收益主要取决于几个变量:

  • 候选接受率:drafter 的预测与目标模型越一致,可接受的 token 越多。
  • 草拟成本:drafter 即使预测准确,如果运行成本过高,也会抵消节省下来的时间。
  • 候选长度:一次草拟太短,摊薄不了验证开销;太长则可能产生大量被拒绝的候选。
  • 并发与调度:单请求上的最优参数,不一定适合 32 或 64 并发。
  • 工作负载分布:短回答、长代码生成和多轮对话可能呈现不同的接受率。

这也是完整框架比单独发布一组权重更重要的原因。drafter 的训练目标、结构、推理运行时和线上调度必须配合,任何一环的额外开销都可能侵蚀理论收益。

MTP 与 DFly 权重带来的工程价值

本次发布同时包含 Hy3-A21B 的 MTP 和 DFly drafter 权重及训练代码,这让团队可以比较不同 drafter 路线,而不是只能把投机解码当作一个不可修改的推理插件。

从落地角度看,开源训练链路至少支持三类工作:

  • 使用官方权重复现实验,建立硬件和业务环境下的性能基线。
  • 根据私有请求分布继续训练或调整 drafter,观察接受率是否改善。
  • 修改 drafter 架构或训练目标,并通过统一评测判断吞吐收益是否覆盖新增成本。

DFly 在多个并发档位和 benchmark 上取得新结果,也提示了一个常被忽略的问题:投机解码不能只测单请求延迟。线上服务通常同时处理多个请求,批处理形状、KV Cache 压力、验证阶段计算量以及调度器行为都会随并发变化。一个在并发 1 时表现优秀的方案,到了并发 64 时未必仍然占优。

可以这样建立可复现的评测闭环

下面的示例不假设 AngelSpec 的具体命令行接口,而是提供一个可以直接运行的结果汇总脚本。接入时,只需让 AR 基线和 AngelSpec 服务输出相同字段,即可比较吞吐、延迟和加速比。

先创建 results.jsonl

{"mode":"ar","concurrency":4,"requests":200,"output_tokens":24000,"duration_s":120.0,"p50_ms":1800,"p99_ms":4200}
{"mode":"dfly","concurrency":4,"requests":200,"output_tokens":24000,"duration_s":62.0,"p50_ms":1050,"p99_ms":2500}
{"mode":"ar","concurrency":32,"requests":1000,"output_tokens":120000,"duration_s":300.0,"p50_ms":7300,"p99_ms":15800}
{"mode":"dfly","concurrency":32,"requests":1000,"output_tokens":120000,"duration_s":142.0,"p50_ms":3900,"p99_ms":9200}

再保存以下脚本为 summarize.py

#!/usr/bin/env python3
import json
from collections import defaultdict
from pathlib import Path

rows = [
    json.loads(line)
    for line in Path("results.jsonl").read_text(encoding="utf-8").splitlines()
    if line.strip()
]

by_concurrency = defaultdict(dict)
for row in rows:
    row["tokens_per_second"] = row["output_tokens"] / row["duration_s"]
    by_concurrency[row["concurrency"]][row["mode"]] = row

header = (
    f"{'并发':>6} {'AR tok/s':>12} {'DFly tok/s':>12} "
    f"{'吞吐加速':>10} {'DFly p50':>12} {'DFly p99':>12}"
)
print(header)
print("-" * len(header))

for concurrency in sorted(by_concurrency):
    modes = by_concurrency[concurrency]
    if "ar" not in modes or "dfly" not in modes:
        continue

    ar = modes["ar"]
    dfly = modes["dfly"]
    speedup = dfly["tokens_per_second"] / ar["tokens_per_second"]

    print(
        f"{concurrency:>6} "
        f"{ar['tokens_per_second']:>12.1f} "
        f"{dfly['tokens_per_second']:>12.1f} "
        f"{speedup:>9.2f}x "
        f"{dfly['p50_ms']:>9.0f} ms "
        f"{dfly['p99_ms']:>9.0f} ms"
    )

运行命令:

python3 summarize.py

示例中的数字仅用于演示数据格式,不代表 AngelSpec 的官方测试结果。实际评测时,建议固定模型版本、精度、GPU 型号、输入长度分布、最大输出长度、采样参数和预热轮数,否则加速比无法横向比较。

部署配置需要显式记录

如果要把实验推进到灰度环境,可以用一份独立配置记录关键变量。下面是一个需要根据 AngelSpec 实际接口改造的配置模板,并非官方配置格式:

# ang_spec_experiment.yaml
experiment:
  name: hy3-a21b-dfly-canary
  baseline: autoregressive

model:
  target: /models/Hy3-A21B
  drafter: /models/Hy3-A21B-DFly
  dtype: bfloat16

speculative_decoding:
  enabled: true
  draft_tokens: 6

benchmark:
  concurrency: [4, 8, 16, 32, 64]
  warmup_requests: 50
  measured_requests: 1000
  metrics:
    - output_tokens_per_second
    - time_to_first_token_ms
    - inter_token_latency_ms
    - p50_request_latency_ms
    - p99_request_latency_ms
    - acceptance_rate

rollout:
  canary_traffic_percent: 5
  rollback_on:
    p99_latency_regression_percent: 10
    error_rate_percent: 1

draft_tokens 不应直接照搬示例值。应在真实输入分布上扫描多个候选长度,并同时观察吞吐、P99 延迟和接受率。只追求 tokens/s,可能掩盖首 token 延迟上升或长尾请求恶化。

上线前应检查哪些边界

投机解码通常保持目标模型的验证过程,因此它不是简单地用小模型替换大模型。不过,工程团队仍需验证采样参数、停止条件、流式输出、结构化生成以及不同精度设置下的行为一致性。

建议在采用 AngelSpec 时依次完成以下检查:

  • 用同一批请求比较 AR、MTP 和 DFly,避免不同数据集造成偏差。
  • 覆盖 4 至 64 等多个真实并发档位,而不是只报告单点峰值。
  • 同时记录吞吐、首 token 延迟、token 间延迟、P50、P99 和错误率。
  • 按任务类型拆分接受率,例如对话、代码、数学和长文本生成。
  • 计算单位请求或百万 token 的 GPU 成本,而不仅是理论加速比。
  • 通过少量流量灰度验证显存峰值、调度稳定性和回滚路径。

AngelSpec 的意义在于把 drafter 的训练、结构探索和线上部署放进同一套开源链路。团队可以从官方权重和训练代码开始复现,但是否值得上线,最终仍应由自己的模型、硬件、并发曲线和请求分布决定。平均 1.98 至 2.40 倍的公开结果可以作为参考目标,不能替代面向真实业务的端到端测量。


相关推荐