<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Llama.cpp on Jiangwan&#39;s Blog</title>
        <link>https://jiangwan.ink/tags/llama.cpp/</link>
        <description>Recent content in Llama.cpp 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/llama.cpp/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>
        
    </channel>
</rss>
