大模型推理优化与部署 — 完全指南

2025年Agent工程师必考内容。涵盖推理原理、优化技术、框架对比、MoE、生产部署及20道面试题。


一、推理基础

1.1 LLM推理流程

Prefill阶段 vs Decode阶段

LLM推理分为两个截然不同的阶段:

Prefill(预填充)阶段:

  • 将用户输入的所有Token一次性并行送入模型,计算每一层的KV(Key-Value)表示并缓存

  • 这个阶段是计算密集型(Compute-bound),因为所有输入Token可以并行处理,GPU的算力是瓶颈

  • 延迟主要取决于输入长度,典型场景下一个2048 Token的Prompt在A100上约需50-200ms(取决于模型大小)

  • 输出:生成第一个Token + 完整的KV Cache

Decode(解码)阶段:

  • 逐Token生成输出,每生成一个Token都需要:读取整个KV Cache → 计算Attention → 过FFN → 采样

  • 这个阶段是内存带宽密集型(Memory-bound),因为每次只处理1个Token,但需要读取全部KV Cache

  • GPU计算利用率极低(通常<10%),大量时间花在从HBM读取权重和KV Cache上

  • 每个Token的生成延迟相对固定,典型值为10-50ms/token

关键指标:

  • TTFT(Time To First Token):从请求到第一个Token返回的时间,主要由Prefill决定

  • TPS(Tokens Per Second)/ TPOT(Time Per Output Token):Decode阶段每秒生成Token数

Autoregressive生成的本质

自回归生成的核心是:每个新Token的生成依赖于前面所有Token的信息。数学上:

1
P(x_t | x_1, x_2, ..., x_{t-1})

这意味着:

  1. Token必须串行生成,无法并行(这是推理慢的根本原因)

  2. 每生成一个Token,Attention需要关注之前所有Token的K和V → KV Cache存在的意义

  3. 生成100个Token就需要100次前向传播(Decode步骤)

为什么推理慢?瓶颈在哪?

瓶颈 阶段 原因 影响
内存带宽 Decode 每步需读取全部模型权重(70B模型=140GB FP16)和KV Cache,但只计算1个Token GPU算力利用率<5%
KV Cache显存 全程 长序列+大batch时KV Cache爆炸,限制并发数 吞吐量受限
串行依赖 Decode 自回归本质决定无法并行生成 延迟线性增长
计算量 Prefill 输入越长计算量越大(Attention是O(n²)) TTFT增大

核心矛盾: Decode阶段的Arithmetic Intensity(计算/访存比)极低,约为1-2 FLOP/Byte,远低于GPU的峰值计算/带宽比(A100约为312 TFLOPS / 2TB/s ≈ 156 FLOP/Byte)。这意味着GPU大部分时间在等数据从显存搬运过来。


1.2 KV Cache

什么是KV Cache?为什么需要?

在Transformer的Self-Attention中,每个Token需要与之前所有Token做注意力计算:

1
Attention(Q, K, V) = softmax(QK^T / √d_k) · V

如果不用KV Cache: 生成第t个Token时,需要重新计算前面所有t-1个Token的K和V,计算量是O(t²),总生成n个Token的计算量是O(n³)——完全不可接受。

用了KV Cache: 把之前每个Token在每一层的K和V向量缓存下来,生成新Token时只需计算新Token的Q,与已缓存的K做点积、与V做加权求和。计算量降为每步O(t),总计O(n²)。

形象理解: 想象你在写考试答案,KV Cache就像你的草稿纸。没有草稿纸,每写一个字都要从头重新推导;有了草稿纸,只需要查看之前的中间结果。

KV Cache的显存占用计算

公式:

1
KV Cache显存 = 2 × num_layers × num_kv_heads × head_dim × seq_len × batch_size × bytes_per_element

以LLaMA-2 70B为例(FP16):

  • num_layers = 80

  • num_kv_heads = 8(GQA,原始64个heads分8组)

  • head_dim = 128

  • seq_len = 4096

  • batch_size = 1

  • bytes_per_element = 2(FP16)

1
2
3
= 2 × 80 × 8 × 128 × 4096 × 1 × 2 bytes
= 2 × 80 × 8 × 128 × 4096 × 2
= 1,073,741,824 bytes ≈ 1GB

单个请求4K上下文就需要~1GB KV Cache!如果是batch_size=32,就是32GB。

对比LLaMA-2 70B用MHA(非GQA):

  • num_kv_heads = 64(与query heads相同)

  • KV Cache = 1GB × (64/8) = 8GB/请求 → 32个并发 = 256GB,远超单卡显存

这就是GQA/MQA如此重要的原因。

KV Cache的问题

1. 显存爆炸:

  • 长上下文场景(128K tokens)下,即使GQA,单请求KV Cache也可达数十GB

  • 限制了可同时服务的请求数(batch size),直接影响吞吐量

2. 碎片化:

  • 不同请求的序列长度不同,KV Cache大小各异

  • 传统方式预分配最大长度的连续显存 → 短序列浪费、长序列不够

  • 碎片导致显存利用率仅60-70%

  • 这正是vLLM的PagedAttention要解决的核心问题

3. 动态增长:

  • 生成过程中KV Cache逐Token增长,无法预知最终长度

  • 需要动态内存管理机制


二、推理优化技术(重点!)

2.1 PagedAttention (vLLM)

核心思想

PagedAttention的灵感直接来自操作系统的虚拟内存分页机制

  • OS中: 物理内存被分为固定大小的页框(Page Frame),进程的虚拟地址空间通过页表映射到不连续的物理页框

  • PagedAttention中: GPU显存被分为固定大小的KV Block,每个请求的KV Cache通过Block Table映射到不连续的物理Block

详细工作原理

1. Block划分:

  • 将KV Cache划分为固定大小的Block,每个Block存储固定数量Token的KV向量

  • 典型Block Size = 16个Token

  • 例如:一个序列有100个Token,需要 ⌈100/16⌉ = 7个Block

2. Block Table(类比页表):

1
2
3
4
5
请求A的Block Table:
逻辑Block 0 → 物理Block 7
逻辑Block 1 → 物理Block 3
逻辑Block 2 → 物理Block 15
...
  • 逻辑Block连续,物理Block可以不连续

  • 每个请求维护自己的Block Table

3. 按需分配:

  • 新请求到来时,不预分配全部显存

  • 每生成16个Token,才分配一个新的物理Block

  • 请求结束后,物理Block归还到Free Block池

4. 内存共享(Copy-on-Write):

  • Parallel Sampling(同一Prompt生成多个回复)时,Prompt部分的KV Cache可共享

  • Beam Search中,不同Beam共享前缀的KV Block

  • 修改时才复制(CoW),显著减少显存占用

原理示意(文字版):

1
2
3
4
5
6
7
8
9
10
11
12
GPU显存(物理Block池):
[B0][B1][B2][B3][B4][B5][B6][B7][B8]...

请求1 (序列长50 tokens, 需4个Block):
逻辑: [L0] [L1] [L2] [L3]
映射: B2 B5 B0 B7 ← 物理上不连续!

