大模型推理成本优化实战:vLLM 与 KV Cache 调优指南

简介: 大模型落地后,真正制约成本的常非模型本身,而是每生成1个Token的开销。长上下文与高并发下,KV Cache迅速吞噬显存,成为性能瓶颈。vLLM通过PagedAttention、Continuous Batching、Prefix Caching等系统性优化,显著提升GPU利用率与吞吐,降低单位Token成本。

大模型真正进入生产环境以后,最容易被低估的问题往往不是“模型能不能跑起来”,而是“每生成一个 Token 到底要花多少钱”。

在实验环境中,单次请求跑得快、显存占得满,并不意味着线上服务具有良好的经济性。生产环境面对的是持续到来的并发请求、长度差异巨大的 Prompt、不断增长的 KV Cache,以及 TTFT(Time To First Token)、TPOT(Time Per Output Token)、吞吐量和显存利用率之间复杂的权衡。

尤其对于长上下文和高并发场景,模型权重本身反而不一定是第一瓶颈。随着请求数量和上下文长度增长,KV Cache 会迅速占据大量 GPU 显存,并进一步限制 batch size、并发数和整体吞吐。

因此,大模型推理成本优化不能简单理解为“把模型从 FP16 换成 INT4”。

真正有效的优化通常来自一个完整的推理栈:

模型量化 + PagedAttention + KV Cache 管理 + Continuous Batching + Prefix Caching + Kernel 优化 + 并发调度 + 硬件利用率优化

vLLM 正是围绕这一类问题设计的高性能 LLM 推理框架。当前官方文档已经将 PagedAttention、Continuous Batching、Chunked Prefill、Prefix Caching、量化、FlashAttention/FlashInfer、CUDA Graph、Speculative Decoding 等能力集成到统一推理框架中。(vLLM)

本文从 Transformer 推理原理出发,重点分析 KV Cache 为什么会成为成本瓶颈,以及如何使用 vLLM 对推理服务进行系统性优化。


一、先理解一个事实:LLM 推理为什么昂贵

Transformer 的自回归生成过程可以简单理解为:

输入 Prompt
    │
    ▼
Tokenizer
    │
    ▼
Prefill
    │
    ├── 计算整个 Prompt
    ├── 生成 K/V
    └── 保存到 KV Cache
    │
    ▼
Decode
    │
    ├── 读取历史 KV
    ├── 计算下一个 Token
    ├── 生成新的 K/V
    └── 写入 KV Cache
    │
    ▼
下一个 Token

其中可以把推理过程分成两个阶段:

1. Prefill

Prefill 负责处理用户提交的 Prompt。

例如:

System Prompt       200 tokens
User Context        5000 tokens
Question             200 tokens
--------------------------------
Total               5400 tokens

模型需要一次性处理这 5400 个 Token。

Prefill 通常具有较高的计算并行度,因此更容易表现为计算密集型任务。

2. Decode

生成阶段则完全不同。

假设模型需要生成 500 Token:

Token 1
   ↓
Token 2
   ↓
Token 3
   ↓
...
Token 500

每一步生成下一个 Token 都依赖之前已经生成的内容。

因此 Decode 是典型的自回归过程。

如果每次都重新计算完整上下文,计算量会非常巨大。

KV Cache 的核心价值就在这里:

已经计算过的 Key 和 Value 不需要每个 Decode Step 重新计算。

这也是为什么 KV Cache 是现代 LLM 推理系统的核心资源之一。


二、KV Cache 到底缓存了什么

Transformer Attention 的核心计算可以简化为:

Attention(Q, K, V)
=
softmax(QKᵀ / √d)V

其中:

  • Q:Query
  • K:Key
  • V:Value

在自回归生成过程中,新 Token 会产生新的 Q、K、V。

但是历史 Token 的 K、V 已经计算过。

例如:

Token 1 → K1 V1
Token 2 → K2 V2
Token 3 → K3 V3
Token 4 → K4 V4

生成 Token 5 时:

Q5
 │
 ├── K1
 ├── K2
 ├── K3
 └── K4

V1
V2
V3
V4

因此系统可以直接读取:

[K1,K2,K3,K4]
[V1,V2,V3,V4]

而不需要重新计算历史 Token。

这就是 KV Cache。


2.1 KV Cache 为什么特别吃显存

假设一个模型具有:

Layers = 32
KV Heads = 8
Head Dimension = 128
Datatype = FP16

那么每个 Token 的 KV Cache 大小近似为:

KV bytes/token
=
Layers
× KV Heads
× Head Dimension
× 2(K,V)
× bytes_per_element

