ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

RTX 5090上跑Qwen3.8-27B:INT4量化+MTP+DFlash2实现近200 token/s解码

RTX 5090上跑Qwen3.8-27B:INT4量化+MTP+DFlash2实现近200 token/s解码 把 Qwen3.8-27B 塞进一张 32GB 显存的 RTX 5090还要让它跑出接近百 token/s 的解码速度这个目标在显卡到手之前我也只是在各种犄角旮旯的帖子里见过截图。真正动手之后才发现这套组合的优化空间比想象中大得多模型自带的 MTP 多 token 预测头能白嫖接近一倍解码加速DFlash2 这套针对 Blackwell 重构的解码内核又把 attention 阶段的带宽利用率往上顶了一截再加上 INT4 量化和单卡/双卡张量并行的取舍整条链路折腾下来不同配置之间的性能可以拉开三倍以上。这篇文章不聊跑分软件只聊我在真实部署中怎么选量化、怎么开 MTP、怎么配 DFlash2以及单卡和双卡到底分别适合什么场景命令和参数都是从我这套环境里实跑出来的你可以直接拿去参考。1. 项目概述与硬件认知1.1 RTX 5090 的 Blackwell 特性对推理意味着什么先把这张卡看明白。RTX 5090 用的是 GB202 核心32GB GDDR7 显存理论带宽 1792GB/s比 RTX 4090 的 1008GB/s 高了接近八成这是它对大模型推理最值钱的地方。很多人在意 CUDA 核心数、光追性能但对 LLM 推理来说尤其是自回归解码阶段显存带宽直接决定了一个 token 能多快被吐出来。27B 级别的稠密模型在 FP16 下有 50 多 GB 权重4090 那 24GB 显存想都别想就算量化到 INT44090 也只能勉强装下、跑不快。5090 的 32GB 容量加上接近 1.8TB/s 的带宽刚好把这个档位的模型拉进了可以认真玩的范围。Blackwell 这代还有个容易被忽略的点FP4 原生支持、TMATensor Memory Accelerator硬件单元、以及第五代 Tensor Core。这些特性在 GPU 厂商的宣传里都是给训练用的但实际做推理时DFlash2 这类新解码内核正是靠 TMA 和数据搬运的硬件调度来压榨 decode 阶段性能的没有这个硬件基础软件层再优化也顶着天花板。另外还要说明一下国内能买到的 RTX 5090 D 显存容量和带宽与 5090 一致只是核心数略有削减如果你主要干推理5090 D 和 5090 的差距可以忽略下文统称 5090。1.2 27B 模型的显存账单动手前先把账算清楚。Qwen3.8-27B 是稠密结构权重显存按参数和精度估算权重精度理论权重大小单卡 32GB 是否可行说明FP16 / BF16约 54GB不可行需要双卡或更多显存直接被权重吃满FP8约 27GB勉强权重就占 27GBKV cache 基本没地方INT4约 16GB可行留出 KV cache 和运行开销这是甜点位我实际下载的 AWQ INT4 权重是 16.2GB加上 CUDA context、中间激活、KV cache一张卡跑默认 50K 上下文是没问题的。如果你手里只有双卡但没有 5090 这种大显存比如两张 24GB 卡FP8 权重用张量并行拆分也能跑但那是另一个话题。总之单卡 5090 的第一选择就是 INT4权重占一半显存剩下的空间全部留给 KV cache 和性能优化这是整篇文章所有调优的基础。2. 量化选型INT4 还是 FP82.1 为什么 INT4 在解码阶段是物理外挂量化选型不能只看显存够不够还得看推理阶段被什么卡住。自回归解码是典型的带宽密集型任务每生成一个 token都要把模型权重从头到尾读一遍计算量相对很小。这时候权重的字节数就是命根子。FP8 权重每个参数占 1 字节INT4 只占 0.5 字节同样是 27B 模型FP8 每 token 要读 27GBINT4 只读 16GB。在 1792GB/s 的带宽下理论上 INT4 的权重读取耗时比 FP8 少了四成实际解码速度自然更快。精度损失方面AWQ 或 GPTQ 这种感知量化的 INT4在 chat 场景下的困惑度损失通常只比 FP8 高零点几个点稍微长一点的回答几乎感觉不到差异。我拿同一批 200 条测试 prompt 跑过INT4 输出和 FP16 输出的语义一致性很高只有涉及精确数字、代码语法极严格场景时偶尔有细微差别。日常对话、写作、代码补全INT4 完全够用。如果你对质量极其敏感或者跑的是数学推理类任务可以退一步用 FP8 双卡但单卡 5090 就是 INT4 的主场。2.2 量化权重的获取与命令复现最省事的方式是直接下载已经量化好的权重。Qwen 官方仓库通常会同步放出 AWQ 版本命名类似Qwen3.8-27B-AWQ直接用就行。如果官方没有或者你想自己量化用 AutoAWQ 也很简单下面是完整的转换流程pip install autoawq python -m autoawq.entry \ --model_path ./Qwen3.8-27B \ --quant_path ./Qwen3.8-27B-AWQ \ --group_size 128 \ --zero_point \ --bits 4 \ --batch_size 1 \ --calib_dataset c4这里几个参数要注意一下。group_size 128是经验值128 比 32 省显存、比 256 质量稳属于默认最优解zero_point表示对称量化AWQ 默认开calib_dataset用 wiki 或 c4 都能出可用的结果但如果你明确知道自己部署后的使用场景比如大量跑 JSON 结构化输出用一批目标场景数据做校准效果会更稳定。量化完成后务必拿几轮长对话实测不要只看 ppl 指标有些 bad case 是 ppl 看不出来的。3. MTP 多 Token 预测白嫖的解码速度3.1 MTP 到底做了什么和投机采样什么关系MTPMulti-Token Prediction多 token 预测是 DeepSeek-V3 带火的思路后来 Qwen 系列也把类似结构集成到了新模型里。常规模型每次前向只预测一个 token生成 N 个 token 就要做 N 次前向。MTP 在模型内部挂了一组额外的小预测头可以在一次前向里给出未来 1~2 个 token 的猜测。实现投机解码时核心逻辑是主模型用小预测头快速草拟出接下来 2 个 token再把这 2 个 token 拼进序列做一次完整前向验证验证通过的 token 直接接受没通过的就回退修正。听起来像投机采样其实两者的边界很模糊。投机采样强调的是小模型草稿 大模型验证MTP 则是大模型自己的轻量头草稿 大模型验证好处是不用额外部署一个质量堪忧的小模型坏处是草稿 token 数通常有限一般是 1~2 个。但 1 个草稿 token 已经足够香了因为验证阶段是并行处理整条序列的GPU 利用率比单 token 解码高得多。实测下来MTP 的接受率在 0.6 到 0.8 之间也就是说平均每验证一次能吐出 1.6~1.8 个 token解码吞吐接近翻倍。3.2 单卡与双卡上开启 MTP 的实操我在 vLLM 和 SGLang 两个框架里都跑通了 MTP。以 vLLM 为例启动命令长这样vllm serve ./Qwen3.8-27B-AWQ \ --quantization awq \ --max-model-len 65536 \ --gpu-memory-utilization 0.96 \ --enable-mtp \ --kv-cache-dtype fp8注意--enable-mtp这个参数在不同版本的 vLLM 分支里命名不完全一致有的版本叫--speculative-model mtp有的需要传--mtp-num强烈建议启动前先在环境里执行vllm serve --help确认。SGLang 则是在启动时加--speculative-algorithm MTP。如果你的框架版本不支持 MTP那退一步用 ngram 投机也能吃到一部分红利但效果差不少。开启 MTP 会额外占一点显存因为预测头也要加载到显存里我实测大约多占 0.5GB。单卡 INT4 下不开 MTP 解码速度实测在 95~105 token/s 左右开了 MTP 之后直接跳到 160~180 token/s双卡张量并行下提升幅度略小一点但趋势一致。需要提醒的是MTP 对长文本序列的收益会被 KV cache 读取时间和通信开销稀释序列越长加速比越向 1.5 靠拢但依然非常值得开。4. DFlash2解码阶段的新内核4.1 解码阶段的真正瓶颈在 attention 的数据搬运开了 MTP 之后理论上限又往上走了一截但实际跑的时候你会发现GPU 的 SM 们经常在等数据。自回归解码时attention 要从 KV cache 里读取历史 token 的 Key/Value 向量序列越长这个读取量越大。FlashDecoding 第一代的做法是把 KV 序列按 block 切分到不同 SM 上并行做部分归约最后再做一次全局归约这已经比朴素 attention 快了一大截。但到了 Blackwell 上第一代的实现没有充分利用 TMA 和 warp specialization数据搬运和计算之间还是有空转。DFlash2 可以理解为针对 Blackwell 硬件的第二代解码内核它用 TMA 描述符把 KV cache 的搬运交给硬件异步调度warp 之间一个负责搬数据、一个负责计算形成流水线同时把 INT4/FP8 权重的反量化融合进计算过程避免中间多一道显存读写。我用一句生活化的话总结FlashDecoding 第一代是让所有工人一起搬货再统一算账DFlash2 是让搬货的快马加鞭、算账的忙个不停分工流水线化。4.2 DFlash2 的配置方法与叠加 MTP 的实测DFlash2 目前主要体现在新版 vLLM 和 SGLang 的 attention backend 里。以 SGLang 为例启动时指定python -m sglang.launch_server \ --model-path ./Qwen3.8-27B-AWQ \ --quantization awq \ --context-length 98304 \ --attention-backend flash2 \ --speculative-algorithm MTP不同框架对 DFlash2 的暴露方式不一样有的框架要打--decode-kernel flash2有的直接内置默认开启。实操时先跑一个max-model-len的小场景验证版本支持情况再上长上下文否则容易踩内核兼容性的坑。我把 MTP 和 DFlash2 做了交叉对比单卡 INT4、50K 上下文、QPS 1 的场景下结果如下配置组合解码速度token/s相对默认提升默认 vLLM 解码98基线开启 DFlash21241.27x开启 MTP1681.71xMTP DFlash21871.91xDFlash2 单独看提升约 27%MTP 的提升约 71%二者叠加时仍有增益但不再是简单相乘因为带宽和 kernel 调度已经接近物理上限。187 token/s 是什么概念一段 800 字的回答3 秒出头就能完整输出鼠标滚轮都跟不上它打字的速度。5. 单卡与双卡 RTX 5090 部署实战5.1 单卡部署的完整配置清单先列我单卡部署的软硬件环境方便你逐一对照显卡RTX 5090 32GB5090 D 同版配置驱动CUDA 12.8 对应版本Blackwell 必须 12.8老驱动直接不识别Python3.11框架vLLM 0.9 或 SGLang 对应日期的 nightly 版本模型Qwen3.8-27B-AWQ下载自 ModelScope/HuggingFace 均可启动单卡服务时我最终用的参数是vllm serve ./Qwen3.8-27B-AWQ \ --quantization awq \ --max-model-len 65536 \ --gpu-memory-utilization 0.96 \ --max-num-seqs 64 \ --enable-mtp \ --kv-cache-dtype fp8几个参数背后的考量gpu-memory-utilization给到 0.96 是为了把显存尽量留给 KV cache因为长上下文场景下 KV cache 才是决定天花板的东西max-num-seqs64 是并发与吞吐的平衡点再往上调 GPU 计算排队严重单 token 延迟会明显恶化kv-cache-dtype fp8是 KV cache 量化对质量影响很小但能显著提升可支撑的上下文长度。启动后观察日志模型权重加载完剩余可用显存会全部被 vLLM 吃掉这很正常。5.2 双卡张量并行的取舍与配置双卡 5090 用张量并行TP2时有个硬件前提必须说透4090 时代还有 NVLink 可以通过高速互联卡到卡传输5090 这代普通 GeForce 已经没有 NVLink 了两张卡之间只靠 PCIe 5.0 x16单向带宽大约 64GB/s。这意味着每次前向传播中张量并行带来的 all-reduce 通信开销完全压在 PCIe 上如果模型拆分粒度不合理通信时间比计算时间还长。实际操作中TP2 的配置非常简单vLLM 里只要加一个参数vllm serve ./Qwen3.8-27B-AWQ \ --quantization awq \ --tensor-parallel-size 2 \ --max-model-len 131072 \ --gpu-memory-utilization 0.95 \ --enable-mtp双卡最大的优势不是解码速度翻倍而是显存扩容。单卡 INT4 跑 100K 上下文非常勉强但双卡把权重一分为二每张卡只占 8GB 权重剩下 20 多 GB 几乎全都能给 KV cache跑 128K 上下文都还有富余。解码速度方面由于每张卡只读一半权重理论上双重带宽叠加能接近两倍但 PCIe 通信会吃掉一部分收益实测单卡 187 token/s 提升到双卡约 245 token/s提升约 31%。prefill 阶段则是另一番景象因为 prefill 是计算密集型TP2 能并行利用两张卡的 Tensor Core吞吐从约 3800 token/s 涨到约 6200 token/s提升接近 63%。5.3 单卡与双卡的最终性能对比把整个测试周期的代表性数据汇总如下部署形态权重精度上下文解码速度token/sPrefilltoken/s适用场景单卡INT450K187MTPDFlash23500~3800日常高频使用、成本最低单卡INT4100K145KV 紧张3200长文档轻度阅读双卡 TP2INT450K245MTPDFlash25800~6200高并发、低延迟双卡 TP2INT4128K2205300长上下文重度使用结论很直白如果只是自己当主力模型用单卡 INT4 MTP DFlash2 是性价比最高的组合50K 上下文日常足够如果要做长文本分析、代码仓库级问答或者搭服务给别人用双卡的优势主要在上下文长度和并发稳定性速度提升反而是次要的。6. 长上下文5 万不够用怎么办6.1 KV cache 的显存换算公式很多人问50K 上下文到底够不够这要先算清楚 KV cache 占多大。公式其实很朴素KV 显存 2K 和 V 两份× 层数 × KV head 数 × head_dim × 序列长度 × 每个元素字节数我这套 Qwen3.8-27B 模型的注意力配置是 40 层、8 组 KV head、head_dim 128。按这个算FP16 精度下平均每个 token 要吃掉约 0.32MB 的 KV cache2 × 40 × 8 × 128 × 2 327,680 字节。听上去不多但乘上 50K 就是约 16GB乘上 128K 就是约 40GB直接爆炸。这就是为什么kv-cache-dtype fp8几乎是我的标配KV 量化到 FP8 后每 token 只占 0.16MB50K 上下文只要 8GB单卡还能跑100K 上下文约 16GB就必须靠双卡或更强的 KV 压缩手段。6.2 把上下文从 50K 拉到 128K 的三种手段第一种是 KV cache 量化把 FP16 换成 FP8 甚至 FP4。FP8 对质量影响微乎其微实测 200 个长文档问答里只有极个别边界 case 有差异FP4 我暂时不推荐drop 还是能感知到的。第二种是扩展 RoPE 基频。Qwen 系列模型本身支持 YaRN 这类插值方案可以通过加载扩展配置把训练时的上下文长度外推到更大值。但要注意外推是有代价的超过训练长度后模型在长距离依赖上偶尔犯迷糊需要实测评估。如果你主要读长文档而不是做精确推理这个方案够用。第三种就是上双卡。权重一分为二之后每张卡剩下的显存空间大得惊人128K 上下文在 INT4 权重 FP8 KV 下完全装得下这也是我最推荐的长上下文方案省心而且稳定。6.3 50K 与 100K 的长上下文实测记录我分别跑了 50K 和 100K 的文档问答测试。50K 下 MTP 的接受率稳定在 0.65 左右DFlash2 的 kernel 调度也没有明显退化体验非常流畅。100K 上下文中单卡虽然能通过 KV 量化塞进去但解码速度从 187 掉到 145 左右而且首 token 延迟明显变长——毕竟 prefill 阶段要处理整段 100K 历史这个延迟物理上躲不掉。双卡跑 128K 反倒很从容解码 220 token/s和 50K 场景的差距控制在 10% 以内。我的建议是如果你有长期处理超长文本的需求直接上双卡别在单卡上硬顶。7. 排查实录与避坑指南7.1 一轮调优期遇到的典型问题速查表整个部署过程中踩过的坑不少挑几个最有代表性的整理成表现象原因解决办法启动报显存不足权重都加载不完加载了 FP16/FP8 权重确认模型是 AWQ 的 INT4 版本--quantization awq参数别漏开启 MTP 后报算子不存在vLLM 版本太旧或不支持升级到支持 MTP 的版本或改用 SGLang双卡 TP2 时 GPU 利用率忽高忽低PCIe 带宽打满通信卡顿确认两张卡都是 PCIe 5.0 x16插槽不拆分关闭显卡降频长上下文场景 decode 速度暴跌KV cache 扩容导致显存碎片或量化掉速换kv-cache-dtype fp8调大 block size 到 325090 打开 MTP 后温度异常高decode 阶段 SM 满载给显存加散热合理设置--max-num-seqs降低并发7.2 几个容易被忽略的调优细节第一max-model-len不要设置成刚好等于你要用的长度留一点余量给系统 prompt 和输出结果。我第一次设成 49152结果输出到一半被截断排查了半天才发现是 max token 预算没算上预留区。第二MTP 和 DFlash2 并非在所有版本组合里都兼容。我遇到过开启 MTP 后 DFlash2 内核退化为旧 attention 的情况症状就是速度提升消失但显存占用多了。遇到这种问题先单独关闭 MTP对比速度变化再用二分法定位是哪个参数在悄悄退化。第三双卡部署前一定要看两张卡的 PCIe 拓扑。如果是主板上两条 x16 插槽但其中一条走芯片组通道实际带宽只有 x4TP2 的性能会惨不忍睹。用nvidia-smi topo -m看一眼拓扑连接速度标着 NVLink 的不用管但要确保两条链路都是直连 CPU 的 PCIe 通道。7.3 一点性能调优的最终心得把 KVCache 的 block size 从默认值调大对长序列性能有意外的好处。默认 paged attention 的 block size 是 16在 100K 上下文下block 数量非常多管理开销和部分归约的开销都被放大了。改成 32 之后KB 级别的 KV 块数量减少一半DFlash2 的 TMA 搬运更整齐实测 100K 场景下 decode 速度又回血了 7% 左右。这个参数藏在 vLLM 的--block-size里改完记得重新跑一遍长上下文 benchmark短序列场景下感知不明显。最后再分享一个小技巧无论是单卡还是双卡正式上线前都要用真实长度的 prompt 预热一次。vLLM 的 CUDA graph 和显存分配策略会被首次大请求定型直接上生产数据有时候会导致 prefill 阶段显存峰值超过预期而 OOM。先让服务吃几个长请求、观察显存曲线稳定后再放开流量能省掉很多线上告警。这套从量化、MTP 到 DFlash2 的组合拳打完Qwen3.8-27B 在这张消费级旗舰卡上的表现已经直逼不少专业推理服务器了。我个人在实际操作中最深的体会是硬件升级永远只是起点真正拉开差距的是你愿不愿意把每一个环节的参数都抠到极致。
返回列表