请求2 (序列长30 tokens, 需2个Block):
逻辑: [L0] [L1]
映射: B3 B8

空闲Block: B1, B4, B6 → 可分配给新请求

效果

指标 传统方式 PagedAttention
显存利用率 60-70% 90-98%
显存浪费 预分配max_len导致大量浪费 仅Block内部碎片(最后一个Block可能未满)
并发请求数 受限于最大序列长度预分配 显著增加(2-4倍)
内存共享 不支持 CoW支持,Beam Search节省60%+

2.2 Continuous Batching

传统Static Batching的问题

1
2
3
4
5
6
7
时间 →
请求A: [████████████████████] ← 生成20个token就完了
请求B: [████████████████████████████████████████] ← 需要40个token
请求C: [██████████████████████████████] ← 30个token

Static Batch: 必须等最慢的请求B完成,A和C完成后GPU空转
整个Batch延迟 = max(所有请求的延迟)

问题:

  1. 短请求完成后GPU空转,利用率低

  2. 整个Batch的延迟由最慢的请求决定

  3. 新请求必须等当前Batch全部完成才能加入

  4. 吞吐量受限

Continuous Batching如何动态调度

1
2
3
4
5
6
7
时间 →
Step 1: [A, B, C] ← 3个请求同时处理
Step 5: [A完成, B, C] ← A完成,立即插入D
→ [D, B, C]
Step 8: [D, B, C完成] ← C完成,立即插入E
→ [D, B, E]
...

核心机制:

  1. Iteration-level调度: 每个Decode Step后检查是否有请求完成/新请求到达

  2. 完成即释放: 请求完成后立即释放资源(GPU计算槽+KV Cache Block)

  3. 即时插入: 新请求可在任意Step加入当前Batch(需先做Prefill)

  4. Prefill-Decode混合: 可以在同一Step中,部分请求做Prefill,部分做Decode

效果:

  • 吞吐量提升2-5倍(相比Static Batching)

  • GPU利用率显著提高

  • 请求等待时间大幅降低

  • 几乎所有现代推理框架(vLLM、TGI、TensorRT-LLM)都采用此方案

Chunked Prefill(进阶优化):

  • 长Prompt的Prefill可能阻塞Decode请求

  • 将Prefill拆成多个Chunk,与Decode请求交替执行

  • 避免Prefill导致的延迟尖峰


2.3 量化(Quantization)

量化的核心思想:用更少的bit表示模型权重/激活,减少显存占用和访存量,提升推理速度。

INT8量化

原理: 将FP16(16bit)权重映射到INT8(8bit),显存减半。

两种方式:

  1. W8A8(权重和激活都量化):

    • 使用INT8矩阵乘法(GEMM),需要硬件支持(A100/H100的INT8 Tensor Core)
    • 吞吐量理论提升2倍
    • 需要校准数据集确定缩放因子
  2. W8A16(仅权重量化):

    • 权重INT8存储,计算时反量化为FP16
    • 减少访存量(Decode阶段的主要瓶颈),速度提升明显
    • 精度损失更小

精度影响: 在大多数7B+模型上,INT8量化的精度损失<1%(以perplexity衡量)。

INT4/NF4量化

INT4: 4bit整数量化,显存为FP16的1/4。

NF4(NormalFloat4): QLoRA论文提出的4bit数据类型:

  • 基于正态分布的最优量化级别

  • 比普通INT4精度更高

  • 专为预训练权重的近似正态分布设计

Group-wise量化:

  • 不是整个Tensor共享一个缩放因子

  • 将权重分成小组(如128个元素一组),每组独立缩放

  • 显著提升INT4的精度

GPTQ vs AWQ vs GGUF

特性 GPTQ AWQ GGUF
方法 逐层量化,基于Hessian信息最小化量化误差 保护"重要"权重通道(基于激活值大小) llama.cpp生态的量化格式
精度 好(INT4接近FP16) 更好(比GPTQ低0.1-0.3 perplexity) 取决于量化等级(Q4_K_M等)
速度 需GPU(CUDA kernel) 需GPU,推理速度略优于GPTQ CPU/GPU通吃
量化时间 较长(需校准数据) 较短 较短
生态 HuggingFace/vLLM支持 vLLM/TGI支持 llama.cpp/Ollama
适用场景 GPU服务器部署 GPU服务器部署(推荐) 本地/边缘设备/CPU推理

2025年推荐:

  • GPU部署 → AWQ(精度和速度的最佳平衡)

  • 本地部署 → GGUF Q4_K_M(Ollama生态)

  • 微调 → QLoRA用NF4/bitsandbytes

量化对精度的影响

以LLaMA-2 70B在常见Benchmark上的表现:

量化方式 显存 Perplexity变化 MMLU变化
FP16(基线) 140GB 基线 基线
INT8 70GB <+0.1 <-0.5%
INT4 (GPTQ) 35GB +0.2~0.5 -1~2%
INT4 (AWQ) 35GB +0.1~0.3 -0.5~1%
INT3 26GB +1.0~2.0 -3~5%

经验法则:

  • 13B+ 模型的INT4量化几乎无感知精度损失

  • 7B模型INT4有轻微损失但可接受

  • INT3以下不推荐用于生产

  • 小模型(<3B)对量化更敏感


2.4 投机采样(Speculative Decoding)

核心思想

利用一个**小模型(Draft Model)快速生成多个候选Token,再用大模型(Target Model)**一次性并行验证,从而将多步串行Decode变为一步并行验证。

工作流程

1
2
3
4
5
6
7
8
9
10
11
12
13
1. Draft Model(如LLaMA-7B)自回归生成K个Token:
→ token_1, token_2, ..., token_K (快,每步~5ms)

2. Target Model(如LLaMA-70B)一次前向传播验证所有K个Token:
→ 并行计算 P_target(token_i | prefix + token_1..token_{i-1})
(一次前向,~50ms,但验证了K个Token)

3. 从左到右逐个验证:
- 如果 token_i 被接受(符合Target分布),继续
- 如果 token_i 被拒绝,从Target分布重新采样,丢弃后续Token

4. 最终输出的Token序列的分布与直接用Target Model生成完全一致
(数学上可证明,不损失精度!)

关键特性

数学保证: 通过修正的拒绝采样(Modified Rejection Sampling),最终输出分布与直接用Target Model采样完全相同——零精度损失

加速比分析:

  • Draft Model生成K个Token耗时:K × t_draft

  • Target Model验证耗时:t_target(无论K多大,一次前向传播)

  • 平均接受长度:α(取决于两个模型的分布相似度)

  • 加速比 ≈ α / (K × t_draft/t_target + 1)

典型加速比:2-3倍(当Draft Model与Target Model质量匹配较好时)

适用场景

场景 效果
代码生成 好(模式化强,接受率高~80%)
翻译 好(目标确定性高)
开放对话 一般(创意性任务接受率低~50%)
单请求低延迟 非常好(延迟优化的核心手段)
高吞吐批处理 不适合(验证步骤增加计算量)

