<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>NVFP4 on Jiangwan&#39;s Blog</title>
        <link>https://jiangwan.ink/tags/nvfp4/</link>
        <description>Recent content in NVFP4 on Jiangwan&#39;s Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Fri, 28 Aug 2026 10:00:00 +0800</lastBuildDate><atom:link href="https://jiangwan.ink/tags/nvfp4/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>为什么生产推理我默认 vLLM：从 NVFP4、Kernel 到 CUDA Graph</title>
        <link>https://jiangwan.ink/p/vllm-production-inference-nvfp4-cuda-graph/</link>
        <pubDate>Fri, 28 Aug 2026 10:00:00 +0800</pubDate>
        
        <guid>https://jiangwan.ink/p/vllm-production-inference-nvfp4-cuda-graph/</guid>
        <description>&lt;blockquote&gt;
&lt;p&gt;📚 &lt;strong&gt;双 RTX 5060 Ti 部署 Qwen3.8 系列 · 4/6&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;导读&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;llama.cpp 和 vLLM 并不是简单的“谁更快”。前者把个人硬件能触碰到的模型规模往上推，后者则更适合在模型可以完整驻留 GPU 后继续追求 Serving 效率。这篇从 Qwen3.8-Flash-Next 的 CPU Offload 讲到 NVFP4、Kernel、Compile 和 CUDA Graph，也解释为什么我的 27B 生产部署默认从 vLLM 开始。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;前面三篇已经解决了三个问题：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;27B 怎么装进双 16GB
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;两张 GPU 到底怎么并行
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;TP2 为什么能加速、又为什么达不到理想 2×
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;到了真正部署服务时，我现在有一个比较明确的默认选择：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;只要是 NVIDIA GPU、模型能够合理地完全驻留 GPU，并且目标是长期提供推理服务，我会优先从 vLLM 开始。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;原因并不只是 PagedAttention，也不只是 KV Cache。&lt;/p&gt;
&lt;p&gt;真正让我倾向 vLLM 的，是它把整个 GPU 推理执行链放在同一个系统里优化：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4 / FP8 等低精度格式
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Optimized GEMM / Attention Kernel
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;torch.compile / Inductor
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CUDA Graph
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;TP / PP
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Scheduler / Continuous Batching
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Cache / Prefix Cache
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这些东西单独拿出来都只是一个优化点。&lt;/p&gt;
&lt;p&gt;组合起来以后，才是一套真正面向 GPU Serving 的推理引擎。&lt;/p&gt;
&lt;p&gt;不过在谈 vLLM 之前，先要把一个经常被混在一起的问题说清楚：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“模型能不能跑”和“这个模型适不适合做高性能 GPU Serving”，不是同一个问题。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Qwen3.8-Flash-Next 恰好是一个非常好的例子。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;1-qwen38-flash-nextcpu-offload-为什么依然有价值&#34;&gt;1. Qwen3.8-Flash-Next：CPU Offload 为什么依然有价值
&lt;/h2&gt;&lt;p&gt;写这组文章的时候，Qwen3.8-27B 才开放权重大约两周。&lt;/p&gt;
&lt;p&gt;然后 2026 年 8 月 26 日，Qwen 又开放了 Qwen3.8-Flash-Next。&lt;/p&gt;
&lt;p&gt;它的体量已经完全不是 27B 这一级别：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Language Model：125B 参数，约 6B activated
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;51B n-gram embedding
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4B MTP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;总体参数规模大约到了 180B 量级。&lt;/p&gt;
&lt;p&gt;直接看权重文件更直观：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;官方 BF16：约 360GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;官方 FP8：约 186GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Unsloth UD-Q4_K_XL GGUF：约 111GB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这时“显存不够”已经不是双 16GB 能不能稍微规划一下的问题了。&lt;/p&gt;
&lt;p&gt;甚至假设有：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;8 × RTX 3090 24GB = 192GB VRAM&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这种对个人用户已经非常夸张的配置，仅从总量上看，官方 FP8 的约 186GB 权重就已经快把聚合显存吃满了。&lt;/p&gt;
&lt;p&gt;而真正运行模型显然还要给：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Runtime&lt;/li&gt;
&lt;li&gt;Cache&lt;/li&gt;
&lt;li&gt;Activation&lt;/li&gt;
&lt;li&gt;Workspace&lt;/li&gt;
&lt;li&gt;CUDA Graph&lt;/li&gt;
&lt;li&gt;通信 Buffer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;留下空间。&lt;/p&gt;
&lt;p&gt;更不用说 8 张 3090 的拓扑、供电、散热和整机成本，本身就已经脱离绝大多数个人开发者的现实环境。&lt;/p&gt;
&lt;p&gt;我当然也不会为了试一个刚发布的模型，先准备一台 8×3090 的机器。&lt;/p&gt;
&lt;p&gt;这时候 llama.cpp 的另一种价值就非常明显了：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;它可以把“GPU 显存不够”这个硬边界，扩展成“GPU VRAM + System RAM 能不能一起把模型跑起来”。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;例如一个 100GB 级 GGUF，可以让一部分权重留在 GPU，一部分权重放在系统内存，通过 CPU + GPU 的混合路径运行。&lt;/p&gt;
&lt;p&gt;原本的问题是：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;模型 &amp;gt; 总 VRAM → 根本放不下&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;现在变成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GPU VRAM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System RAM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 有机会真正运行起来
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;对于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;刚发布的超大模型&lt;/li&gt;
&lt;li&gt;能力测试&lt;/li&gt;
&lt;li&gt;本地研究&lt;/li&gt;
&lt;li&gt;个人消费级硬件&lt;/li&gt;
&lt;li&gt;显存容量不规则的机器&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种能力非常有价值。&lt;/p&gt;
&lt;p&gt;所以我并不认同一种简单的判断：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“CPU Offload 很慢，所以没有意义。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;它当然有意义。&lt;/p&gt;
&lt;p&gt;它改变的是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“我能够接触和测试多大的模型”。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但另一方面，也不能把 RAM 当成“更便宜的显存”。&lt;/p&gt;
&lt;p&gt;如果 Forward 需要频繁从系统内存取热点权重，那么整个性能模型就会受到：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU 内存带宽
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU-GPU 数据路径
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PCIe
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;限制。&lt;/p&gt;
&lt;p&gt;GPU 本地 GDDR 能提供数百 GB/s 级带宽，而系统 RAM 与 CPU↔GPU 的 PCIe 路径在有效带宽、延迟和访问方式上都明显不同。&lt;/p&gt;
&lt;p&gt;Offload 越重，Decode 越不可能维持纯 GPU Resident 模型的性能特征。&lt;/p&gt;
&lt;p&gt;所以我现在更愿意这么定义它：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;CPU / RAM Offload 很擅长扩大“能跑的模型范围”，但通常不是扩大“高性能生产 Serving 范围”的办法。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这也正好解释了 llama.cpp 和 vLLM 为什么不是简单的“谁替代谁”。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;2-对-27b-来说我反而会优先追求-gpu-resident&#34;&gt;2. 对 27B 来说，我反而会优先追求 GPU Resident
&lt;/h2&gt;&lt;p&gt;Flash-Next 这种百 GB 级模型，RAM Offload 很合理。&lt;/p&gt;
&lt;p&gt;但回到前面一直测试的 Qwen3.8-27B，情况完全不同。&lt;/p&gt;
&lt;p&gt;它不是“无论如何都放不下”。&lt;/p&gt;
&lt;p&gt;通过合适的量化，双 16GB 本来就有机会让权重完整驻留 GPU。&lt;/p&gt;
&lt;p&gt;这时候我的优化顺序会变成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;选择质量可以接受的量化
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;尽量让权重完整 GPU Resident
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;给 Cache / Context 留空间
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;选择 TP / PP
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;再优化 Kernel、Compile、CUDA Graph 和调度
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这也是为什么前面最终更倾向 NVFP4。&lt;/p&gt;
&lt;p&gt;FP8 约 31GB：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;32GB 总 VRAM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;约 31GB 权重
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;≈
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;几乎没有运行余量
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;NVFP4 约 23GB：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;32GB 总 VRAM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;约 23GB 权重
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;≈
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;还有约 9GB 名义空间
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;第一篇主要解释的是 NVFP4 的容量价值。&lt;/p&gt;
&lt;p&gt;但到了 vLLM 这一篇，NVFP4 还有另一半更重要的意义：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;它不只是“存储格式”，还可以直接参与低精度计算。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-nvfp4容量只是第一层价值&#34;&gt;3. NVFP4：容量只是第一层价值
&lt;/h2&gt;&lt;p&gt;如果一个 4bit 量化只解决存储，那么执行路径可能是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4bit Weight
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;读取 / 解码
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;反量化到更高精度
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;再执行通用 GEMM
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这依然能节省：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;权重显存&lt;/li&gt;
&lt;li&gt;Weight Traffic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但真正更有意思的是硬件原生低精度路径：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4 Weight
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;低精度 Activation / Scale
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;FP4 适配的 Tensor Core / MMA 路径
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4 GEMM
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这时量化同时改变了两件事：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Memory Traffic ↓ + 低精度计算吞吐 ↑&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;NVIDIA 的 NVFP4 本身就是为 Blackwell 低精度计算设计的格式，而不是单纯“把 FP16 截成 4bit”。&lt;/p&gt;
&lt;p&gt;所以：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NVFP4 在 Blackwell 上的价值，不能只用“省了多少 GB 显存”解释。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果框架真的走到了合适的 FP4 Kernel，它还会改变 GEMM 本身的执行路径。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;rtx-5060-ti-属于-blackwell这件事对-nvfp4-很重要&#34;&gt;RTX 5060 Ti 属于 Blackwell，这件事对 NVFP4 很重要
&lt;/h3&gt;&lt;p&gt;RTX 5060 Ti 属于 Blackwell 消费级 GPU，CUDA Compute Capability 为 12.0，也就是常说的 SM120。&lt;/p&gt;
&lt;p&gt;这意味着这张卡并不是“只能保存 NVFP4，然后全部转回旧精度算”。&lt;/p&gt;
&lt;p&gt;在合适的软件栈下，它有对应的 Blackwell 低精度计算能力可以利用。&lt;/p&gt;
&lt;p&gt;于是可以形成一条完整链路：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;RTX 5060 Ti / SM120
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4 Checkpoint
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4-aware Kernel
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Blackwell 低精度 Tensor Core 路径
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但这里有一个很重要的前提：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;模型文件写着 NVFP4，不代表执行时一定走到了最优 NVFP4 Kernel。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这也是我开始真正关心 vLLM Kernel Dispatch 的原因。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;支持-nvfp4和nvfp4-跑得快是两回事&#34;&gt;“支持 NVFP4”和“NVFP4 跑得快”是两回事
&lt;/h3&gt;&lt;p&gt;假设两个框架都能成功加载：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Qwen3.8-27B NVFP4&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这只能证明格式兼容。&lt;/p&gt;
&lt;p&gt;真正执行时，可能存在完全不同的路径。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;路径 A
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;额外转换 / 反量化
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;较通用的 GEMM
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;和：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;路径 B
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;专用 NVFP4 GEMM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;适合当前 Blackwell GPU 的 Kernel
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;模型格式一样，最终性能完全可能不同。&lt;/p&gt;
&lt;p&gt;vLLM 当前的 NVFP4 执行路径会根据平台与可用组件选择对应 GEMM backend，例如 FlashInfer / CUTLASS 一类实现，并在不同硬件能力下选择合适的 fallback。&lt;/p&gt;
&lt;p&gt;所以现在看量化模型，我会同时问两个问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;这个框架能不能加载它？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以及：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;加载以后，Linear 最终 Dispatch 到哪个 Kernel？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第二个问题对性能往往更重要。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;4-为什么-kernel-对单流-decode-特别重要&#34;&gt;4. 为什么 Kernel 对单流 Decode 特别重要？
&lt;/h2&gt;&lt;p&gt;一颗 token 的生成不是“一次巨大的 GPU 运算”。&lt;/p&gt;
&lt;p&gt;更像是几十层不断重复：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Attention
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Linear
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Norm
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Linear
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Activation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Linear
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;下一层
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;前面 TP2 的单流实测大约是：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;33.5 token/s&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;也就是一颗 token：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;≈ 30ms&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在这个时间尺度里，每层多一点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;量化转换&lt;/li&gt;
&lt;li&gt;不合适的 GEMM Shape&lt;/li&gt;
&lt;li&gt;Memory Access&lt;/li&gt;
&lt;li&gt;Kernel Launch&lt;/li&gt;
&lt;li&gt;同步&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;乘上几十层以后，就会变成很明显的最终差距。&lt;/p&gt;
&lt;p&gt;所以现代 LLM 推理框架真正优化的不是某一个“神奇开关”。&lt;/p&gt;
&lt;p&gt;而是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;大量重复的小执行路径能不能全部落到更合适的 Kernel 上。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这也是为什么“模型能加载”离“模型跑得好”还差很远。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;5-cuda-graphkernel-快了以后还要减少-launch&#34;&gt;5. CUDA Graph：Kernel 快了以后，还要减少 Launch
&lt;/h2&gt;&lt;p&gt;即使每个 CUDA Kernel 本身已经很快，单 token Decode 还有另一个问题。&lt;/p&gt;
&lt;p&gt;普通执行更接近：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU → Launch Kernel A
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU → Launch Kernel B
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU → Launch Kernel C
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU → Launch Kernel D
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;GPU 做完一个小任务，CPU 再继续提交后面的工作。&lt;/p&gt;
&lt;p&gt;对于非常大的矩阵，这点 Launch Overhead 往往不突出。&lt;/p&gt;
&lt;p&gt;但 Decode 每颗 token 都要重复大量小操作。&lt;/p&gt;
&lt;p&gt;这时“启动 GPU 工作”本身也开始变得有成本。&lt;/p&gt;
&lt;p&gt;CUDA Graph 的思路就是把一串 GPU 操作提前 Capture：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;普通模式
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU → A
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU → B
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU → C
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU → D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;变成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CPU
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Replay Graph
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;A → B → C → D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;从而减少重复的 CPU 调度与 Kernel Launch 开销。&lt;/p&gt;
&lt;p&gt;所以对单 token Decode 来说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;CUDA Graph 不是锦上添花的小功能，而是很自然的一层低延迟优化。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&#34;生产-serving-的-cuda-graph-不是简单的-on--off&#34;&gt;生产 Serving 的 CUDA Graph 不是简单的 ON / OFF
&lt;/h3&gt;&lt;p&gt;如果只是跑一个固定 Shape Benchmark，Capture 一张 Graph 很容易理解。&lt;/p&gt;
&lt;p&gt;但真正 Serving 时，Batch 是动态的：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;有时全是 Decode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;有时有 Prefill
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;有时是 Prefill + Decode 混合
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Batch Size 也一直变化
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所以实际问题不是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“支不支持 CUDA Graph？”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;不同 Runtime Batch 到底应该走哪种 Graph 模式？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;vLLM 当前把 CUDA Graph 分成多个运行模式，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NONE
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PIECEWISE
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;FULL
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;FULL_DECODE_ONLY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;FULL_AND_PIECEWISE
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中在支持对应能力的 V1 配置里，纯 Decode 可以使用更完整的 Graph，而 Prefill / Mixed Batch 可以走 Piecewise 路径，再由 Runtime 根据当前 Batch 类型选择。&lt;/p&gt;
&lt;p&gt;这件事对我来说很重要。&lt;/p&gt;
&lt;p&gt;因为 CUDA Graph 已经不再只是：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Benchmark 时手动打开的优化开关&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;而开始变成：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Serving Runtime 自己的一部分执行策略。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&#34;cuda-graph-上面还有-compile--inductor&#34;&gt;CUDA Graph 上面还有 Compile / Inductor
&lt;/h3&gt;&lt;p&gt;再往上一层还有：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;torch.compile / Inductor&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;vLLM V1 并不是简单把整个模型丢给一个默认 &lt;code&gt;torch.compile(model)&lt;/code&gt; 就结束。&lt;/p&gt;
&lt;p&gt;它会围绕自身 Serving 执行方式处理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Graph capture / partition&lt;/li&gt;
&lt;li&gt;Compilation cache&lt;/li&gt;
&lt;li&gt;Shape specialization&lt;/li&gt;
&lt;li&gt;Piecewise compilation&lt;/li&gt;
&lt;li&gt;Inductor&lt;/li&gt;
&lt;li&gt;自定义优化 pass&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是整个执行链可以粗略理解成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Model
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Graph / Compile
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Inductor / Custom Pass
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Optimized Kernel
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CUDA Graph
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Runtime Replay
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;走到这一层以后，再把 vLLM 理解成“一个用了 PagedAttention 的 API Server”已经明显不够了。&lt;/p&gt;
&lt;p&gt;它真正做的是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;把模型执行、Kernel、Graph 和 Serving Runtime 连在一起。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;6-tpnvfp4kernelcuda-graph-应该放在一条链里看&#34;&gt;6. TP、NVFP4、Kernel、CUDA Graph 应该放在一条链里看
&lt;/h2&gt;&lt;p&gt;前面几篇是分开讲的：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 让权重更小
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;TP2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 两张 GPU 同时参与同一层
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Kernel
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 当前矩阵到底怎么执行
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CUDA Graph
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ 减少 Launch / CPU 调度
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但生产部署里它们其实是一条链。&lt;/p&gt;
&lt;p&gt;以这次双 5060 Ti 为例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Qwen3.8-27B NVFP4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;权重完整 GPU Resident
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;TP2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;两卡同时处理权重分片
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4 / Attention Kernel
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Compile
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CUDA Graph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;任何一层没有走到理想路径，最后的 token/s 都会受到影响。&lt;/p&gt;
&lt;p&gt;所以我现在不太喜欢只问：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NVFP4 能快多少？&lt;/li&gt;
&lt;li&gt;CUDA Graph 能快多少？&lt;/li&gt;
&lt;li&gt;TP 能快多少？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更值得看的问题是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;这几个优化组合以后，整条执行链有没有真正工作。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;7-vllm-的优势最后还会延伸到-serving-层&#34;&gt;7. vLLM 的优势最后还会延伸到 Serving 层
&lt;/h2&gt;&lt;p&gt;GPU 执行链做好以后，生产服务还有另一类问题：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;请求 A：正在 Decode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;请求 B：100K Prefill
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;请求 C：刚到达
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;请求 D：和上一轮共享大量 Prefix
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这时单纯让一个 GEMM 再快一点已经不够。&lt;/p&gt;
&lt;p&gt;还需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scheduler&lt;/li&gt;
&lt;li&gt;Continuous Batching&lt;/li&gt;
&lt;li&gt;Chunked Prefill&lt;/li&gt;
&lt;li&gt;Paged Cache / Block 管理&lt;/li&gt;
&lt;li&gt;Prefix Cache&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;来决定：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GPU 当前这一轮到底应该算谁，以及哪些东西根本不用重新算。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这也是 vLLM 让我更愿意拿来做长期 Serving 的另一半原因。&lt;/p&gt;
&lt;p&gt;但这部分我不会在这一篇展开。&lt;/p&gt;
&lt;p&gt;因为第六篇会专门讨论：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;100K Context 装得下以后，Prefix Cache、Chunked Prefill、Continuous Batching 和 MTP 到底分别解决什么问题。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里先记住一点就够了：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;vLLM 的优化不只发生在单颗 token 的 Kernel 内，也发生在请求之间。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;8-那-llamacpp-呢&#34;&gt;8. 那 llama.cpp 呢？
&lt;/h2&gt;&lt;p&gt;这并不是说 llama.cpp 没有 GPU Kernel、Batching 或 CUDA Graph 一类优化。&lt;/p&gt;
&lt;p&gt;它同样是一套非常成熟、而且极其重要的推理 Runtime。&lt;/p&gt;
&lt;p&gt;我认为二者真正的区别，不应该写成：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;llama.cpp 慢 / vLLM 快&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这种过度简单的判断。&lt;/p&gt;
&lt;p&gt;更准确的定位是：&lt;/p&gt;
&lt;h3 id=&#34;llamacpp-更擅长把可部署硬件范围做得非常宽&#34;&gt;llama.cpp 更擅长把“可部署硬件范围”做得非常宽
&lt;/h3&gt;&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GGUF&lt;/li&gt;
&lt;li&gt;大量量化格式&lt;/li&gt;
&lt;li&gt;CPU-only&lt;/li&gt;
&lt;li&gt;CPU + GPU&lt;/li&gt;
&lt;li&gt;RAM Offload&lt;/li&gt;
&lt;li&gt;异构 GPU&lt;/li&gt;
&lt;li&gt;不同显存容量&lt;/li&gt;
&lt;li&gt;本地桌面与个人设备&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;像 Flash-Next 这种模型，如果个人硬件根本不可能全 GPU Resident，那么 llama.cpp 的 CPU + GPU 路线反而可能是最现实的入口。&lt;/p&gt;
&lt;h3 id=&#34;vllm-更适合在模型可以-gpu-resident以后继续追求-serving-效率&#34;&gt;vLLM 更适合在“模型可以 GPU Resident”以后继续追求 Serving 效率
&lt;/h3&gt;&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TP / PP&lt;/li&gt;
&lt;li&gt;高性能量化 Kernel&lt;/li&gt;
&lt;li&gt;Compile&lt;/li&gt;
&lt;li&gt;CUDA Graph&lt;/li&gt;
&lt;li&gt;Continuous Batching&lt;/li&gt;
&lt;li&gt;Scheduler&lt;/li&gt;
&lt;li&gt;Prefix Cache&lt;/li&gt;
&lt;li&gt;高吞吐 API Serving&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以我更愿意用一句话概括两者：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;llama.cpp 把个人硬件能触碰到的模型上限往上推；vLLM 则在模型能够 GPU Resident 以后，把 NVIDIA GPU Serving 的性能上限继续往上推。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这两个价值并不冲突。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;9-为什么我的-27b-生产部署默认选-vllm&#34;&gt;9. 为什么我的 27B 生产部署默认选 vLLM？
&lt;/h2&gt;&lt;p&gt;回到这套实际硬件：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2 × RTX 5060 Ti 16GB + Qwen3.8-27B&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;我们已经找到一种方式，让模型能够：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;完整 GPU Resident
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;给 Cache 留空间
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这时候我就没有太强的理由主动把热点权重再搬回 CPU。&lt;/p&gt;
&lt;p&gt;我的关注点已经从：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;怎么把模型塞进去？&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;转向：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;怎么让两张 GPU 同时工作？
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;怎么让 NVFP4 走正确 Kernel？
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;怎么减少 Kernel Launch？
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;怎么提高 Serving 吞吐？
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;怎么避免重复 Prefill？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;而这些问题正好是 vLLM 的主场。&lt;/p&gt;
&lt;p&gt;所以对这类场景，我现在的默认选择是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;先用 vLLM，把完整 GPU Serving 路线跑通。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果模型大到根本做不到合理 GPU Resident，再回到 llama.cpp / GGUF / RAM Offload 的容量路线。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;10-我的生产推理优化顺序&#34;&gt;10. 我的生产推理优化顺序
&lt;/h2&gt;&lt;p&gt;现在让我重新部署一个 27B 服务，我大概会按这个顺序：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1. 选择模型与可接受的量化
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2. 尽量让权重完整 GPU Resident
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3. 确认量化格式真的有当前 GPU 的有效计算路径
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4. 选择合适的 TP / PP
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;5. 确认 GEMM / Attention Kernel
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;6. Compile / CUDA Graph
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;7. Context / Cache 规划
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;8. Scheduler / Continuous Batching
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;9. Prefix Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;10. 最后再评估 MTP-based Speculative Decoding
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中最重要的变化是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;我已经不把“模型成功启动”当成部署完成。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;真正想要的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模型质量合理&lt;/li&gt;
&lt;li&gt;权重尽量 GPU Resident&lt;/li&gt;
&lt;li&gt;低精度硬件能力被正确利用&lt;/li&gt;
&lt;li&gt;Kernel 走在合适路径&lt;/li&gt;
&lt;li&gt;GPU 尽量少空转&lt;/li&gt;
&lt;li&gt;重复计算尽量少做&lt;/li&gt;
&lt;li&gt;多卡和多请求都能有效调度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这时候 NVFP4 就不只是“省了几 GB 显存”。&lt;/p&gt;
&lt;p&gt;vLLM 也不只是“KV Cache 管得比较好”。&lt;/p&gt;
&lt;p&gt;它们最终都属于同一件事：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;把有限的 GPU 资源尽可能转化成真正可用的 Token。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;接下来就进入剩余显存里最大的一块变量之一：长上下文 Cache。&lt;/p&gt;
&lt;p&gt;下一篇：&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://jiangwan.ink/p/qwen38-27b-200k-context-kv-cache/&#34; &gt;《200K Context 到底需要多少显存？从 KV Cache 算到 Qwen3.8 的真实部署》&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;系列导航：&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://jiangwan.ink/p/rtx-5060-ti-tp2-pcie-p2p/&#34; &gt;← 上一篇：两张 RTX 5060 Ti 为什么没有两倍推理速度？显存带宽、PCIe 与 P2P&lt;/a&gt; · &lt;a class=&#34;link&#34; href=&#34;https://jiangwan.ink/p/qwen38-27b-200k-context-kv-cache/&#34; &gt;下一篇：200K Context 到底需要多少显存？从 KV Cache 算到 Qwen3.8 的真实部署 →&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>2× RTX 5060 Ti 16GB 能跑 27B 大模型吗？先把显存算清楚</title>
        <link>https://jiangwan.ink/p/dual-rtx-5060-ti-27b-vram/</link>
        <pubDate>Sun, 23 Aug 2026 10:00:00 +0800</pubDate>
        
        <guid>https://jiangwan.ink/p/dual-rtx-5060-ti-27b-vram/</guid>
        <description>&lt;blockquote&gt;
