I benchmarked Unsloth's Qwen3.6-27B NVFP4 on 1x/2x 5090s. MTP is great until it really isn't.

Reddit r/LocalLLaMA 新闻

摘要

详细基准测试:Unsloth的Qwen3.6-27B NVFP4模型在RTX 5090 GPU上的表现,显示MTP(多令牌预测)在短上下文的单次请求中能显著加速,但在批量并发或长上下文场景下则会带来不利影响。

我使用Qwen3.6-27B的GGUF版本有一段时间了,所以当Unsloth发布NVFP4版本时,我想看看它在vLLM中的表现。先澄清一下:这是Unsloth的Qwen3.6-27B NVFP4版本,不是NVIDIA单独的NVFP4版本。我最想弄清楚的是如何设置num_speculative_tokens参数。另外,我还想知道将模型分到两张5090上是否真的能提升生成速度,以及在加入并发或大上下文后,MTP是否仍然有效。简而言之:对于单个用户、短上下文的情况,nspec=3表现非常好。一旦GPU忙于批处理,或者上下文变大,优势基本消失,反而可能带来明显的速度下降。 https://preview.redd.it/dht5v418ileh1.png?width=2400&format=png&auto=webp&s=f4517815a4db1324b2ba16a4c5bf27ff1c0364aa ### 设置 - **模型**: Unsloth Qwen3.6-27B-NVFP4(压缩张量;NVFP4 MLP,FP8注意力) - **GPU**: 2× RTX 5090,每张32 GB - **vLLM**: 0.25.1 - **PyTorch**: 2.11.0+cu130 - **驱动**: 580.159.03 - **注意力后端**: TRITON_ATTN - **最大模型长度**: 65,536 - **1 GPU**: tensor_parallel_size=1, max_num_seqs=16 - **2 GPU**: tensor_parallel_size=2, max_num_seqs=32 - **MTP方法**: qwen3_5_mtp 对于MTP和并发测试,我使用了Spec-Bench提示数据集,而不是像"数到100"这样的合成提示。 - **单请求测试**: 24个提示,请求512个输出token - **并发测试**: 256个输出token,并发数1/4/8/12/16下分别有8/16/32/48/64个提示 - **上下文测试**: 每个上下文大小下四个固定长度的随机提示,256个输出token 上下文样本较小,因此我将这些数字视为该配置下的强信号,而非普遍规律。我保留了模型的默认采样参数:temperature=1.0, top_k=20, top_p=0.95。这意味着实际的接受率和MTP速度在不同运行间可能有所波动。对于第1节和第3节,解码速度为1000 / 中位数TPOT。通俗来说,这是首个token之后的生成速度,已排除提示处理时间。第2节则不同,它报告了整个服务器在所有活跃请求上的合计输出吞吐量。 ### 1. 单GPU搭配MTP比双GPU更快 | GPU | MTP | 解码tok/s | 与同GPU基线相比的变化 | |------|------|-------------|------------------------| | 1× 5090 | 关闭 | 66 | 基线 | | 1× 5090 | nspec=3 | 120 | +82% | | 2× 5090 | 关闭 | 99 | 基线 | | 2× 5090 | nspec=3 | 108 | +9% | 这是第一个让我意外的结果。一张5090搭配nspec=3达到了120 tok/s,而两张5090使用相同的MTP设置仅为108 tok/s。这并不意味着第二张卡毫无用处。它为你提供了更大的KV缓存、上下文、批处理和预填充空间。只是在这个测试中,它对单请求解码速度没有帮助。我猜测是张量并行的通信开销显著改变了MTP的权衡。此外,TP=2时运行间的波动也更大。我较早的一次运行结果是单GPU 117 tok/s,双GPU 118 tok/s。单GPU的结果非常稳定,双GPU则不然。我不建议将108视为每个人应得的固定数值。 ### 2. 批处理接管后,MTP优势消失 以下是单张RTX 5090上整个服务器的总输出token数(每秒)。该数值是所有活跃请求的总和,而非每个用户单独看到的。 | 并发请求数 | MTP关闭 | nspec=3 | 变化 | |------------|----------|---------|------| | 1 | 64 | 121 | +87% | | 4 | 228 | 414 | +81% | | 8 | 453 | 475 | +5% | | 12 | 638 | 501 | -22% | | 16 | 789 | 498 | -37% | 在1个请求时,MTP几乎使吞吐量翻倍。在8个请求时几乎没什么帮助。在12和16个请求时,它反而拖慢了服务器。有趣的是,接受率在负载下并未崩溃:并发1时约为73%,并发16时约为71%。我的解读是,常规批处理已经使GPU保持忙碌,因此推测验证变成了额外的工作,不再能节省足够的解码步骤来证明其合理性。这里的异常点是并发4。这次运行测得MTP为414 tok/s,但较早的一次运行只有250 tok/s,并且尾部延迟非常糟糕。基线数值以及并发1/8/12/16的行为都复现得相当一致。在多做几次重复测试之前,我不会对并发4下+81%的数据过于信任。 ### 3. 长上下文最终使MTP从加速变为减速 **单张RTX 5090,单一活跃请求** | 输入长度 | MTP关闭 | nspec=3 | 变化 | |----------|---------|---------|------| | 2k | 66 | 107 | +62% | | 8k | 65 | 100 | +54% | | 32k | 61 | 62 | +2% | | 60k | 57 | 46 | -20% | **两张RTX 5090搭配张量并行,单一活跃请求** | 输入长度 | MTP关闭 | nspec=3 | 变化 | |----------|---------|---------|------| | 2k | 99 | 105 | +6% | | 8k | 96 | 117 | +22% | | 32k | 89 | 72 | -19% | | 60k | 81 | 45 | -44% | 交叉点因GPU配置而异。在单GPU上,MTP在32k时基本持平,60k时慢20%。在TP=2时,32k时已慢19%,60k时慢44%。在双GPU上,接受率从8k时的约71%降至60k时的60%。与此同时,随着KV缓存增长,每次验证传递的成本也越来越高。这种组合似乎很快扼杀了收益。因此我不会使用像"超过16k就始终禁用MTP"这样的一刀切规则。在这台机器上,交叉点出现在8k到32k之间(TP=2时),以及32k到60k之间(单GPU时)。你的提示和接受率会改变这个点的位置。 ### 我目前实际使用的设置 - **单个交互用户,短上下文**: num_speculative_tokens=3 - **约八个并发请求**: 两者都测试;这里MTP仅带来+5% - **单张5090上12+个并发请求**: 关闭MTP - **TP=2时32k上下文**: 关闭MTP - **任一配置下60k上下文**: 关闭MTP 另有一个警告来自更大范围的扫描:TP=2搭配nspec=8在并发16时导致vLLM服务器两次崩溃,错误为"CUDA error: an illegal memory access was encountered"。在此特定模型/后端组合下,两次尝试均失败。我并非声称nspec=8在所有地方都有问题。 ### 快速质量检查 基准测试数值如果量化模型做不了任何有趣的事情就没什么用,所以我还在自己构建的桌面应用中给了它一个智能体任务:"构建Flappy Bird"。没有后续提示,没有修正,没有提示。它规划了任务,编写了代码,并一次性启动了一个可玩的游戏。 https://reddit.com/link/1v2l1zi/video/lfslklsukleh1/player 显然,一次成功的演示不是质量基准,也不能证明与BF16或GGUF版本相当。我仅将其作为合理性检查,表明该模型在相当复杂的智能体工作流中仍然可用。 ### 复现命令 这是单GPU、nspec=3的服务器配置: ```bash vllm serve /path/to/Qwen3.6-27B-NVFP4 \ --served-model-name qwen \ --tensor-parallel-size 1 \ --attention-backend TRITON_ATTN \ --max-model-len 65536 \ --gpu-memory-utilization 0.90 \ --max-num-seqs 16 \ --reasoning-parser qwen3 \ --speculative-config '{"method":"qwen3_5_mtp","num_speculative_tokens":3}' ``` 这是单请求Spec-Bench客户端: ```bash vllm bench serve \ --backend openai-chat \ --endpoint /v1/chat/completions \ --model /path/to/model \ --served-model-name qwen \ --tokenizer /path/to/model \ --dataset-name spec_bench \ --dataset-path spec_bench_question.jsonl \ --spec-bench-output-len 512 \ --num-prompts 24 \ --max-concurrency 1 \ --ignore-eos \ --percentile-metrics ttft,tpot,itl,e2el ``` 有没有其他人测试过这个Unsloth版本在两张5090上的表现?我很好奇,如果换用另一个注意力后端,TP=2下MTP扩展性弱的现象是否仍然复现。我也希望看到有人用确定性采样和更多提示重复长上下文扫描。
查看原文

相似文章

@Snixtp: https://x.com/Snixtp/status/2055734339346768225

X AI KOLs Timeline

某用户使用llama.cpp在单张RTX 3090上对Qwen3.6 27B的MTP变体与普通版本进行了基准测试,发现MTP在长上下文(32k-64k)下生成速度最高可提升2.37倍,但预填充较慢且暂不支持并发。