代入:

32 × 8 × 128 × 2 × 2
=
131072 bytes

也就是:

128 KB / token

如果一个请求上下文达到 8192 Token:

8192 × 128 KB
≈ 1 GB

注意,这只是一个请求的数量级估算。

如果同时存在:

16 requests

理论上就可能需要接近:

16 GB

的 KV Cache。

所以在长上下文、高并发服务中,真正限制并发能力的往往不是模型权重,而是 KV Cache。


三、为什么传统 KV Cache 管理效率并不高

最早的推理实现通常会为每个请求分配连续显存:

Request A
┌───────────────────────────────┐
│ K/V Token 0 ... Token 4095    │
└───────────────────────────────┘

Request B
┌───────────────────────────────┐
│ K/V Token 0 ... Token 2047    │
└───────────────────────────────┘

问题在于请求长度并不固定。

例如:

Request A = 4096 tokens
Request B = 900 tokens
Request C = 12000 tokens
Request D = 2300 tokens

如果系统按照最大长度预分配,就会产生大量浪费。

如果动态扩容,又容易产生显存碎片。

这和传统操作系统内存分配非常类似:

连续内存
    ↓
动态增长
    ↓
碎片
    ↓
分配困难

这正是 vLLM PagedAttention 要解决的问题。


四、PagedAttention:把 KV Cache 像虚拟内存一样管理

vLLM 的 PagedAttention 借鉴了操作系统虚拟内存和分页机制。

它不再要求一个请求的 KV Cache 必须连续存储,而是把 KV Cache 切成多个固定大小的 Block。

逻辑上:

Request A

Logical KV Cache

[Block 0][Block 1][Block 2][Block 3]

实际 GPU 显存可能是:

Physical GPU Memory

[Block 7]
[Block 2]
[Block 19]
[Block 4]

然后通过 Block Table 建立映射:

Logical Block     Physical Block

Block 0     ───→   Block 7
Block 1     ───→   Block 2
Block 2     ───→   Block 19
Block 3     ───→   Block 4

于是:

逻辑连续
    ↓
物理离散

这就是 PagedAttention 最核心的思想。


4.1 PagedAttention 带来的收益

首先是显存碎片显著降低。

传统模式:

连续分配
AAAAAAAAAAAA
BBBBBB
CCCCCCCC
AAAAAA

容易出现:

Free
Used
Free
Used
Free

而分页方式:

Block Pool

[Free]
[Used]
[Used]
[Free]
[Used]
[Used]
[Free]

请求需要多少 Block 就分配多少。

当请求结束:

Request A
    ↓
释放 Block
    ↓
Block Pool
    ↓
其他 Request 复用

因此 GPU 显存可以更加充分地服务于真实 Token。

PagedAttention 正是 vLLM 的核心内存管理机制之一。(vLLM)


五、Continuous Batching:不要等待整个 Batch 结束

传统静态 Batch 的逻辑通常是:

Batch
 ├── Request A
 ├── Request B
 ├── Request C
 └── Request D

全部完成
    ↓
Batch 结束
    ↓
下一批

最大的问题是:

Request A → 100 tokens
Request B → 2000 tokens
Request C → 300 tokens
Request D → 5000 tokens

如果按照最长请求同步执行:

A ──────────┐
B ─────────────────────
C ───────────
D ────────────────────────────────

短请求会被迫等待。

GPU 的计算资源也会因此出现大量浪费。


5.1 Continuous Batching 的思想

Continuous Batching 则把请求生命周期拆开:

Time →

A  █████████
B  █████████████████
C  ██████
D        █████████████
E             ███████

某个请求完成后:

Request A
    ↓
立即退出 Batch
    ↓
Request E
    ↓
立即进入

因此 GPU 在每一个 iteration 中都可以尽可能装载更多可执行请求。

vLLM 官方当前版本将 Continuous Batching、Chunked Prefill、Prefix Caching 等作为核心服务能力。(vLLM)


六、vLLM 的完整推理架构

生产环境中的 vLLM 可以理解为:

                   Client
                      │
                      ▼
              ┌───────────────┐
              │ API Gateway   │
              └───────┬───────┘
                      │
                      ▼
              ┌───────────────┐
              │ vLLM Server   │
              └───────┬───────┘
                      │
          ┌───────────┴───────────┐
          ▼                       ▼
   Request Scheduler        KV Cache Manager
          │                       │
          ▼                       ▼
 Continuous Batching        Paged KV Blocks
          │                       │
          └───────────┬───────────┘
                      ▼
                Attention Kernel
                      │
          ┌───────────┴───────────┐
          ▼                       ▼
      FlashAttention          GEMM Kernel
          │                       │
          └───────────┬───────────┘
                      ▼
                     GPU