变体

  • Self-Speculative Decoding: 用模型自身的浅层作为Draft,省去额外模型

  • Medusa/EAGLE: 用额外的预测头代替Draft Model(见2.6节)

  • Lookahead Decoding: 利用Jacobi迭代并行猜测


2.5 FlashAttention

标准Attention的IO瓶颈

标准Self-Attention计算:

1
2
3
S = Q @ K.T        # (N, N) 中间矩阵 — 需要写入HBM
P = softmax(S) # (N, N) — 需要写入HBM
O = P @ V # (N, d) — 结果

问题: 中间矩阵S和P的大小是O(N²),N=序列长度。

操作 计算量 HBM读写量
Q@K^T O(N²d) 写O(N²)到HBM
softmax O(N²) 读O(N²)从HBM,写O(N²)到HBM
P@V O(N²d) 读O(N²)从HBM
总IO O(N²)

当N=4096, d=128时:

  • 计算量 = ~4G FLOP → A100在~0.01ms完成

  • IO量 = ~128MB → A100 HBM带宽2TB/s需~0.06ms

  • IO时间是计算时间的6倍! → 完全IO-bound

FlashAttention的分块计算策略

核心思想: 不在HBM中存储N×N的中间矩阵,而是在SRAM(片上高速缓存,~20MB,带宽19TB/s)中分块计算。

算法:

  1. 将Q分成Block:Q_1, Q_2, ..., Q_Br(每块放得进SRAM)

  2. 将K, V分成Block:K_1, V_1, K_2, V_2, ..., K_Bc

  3. 对每个Q_i:

    • 依次加载K_j, V_j到SRAM
    • 在SRAM中计算 S_ij = Q_i @ K_j^T
    • 在SRAM中计算局部softmax(用Online Softmax算法)
    • 在SRAM中计算局部 O_ij = P_ij @ V_j
    • 累加到输出(用rescaling技巧保证数值正确)
  4. 中间的S、P矩阵从不写入HBM

Online Softmax技巧:

  • 传统softmax需要完整的一行才能计算(需要全局max和sum)

  • Online Softmax通过维护running max和running sum,支持流式计算

  • 每看到新的一块数据,rescale之前的结果

IO复杂度对比:

HBM读写
标准Attention O(N²)
FlashAttention O(N²d / SRAM_size)
加速比 ~SRAM_size/d ≈ 4-8倍

FlashAttention v1 vs v2 vs v3

版本 发布时间 关键改进
v1 2022.6 提出分块计算+Online Softmax,减少HBM IO,速度2-4倍
v2 2023.7 优化并行策略(序列维度→head维度并行)、减少非矩阵运算、支持更大head dim。速度比v1快2倍
v3 2024.7 针对Hopper架构(H100)优化:利用WGMMA/TMA指令、FP8支持、异步Warp Specialization。速度比v2快1.5-2倍,接近H100理论峰值

实际效果(A100, seq_len=2048, head_dim=128):

  • 标准Attention: ~10ms

  • FlashAttention v1: ~3ms

  • FlashAttention v2: ~1.5ms


2.6 其他优化

Tensor Parallelism (TP) / Pipeline Parallelism (PP)

Tensor Parallelism(张量并行):

  • 将模型的每一层切分到多张GPU上

  • 具体:将Attention的QKV投影矩阵按列切分,将FFN的第一层按列切分、第二层按行切分

  • 每一层的计算在多GPU间并行,需要AllReduce通信

  • 适合单机多卡(NVLink高带宽),通信开销低

  • 典型用法:TP=4或TP=8在单机8卡上

Pipeline Parallelism(流水线并行):

  • 将模型的不同层放到不同GPU上

  • GPU 0: Layer 0-19, GPU 1: Layer 20-39, ...

  • 存在"气泡"(Pipeline Bubble)——前面的GPU等后面的GPU

  • 通过Micro-batching减少气泡

  • 适合多机部署(跨机通信只需点对点传输)

选择策略:

1
2
3
单机内:TP(利用NVLink高带宽)
跨机间:PP(只需较低的跨机带宽)
混合:TP within node + PP across nodes

Prefix Caching

场景: 多个请求共享相同的System Prompt或少量模板前缀。

原理:

  1. 计算共享Prefix的KV Cache,缓存到GPU显存/CPU内存/磁盘

  2. 新请求匹配到已缓存的Prefix时,直接复用KV Cache

  3. 只需为非共享的后续部分做Prefill

效果:

  • System Prompt 1000 Token → 每个请求节省1000 Token的Prefill计算

  • 100个并发请求共享同一Prefix → 节省99×的重复计算

  • TTFT降低30-80%(取决于Prefix占比)

vLLM中的实现: Automatic Prefix Caching(APC),基于Hash匹配,自动检测共享前缀。

Medusa / EAGLE 多头预测

Medusa:

  • 在LLM最后一层后添加多个"预测头"(Medusa Heads)

  • 每个头预测未来第i个Token(i=1,2,...,K)

  • 构建候选Tree,用Tree Attention一次验证多条路径

  • 无需额外Draft Model,训练成本低(只需训练Medusa Heads)

  • 加速比:1.5-2.5倍

EAGLE(2024,效果更好):

  • 使用一个轻量级的自回归Draft Head

  • 在特征空间(而非Token空间)做预测

  • 接受率比Medusa高10-20%

  • 加速比:2-3倍,接近投机采样的效果

KV Cache压缩:GQA / MQA

Multi-Head Attention (MHA):

  • 每个Attention Head有独立的Q、K、V

  • KV Cache大小 ∝ num_heads

Multi-Query Attention (MQA):

  • 所有Query Head共享同一组K和V

  • KV Cache缩小为 1/num_heads

  • 速度大幅提升,但精度有一定损失

Grouped-Query Attention (GQA):

  • 折中方案:将Query Heads分成G组,每组共享一组KV

  • KV Cache缩小为 G/num_heads(如LLaMA-2 70B: G=8, heads=64, 缩小8倍)

  • 精度接近MHA,速度接近MQA

  • 2024-2025年主流模型标配(LLaMA-3、Qwen-2、Mistral等)

对比:

KV Heads KV Cache 精度
MHA = Q Heads (64) 最佳
GQA G组 (8) 1/8× 接近MHA
MQA 1 1/64× 略差

三、推理框架对比

3.1 vLLM

核心特性:

  • PagedAttention → 高效KV Cache管理

  • Continuous Batching → 高吞吐

  • OpenAI兼容API → 易迁移

  • 支持TP/PP → 多卡部署

  • Prefix Caching → 共享前缀加速

  • 投机采样支持

优势:

  • 开源社区最活跃(50K+ GitHub Stars)

  • 吞吐量业界领先

  • 模型支持最广(HuggingFace生态全覆盖)

适用场景: 生产环境高吞吐服务、在线API服务

3.2 TGI (Text Generation Inference)