&lt;p&gt;📚 &lt;strong&gt;双 RTX 5060 Ti 部署 Qwen3.8 系列 · 1/6&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;导读&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;从两张 RTX 5060 Ti 16GB 能不能跑好 27B 模型这个问题开始，先把 BF16、FP8、NVFP4 的权重和运行显存拆开算清楚。真正决定能不能长期使用的，不只是模型文件能否塞进 32GB，而是权重之外还能给 Cache、Runtime 和长上下文留下多少空间。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Qwen3.8-27B 在 2026 年 8 月 14 日开放权重。写这篇的时候，它出来已经一个多星期。&lt;/p&gt;
&lt;p&gt;这一周我基本把空闲的 GPU 时间都花在了它身上。&lt;/p&gt;
&lt;p&gt;最开始的问题其实很简单：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;两张 RTX 5060 Ti 16GB，到底能不能把一个 27B 模型跑好？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一开始我以为这只是一个显存问题：32GB 总显存，算一下权重，挑一个合适的量化，然后把服务启动起来，大概就结束了。&lt;/p&gt;
&lt;p&gt;真正开始部署以后，问题却一层一层冒了出来：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;27B 到底应该选 BF16、FP8、NVFP4，还是普通 4bit？&lt;/li&gt;
&lt;li&gt;2×16GB 为什么不能简单当成一张 32GB？&lt;/li&gt;
&lt;li&gt;模型分到两张卡以后，TP、PP、Layer Split 到底谁真的会让 Decode 变快？&lt;/li&gt;
&lt;li&gt;没有 NVLink，甚至实际机器没有 CUDA P2P，TP 为什么还能有不错的 Scaling？&lt;/li&gt;
&lt;li&gt;同样写着 NVFP4，“能加载”和“真正跑到适合 Blackwell 的低精度 Kernel”是不是一回事？&lt;/li&gt;
&lt;li&gt;100K、200K Context 到底需要多少显存？&lt;/li&gt;
&lt;li&gt;模型终于跑起来以后，Prefix Cache、Continuous Batching、CUDA Graph、MTP 又分别在优化什么？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是原本一个“能不能跑”的问题，最后变成了这组六篇文章。&lt;/p&gt;
&lt;p&gt;整个系列基本按照我实际部署时遇到问题的顺序展开：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;显存与量化 → 多卡并行 → PCIe 与通信 → vLLM 执行栈 → 长上下文显存 → 长上下文 Serving 优化。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;硬件则一直尽量保持在个人开发者真正可能接触到的范围：消费级 RTX 5060 Ti、PCIe 多卡、没有 NVLink。&lt;/p&gt;
&lt;p&gt;所以这组文章并不是讨论“如果我有 8 张 H100 应该怎么部署”，而是想回答另一个更现实的问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;在有限的消费级 GPU 上，怎么让一个足够强的模型不只是成功启动，而是真正达到可以长期使用的状态？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第一步还是最朴素的：先把显存算清楚。&lt;/p&gt;
&lt;p&gt;双 RTX 5060 Ti 16GB，一共 32GB 显存。27B 模型到底能不能跑？&lt;/p&gt;
&lt;p&gt;结论先说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;可以，但基本要进入高质量 4bit / NVFP4 这一档。BF16 明显不够，FP8 对双 16GB 来说通常也太挤。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;真正需要计算的不是“模型文件有没有小于 32GB”，而是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;显存预算
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;=
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;模型权重
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ CUDA / Runtime
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Activation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ 框架额外开销
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;而且还有一个贯穿整个系列的前提：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2×16GB 也不等于一张 32GB GPU。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;1-27b-模型到底需要多少显存&#34;&gt;1. 27B 模型到底需要多少显存？
&lt;/h2&gt;&lt;p&gt;27B 表示大约 270 亿参数。&lt;/p&gt;
&lt;p&gt;最简单的权重估算公式是：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;权重大小 ≈ 参数量 × 每参数字节数&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;于是：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;权重精度&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;27B 理论权重大小&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;BF16 / FP16&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;≈54GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;FP8 / INT8&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;≈27GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;FP4 / INT4&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;≈13.5GB&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;从理论值已经能看到大致边界：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2 × RTX 5060 Ti 16GB = 32GB 总显存&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;BF16 基本不用考虑。&lt;/p&gt;
&lt;p&gt;FP8 看起来接近能放下。&lt;/p&gt;
&lt;p&gt;4bit 则开始进入比较合理的范围。&lt;/p&gt;
&lt;p&gt;但这里的 13.5GB 只是“27B × 4bit”的理想数学值，不等于实际模型文件大小。&lt;/p&gt;
&lt;p&gt;实际量化模型还可能包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scale&lt;/li&gt;
&lt;li&gt;部分高精度 Tensor&lt;/li&gt;
&lt;li&gt;Embedding&lt;/li&gt;
&lt;li&gt;Norm&lt;/li&gt;
&lt;li&gt;Output Head&lt;/li&gt;
&lt;li&gt;量化元数据&lt;/li&gt;
&lt;li&gt;其他未按同一 bit 数保存的权重&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以“4bit”不能直接理解成“模型一定只有 13.5GB”。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;2-用实际-qwen38-27b-看更直观&#34;&gt;2. 用实际 Qwen3.8-27B 看更直观
&lt;/h2&gt;&lt;p&gt;以这次部署的 Qwen3.8-27B 为例，不同版本大致是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BF16      ≈ 55GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FP8       ≈ 31GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NVFP4     ≈ 23GB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;放到双 5060 Ti 16GB 上就很直观了。&lt;/p&gt;
&lt;h3 id=&#34;bf16&#34;&gt;BF16
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;权重 ≈ 55GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;总显存 = 32GB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;明显放不下。&lt;/p&gt;
&lt;p&gt;当然，可以通过 CPU / RAM Offload 把一部分权重留在系统内存，但那已经是另一种性能模型，不能再算正常的“双 GPU 全显存部署”。&lt;/p&gt;
&lt;h3 id=&#34;fp8&#34;&gt;FP8
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;权重 ≈ 31GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;总显存 = 32GB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;数字上看似乎只差一点。&lt;/p&gt;
&lt;p&gt;但对于推理服务，这种“刚好塞进去”基本没有意义。&lt;/p&gt;
&lt;p&gt;因为权重之外还要给下面这些东西留显存：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CUDA Context
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Runtime
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Activation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CUDA Graph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也就是说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“权重能塞进去”和“模型能正常提供服务”是两回事。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果还希望跑几十 K、100K 甚至更长 Context，FP8 在双 16GB 上就更难留出足够的运行空间。&lt;/p&gt;
&lt;h3 id=&#34;nvfp4&#34;&gt;NVFP4
&lt;/h3&gt;&lt;p&gt;NVFP4 权重进入约 23GB 以后，情况明显不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;总显存 ≈ 32GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;权重   ≈ 23GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;名义剩余 ≈ 9GB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然，这 9GB 也不能全部给 Cache。&lt;/p&gt;
&lt;p&gt;Runtime、Workspace、CUDA Graph 等仍然会吃掉一部分。&lt;/p&gt;
&lt;p&gt;但至少从这里开始，才真正有空间继续规划 Context 和 Serving。&lt;/p&gt;
&lt;p&gt;所以对于：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2 × RTX 5060 Ti 16GB + 27B 模型&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果只谈&lt;strong&gt;这套硬件上的部署适配度&lt;/strong&gt;，我的顺序会很明确：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;高质量 NVFP4 / 4bit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;FP8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;BF16
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这不是在说 FP4 的模型质量天然高于 FP8，而是双 16GB 的容量约束决定了 FP8 很难给实际推理留下足够空间。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-模型权重不是唯一的显存开销&#34;&gt;3. 模型权重不是唯一的显存开销
&lt;/h2&gt;&lt;p&gt;部署 LLM 时，一个非常常见的误区是：&lt;/p&gt;
&lt;p&gt;模型文件约 &lt;strong&gt;23GB&lt;/strong&gt;、总显存 &lt;strong&gt;32GB&lt;/strong&gt;，表面上看似乎“还剩 9GB”。&lt;/p&gt;
&lt;p&gt;实际不能这么算。&lt;/p&gt;
&lt;p&gt;更合理的模型是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;VRAM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;=
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Weights
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Runtime
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Activation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ CUDA Graph
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Framework Buffer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中很多项还会随着配置变化。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Context Length&lt;/li&gt;
&lt;li&gt;Batch Size&lt;/li&gt;
&lt;li&gt;并发数量&lt;/li&gt;
&lt;li&gt;CUDA Graph&lt;/li&gt;
&lt;li&gt;Attention Backend&lt;/li&gt;
&lt;li&gt;KV / Cache dtype&lt;/li&gt;
&lt;li&gt;推理框架&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;都会改变最终显存占用。&lt;/p&gt;
&lt;p&gt;所以部署之前，我现在更习惯把问题拆成两步。&lt;/p&gt;
&lt;p&gt;第一步：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;模型权重能不能装下？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第二步：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;装完权重以后，还剩多少显存能够真正用于推理？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第二步往往比第一步更重要。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;4-为什么-216gb-不等于-132gb&#34;&gt;4. 为什么 2×16GB 不等于 1×32GB？
&lt;/h2&gt;&lt;p&gt;假设模型权重是 24GB。&lt;/p&gt;
&lt;p&gt;如果是一张 32GB GPU：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GPU0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── 24GB 权重
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── Runtime
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;总上限：32GB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所有显存都在同一个 GPU 的地址空间和资源预算里。&lt;/p&gt;
&lt;p&gt;双 16GB 则不同：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GPU0                  GPU1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── 一部分权重         ├── 一部分权重
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── Runtime            ├── Runtime
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── Cache              ├── Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── Workspace          └── Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;上限 16GB              上限 16GB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果出现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GPU0：16.1GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPU1：13GB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;即使 GPU1 还剩 3GB，也不能简单理解成 GPU0 可以把这 3GB 当成本地显存继续使用。&lt;/p&gt;
&lt;p&gt;所以多卡部署不仅要看：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;总显存够不够&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;还要看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每张卡分别放了什么？&lt;/li&gt;
&lt;li&gt;每张卡分别占多少？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这也是为什么“模型怎么切”会直接影响能不能启动以及最终能开多大 Context。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;5-模型分到两张卡只是下一层问题的开始&#34;&gt;5. 模型分到两张卡，只是下一层问题的开始
&lt;/h2&gt;&lt;p&gt;模型单卡放不下以后，常见思路大致可以先分成两类。&lt;/p&gt;
&lt;p&gt;一种是按层拆：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GPU0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Layer 0 ~ 31
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GPU1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Layer 32 ~ 63
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;另一种是让两张 GPU 同时参与同一层：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          Layer N
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     GPU0       GPU1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      1/2        1/2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        \        /
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         聚合结果
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;前者首先解决容量问题；后者除了容量，还可能真正聚合多张卡的计算和显存带宽。&lt;/p&gt;
&lt;p&gt;所以：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;模型能不能分到两张卡，和两张卡能不能让单请求跑得更快，不是同一个问题。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;具体的 Layer Split、PP、TP、DP，下一篇单独拆开讲。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;6-双卡-448gbs-能不能直接变成-896gbs&#34;&gt;6. 双卡 448GB/s 能不能直接变成 896GB/s？
&lt;/h2&gt;&lt;p&gt;RTX 5060 Ti 16GB 单卡显存带宽约为：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;448 GB/s&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;两张卡的物理显存带宽总和当然是：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;448 × 2 = 896 GB/s&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;但推理时能不能真正把它变成接近 2× 的单 token 性能，取决于并行方式。&lt;/p&gt;
&lt;p&gt;按层串行执行时，两张卡并不会一直同时为同一颗 token 读取权重。&lt;/p&gt;
&lt;p&gt;Tensor Parallel 则更有机会让两张卡在同一层同时工作，但又会引入跨卡通信和同步。&lt;/p&gt;
&lt;p&gt;所以这里不能简单写成：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2 张 GPU = 2× token/s&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;第三篇会直接用 TP2 的实测数据、PCIe、P2P 和 AllReduce 把这笔账算清楚。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;7-长上下文会继续吃掉剩余显存&#34;&gt;7. 长上下文会继续吃掉剩余显存
&lt;/h2&gt;&lt;p&gt;如果只是跑 4K、8K 对话，权重通常是最大的显存项目之一。&lt;/p&gt;
&lt;p&gt;但我的实际目标还包括长代码 Context，所以还会继续关注：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;32K
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;64K
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;100K
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;128K
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;200K
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这时剩余显存会继续被 Cache 消耗。&lt;/p&gt;
&lt;p&gt;经典 Transformer 经常用 KV Cache 公式估算：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;KV Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;≈
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Token 数
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× Layer 数
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× KV Head
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× Head Dimension
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× K/V
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× dtype
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但现代模型不能一律直接套这个公式。&lt;/p&gt;
&lt;p&gt;Qwen3.8-27B 是混合 Attention 架构，并不是 64 层全部使用传统 Full Attention。&lt;/p&gt;
&lt;p&gt;因此：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;200K Context 到底需要多少显存，必须结合模型结构计算。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这部分放到第五篇专门算。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;8-双-5060-ti-跑-27b我目前会怎么选&#34;&gt;8. 双 5060 Ti 跑 27B，我目前会怎么选？
&lt;/h2&gt;&lt;p&gt;如果硬件固定为：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2 × RTX 5060 Ti 16GB&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;目标是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;27B
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;长 Context
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;代码 / Agent
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我的选择会是：&lt;/p&gt;
&lt;h3 id=&#34;bf16-1&#34;&gt;BF16
&lt;/h3&gt;&lt;p&gt;不考虑。容量明显不足。&lt;/p&gt;
&lt;h3 id=&#34;fp8-1&#34;&gt;FP8
&lt;/h3&gt;&lt;p&gt;权重本身已经接近吃满 32GB，总体精度很好，但在双 16GB 上很难留下足够的 Runtime 和 Cache 空间。&lt;/p&gt;
&lt;h3 id=&#34;高质量-nvfp4--4bit&#34;&gt;高质量 NVFP4 / 4bit
&lt;/h3&gt;&lt;p&gt;优先考虑。&lt;/p&gt;
&lt;p&gt;权重压到 20 多 GB 后，双 16GB 才真正有空间继续规划：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cache&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;并发&lt;/li&gt;
&lt;li&gt;Runtime&lt;/li&gt;
&lt;li&gt;CUDA Graph&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以对消费级双 16GB GPU 来说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;量化的意义不只是让模型“装得下”，更重要的是给实际推理留下显存。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;9-结论&#34;&gt;9. 结论
&lt;/h2&gt;&lt;p&gt;双 RTX 5060 Ti 16GB 可以部署 27B 级模型，但不能只用：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;16GB × 2 = 32GB&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;来判断。&lt;/p&gt;
&lt;p&gt;真正需要看的，是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;模型权重
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Runtime
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;其他运行开销
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;对于 Qwen3.8-27B 这类 27B 模型，在双 16GB 上大致可以形成这样的判断：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;BF16：容量明显不足
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;FP8：权重已经接近吃满总显存
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NVFP4 / 高质量 4bit：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;开始进入比较合理的部署区间
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同时记住两个结论：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2×16GB 不等于 1×32GB。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;容量扩展不等于性能扩展。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;模型能分到两张卡，只解决了“装不装得下”。&lt;/p&gt;
&lt;p&gt;至于两张卡到底怎么分、谁负责容量、谁负责单请求加速、谁负责并发吞吐，就进入下一篇：&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://jiangwan.ink/p/multi-gpu-llm-tp-pp-dp-layer-split/&#34; &gt;《双卡部署大模型：TP、PP、DP 和 Layer Split 到底有什么区别？》&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;系列导航：&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://jiangwan.ink/p/multi-gpu-llm-tp-pp-dp-layer-split/&#34; &gt;下一篇：双卡部署大模型：TP、PP、DP 和 Layer Split 到底有什么区别？ →&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