如果把整个优化过程抽象成一条链:

请求调度
   ↓
Batching
   ↓
KV Cache 分配
   ↓
Attention Kernel
   ↓
GEMM
   ↓
GPU

其中任何一个环节成为瓶颈,整体吞吐都会下降。


七、第一步优化:不要盲目追求最大 Batch

这是生产环境非常容易犯的错误。

很多人看到 GPU 显存还有空间,就认为:

Batch 越大越好。

实际上并不是。

Batch 增大通常意味着:

吞吐 ↑
显存占用 ↑
排队延迟 ↑
TTFT 可能 ↑
调度复杂度 ↑

尤其是长 Prompt 场景。

例如:

Batch = 8
Average Input = 2K

和:

Batch = 8
Average Input = 32K

虽然 Batch 一样,但第二种情况的 KV Cache 压力完全不是一个数量级。

因此真正应该关注的是:

tokens / batch

而不是简单的:

requests / batch

八、max-num-batched-tokens 是关键参数

vLLM 的生产调优不应该只盯着:

max_num_seqs

更重要的是控制每个 iteration 中处理的 Token 数量。

典型启动方式:

vllm serve Qwen/Qwen3-8B \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 128 \
  --max-num-batched-tokens 16384

这里的思路是:

max-num-seqs
    ↓
限制并发请求数量

max-num-batched-tokens
    ↓
限制单次调度 Token 工作量

两者应该联合调节。


九、GPU Memory Utilization 不是越高越好

vLLM 可以利用 GPU 显存的一定比例作为推理资源。

例如:

--gpu-memory-utilization 0.90

很多生产环境喜欢直接:

0.95
0.98

但这样做风险较高。

GPU 显存并不只有模型权重:

GPU Memory
├── Model Weights
├── KV Cache
├── CUDA Runtime
├── Temporary Buffers
├── Activation
├── Kernel Workspace
└── Other Runtime Memory

如果把显存压得过满,可能出现:

OOM

甚至:

偶发 OOM

这种问题比启动时直接 OOM 更难排查。

更合理的方法是:

0.85
 ↓
0.90
 ↓
0.92

逐级压测。


十、KV Cache 优化的核心公式

对于标准 MHA,可以近似表示 KV Cache:

KV Cache Memory
≈
2 × Layers × KV Heads × Head Dim
× Sequence Length
× Batch Size
× Bytes

这里最值得关注的是:

KV Heads

现代模型大量使用 GQA(Grouped Query Attention)或者 MQA(Multi-Query Attention)。

例如:

Query Heads = 32
KV Heads    = 8

那么 KV Cache 的 Head 数量不是 32,而是 8。

理论上,相比:

32 KV Heads

可以把 KV Cache 的这一部分降低到:

8 / 32 = 25%

这也是 GQA 对推理系统非常重要的原因。

TensorRT-LLM 的 KV Cache 文档同样明确利用 MHA、MQA 和 GQA 的不同 KV Head 结构来优化 KV Cache 内存。(NVIDIA GitHub)


十一、Prefix Caching:重复 Prompt 不要重复计算

很多企业应用存在高度重复的 Prompt。

例如:

System Prompt
+
企业知识库规则
+
工具定义
+
Agent Instructions
+
用户问题

其中前面几千 Token 可能完全相同。

如果每次请求都重新 Prefill:

Request 1
System Prompt → Compute

Request 2
System Prompt → Compute

Request 3
System Prompt → Compute

Request 4
System Prompt → Compute

这是明显的浪费。

Prefix Caching 的思想就是:

第一次请求

Prefix
  ↓
Compute
  ↓
KV Cache
  ↓
保存


后续请求

Prefix
  ↓
匹配
  ↓
直接复用 KV
  ↓
只计算新增内容

因此:

TTFT ↓
GPU Compute ↓
成本 ↓

对于以下场景尤其有效:

  • Chatbot
  • Agent
  • RAG
  • 企业知识库
  • 固定 System Prompt
  • 大量工具定义
  • 多轮对话

十二、Chunked Prefill:解决长 Prompt 阻塞 Decode

一个非常典型的问题:

当前有 100 个 Decode 请求

突然来了:

一个 100K Token Prompt

如果直接进行完整 Prefill:

100K Token Prefill
       ↓
GPU 被长时间占用
       ↓
