1. vLLM 为什么快?
核心:PagedAttention + 连续批处理 + 高效调度。
① PagedAttention
传统 KV Cache 要预分配连续显存,碎片多、浪费大。
vLLM 把 KV Cache 分成固定大小的 block,像操作系统分页一样管理,按需分配,减少碎片。
② 连续批处理
传统 batch 要等最长序列跑完才能下一批。
vLLM 允许请求动态进出,GPU 不空转,吞吐大幅提升。
③ 高效调度
请求排队、优先级
显存预占、回收
多请求共享 KV block
一句话:PagedAttention 省显存,连续批处理提吞吐。
2. PagedAttention 原理?
类比操作系统的虚拟内存分页。
传统 KV Cache 的问题
每个请求预分配最大长度显存
实际用不到,浪费
碎片多,无法复用
PagedAttention 做法
把 KV Cache 切成固定大小的block(比如 16 个 token 一块)
每个请求维护一个block table,逻辑块 → 物理块
物理块可以不连续,按需分配
多个请求可以共享物理块(比如相同 prompt)
好处
显存利用率高
支持更大 batch
吞吐提升
一句话:把 KV Cache 分页管理,像 OS 管内存一样。
3. 显存怎么估算?
推理显存 = 模型权重 + KV Cache + 激活 + 框架开销。
① 模型权重
text
权重显存 = 参数量 × 精度字节数
FP16:2 字节
INT8:1 字节
INT4:0.5 字节
例:7B 模型 FP16 = 7e9 × 2 = 14 GB
② KV Cache
text
KV = 2 × layers × heads × head_dim × seq_len × batch × 精度
简化:
text
KV ≈ 2 × layers × hidden × seq_len × batch × 2 字节
例:7B(32 层,hidden 4096),seq 2048,batch 1:
text
2 × 32 × 4096 × 2048 × 2 ≈ 1.07 GB
③ 激活
推理时激活很小,训练时大。
④ 框架开销
CUDA context、临时 buffer,约 1~2 GB。
一句话:权重 + KV + 激活 + 开销。
4. ZeRO 三个阶段?
ZeRO = 把训练状态分片,减少每卡显存。
训练状态有三块:
优化器状态(最大)
梯度
参数
ZeRO-1
只分片优化器状态。
显存降 4 倍(Adam 有 2 个动量 + 1 个方差 + fp32 主权重)。
ZeRO-2
分片优化器状态 + 梯度。
显存降 8 倍。
ZeRO-3
分片优化器状态 + 梯度 + 参数。
显存降与卡数成正比。
代价:通信量增加。
一句话:ZeRO-1 分优化器,ZeRO-2 加梯度,ZeRO-3 加参数。
5. DDP 和 FSDP 区别?
| DDP | FSDP | |
|---|---|---|
| 全称 | DistributedDataParallel | FullyShardedDataParallel |
| 参数 | 每卡一份完整 | 分片 |
| 梯度 | 每卡一份完整 | 分片 |
| 优化器 | 每卡一份完整 | 分片 |
| 显存 | 高 | 低 |
| 通信 | AllReduce 梯度 | AllGather + ReduceScatter |
| 适合 | 小模型 | 大模型 |
| 本质 | 数据并行 | ZeRO-3 实现 |
一句话:DDP 每卡全量,FSDP 分片,省显存但通信多。
6. 量化怎么做?精度损失?
常见方式
| 方式 | 说明 |
|---|---|
| PTQ | 训练后量化,简单 |
| QAT | 训练时量化,精度好 |
| GPTQ | 逐层量化,用校准数据 |
| AWQ | 激活感知,保护重要权重 |
| GGUF | llama.cpp 用,CPU 友好 |
| FP8 | 新硬件支持 |
精度损失
| 精度 | 损失 |
|---|---|
| FP16 → INT8 | 很小,通常 <1% |
| FP16 → INT4 | 有,2~5% |
| FP16 → FP8 | 很小 |
关键:校准数据要覆盖真实分布。
一句话:PTQ 简单,QAT 精度好,INT8 损失小,INT4 损失大。
7. 怎么提高吞吐?
吞吐 = 单位时间处理的 token 数。
方法
连续批处理:请求动态进出
增大 batch:提高 GPU 利用率
PagedAttention:省显存,支持更大 batch
量化:省显存,提高并发
张量并行:多卡分担
Prefill / Decode 分离:不同阶段不同优化
投机解码:小模型草稿,大模型验证
KV Cache 复用:相同 prompt 共享
一句话:连续批处理 + 大 batch + 量化 + 并行。
8. 怎么降低延迟?
延迟 = 首 token 时间 + 每 token 时间。
首 token 延迟(TTFT)
Prefill 优化
减少 prompt 长度
并行 prefill
每 token 延迟(TPOT)
减少 KV Cache 读取
量化
算子融合
投机解码
减少 batch(batch 大延迟高)
一句话:Prefill 优化降首 token,Decode 优化降每 token。
9. NCCL 通信原理?
NCCL = NVIDIA Collective Communications Library,多卡通信库。
核心操作
| 操作 | 作用 |
|---|---|
| AllReduce | 所有卡求和,结果广播 |
| AllGather | 收集所有卡数据 |
| ReduceScatter | 求和后分片 |
| Broadcast | 广播 |
| AllToAll | 全交换,MoE 用 |
通信方式
Ring:环形,适合大消息
Tree:树形,适合小消息
NVLink:卡间高速
RDMA:跨机
关键
拓扑感知
通信与计算重叠
梯度压缩
一句话:NCCL 是多卡通信库,核心是 AllReduce,靠 Ring/Tree 和 NVLink/RDMA。
10. 怎么排查 OOM?
OOM = Out Of Memory。
排查步骤
看是哪块显存爆了
权重
KV Cache
激活
临时 buffer
看是训练还是推理
训练:激活大
推理:KV 大
常用手段
减小 batch
减小序列长度
梯度累积
梯度检查点
混合精度
ZeRO / FSDP
量化
offload
工具
torch.cuda.memory_summary()nvidia-smiPyTorch Profiler
常见原因
显存碎片
泄漏(没释放)
batch 太大
序列太长
一句话:先定位哪块爆,再减 batch/序列,上 ZeRO、量化、offload。
快速复习表
| 题 | 关键词 |
|---|---|
| vLLM 快 | PagedAttention + 连续批处理 |
| PagedAttention | KV 分页,按需分配 |
| 显存估算 | 权重 + KV + 激活 + 开销 |
| ZeRO | 1 优化器,2 加梯度,3 加参数 |
| DDP vs FSDP | 全量 vs 分片 |
| 量化 | PTQ/QAT,INT8 损失小,INT4 大 |
| 吞吐 | 连续批处理 + 大 batch + 量化 |
| 延迟 | Prefill + Decode 分开优化 |
| NCCL | AllReduce,Ring/Tree,NVLink |
| OOM | 定位 + 减 batch + ZeRO/量化 |