四张 2017 年 V100 跑通 Qwen 3 NVFP4 推理,性能追平 RTX 5090
开发者自研 QPN 内核,让无 FP4/FP8 硬件支持的 V100 运行 Qwen 3.8 NVFP4,单请求解码吞吐…
一位开发者日前在 GitHub 开源了项目 v100-skinny,让 2017 年发布的四张 Tesla V100 以 NVFP4 精度原生运行 Qwen 3.8 27B 模型,单请求解码吞吐达到 219.1 ± 5.9 tok/s,与使用 NInfer 引擎的 RTX 5090(214.7 ± 9.2 tok/s)基本持平。这是首次在 Volta 架构上实现 NVFP4 推理并达到与 Blackwell 消费级旗舰显卡相当的性能。
测试方法与关键结果
测试环境为同一实验室下的两组系统:四张 V100(v100-skinny)与单张 RTX 5090(NInfer)。两边都使用 Qwen 3.8 自带的 MTP(Multi-Token Prediction)机制,并在同一组 AIME 2026 第一题上跑五个种子,参数统一为 temperature 0.6、top-p 0.95、top-k 20、presence penalty 1.0,开启 thinking 模式。
核心数据对比如下:
- 解码吞吐:V100 219.1 ± 5.9 tok/s,5090 214.7 ± 9.2 tok/s,V100 略高约 2%;
- 答对题目耗时:V100 6.90 ± 0.30 s,5090 6.56 ± 1.34 s,差距在误差区间内;
- 每轮 round 延迟:V100 26.9 ms,5090 19.9 ms(5090 更快);
- 每轮提交 token 数:V100 5.89,5090 4.27(V100 更大)。
5090 每轮更快,但 V100 因 MTP 深度更高(k=7 vs 5)每轮可验证更多 token,慢轮与深轮几乎互相抵消,最终吞吐持平。
自研 QPN 内核:让 Volta 跑 NVFP4
V100(SM70)没有 FP4 与 FP8 Tensor Core 指令,而 NVFP4 是为 Blackwell 设计的。开发者没有走「先把模型反量化为 FP16 再跑」的常规路径,而是写了一个 QPN(Quantized-Prefix / Narrow)内核,让模型权重在从 HBM 读出时保持压缩状态,并在寄存器内直接转换成 FP16 格式,让 Volta 现有的 Tensor Core 可以消化。
在 Qwen 3.8 实际张量形状下,QPN 达成了如下有效带宽:
- QPN2 / NVFP4,M=1:679.5 GB/s(879 GB/s 理论上限的 77%);
- QPN2 / NVFP4,M=8:619.8 GB/s(71%);
- QPN8 / FP8,M=1–4:约 719 GB/s(82%);
- 原生 4-bit lm_head:842.9 GB/s(96%)。
M=8 路径对应 k=7 的投机验证 round。Volta 的 Tensor Core 天然按 8 行 tile 工作,开发者把 k=7 的验证映射到这 8 行上,让多验证几个候选 token 的代价变得很低。
v1.1 的关键改进:保留官方混合精度分配
v1.0 为了让不支持的 FP8 区域跑起来,被迫将它们一并转成 NVFP4,相当于在跑一个衍生检查点。v1.1 给 FP8 区域补上了真正的 SM70 执行路径,使官方发布的 FP4/FP8 混合分配得以完整保留:FP4 区域走 QPN2,FP8 区域走 QPN8,激活与 KV 缓存分别为 FP16。
这种完整性对生成质量有实质影响。在一项 50 项的硬件代际测试中,全 FP4 衍生检查点只生成了 12 个品类的有效输出、且 50 项全部重复相同品牌名,而官方混合权重版本则覆盖 50 个独立品类且无重复。
一些工程细节与长上下文发现
除核心解码路径外,开发者还排查并修复了多项 SM70 的隐藏问题:
- 检查点中 FP8-KV 指令会让 Volta 走慢速标量 attention 路径,生产环境改用 FP16 KV;
- SM70 drafter 默认对自己的 proposal 采样而非用贪心/局部 argmax;
- target verify 路径存在多余的状态同步与拷贝;
- 声明的 max context 会污染解码分区几何。
在长上下文方面,k=7 并非永远最优。当 live context 约 65K 时,MTP k=7 的吞吐降到 54.7 tok/s,而 k=3 反而达到 76.3 tok/s,因为每多一步 drafter 都要遍历长 KV 历史的代价变大。结论不是「长上下文关掉投机」,而是最佳深度随上下文变化。后续计划加入 per-request 自动深度选择。
目前 262K 完整窗口在该硬件上属于内存边缘状态,244,608 是两边都能稳定启动的最大配置。完整代码与说明已在 GitHub 开源。
(原文:Reddit r/LocalLLaMA,作者:dnv2003)