Decode 请求等待
       ↓
用户感知延迟暴涨

Chunked Prefill 可以把长 Prompt 拆成多个 Chunk:

100K Prompt

[Chunk 1]
[Chunk 2]
[Chunk 3]
[Chunk 4]
...

然后让 Prefill 和 Decode 更合理地共享 GPU 计算资源。

例如:

Iteration 1
Decode + Prefill Chunk

Iteration 2
Decode + Prefill Chunk

Iteration 3
Decode + Prefill Chunk

这实际上是在解决:

吞吐与交互延迟之间的调度问题。

所以生产系统不能只看 tokens/s,还必须同时观察:

TTFT
ITL / TPOT
P99 Latency
Queue Time
Throughput

十三、量化:降低模型权重成本

如果模型采用 BF16:

2 bytes / parameter

那么一个 70B 模型,仅权重理论存储量大约:

70B × 2
≈ 140 GB

还没有计算:

KV Cache
Runtime Memory
Temporary Buffer

如果使用 INT4:

70B × 0.5
≈ 35 GB

这意味着同样的 GPU 集群可能运行更大的模型,或者运行更多副本。

常见量化方案包括:

FP8
INT8
INT4
GPTQ
AWQ

当前 vLLM 官方文档已经支持包括 FP8、MXFP8/MXFP4、NVFP4、INT8、INT4、GPTQ、AWQ、GGUF 等多种量化方式。(vLLM)


十四、为什么不能简单认为 INT4 一定比 FP8 快

这是推理优化中非常重要的一点。

量化影响的不只是显存。

还涉及:

Memory Bandwidth
Compute Throughput
Kernel Efficiency
Dequantization
Tensor Core Utilization
Accuracy

例如:

FP8

在现代 NVIDIA GPU 上往往具有非常成熟的硬件支持。

而某些 INT4 格式虽然理论上更省显存:

4 bit

但是如果对应 Kernel 不够高效:

Memory ↓
但
Kernel efficiency ↓

最终吞吐不一定更好。

所以量化选择应该通过 Benchmark 决定,而不是根据 Bit 数字大小决定。


十五、KV Cache 本身也可以量化

这是很多部署团队容易忽略的一层。

传统情况下:

Model Weight → Quantized
KV Cache     → FP16 / BF16

实际上 KV Cache 也可以进行低精度存储。

例如:

FP16 KV Cache
↓
FP8 KV Cache

理论上:

2 bytes
↓
1 byte

KV Cache 存储量约减少一半。

对于长上下文、高并发场景,这个收益非常直接。

NVIDIA TensorRT-LLM 当前文档明确支持 FP8 KV Cache,并给出了量化 KV Cache 后吞吐提升的 benchmark 示例;但官方也特别指出,KV Cache 量化需要关注输出质量退化风险。(NVIDIA GitHub)

因此:

权重量化解决“模型装不下”的问题,KV Cache 量化解决“并发撑不住”的问题。

两者不是一回事。


十六、vLLM 中如何做 KV Cache 调优

实际部署时,可以先从一个相对保守的配置开始:

vllm serve Qwen/Qwen3-8B \
  --host 0.0.0.0 \
  --port 8000 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 64 \
  --max-num-batched-tokens 8192

然后根据压测结果调整。

典型调优路径:

Step 1
固定模型
    ↓
Step 2
固定 Prompt
    ↓
Step 3
固定输出长度
    ↓
Step 4
测试并发
    ↓
Step 5
观察 TTFT / TPOT
    ↓
Step 6
调整 max-num-seqs
    ↓
Step 7
调整 max-num-batched-tokens
    ↓
Step 8
调整 GPU Memory
    ↓
Step 9
启用 Prefix Cache
    ↓
Step 10
测试量化

不要一次修改十个参数。

否则最后根本无法判断:

到底是哪一个参数带来了提升?

十七、生产环境推荐的服务架构

如果是企业级 RAG / Agent 服务,不建议直接把 vLLM 暴露给公网。

更合理的架构是:

                    Internet
                       │
                       ▼
               ┌───────────────┐
               │ API Gateway   │
               └───────┬───────┘
                       │
            ┌──────────┴──────────┐
            ▼                     ▼
      Rate Limiter          Auth / Billing
            │                     │
            └──────────┬──────────┘
                       ▼
                ┌─────────────┐
                │ LoadBalance │
                └──────┬──────┘
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
       vLLM-1        vLLM-2       vLLM-3
          │            │            │
          ▼            ▼            ▼
        GPU          GPU          GPU

进一步可以把:

Prefill
Decode

进行资源隔离。

高级架构可以设计为:

                API Gateway
                     │
                     ▼
              Request Router
                     │
          ┌──────────┴──────────┐
          ▼                     ▼
    Prefill Cluster        Decode Cluster
          │                     │
       GPU Pool              GPU Pool

vLLM 当前也已经提供 Prefill、Decode、Encode 等阶段解耦相关能力,为这类架构提供了基础。(vLLM)


十八、RAG 场景下,真正应该优化的是 Token

RAG 系统经常存在一个误区:

检索更多文档,回答一定更准确。

实际上:

TopK = 20

并不一定比:

TopK = 5

更好。

假设:

每个 Chunk = 700 tokens

TopK = 20

700 × 20
=
14000 tokens

再加:

System Prompt
Conversation History
Question
Instructions

很容易达到:

16K ~ 20K tokens

如果每天:

100万请求

那么输入 Token 成本会非常可观。

因此 RAG 优化应该首先从:

Retrieval
 ↓
Rerank
 ↓
Compression
 ↓
Context

开始。

例如:

召回 20
   ↓
Rerank
   ↓
保留 6
   ↓
Context Compression
   ↓
最终 3K tokens

这往往比单纯优化 GPU 更便宜。


十九、Agent 场景更加依赖 Prefix Cache

Agent 的 Prompt 通常具有高度重复结构:

System Prompt
+
Tools
+
Rules
+
Memory
+
Previous Messages
+
Current Task

其中:

System Prompt
Tools
Rules

通常长期稳定。

可以将 Prompt 设计成:

[Stable Prefix]
System
Tools
Rules
Policies

[Dynamic Suffix]
Memory
User Input
Current State

这样 Prefix Cache 才更容易命中。

这是一个很重要的工程原则:

缓存优化不仅是推理框架问题,也是 Prompt Architecture 问题。

如果每一次请求都改变 Prompt 的前半部分,那么 Prefix Cache 的收益自然有限。


二十、不要忽略输出 Token

很多团队优化时只盯着输入。

实际上:

总 Token
=
Input Tokens
+
Output Tokens

如果一个 Agent:

Input = 5K
Output = 5K

那么输出长度已经占到一半。

如果模型每次都生成:

大量解释
JSON
中间推理
工具描述

成本会明显增加。

因此应该设置合理的:

max_tokens

同时从 Prompt 层面减少不必要输出。

例如:

返回 JSON
不要解释
字段固定

相比:

请详细分析这个问题,并从多个角度进行解释……

更容易控制输出长度。


二十一、Speculative Decoding:进一步降低 Decode 延迟

当 Decode 成为主要瓶颈时,可以考虑 Speculative Decoding。

基本思想:

Small Draft Model
       │
       ▼
生成多个候选 Token
       │
       ▼
Large Target Model
       │
       ▼
并行验证

例如:

Draft Model

A B C D E
─────────►

Target Model

验证 A B C D E
──────────────►

如果候选 Token 大量被接受:

一次 Target Forward
=
多个 Token

那么有效 Decode 速度就可以提高。

vLLM 当前官方能力列表已经包含多种 Speculative Decoding 方法,包括 n-gram、EAGLE、DFlash 等。(vLLM)

不过 Speculative Decoding 并不是所有模型、所有工作负载都有效。

如果:

Draft Acceptance Rate 很低

那么额外的 Draft 计算反而可能浪费资源。

所以依然应该 Benchmark。


二十二、真正有效的 Benchmark 怎么做

不要使用:

单请求
短 Prompt
短输出

测试出来的结果作为生产性能。

应该至少建立四类测试。

Case A:短上下文

Input = 512
Output = 256
Concurrency = 1 / 8 / 32 / 64

Case B:中等上下文

Input = 4K
Output = 512
Concurrency = 8 / 32 / 64

Case C:长上下文

Input = 16K
Output = 1K
Concurrency = 8 / 16 / 32

Case D:真实业务

RAG
Agent
Tool Calling
Multi-turn Chat

最终比较:

指标 基线 优化后
TTFT P50
TTFT P95
TPOT
P95 Latency
Output tok/s
Total tok/s
GPU Utilization
KV Cache Usage
Requests/s
Cost / 1M tokens

二十三、成本应该按照 Token 计算,而不是只看 GPU 租金

假设一张 GPU:

$2 / hour

平均吞吐:

1000 tokens/s

那么:

3600 × 1000
=
3.6M tokens/hour

理论 GPU 成本:

$2 / 3.6M
≈ $0.56 / 1M tokens

