SpecPilot: Autonomous Algorithm Discovery and Systems Optimization for Speculative Decoding
Kunjun Li, Wenhao Chai, Yihao Liang, Yuezhou Hu, Shuyao Xu, Yi Pan, William X. Zheng, Kannan Ramchandran, Kurt Keutzer, Jiantao Jiao
cs.LG
2026-11-02
SpecPilot按部署搜出无损优化,不额外训练,单请求加速从4.46倍到10.87倍,批量从1.94倍到3.93倍。
投机解码用小起草器先猜 token,再由目标模型一次前向验证。并行起草器把猜测收成 8 或 16 个 token 的一块。单请求时,读目标权重占掉一步的绝大部分,多验几行几乎不加延迟。H100 上 Qwen3.8-27B 在第一轮优化后,23.61 ms 的一步有 80% 在读权重;打满 3.35 TB/s,读权重仍占这一步全部字节时间的 92%。
stock 只验一条贪心链。离线回放里,DFlash2 的 8 位置链每步收下 4.25 个 token。只要目标 token 还在 top-16 里就继续收的 oracle,8 位能到 6.42,16 位能到 8.20。进入批量后,每个请求自带注意力、循环状态和 prefill,加速大约腰斩:FP8 的 Qwen3.8-27B 从 3.40 倍掉到 24 并发的 1.89 倍。低精度预检在单请求上加快,到 BF16 批量反而慢 13%。
SpecPilot 把改代码的 agent 和测量用的控制器拆开,由 Claude Opus 5.5 在 SGLang 上按部署搜索。
相对自回归(AR)的加速写成 τ 除以步长时间比。天花板按「最优树、一次精确验证、kernel 跑到字节下限」估算,下限取峰值算力 60% 与峰值带宽 90% 中较慢者。树、kernel、计时开销三个因子里最大的,就是这一轮的方向。一个方向一张 GPU。净收益不到 3% 就不写新算法。95% 下界要超过 1% 加两倍噪声才晋升,输出有分歧则门槛约 3%。
无损靠构造保证:收下的 token 必须落在精确权重那次前向的 argmax 上。Token forcing 把输出送回 stock 的 FP32 LM head,逐 token 核对。stock 因舍入已有 0.72% 对不上。失配率再高出 0.5 个百分点以上,或大差距事件变多,就拒绝。任务分抓不住这件事。给每 7 个词表 id 加 2 的 logit bias 后,准确率置信区间仍含 0。过关机制进入记忆,现有 140 条。换部署要重测,不算新发现。
W12 把 BF16 收成 12 bit,加载时与检查点逐 bit 核对。同一输出通道的权重多落在少数二的幂区间,每通道开一个 16 区间的窗口,存符号、4 bit 指数偏移和 7 bit 尾数,窗外的数走稀疏逃生表。Qwen3.8-27B 转换层从 44.67 GB 降到 33.58 GB。解码在寄存器里完成。11 bit 更密,解码耗时约 3 倍,被微基准放弃。H100 的 LM head 留 BF16,用带误差界的 INT8 副本丢掉不可能赢的 token,878 μs 降到 482 μs,argmax 不变。RTX PRO 6000 上该头更慢(2598 对 1750 μs),LM head 改走 W12。
Qwen3.8-27B 有 48 层 Gated DeltaNet,每层维护一块固定大小的循环状态。按节点存这份状态,N=24 大约要 18 GB,树就沿根路径重算。WY kernel 把秩一更新收成矩阵乘,48 层从 1485 μs 降到 542 μs。边分是给定父节点的选择器对数概率。起草 16 位、验证 32 个节点。DSpark 的 Markov head 也看前一个 token,同一套建树直接用。
两级验证用 W12 里嵌好的 8 bit 视图做 Q pass,只圈路径、不改状态,再从末端起草一次。只有后面那次精确前向接受 token。两套 top-1 在 98.7% 的位置一致。
批量只挑行。请求共享节点预算,FP8 在 24 并发时取 192,卡在 GEMM 耗时平台上。各请求按近期接受情况起草 16、12 或 8 位。新 prompt 只在即将被挂起时并进同一次权重读取。
四个目标模型、三种起草器、两张 GPU、五个 benchmark,贪心解码并开启 thinking。表内是相对 AR 的加速和 τ,等权几何平均。
| 设置 | stock | SpecPilot |
| 单请求 H100,Qwen3.8-27B + DFlash2 | 3.95× / 4.65 | 8.86× / 13.08 |
| 单请求 H100,同模型 + DSpark | 3.74× / 4.42 | 9.41× / 12.85 |
| 单请求 RTX,同模型 + DFlash2 | 4.46× / 5.23 | 10.87× / 12.80 |
| 单请求 RTX,Muse-Glimmer-30B | 4.69× / 5.16 | 10.63× / 12.64 |
| 批量 H100,FP8 + DSpark | 1.94× / 4.37 | 3.93× / 5.42 |
| 批量 H100,Qwen3.5-4B | 1.51× / 6.58 | 3.77× / 6.97 |
| 批量 H100,Gemma-4-12B + EAGLE-3 | 0.68× / 2.04 | 2.09× / 2.54 |
4.46 倍到 10.87 倍是 RTX 上 Qwen3.8-27B 这一格。τ 按精确前向计,两级验证把两稿串在同一次前向里,所以从 4 个多跳到 13 左右;只建树的回放只把 4.25 提到 5.38。H100 单请求的速度是 DDTree 的 1.84 倍,DDTree 相对 AR 为 4.82 倍。未见请求上相对 stock,单请求密封增益 2.13–2.44 倍,批量 1.85–3.11 倍。H100 上 FP8 的 DFlash2 从 2.02 倍到 3.90 倍。BF16、6 到 10 并发时,相对 AR 从 stock 的 3.20 倍到 5.67 倍。Gemma 上 stock 慢于 AR。
H100 单请求从 184 tok/s 走到 416:建树到 270,再切权重字节,最后拆掉「一步只验一次」。同设置去掉成本模型,单 agent 三轮只有 stock 的 1.34 倍,SpecPilot 是 2.13 倍。权重读取占步长 80%,那条循环没去动。
不投机时,W12 在 Muse-Glimmer-30B、Qwen3.8-27B、Gemma-4-12B 和 Llama-3.1-8B 上,单请求 AR 是 BF16 的 1.19–1.28 倍,权重少 14–22%,Qwen3.8-27B 的 KV 池放到 2.0 倍。1 到 32 行的 GEMM 是 cuBLAS 的 1.17–1.47 倍。RTX 的 stock 已调过,比照搬 H100 快 9.9%。
剩余加速主要在部署。单请求吃带宽,多验、预检、瘦权重都划算;批量吃逐行计算,这些招会亏,要改成挑行。不额外训练、不改贪心输出,单请求吞吐可以到 stock 的两倍出头。没有 wgmma 的 RTX PRO 6000 上,移植树和 W12 就有密封 1.92 倍,加上两级验证到 2.44 倍。
无损按贪心定义,允许浮点归约带来的近并列。stock 与 AR 第一次分叉,log 概率最多差 0.232 nats。采样没测。
相对 AR 的倍数来自开发集上的交错测量,与未见请求的密封增益差在 −2% 到 +6%。搜索用 Claude Opus 5.5,GPU 时和人工收尾的比例没有给。
FP8 批量上 24 节点的树亏 14.9%,BF16 批量上两级验证亏 13%。Q pass 已占一步的 0.80–0.88,收不到近两倍 token 就打平不了。60% 算力、90% 带宽的字节下限是估计。RTX 结果超过 2.12 倍天花板,因为天花板假定一稿只配一次精确前向。改掉步定义的招,成本模型事先看不到。Token forcing 对照的是 stock 已有的 0.72% 失配,再偏但不超过 0.5 个百分点仍会通过。