核心特性:

  • HuggingFace官方出品

  • Rust实现的高性能Token Streaming

  • 内置安全功能(水印、敏感词过滤)

  • 原生HuggingFace Hub集成

适用场景: HuggingFace生态用户、需要安全特性的场景

3.3 TensorRT-LLM

核心特性:

  • NVIDIA官方优化

  • 基于TensorRT的极致kernel优化

  • FP8/INT4/INT8硬件级量化

  • 多种并行策略(TP/PP/EP)

  • Inflight Batching

优势: 单请求延迟最低,NVIDIA硬件上性能最佳 劣势: 需要编译模型(耗时)、API不如vLLM友好、模型支持滞后

适用场景: 对延迟要求极高的生产环境、NVIDIA GPU专属部署

3.4 Ollama

核心特性:

  • 基于llama.cpp

  • 一行命令运行模型(ollama run llama3

  • CPU/GPU混合推理

  • 本地Modelfile生态

适用场景: 本地开发测试、边缘设备、个人使用

3.5 SGLang

核心特性:

  • RadixAttention(高级Prefix Caching)

  • 结构化生成优化(JSON、正则约束)

  • 高效的编程接口

  • 与vLLM竞争的吞吐量

适用场景: 需要结构化输出的Agent场景、复杂Prompt编排

框架对比表

维度 vLLM TGI TensorRT-LLM Ollama SGLang
吞吐量 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐
单请求延迟 ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐
易用性 ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐
模型支持 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
CPU推理
结构化输出 ⭐⭐⭐ ⭐⭐⭐ ⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐
社区活跃度 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
生产就绪 ⚠️

2025年选型建议:

  • 通用生产部署 → vLLM

  • 极致性能+NVIDIA → TensorRT-LLM

  • Agent/结构化输出 → SGLang

  • 本地开发 → Ollama


四、MoE (Mixture of Experts)

4.1 MoE原理

稀疏激活

核心思想: 模型参数量巨大,但每次推理只激活其中一小部分。

在标准Transformer中,FFN层占了约2/3的参数量。MoE将FFN层替换为多个"Expert"(每个Expert是一个独立的FFN),每次只激活其中Top-K个。

1
2
3
4
5
6
7
8
标准Transformer FFN:
输入 → FFN → 输出 (100%参数参与计算)

MoE FFN:
输入 → Router → 选择Top-2 Expert
→ Expert_3(输入) × w_3 + Expert_7(输入) × w_7
→ 加权求和 → 输出
(只有2/N的Expert参数参与计算)

效果: Mixtral 8x7B有47B总参数,但每次推理只激活约13B参数(Top-2 of 8),计算量接近13B模型,但性能超越LLaMA-2 70B。

Router/Gating机制

Router是一个简单的线性层 + Softmax,输入Token的隐层表示,输出每个Expert的权重分数:

1
2
gate_logits = Linear(hidden_states)  # (batch, num_experts)
weights = softmax(topk(gate_logits, k=2)) # 选Top-2

Token-level路由: 每个Token独立选择Expert(不是整个序列共用)

负载均衡问题

问题: Router容易"偏科"——某些Expert被过度使用(热门Expert),其他Expert几乎不用(冷门Expert)。

后果:

  • 计算负载不均衡,热门Expert成为瓶颈

  • 冷门Expert参数浪费

  • 模型质量下降

解决方案:

  1. 辅助损失(Auxiliary Loss): 训练时添加负载均衡loss,鼓励均匀分配

  2. Expert Capacity: 限制每个Expert处理的Token数上限,溢出的Token丢弃或重路由

  3. DeepSeek的细粒度Expert: 使用更多更小的Expert(如256个),统计上更均衡


4.2 MoE推理特点

显存大但计算快

显存需求: 所有Expert的参数都要加载到显存中(即使每次只用Top-2)。

模型 总参数 激活参数 FP16显存 等效Dense模型
Mixtral 8x7B 47B 13B ~94GB ~LLaMA-2 70B性能
DeepSeek-V3 671B 37B ~1.3TB 超越GPT-4级

计算量: 由激活参数决定,远小于总参数暗示的计算量。

矛盾: 显存像70B模型,计算像13B模型 → 推理时GPU计算利用率更低(更加Memory-bound)。

Expert并行策略 (EP)

Expert Parallelism: 将不同Expert放在不同GPU上。

1
2
3
4
GPU 0: Expert 0, 1(+ 共享层:Attention、Embedding)
GPU 1: Expert 2, 3
GPU 2: Expert 4, 5
GPU 3: Expert 6, 7

通信模式: All-to-All

  • Router决定Token去哪个Expert → 需要将Token发送到对应GPU

  • Expert计算完后,结果发回原始GPU

  • 通信量取决于Batch中Token的路由分布

实践中常用:TP + EP混合

  • Attention层用TP(需要AllReduce)

  • FFN/Expert层用EP(需要All-to-All)


4.3 代表模型

Mixtral 8x7B(Mistral AI, 2023.12)

  • 8个Expert,每次激活2个

  • 总参数47B,激活13B

  • 性能超越LLaMA-2 70B

  • 开源MoE的开山之作

  • 32K上下文窗口

DeepSeek-V2/V3 MoE(DeepSeek, 2024-2025)

DeepSeek-V2(2024.5):

  • 创新的MLA(Multi-head Latent Attention):将KV Cache压缩为低维latent向量

  • 160个细粒度Expert + 2个共享Expert,Top-6路由

  • KV Cache比标准GQA再减少90%+

  • 总参数236B,激活21B

DeepSeek-V3(2025.1):

  • 671B总参数,37B激活

  • 256个细粒度Expert + 1个共享Expert

  • 训练成本仅~$5.5M(H800集群),远低于同级模型

  • 性能对标GPT-4o / Claude-3.5

  • FP8混合精度训练

Qwen-MoE(阿里, 2024-2025)

  • Qwen1.5-MoE-A2.7B:14.3B总参数,2.7B激活

  • 性能媲美7B Dense模型

  • Qwen2.5系列延续MoE路线


五、生产部署

5.1 模型服务架构

部署拓扑

单机单卡:

  • 适用模型:7B-13B(FP16)或量化后的70B(INT4 ~35GB)

  • 硬件:单A100 80GB / H100 80GB

  • 框架:vLLM单进程启动

单机多卡(最常用):

  • 适用模型:70B FP16(需2×A100或4×A100)

  • 使用Tensor Parallelism(TP=2或TP=4)

  • NVLink提供高速卡间通信(600GB/s on A100)

  • 框架:vLLM --tensor-parallel-size 4

多机多卡:

  • 适用模型:超大模型(671B DeepSeek-V3等)

  • 机内TP + 机间PP(或EP for MoE)

  • 需要高速网络(InfiniBand 200-400Gbps)

典型生产架构

大模型推理服务部署拓扑

关键组件:

  1. API Gateway: 统一入口,OpenAI兼容API,鉴权和限流

  2. 负载均衡: 基于请求队列长度的智能路由(而非简单轮询)

  3. 模型服务: vLLM实例,每个实例可处理多并发

  4. 请求队列: 异步处理,削峰填谷


5.2 弹性伸缩

基于指标的HPA(Horizontal Pod Autoscaler)

关键伸缩指标:

指标 扩容阈值 缩容阈值 说明
GPU利用率 >80% <30% 计算层面是否饱和
请求队列长度 >50 <5 用户等待体验
QPS >目标QPS的80% <目标QPS的20% 流量维度
TTFT P99 >SLA阈值 - 用户体验保障

K8s HPA配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: gpu_utilization
target:
type: AverageValue
averageValue: "75" # 75%

冷启动优化

GPU推理服务的冷启动痛点:

  1. 模型加载慢: 70B模型从磁盘加载到GPU需2-5分钟

  2. CUDA初始化: 首次推理需编译kernel,额外耗时

优化手段:

  • 模型预热: 容器启动后发送dummy请求,触发CUDA kernel编译

  • 模型缓存: 将模型权重放在高速存储(NVMe SSD/RAM Disk),加载时间从5min→30s

  • Safetensors格式: 支持mmap直接映射,加载速度比pickle快5-10倍

  • 预留最小实例: 保持minReplicas≥1,避免从0扩容

  • 分层加载: 先加载部分层开始服务,后台异步加载剩余层


5.3 监控与可观测

核心指标

延迟指标:

  • TTFT(Time To First Token): 从请求到返回第一个Token,反映Prefill性能和排队时间

    • P50 < 500ms, P99 < 2s(典型SLA)
  • TPOT(Time Per Output Token): 每个输出Token的延迟,反映Decode性能

    • 目标:< 50ms/token(即 >20 TPS)
  • E2E Latency: 端到端延迟 = TTFT + output_tokens × TPOT

吞吐指标:

  • Request Throughput: QPS(每秒处理请求数)

  • Token Throughput: 每秒生成的Token数(所有请求合计)

    • vLLM在A100上的典型吞吐:~2000-5000 tokens/s(取决于模型和batch size)

资源指标:

  • GPU利用率(SM Occupancy): 目标>70%

  • GPU显存占用: 模型权重 + KV Cache + 临时buffer

  • GPU显存碎片率: PagedAttention下应<5%

  • CPU内存: 注意offload场景

队列指标:

  • 排队请求数: >100则需要扩容

  • 排队等待时间: P99应<5s

  • 拒绝率: 应<0.1%

监控工具链

1
2
3
4
5
6
7
8
9
Prometheus(指标采集)
→ Grafana(可视化Dashboard)
→ AlertManager(告警)

vLLM暴露Prometheus metrics:
/metrics endpoint → 请求延迟、吞吐、队列长度等

NVIDIA DCGM(GPU监控):
→ GPU利用率、显存、温度、功耗

六、面试题(20题)+ 完整参考答案

1. 解释LLM推理的Prefill和Decode两个阶段

LLM推理分为两个阶段。Prefill阶段将用户输入的所有Token一次性并行送入模型,计算所有层的KV Cache并生成第一个输出Token。这个阶段是计算密集型(Compute-bound),因为输入Token可以并行处理,GPU的算力被充分利用。Prefill的延迟决定了TTFT(Time To First Token),直接影响用户感知的响应速度。

Decode阶段是逐Token串行生成的过程。每一步只处理1个Token,但需要读取之前所有Token的KV Cache来计算Attention。这个阶段是内存带宽密集型(Memory-bound),因为计算/访存比极低——生成1个Token需要读取整个模型权重(70B模型=140GB FP16)和不断增长的KV Cache,但只做极少量计算。GPU利用率通常不到10%。

两个阶段的优化方向不同:Prefill优化关注计算效率(FlashAttention、Chunked Prefill),Decode优化关注减少访存(量化、KV Cache压缩、投机采样)。实际部署中需要平衡两者,Continuous Batching通过混合调度两类请求来提升整体吞吐。


2. KV Cache是什么?为什么需要?占多少显存?

KV Cache是推理时缓存的每一层Attention中的Key和Value张量。由于自回归生成的特性,每个新Token的生成需要与之前所有Token做注意力计算。如果不缓存KV,生成第t个Token就需要重新计算前t-1个Token的所有KV,计算量从O(n²)退化到O(n³),完全不可接受。

显存计算公式: 2 × L × H_kv × d × S × B × 2bytes,其中L=层数,H_kv=KV头数,d=头维度,S=序列长度,B=batch size,2bytes表示FP16。以LLaMA-2 70B(GQA, L=80, H_kv=8, d=128)为例,单请求4K上下文的KV Cache约1GB。如果用MHA(H_kv=64),则为8GB/请求——这就是GQA如此重要的原因。

KV Cache的核心问题是:(1) 显存占用大,限制并发batch size,直接影响吞吐量;(2) 不同请求长度不同导致显存碎片化,传统预分配方式浪费30-40%显存;(3) 随生成过程动态增长,需要高效的内存管理。vLLM的PagedAttention和GQA/MQA正是针对这些问题的关键优化。


3. PagedAttention的原理和优势?

PagedAttention借鉴了操作系统虚拟内存的分页管理思想。它将KV Cache划分为固定大小的Block(如每Block存16个Token的KV),物理Block散布在GPU显存中,通过Block Table(类似OS页表)维护逻辑到物理的映射关系。

工作方式: 新请求不预分配max_length的连续显存,而是按需逐Block分配——每生成16个Token才分配一个新Block。请求结束后Block归还到空闲池。不同请求的Block在物理上可以不连续,消除了外部碎片。对于共享前缀的场景(如相同System Prompt、Beam Search),多个请求可通过Copy-on-Write共享同一物理Block,修改时才复制。

量化优势: 显存利用率从传统方式的60-70%提升到90-98%,直接效果是同等显存下可服务的并发请求数增加2-4倍。在Beam Search场景中,KV Cache的共享可节省60%以上的显存。内部碎片仅存在于最后一个未填满的Block中(平均浪费Block_size/2个Token的空间),远小于传统方式的浪费。PagedAttention是vLLM的核心创新,也是其吞吐量领先的关键原因。


4. vLLM的核心创新点?

vLLM的核心创新有三个层次。第一,PagedAttention——将KV Cache的管理从预分配连续内存改为按需分页管理,显存利用率从~65%提升到>95%,这是vLLM最根本的贡献。

第二,Continuous Batching——请求完成即释放资源、新请求随时加入,消除了Static Batching中短请求等待长请求的GPU空转问题,吞吐量提升2-5倍。

第三,系统工程层面的优化: 高效的CUDA kernel实现(与FlashAttention集成)、Prefix Caching(自动检测并复用共享前缀的KV Cache)、投机采样支持、多种并行策略(TP/PP)、OpenAI兼容API接口。2024-2025年vLLM还加入了Chunked Prefill(避免长Prompt阻塞Decode)、FP8量化、多模态模型支持等。

vLLM的论文发表于2023年SOSP,是将OS思想应用于ML系统的典范。其开源项目GitHub Stars超过50K,成为事实上的LLM推理标准框架。核心贡献者来自UC Berkeley Ion Stoica团队,后成立Anyscale/vLLM公司商业化。


5. Continuous Batching vs Static Batching?

Static Batching: 收集一批请求组成固定Batch,所有请求一起开始、一起结束。最短的请求完成后必须等最长的请求结束才能释放,期间GPU对已完成请求的计算完全浪费。新请求必须等整个Batch处理完毕才能加入。如果Batch中有1个请求需要生成500 Token,其他9个只需50 Token,那90%的GPU时间在做无用功。

Continuous Batching: 在每个Decode Step的粒度上做调度——请求一完成就移出,新请求立即加入。GPU始终在为有效请求工作,利用率大幅提升。典型实现中还支持Prefill和Decode请求混合执行——新加入的请求做Prefill的同时,其他请求继续Decode。

实测对比(LLaMA-13B, A100, 混合长度请求):

  • Static Batching: ~800 tokens/s

  • Continuous Batching: ~2500 tokens/s(3倍+提升)

进阶优化Chunked Prefill将长Prompt的Prefill拆成多个Chunk,避免单次Prefill耗时过长导致Decode请求"卡顿"。2025年所有主流推理框架(vLLM、TGI、TensorRT-LLM、SGLang)都默认使用Continuous Batching。


6. INT8/INT4量化的原理和trade-off?

INT8量化将FP16的16bit权重映射到8bit整数。核心是找到合适的缩放因子:q = round(w / scale),推理时w ≈ q × scale。W8A8方案使用INT8 Tensor Core做矩阵乘法(A100/H100支持),理论吞吐翻倍;W8A16方案仅权重量化存储,计算时反量化为FP16,主要减少访存量。INT8对13B+模型精度损失极小(<0.1 perplexity),是最安全的量化选择。

INT4量化更激进,每个权重仅4bit,显存减至FP16的1/4。因为精度表示范围极小(16个离散值),需要Group-wise量化(每128个权重一组、独立缩放因子)来保证精度。GPTQ基于Hessian矩阵逐层最优化量化误差;AWQ基于激活值的重要性保护关键权重通道,通常比GPTQ精度好0.1-0.3 perplexity。

Trade-off: INT8几乎无精度损失,显存减半,推理加速1.5-2倍,适合任何场景。INT4显存减至1/4,可让70B模型跑在单卡上(35GB),但小模型(<7B)精度损失明显,大模型(13B+)损失可接受。经验法则:优先INT8,显存不够再用INT4(AWQ),7B以下模型慎用INT4。


7. GPTQ vs AWQ的区别?

GPTQ(GPT-Quantization, 2023): 基于OBQ(Optimal Brain Quantization)的逐层量化方法。核心思想是利用Hessian矩阵(二阶梯度信息)找到最优的量化顺序和误差补偿方式——先量化对输出影响小的权重,再用未量化的权重补偿已产生的量化误差。需要一个小的校准数据集(128-256条样本)计算Hessian。量化一个70B模型需要数小时。

AWQ(Activation-aware Weight Quantization, 2024): 观察到只有约1%的"重要"权重通道(salient channels)对精度影响巨大——这些通道对应激活值较大的维度。AWQ不直接保护这些权重不量化,而是在量化前对它们乘一个缩放因子使其量化更友好,再除以相同因子补偿。这样做在数学上等价但量化误差更小。量化速度快于GPTQ。

实测对比(LLaMA-2 70B, INT4-128g): AWQ的Perplexity比GPTQ低0.1-0.3,在下游任务上MMLU准确率高约0.5-1%。推理速度两者相当(用相同kernel)。AWQ量化时间更短(无需迭代优化)。2025年推荐:GPU部署优先AWQ。


8. 投机采样如何加速推理?

投机采样的核心洞察是:LLM推理的Decode阶段是Memory-bound,一次前向传播处理1个Token和处理K个Token的耗时几乎相同(计算量增加但仍受限于内存带宽)。利用这一点,用小模型快速"猜测"多个Token,大模型一次验证。

流程: (1) Draft Model(如1.5B参数)自回归生成K个候选Token(耗时K×5ms≈25ms);(2) Target Model(如70B)将K个Token连同前缀一次性前向传播(耗时~50ms,无论K多大);(3) 从左到右验证,用修正拒绝采样保证输出分布与直接用Target Model完全一致——被拒绝的Token及其后续全部丢弃。

加速分析: 假设平均接受K=4个Token中的3个,则一轮(25+50=75ms)生成3个Token,而直接用Target Model需要3×50ms=150ms。加速比=2倍。实际中代码生成场景接受率高达80%+,加速2-3倍;开放对话接受率约50%,加速1.5倍左右。关键在于Draft Model与Target Model的分布匹配度。

数学保证是最大优点: 与量化不同,投机采样零精度损失,最终Token分布与直接采样数学等价。


9. FlashAttention解决什么问题?原理?

FlashAttention解决的是标准Attention实现中的GPU HBM IO瓶颈问题。标准实现中,计算S=QK^T生成N×N的中间矩阵并写入HBM,softmax读回再写出,P@V再读回——总共O(N²)的HBM读写。当序列长度N=4096时,中间矩阵占128MB,反复搬运的IO时间远超实际计算时间(IO耗时约是计算的6倍)。

FlashAttention的原理: 将Q/K/V分成小Block,依次加载到GPU SRAM(片上缓存,容量~20MB但带宽19TB/s,是HBM的10倍)中。在SRAM里完成局部的QK^T、softmax、乘V,中间矩阵永远不写入HBM。技术难点在于softmax需要全局max和sum——这通过Online Softmax算法解决:维护running max和running sum,每处理新Block时rescale之前的结果。

效果: HBM IO从O(N²)降为O(N²d/M)(M=SRAM大小),实际速度提升2-4倍(v1),FlashAttention v2通过优化并行策略和减少非矩阵运算再提升2倍,v3针对H100 Hopper架构利用异步Warp Specialization和FP8支持,接近硬件理论峰值。FlashAttention已成为所有推理框架的标配。


10. MoE模型的推理有什么特点?

MoE推理有四个显著特点。第一,显存大但计算快: Mixtral 8x7B有47B参数(需~94GB FP16),但每次推理只激活13B参数(Top-2 Expert)。显存需求像大模型,计算量像小模型。这使得推理更加Memory-bound——GPU利用率更低。

第二,路由导致的不规则计算: 每个Token被路由到不同的Expert,导致不同Expert处理的Token数量不同(负载不均衡)。这给高效batching和并行带来挑战。在Expert Parallelism中,All-to-All通信的模式取决于路由结果,无法预先优化。

第三,需要Expert Parallelism (EP): 对于超大MoE(如DeepSeek-V3的256个Expert),单卡放不下所有Expert,需要将Expert分散到多GPU。EP与TP结合使用:Attention层用TP(AllReduce),Expert层用EP(All-to-All)。通信模式的切换增加了系统复杂度。

第四,缓存不友好: 不同请求激活不同Expert,权重访问模式不规则,GPU L2 Cache利用率低。DeepSeek-V3通过细粒度Expert(256个小Expert而非8个大Expert)和共享Expert缓解了部分问题。总体而言,MoE推理需要专门的系统优化。


11. GQA/MQA如何减少KV Cache?

标准Multi-Head Attention (MHA)中,每个Query Head有对应的独立K Head和V Head。假设有64个Head,KV Cache需要存64组KV。

MQA(Multi-Query Attention): 所有64个Query Head共享同一组K和V——KV Cache缩小到1/64。GPT-J、Falcon等早期模型采用。优点是KV Cache极小,推理速度快;缺点是多个Query Head被迫共享相同的KV表示,模型表达能力受限,精度有明显下降(MMLU下降1-2%)。

GQA(Grouped-Query Attention): 折中方案。将64个Query Head分成G组(如G=8),每组8个Query Head共享一组KV。KV Cache缩小到8/64=1/8。以LLaMA-2 70B为例:MHA需要8GB/请求KV Cache(4K序列),GQA只需1GB/请求。精度损失<0.5%MMLU,几乎可忽略。

为什么GQA成为标配? KV Cache直接决定可支撑的并发batch size,进而决定吞吐量。GQA让70B模型在4×A100上能同时服务32个用户(32GB KV Cache)而非4个(256GB根本放不下)。LLaMA-2 70B、LLaMA-3、Qwen-2/2.5、Mistral/Mixtral、DeepSeek等2024-2025年几乎所有主流模型都采用GQA。


12. 如何选择推理框架(vLLM/TGI/TensorRT-LLM)?

选择推理框架需考虑5个维度:

性能优先选TensorRT-LLM: NVIDIA官方优化,kernel级别的调优,FP8量化原生支持,单请求延迟最低。但需要离线编译模型(build engine,耗时数十分钟到数小时),模型支持滞后(新模型需等官方适配),API不够友好。适合已确定模型、对延迟SLA严格的生产环境。

通用部署选vLLM: 模型支持最广(HuggingFace直接加载),OpenAI兼容API开箱即用,PagedAttention+Continuous Batching保证高吞吐,社区最活跃(bug修复快、新功能迭代快)。吞吐量与TensorRT-LLM相当,延迟稍逊。适合需要快速迭代、支持多种模型的场景。

HuggingFace生态选TGI: 与HF Hub深度集成,自带安全特性(水印、token化保护),部署简单。性能略低于vLLM。

Agent/结构化输出选SGLang: RadixAttention对复杂Prompt编排(多轮对话、Tool Calling)有独特优势,结构化输出(JSON Schema约束)性能最佳。

简单总结: 80%的场景选vLLM不会错。极致性能+长期稳定部署选TensorRT-LLM。Agent场景考虑SGLang。本地玩选Ollama。


13. 模型并行策略有哪些?各自适用场景?

Tensor Parallelism (TP): 将每一层的权重矩阵切分到N张GPU上。如Linear(4096, 4096)切成4份,每GPU处理Linear(4096, 1024)。每层计算后需要AllReduce通信同步结果。优点是负载均衡好、延迟低(单层计算时间/N);缺点是通信频繁(每层2次AllReduce)。适合单机多卡(NVLink 600GB/s通信),TP=2/4/8。

Pipeline Parallelism (PP): 将不同层分配到不同GPU。GPU0处理Layer0-19,GPU1处理Layer20-39。通信只在层组边界发生(点对点传输,量小)。缺点是"Pipeline Bubble"——前面的GPU在等后面的GPU完成。通过Micro-batching可将Bubble从(P-1)/P降至更低。适合多机部署(跨机只需低延迟P2P通信)。

Expert Parallelism (EP): MoE模型专用,将不同Expert放到不同GPU。需要All-to-All通信——Token被路由到目标Expert所在的GPU。适合大规模MoE模型

实践组合:

  • 单机8卡部署70B:TP=8

  • 2机16卡部署70B:TP=8(机内) × PP=2(跨机)

  • 4机32卡部署DeepSeek-V3 MoE:TP=8(机内) × EP=4(跨机Expert)


14. 如何监控线上推理服务的性能?

推理监控需要覆盖四个层次。延迟层: TTFT(首Token延迟,反映Prefill+排队)和TPOT(每Token延迟,反映Decode性能),分别监控P50/P95/P99。典型SLA:TTFT P99<2s,TPOT<50ms。突然升高可能表示显存不足导致swap、或新部署的模型有问题。

吞吐层: 请求QPS和Token Throughput(tokens/s)。vLLM在A100上服务LLaMA-70B典型吞吐约2000-4000 tokens/s。吞吐量下降通常与KV Cache碎片或内存不足有关。

资源层: 通过NVIDIA DCGM采集GPU利用率(SM Occupancy目标>70%)、显存占用(关注KV Cache动态增长)、GPU温度(>85°C需关注散热)、功耗。CPU侧监控内存使用和网络IO。

业务层: 请求排队长度(>100需扩容)、排队等待时间、请求拒绝/超时率(<0.1%)、输出Token分布(是否有异常长/短回复)。

工具链: vLLM/SGLang内置Prometheus metrics端点 → Prometheus采集 → Grafana Dashboard → AlertManager告警。关键告警规则:TTFT P99连续5分钟>SLA、GPU利用率>90%持续10分钟、排队长度>200。


15. 推理延迟优化的优先级排序?

按ROI(投入产出比)从高到低排序:

第一优先级——模型层面(成本最低、效果最大):

  1. 使用GQA模型(减少KV Cache 4-8倍,直接提升并发和推理速度)

  2. 量化(INT8几乎零损失,速度提升1.5倍;INT4显存减3/4)

  3. 选择合适大小的模型(用7B能解决就不要上70B)

第二优先级——框架/算法层面: 4. 使用FlashAttention(2-4倍Attention加速,所有框架已默认集成) 5. Continuous Batching(吞吐提升2-5倍) 6. PagedAttention/KV Cache管理(并发提升2-4倍) 7. Prefix Caching(有共享前缀场景下TTFT减少30-80%)

第三优先级——系统优化: 8. 投机采样(2-3倍Decode加速,但增加系统复杂度) 9. Chunked Prefill(减少长Prompt对Decode延迟的影响) 10. 优化batch调度策略

第四优先级——硬件升级: 11. 更高带宽显存(H100 HBM3 3.35TB/s vs A100 HBM2e 2TB/s) 12. 更快的卡间互联(NVLink/NVSwitch)

常见误区: 盲目堆GPU而不优化软件栈、只关注单请求延迟忽视吞吐量、在Prefill不是瓶颈时优化Prefill。


16. 如何做模型服务的弹性伸缩?

GPU推理服务的弹性伸缩与传统Web服务有三个本质差异:冷启动慢(70B模型加载2-5分钟)、资源粒度粗(以GPU卡为单位)、成本高(A100 $2-3/GPU/小时)。

扩容策略: 监控指标优先用请求队列长度(>50触发扩容)和TTFT P99(>SLA阈值触发),而非GPU利用率(高利用率可能是好事)。K8s HPA结合自定义GPU指标(通过DCGM Exporter暴露)。设置合理的cooldown period(5-10分钟避免抖动)。

冷启动优化至关重要: (1) 预留minReplicas≥2确保基线容量;(2) 模型权重放高速NVMe或内存文件系统;(3) 使用Safetensors格式支持mmap,加载从5min→30s;(4) 容器启动后发dummy请求预热CUDA kernel;(5) 考虑"温备"实例——容器已启动、模型已加载但不接流量。

缩容策略: 比扩容更保守。GPU利用率<20%持续30分钟才缩容。确保剩余实例能承接转移流量。缩容前排空正在处理的请求(graceful drain)。

成本优化: 使用Spot/抢占式实例降低50-70%成本(需处理中断)。峰谷分时调度——白天高并发用按需实例,夜间切换到Spot。


17. Prefix Caching如何工作?

Prefix Caching利用了一个关键观察:大量推理请求共享相同的前缀。例如,所有请求共享同一个System Prompt(如"你是一个有帮助的AI助手..."),或RAG场景中多个请求引用同一文档。

工作原理: (1) 将Prompt按固定长度分成Block(如256 Token一块);(2) 对每个Block计算Hash值(基于Token内容);(3) 首次计算后将该Block的KV Cache存入缓存池(GPU显存/CPU内存);(4) 后续请求的Prompt匹配到相同Hash的Block时,直接复用已缓存的KV Cache,跳过这些Block的Prefill计算。

vLLM的Automatic Prefix Caching (APC): 自动检测请求间的公共前缀,无需用户手动配置。基于Block粒度的Hash比较,支持任意长度前缀的匹配。与PagedAttention的Block管理自然融合。

SGLang的RadixAttention: 更进一步,用Radix Tree(基数树)管理所有请求的KV Cache前缀。支持任意位置的前缀匹配(不限于从开头匹配),对多轮对话、Tree-of-Thought等复杂prompt模式效果更好。

效果: 假设System Prompt 1000 Token占Prefill时间的60%,100个并发请求共享Prefix → TTFT减少约60%。在Agent场景中(固定工具描述+系统指令常达2000+ Token),Prefix Caching的收益尤其显著。


18. 如何计算部署一个70B模型需要多少GPU?

计算步骤:

1. 模型权重显存:

  • FP16: 70B × 2 bytes = 140GB

  • INT8: 70GB

  • INT4: 35GB

2. KV Cache显存(以LLaMA-2 70B GQA为例):

  • 单请求4K上下文 ≈ 1GB(FP16)

  • 目标并发32请求 → 32GB KV Cache

3. 其他开销:

  • 激活值临时buffer: ~2-5GB

  • CUDA context + 框架开销: ~2-3GB

  • 安全余量: ~10%

4. 总显存 = 权重 + KV Cache + 其他:

  • FP16: 140 + 32 + 5 + 3 ≈ 180GB → 需要3×A100 80GB(TP=4更稳妥)

  • INT8: 70 + 32 + 5 + 3 ≈ 110GB → 需要2×A100 80GB(TP=2)

  • INT4(AWQ): 35 + 32 + 5 + 3 ≈ 75GB → 1×A100 80GB勉强够(并发受限)

实际推荐:

场景 GPU配置 量化
高吞吐生产 4×A100 80GB, TP=4 FP16
标准生产 2×A100 80GB, TP=2 INT8
成本敏感 1×A100 80GB INT4(AWQ)
消费级 2×RTX 4090 24GB INT4(GPTQ)

关键提醒: TP数最好是2的幂(2/4/8),且需要NVLink连接。没有NVLink的多卡部署(如PCIe)因通信瓶颈性能会下降30-50%。


19. 推理服务的降级策略?

流量过载时的降级优先级(从轻到重):

Level 1 — 请求管理:

  • 限流(Rate Limiting):超过QPS阈值的请求返回429

  • 排队超时:等待超过10s的请求直接拒绝,避免用户重复提交

  • 优先级队列:VIP用户/付费用户优先处理

Level 2 — 输出限制:

  • 减少max_tokens:从4096降到2048或1024

  • 提高Decode终止阈值:更早触发停止条件

  • 效果:每请求GPU时间减少50%,可支撑更高QPS

Level 3 — 模型降级:

  • 将部分流量路由到更小的模型(70B→13B→7B)

  • 或切换到量化更激进的版本(FP16→INT4)

  • 精度下降但延迟大幅改善

Level 4 — 功能降级:

  • 关闭耗资源的功能:停用Beam Search、降低采样温度为0(贪心解码,无需多次采样)

  • 关闭Tool Calling(减少多轮推理)

  • 返回缓存结果(对高频重复问题)

Level 5 — 熔断:

  • 直接返回预设回答:"系统繁忙,请稍后再试"

  • 保护后端服务不被压垮

最佳实践: 自动化降级配置(根据队列长度自动触发);降级决策在API Gateway层实现;监控降级触发频率,持续触发说明需要扩容;降级恢复也要有cooldown,避免抖动。


20. 2025年推理优化的前沿方向?

1. 长上下文优化(>1M Token):

  • Ring Attention / Striped Attention:跨GPU分布式处理超长序列

  • KV Cache压缩/蒸馏:将历史KV Cache压缩为更少的Token

  • 动态稀疏Attention:只关注重要的历史Token

2. 硬件-软件协同设计:

  • FP8/FP4训练和推理(H100/B100原生支持)

  • 定制化AI芯片(Groq LPU、Cerebras、AMD MI300X)

  • 光互联和CXL内存扩展

3. 推理时计算扩展(Inference-time Scaling):

  • OpenAI o1/o3模型的"思考"策略:推理时用更多计算换更好结果

  • 如何动态决定每个请求的思考深度

  • 与投机采样结合:简单问题快速回答,复杂问题深度推理

4. KV Cache跨请求智能复用:

  • Semantic Caching:语义相似的请求复用KV Cache

  • 多轮对话的增量计算

  • 跨会话的知识持久化

5. 异构推理架构:

  • Prefill和Decode分离到不同硬件(Prefill用高算力GPU,Decode用高带宽设备)

  • CPU offload的智能化(关键层在GPU,辅助层在CPU)

  • Disaggregated Serving:Prefill Server + Decode Server分离部署

6. 端侧推理爆发:

  • 手机/笔记本NPU加速(Apple ANE、Qualcomm Hexagon)

  • 2-3B高质量小模型(Phi-3、Gemma-2B)

  • 混合推理:端侧处理简单请求,复杂请求上云

7. 编译优化:

  • Torch.compile / Triton的持续改进

  • 自动Kernel生成和调优

  • MLIR/StableHLO统一编译基础设施

这些方向正在重塑推理优化的格局,2025年将看到多个方向的落地和成熟。


📅 最后更新:2025年3月 📖 建议配合实际部署vLLM和阅读PagedAttention论文加深理解