如果通过优化:

1000 tok/s
↓
2000 tok/s

那么:

$0.56
↓
$0.28 / 1M tokens

GPU 数量没有减少,但单位 Token 成本下降了约 50%。

这就是推理优化真正的经济价值。

因此:

吞吐量提升本质上就是单位 Token 成本下降。


二十四、一个完整的成本优化路线

如果现在有一个成本较高的 LLM 服务,不建议一上来就换模型。

可以按照下面顺序处理。

第一阶段
业务 Token 优化
    │
    ├── Prompt Compression
    ├── RAG TopK
    ├── Output Limit
    └── Conversation Trimming

第二阶段
推理框架优化
    │
    ├── vLLM
    ├── Continuous Batching
    ├── PagedAttention
    └── Chunked Prefill

第三阶段
KV Cache 优化
    │
    ├── Prefix Caching
    ├── GQA / MQA
    └── KV Cache Quantization

第四阶段
模型量化
    │
    ├── FP8
    ├── INT8
    ├── AWQ
    └── GPTQ

第五阶段
Kernel / GPU 优化
    │
    ├── FlashAttention
    ├── CUDA Graph
    ├── Tensor Parallel
    └── Speculative Decoding

这个顺序非常重要。

因为如果:

Prompt 本来就有 20K tokens

你却首先花大量时间优化 CUDA Kernel,收益可能远低于:

20K
↓
8K

这样的上下文优化。


二十五、50%以上成本下降应该如何实现

“成本降低 50%”不能作为一个无条件承诺。

具体收益高度依赖:

模型
GPU
上下文长度
并发
输入/输出 Token 比例
量化方案
Prefix Cache 命中率
业务请求分布

但是在合适的生产场景中,实现 50% 甚至更高的单位 Token 成本下降并非不现实。

一个典型的优化过程可能是:

Baseline

FP16
+
低并发
+
无 Prefix Cache
+
静态 Batch
+
冗余 Context

        ↓

Step 1
Prompt Compression

成本 ↓ 20%

        ↓

Step 2
vLLM + Continuous Batching

吞吐 ↑ 50%

        ↓

Step 3
Prefix Cache

Prefill ↓

        ↓

Step 4
FP8 / INT4

显存 ↓
吞吐 ↑

        ↓

Step 5
KV Cache Optimization

并发 ↑

        ↓

最终

单位 Token 成本
下降 50%+

这里必须强调:

50%并不是某一个参数带来的结果,而是整个推理栈共同优化的结果。


二十六、生产环境推荐的监控指标

推理服务必须建立完整的可观测性。

至少应该监控:

Request Metrics

request_count
request_success
request_error
queue_time
TTFT
TPOT
E2E latency
P50/P95/P99

Token Metrics:

input_tokens
output_tokens
total_tokens
tokens/sec

GPU Metrics:

GPU utilization
GPU memory
SM utilization
Tensor Core utilization
Power
Temperature

KV Cache:

KV Cache Usage
KV Cache Hit Rate
Prefix Cache Hit Rate
Block Allocation
Block Reuse
Eviction

最终形成:

业务指标
     │
     ▼
Token 指标
     │
     ▼
Scheduler 指标
     │
     ▼
KV Cache
     │
     ▼
GPU

只有这样才能定位:

到底是业务 Token 太多?
还是调度效率低?
还是 KV Cache 不够?
还是 GPU Kernel 没吃满?

二十七、一个推荐的生产参数基线

对于一个中等规模的 GPU 推理服务,可以从如下思路开始:

vllm serve /models/Qwen \
  --host 0.0.0.0 \
  --port 8000 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 64 \
  --max-num-batched-tokens 16384

然后逐项压测:

max-num-seqs

32
64
128

以及:

max-num-batched-tokens

4096
8192
16384
32768

建立矩阵:

                    Throughput
                       ↑

                ┌─────────────┐
                │             │
                │ Optimal     │
                │ Region      │
                │             │
                └─────────────┘
                       │
                       └────────→ Latency

目标不是寻找:

最大吞吐

而是寻找:

满足 P95/P99 延迟 SLA 前提下的最高有效吞吐。


二十八、不要把显存利用率等同于计算效率

这是生产部署中非常常见的误判。

例如:

GPU Memory = 90%
GPU Utilization = 35%

说明显存占得很多,但 GPU 计算单元没有充分利用。

可能原因包括:

KV Cache 太大
Batch 太小
Memory Bandwidth 瓶颈
Kernel 不匹配
请求长度差异太大
Decode 占比过高

反过来:

GPU Utilization = 95%
GPU Memory = 70%

也不代表一定需要继续增加 Batch。

可能已经存在:

P99 latency
↑

所以必须同时观察:

Memory
Compute
Latency
Throughput

二十九、vLLM 之外:什么时候考虑 TensorRT-LLM

vLLM 并不是唯一选择。

在 NVIDIA GPU 深度优化场景中,TensorRT-LLM 同样非常重要。

尤其是:

FP8
FP4
KV Cache Quantization
Paged KV Cache
CUDA Kernel
NVIDIA Tensor Core

等场景。

TensorRT-LLM 当前 KV Cache 系统支持 Block 管理、跨请求复用、优先级驱逐以及 MHA/MQA/GQA 等优化;其文档也提供了 KV Cache 容量和复用相关接口。(NVIDIA GitHub)

因此实际选型可以考虑:

通用 LLM Serving
        ↓
      vLLM

NVIDIA 深度定制
        ↓
 TensorRT-LLM

PyTorch 原生研究
        ↓
     PyTorch

高性能推理
        ↓
vLLM / TRT-LLM Benchmark

最终仍然应该以真实模型和真实业务负载测试结果为准。


三十、一个可落地的优化决策树

面对一个已经上线的 LLM 服务,可以直接按照下面的顺序排查:

GPU 成本高
   │
   ▼
Token 是否过多?
   │
   ├── 是 → Prompt/RAG/Output 优化
   │
   └── 否
        │
        ▼
GPU 是否吃满?
        │
        ├── 否 → Batch / Scheduler / Kernel
        │
        └── 是
             │
             ▼
KV Cache 是否成为瓶颈?
             │
             ├── 是 → PagedAttention / Prefix Cache /
             │         KV Quantization / GQA
             │
             └── 否
                  │
                  ▼
             模型量化
                  │
                  ▼
             FP8 / INT8 / INT4
                  │
                  ▼
             Speculative Decoding
                  │
                  ▼
             多 GPU 并行

这比“换一张更贵的 GPU”通常更值得先做。


三十一、最终的生产实践原则

大模型推理优化最终可以归纳成八条原则。

第一,先减少 Token,再优化 GPU

少生成 1 Token

永远比:

花更多钱去生成 1 Token

更直接。


第二,KV Cache 是长上下文服务的核心资源

尤其是:

Long Context
+
High Concurrency

场景。

需要重点关注:

KV Memory
Block Allocation
Cache Hit
Eviction

第三,PagedAttention 解决的是内存管理问题

它不是一个简单的 Attention Kernel。

真正价值在于:

KV Cache
    ↓
Block
    ↓
Dynamic Allocation
    ↓
Reuse

第四,Continuous Batching 决定 GPU 是否高效

GPU 最怕:

Batch 太小
请求到达不均匀
长短请求混杂

Continuous Batching 的核心目标就是让 GPU 尽可能持续工作。


第五,Prefix Cache 是 Agent/RAG 的重要优化点

如果:

System Prompt
+
Tools
+
Rules

高度重复,那么 Prefix Cache 往往值得优先测试。


第六,量化必须看真实吞吐

不要简单认为:

INT4 > INT8 > FP8 > FP16

真实结果取决于:

GPU
Kernel
Model
Batch
Context

第七,优化目标不是最大吞吐

真正的目标是:

SLA
+
吞吐
+
成本
+
质量

四者之间取得平衡。


第八,Benchmark 必须使用真实流量模型

最终应该使用:

真实 Prompt 长度
真实输出长度
真实并发
真实 RAG
真实 Agent
真实 Cache Hit Rate

而不是一个简单的:

Hello World

测试。


三十二、总结

vLLM 的价值并不只是“让模型跑得更快”。

它真正解决的是 LLM 推理服务中几个最昂贵的问题:

KV Cache 管理
       +
Continuous Batching
       +
PagedAttention
       +
Prefix Caching
       +
Chunked Prefill
       +
量化
       +
高性能 Kernel

其中,PagedAttention 解决 KV Cache 的碎片和动态分配问题;Continuous Batching 提高 GPU 的持续利用率;Prefix Caching 减少重复 Prompt 的 Prefill 计算;量化降低模型权重和部分运行时数据的存储压力;KV Cache 量化则进一步提高长上下文场景下的并发能力。

从成本角度看,最值得建立的认知是:

LLM 推理成本
        │
        ├── Input Token
        ├── Output Token
        ├── GPU 时间
        ├── KV Cache
        └── 系统利用率

因此,真正成熟的推理优化不是单点优化,而是:

业务层
 ↓
Token 优化
 ↓
模型层
 ↓
量化
 ↓
推理框架
 ↓
vLLM
 ↓
KV Cache
 ↓
Batch Scheduler
 ↓
Kernel
 ↓
GPU

如果一个生产系统能够同时做到:

减少无效 Context
+
提高 Prefix Cache 命中率
+
PagedAttention
+
Continuous Batching
+
合理量化
+
KV Cache 优化
+
真实负载调度

那么在相同硬件下获得显著的吞吐提升、降低单位 Token 成本是完全有可能的。

但“成本降低 50%”不应该被理解成某个 vLLM 参数能够直接带来的固定收益。它取决于具体模型、GPU、上下文长度、并发结构和业务流量。真正可靠的做法,是建立 Baseline,然后逐项 Benchmark,最终以 $/1M tokens、P95 TTFT、TPOT、GPU 利用率和质量指标 来衡量优化是否真正产生了商业价值。

对于 RAG、企业知识库和 AI Agent 来说,尤其应该把 Prompt 设计、Prefix Cache、KV Cache 和 Continuous Batching 放在同一个优化体系里考虑。只有把“模型怎么计算”和“业务到底让模型计算了多少东西”放在一起,推理成本优化才真正进入工程阶段。

参考资料

  1. vLLM 官方文档 —— vLLM 官方技术文档,涵盖 PagedAttention、Continuous Batching、Prefix Caching、量化、Speculative Decoding 等推理能力。(vLLM)
  2. Efficient Memory Management for Large Language Model Serving with PagedAttention —— vLLM PagedAttention 核心技术论文,系统讨论 LLM Serving 中 KV Cache 的内存管理问题。
  3. NVIDIA TensorRT-LLM KV Cache System —— NVIDIA 官方 TensorRT-LLM KV Cache 技术文档,介绍 Paged KV Cache、Cache Reuse、MHA/MQA/GQA 等机制。(NVIDIA GitHub)
  4. 网渡科技官方文档 https://www.wangdu.net.cn/announcements/61
相关文章
人工智能 缓存 前端开发
6143 18
人工智能 JavaScript 开发工具
3038 4
缓存 JavaScript Shell
1386 1
|
12天前
|
存储 弹性计算 缓存
阿里云服务器租赁费用:新版租赁收费标准及活动报价参考
本文更新了2026年阿里云全系列云服务器租赁活动报价,所有特惠资源均可前往阿里云活动中心选购,整体覆盖从个人入门到企业级高性能场景的全梯度需求。其中轻量应用服务器主打极致性价比,2核2G峰值200M带宽配置每日10点、15点限时抢购价仅38元/年,2核4G配置379元/年起;高性价比的经济型e实例、通用算力型u2i实例覆盖2核4G至4核32G全档位,适配开发测试与中小型企业业务;搭载英特尔至强6处理器的第九代c9i企业级实例算力较上代提升20%,支撑高并发生产环境,不同实例规格价差清晰,用户可根据自身业务负载与预算灵活选型。
2067 121
阿里云服务器租赁费用:新版租赁收费标准及活动报价参考
|
13天前
|
人工智能 程序员 API
Codex 接入 DeepSeek-V4-Flash:还能补上识图,提供两套方案
Codex 接入 DeepSeek-V4-Flash 怎么配?本文覆盖 CLI 与桌面端,再用 qwen3-vl-flash 补识图,两套方案可直接照做
1667 13
缓存 人工智能 算法
639 1
|
10天前
|
编解码 弹性计算 云计算
MiniMax-H3 视频生成模型 — 一键部署与使用指南
MiniMax-H3是MiniMax开源的33B全模态视频生成模型,支持文生视频、图生视频、参考生视频三种模式,原生输出2K/15秒带立体声音频视频,已原生适配ComfyUI,并可通过阿里云计算巢一键部署。(239字)
|
11天前
|
人工智能 API 开发工具
2026 零基础本地 AI 漫剧完整实操教程(8G 笔记本显卡可用|附可直接复制命令与代码)
本方案提供完全离线、本地运行的漫剧全自动制作流程:RTX3060/4050 8G显卡即可驱动,涵盖Qwen写分镜→ComfyUI统一角色绘图→LTX2.3图生微动画→Qwen3-TTS本地配音→FFmpeg自动合成,全程无水印、免API、不限次。专为低显存优化,解决变脸、闪烁、爆内存三大痛点。(239字)
|
19天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1983 10
阿里云联动百位企业安全专家,共识Agent防御最佳实践