DC娱乐网

0xBakeer记录了他是如何优化在单台 DGX Spark跑 Qwen3.8-

0xBakeer记录了他是如何优化在单台 DGX Spark跑 Qwen3.8-27B 的。从7.88 → 75 tok/s,单路生成。16 路并发时,总吞吐量达到 256 tok/s。还有一个结论是如果有并发跑本地模型的需求,这时量化模型是没什么优势的。

“Qwen3.8-27B,单台 DGX Spark:单路从 7.88 → 75 tok/s,16 路总吞吐 256 tok/s。

整个周末我都在折腾怎么让 Qwen3.8-27B 在单台 DGX Spark 上跑得更快,结果最后发现:我一开始的那些假设,几乎全错了。

起点是 7.88 tok/s。原生 FP8,完全没调优。

我原本的想法和大家差不多:想提速,就做量化。4-bit,每个 token 要搬的数据更少,搞定。

错了。或者至少可以说,量化只是答案里最不重要的那一小部分。

在完全相同的 FP8 权重上,推测解码(speculative decoding)直接把速度提高到了 58.5 tok/s。也就是 7.4 倍提速,而且完全不需要改模型权重。

更重要的是,它根本不会改变最终输出,因为完整模型会验证草稿模型生成的每一个 token,凡是完整模型自己不会生成的 token,都会被丢弃。

相当于白捡的性能。我之前居然一直忽略了它。

然后,我又发现了几件完全出乎意料的事。

草稿模型(drafter)的架构,比草稿深度(draft depth)重要得多。

DSpark 是一个独立的 1B 草稿模型,一次可以生成 7 个 token。MTP 则是把 checkpoint 里的某一层重复运行 7 次,而且每次都要支付一次完整词表投影(vocab projection)的计算成本。

DSpark 每轮实际被接受的 token 更少,但速度仍然快了 46%。

每个草稿 token 的成本:DSpark:0.046MTP:0.153

结论是:便宜的推测步骤,比猜得准更重要。

“接受率(acceptance rate)”这个指标也很容易误导人。

把 k 从 7 提高到 14 后,接受率从 98.7% 降到了 68.7%,但生成速度反而提高了 27%。

原因是,草稿靠后的那些 token 基本就像买彩票,而前面的 token 几乎必然会被接受。

真正能够预测吞吐量的指标,是“每次 forward pass 平均产出的 token 数”,而不是接受率。

还有一个问题:前缀缓存(prefix caching)居然一直在悄悄地处于关闭状态。

对于混合注意力(hybrid attention)模型,vLLM 默认会禁用 prefix caching,而 Qwen3.8-27B 报告的 is_hybrid=True。

启动日志里对此完全没有提示。

Claude 帮我一起排查,最后也是读了引擎源码才发现这个问题。

打开 prefix caching 之后:

19K 的共享前缀,prefill 快了 14 倍;53K 的共享前缀,prefill 快了 22 倍。

然后是我真正关心的结果。

单请求时,4-bit 比 FP8 快 27%。

4 个并发请求时,快 20%。

8 个并发请求时,快 10%。

到了 16 个并发请求,两者性能差距只有 0.2%。

基本完全一样。

理解背后的原因之后,这其实很合理。

单路 decode 主要受显存带宽限制(memory bandwidth bound),所以把权重数据量减半,工作量也几乎减半。

但一旦开始批处理,同一次权重读取可以同时服务很多条序列。

这时候瓶颈就从内存带宽转移到了计算能力,权重到底占多少字节就没那么重要了。

所以,如果你的场景是并行运行多个 Agent,那么量化带来的收益几乎为零。

而且在长上下文的 prefill 阶段,4-bit 反而会让你损失 7%–9% 的性能,因为在没有原生 FP4 计算路径的硬件上,每次矩阵乘法之前,都需要先把 4-bit 权重解包。

最终结果:

7.88 → 75 tok/s,单路生成。

16 路并发时,总吞吐量达到 256 tok/s。

所以,在你相信任何 4-bit 版本的性能优势之前,先用你自己的真实任务跑一遍测试。”