一句话结论
推理引擎选型要看调度、KV cache、batching、并行、量化、部署生态和可观测性,不是只比较吞吐。
复习定位
| 维度 | 内容 |
| 所属模块 | LLM 推理系统 |
| 章节类型 | 机制类 |
| 解决问题 | 围绕请求生命周期、Prefill/Decode、KV Cache、Attention 优化、Serving Engine 和性能瓶颈建立系统化面试答案。 |
| 面试抓手 | 把 vLLM、TensorRT-LLM、SGLang、TGI 的定位讲清楚。 |
AI Infra 视角:推理引擎 = 调度器 + 内存系统 + 计算后端 + 分布式策略 + Serving 工程
面向应用的人只需要会用 vLLM 启服务;做 AI Infra 必须能讲清楚引擎内部的请求调度、KV 内存管理、CUDA Kernel 选择、并行切分和容错。下面把推理引擎拆成 5 个子系统,每个子系统直接给出原理、关键数据结构、源码定位和实战要点。
掌握深度分层
| 层级 | 定位 | 典型岗位 | 必须能回答 |
| L1 会用 | 启服务、调参、压测 | 算法工程师 | 怎么起 vLLM、怎么调 max-num-seqs |
| L2 会调优 | 读懂指标,定位瓶颈 | 应用侧 Infra | TTFT 高怎么排查、batch 满了为什么吞吐反降 |
| L3 懂原理 | 解释 PagedAttention、continuous batching、chunked prefill | AI Infra 初级 | KV 块为什么分页,prefill 和 decode 怎么共存 |
| L4 会改源码 | 读 vLLM/SGLang 调度器,写自定义 sampler、kernel | AI Infra 中高级 | vLLM Scheduler 的 waiting/running/swapped 状态机 |
| L5 能设计 | 从零设计推理系统、做 PD 分离、做多机调度 | 资深 / 专家 | 千卡 serving 集群怎么做请求路由、KV 迁移、容灾 |
AI Infra 岗一般要求 L3-L4,资深岗要求 L4-L5。
子系统一:调度器(Scheduler)
调度器决定每个 forward step 跑哪些请求。vLLM 的 Scheduler 是 Python 实现,核心数据结构是三个队列 + 一组 SequenceGroup 状态机。
状态机:每个请求是一个 SequenceGroup,状态在 WAITING → RUNNING → SWAPPED → FINISHED 之间迁移。WAITING 在 waiting 队列里排队等显存;RUNNING 进入 running 队列每个 step 参与 forward;显存不够时被抢占,KV 丢弃则回到 WAITING(recompute),KV 拷到 CPU 则进入 swapped 队列(swap)。
调度循环:每个 step 调用 schedule(),先尝试唤醒 swapped,再调度 running 的 decode,再用剩余 token budget 调度 waiting 的 prefill;预算由 max_num_batched_tokens 限制,并发由 max_num_seqs 限制。
抢占:当 running + 新 prefill 总 KV 块超过可用块时,按 FCFS 反向抢占最近加入的请求;抢占策略 recompute(默认,丢 KV 重算)或 swap(拷到 CPU pinned memory)。
源码:vllm/core/scheduler.py 的 _schedule_default()、_schedule_chunked_prefill()、_preempt();SGLang 在 python/sglang/srt/managers/scheduler.py,使用 RadixAttention 前缀树而非简单队列。
子系统二:KV Cache 内存管理(PagedAttention 详解)
KV Cache 是显存第一稀缺资源。PagedAttention 把 KV 像 OS 虚拟内存一样按 block 管理,把碎片率从 60-80% 压到 < 4%。
核心数据结构:
BlockManager:维护物理 block 池(gpu_blocks、cpu_blocks),用 free list 管理空闲块,引用计数管理共享。
BlockTable:每个 SequenceGroup 一张表,逻辑块号 → 物理块号。生成新 token 时,logical_block_id = pos // block_size,满了就 allocate 一块新物理块挂到表尾。
block_size:默认 16。太小 block table 大、kernel 访存碎;太大内部碎片回到老问题、prefix 共享粒度变粗。
Copy-on-Write:parallel sampling / beam search 共享前缀块,引用计数 > 1;任一分支要写入时,先 copy 一份再写,引用计数减一。这就是 vLLM 比 HuggingFace generate 在 beam=4 时省 4 倍显存的原因。
Prefix Cache:对相同前缀(系统提示词、few-shot)的物理块加哈希签名,跨请求复用,命中后 prefill 阶段直接跳过这些块的计算。开关:enable_prefix_caching=True;命中率指标:vllm:gpu_prefix_cache_hit_rate。
FP8 KV:显存减半,可翻倍 batch 或上下文长度。需要 SM89+(Ada/Hopper),attention kernel 需支持 FP8 反量化;长上下文(>32k)和数学/代码任务要做精度回归。
子系统三:计算后端与 Kernel
同一算法不同 kernel 实现吞吐能差 2-5 倍。AI Infra 必须能看懂下面这些 kernel 的优化点。
FlashAttention v2:把 attention 拆成外层 query block、内层 K/V block,按 K/V 维度做 online softmax,所有中间 S=QK^T、P=softmax(S) 不落 HBM,全部留在 SRAM;并行维度从 batch×head 加到 batch×head×seq_q,长序列也能打满 SM。
FlashAttention v3:针对 H100。① warp specialization(生产者 warp 跑 TMA load,消费者 warp 跑 GEMM/softmax);② async copy(TMA + cp.async)让 load 和 compute overlap;③ FP8 路径用 incoherent processing 抵消量化误差;典型 H100 SXM 上接近 75% MFU。
PagedAttention kernel:不同于 FlashAttention 的 contiguous KV,它每个 query token 要按 block table 间接寻址 KV 块;用 __ldg 做 read-only cache,每个 thread block 处理一个 query token 的多个 head,KV 按 block 顺序加载。
FlashInfer:把 PagedAttention + FlashAttention 合并实现,支持 ragged batch、多种 KV layout(NHD/HND)、动态 block size,vLLM v0.6+ 默认 backend 之一。
CUDA Graphs:decode step 形状固定(batch_size 一定时 input shape 不变),把整个 step 的 kernel launch 序列录成 graph,replay 一次替代上百次 launch;Llama-3-8B BF16 在 A100 上能减 10-15% 延迟。前提是 input shape 不能变,所以 vLLM 给常用 batch_size 各 capture 一份。
算子融合:fused RMSNorm + QKV proj、fused SiLU + gate proj、fused MoE(top-k + dispatch + grouped GEMM);TensorRT-LLM 通过 plugin 把 attention + rotary + KV append 融成一个 kernel。
子系统四:并行与分布式策略
大模型推理必然涉及多卡多机,下面是 4 种并行的具体含义和通信开销。
Tensor Parallel(TP):按列切权重矩阵。Attention:QKV 投影按 head 切,attention 内部不通信,output 投影按行切,每层 attention 末尾一次 all-reduce。FFN:第一层按列切,第二层按行切,FFN 末尾一次 all-reduce。每层 2 次 all-reduce,单 token 通信量 ≈ 2 × hidden_dim × dtype_size。Llama-70B TP=8 在 A100 NVLink 上 all-reduce 占 forward 时间 15-25%;跨机走 IB 会到 50%+,所以 TP 不跨机。
Pipeline Parallel(PP):按层切到不同 GPU,micro-batch 流水。推理 decode 阶段每次只生成 1 个 token,micro-batch 数受限,bubble 严重,所以推理很少单独用 PP,通常和 TP 混合或仅用于跨机。
Expert Parallel(EP):MoE 模型把专家分到不同 GPU。每层 2 次 all-to-all:dispatch(按路由结果把 token 发给对应 expert 卡)、combine(算完再聚回原卡)。瓶颈是 all-to-all 跨机带宽和路由不均;DeepSeek 用 DeepEP 在 H800 NVLink 上做了大量优化,redundant experts 解决热点。
Data Parallel(DP):多副本,配请求路由层;推理服务的横向扩展默认就是 DP。Attention DP + FFN/MoE EP 是当前 MoE 大模型部署的常见组合(SGLang/DeepSeek-V3)。
Sequence Parallel:长上下文场景把序列维度切到不同卡,配合 Ring Attention 或 Striped Attention 做 KV 通信,主要解决单卡放不下超长 prompt 的 KV。
子系统五:Serving 工程化
这部分决定能不能扛生产流量。
01
HTTP/gRPC 入口
接收请求、鉴权、限流和协议适配
02
Tokenizer
独立进程或 worker 处理文本,避免阻塞 GPU 调度
03
调度器队列
排队、batching、KV Cache 预算和优先级决策
04
Forward
GPU worker 执行 prefill/decode 前向计算
05
Detokenizer
逐 token 反解码,准备流式输出
06
SSE/WebSocket 推流
按协议持续返回增量结果
OpenAI 兼容协议:路径 /v1/chat/completions、/v1/completions、/v1/embeddings;流式用 SSE,data: {...}\n\n,结束 data: [DONE]。tool calling、structured output(JSON schema、正则约束)走 Outlines/XGrammar。
核心指标(Prometheus):
vllm:time_to_first_token_seconds:TTFT 直方图,p50/p95/p99 都要看。
vllm:time_per_output_token_seconds:TPOT。
vllm:e2e_request_latency_seconds:端到端。
vllm:request_queue_time_seconds:队列时长,TTFT 涨先看这个。
vllm:num_preemptions_total:抢占次数,常见瓶颈信号。
vllm:gpu_cache_usage_perc、vllm:gpu_prefix_cache_hit_rate:KV 占用与命中。
vllm:num_requests_running/waiting/swapped:三队列长度。
容错与隔离:OOM 自救(recompute/swap)、单卡 NCCL timeout 检测踢出、慢节点用 p99 兜底、超长请求隔离独立队列防尾延迟、请求级超时和取消(client 断开后调度器要立刻 abort 释放 KV)。
滚动升级:weight 持久化到本地 NVMe,新副本起来读完再切流量;KV 一般不持久化(除非 PD 分离场景做 KV migration)。
关键技术点 1:Continuous Batching
调度粒度从 request 级降到 iteration(token)级。Static batching 整批进出,最长那条没结束全 batch 都得等;continuous batching(Orca OSDI'22 提出)每个 forward step 都重组 batch:完成的请求立即返回 finish 槽位,等待中的请求立即加入。
关键实现点:① 不同请求 KV 长度不同,必须配 PagedAttention 这种支持 ragged batch 的内存管理才能真正落地;② 每个 step 重新构建 attention mask 和位置索引;③ token budget 控制单 step 最多处理 N 个 token,避免 prefill 把 step 拉爆。
瓶颈:当 batch 已打满 token budget 或 KV 块用满,新请求触发 preemption;max_num_batched_tokens 太小吞吐上不去,太大 TPOT 抖动。Llama-3-8B BF16 在 H100 上典型设 8192-16384。
关键技术点 2:Chunked Prefill
Prefill 是 compute-bound,单条 8k prompt 一次 forward 把 GPU 占满几百毫秒,期间 decode 的 TPOT 直接卡死,造成尾延迟。Sarathi-Serve 提出把 prefill 拆 chunk。
算法:每个 step 给一个 token budget(如 2048),先用 decode 请求填(每个 decode 1 token),剩余预算用来跑 prefill chunk;长 prompt 分多个 step 完成 prefill。
收益:① decode 的 TPOT 抖动从几百毫秒降到几十毫秒;② GPU 利用率提升(prefill chunk 把 decode 的 memory-bound 间隙填上,变成 compute + memory 混合);代价是单条 prefill 总耗时略涨(多次 kernel launch 和 attention mask 重建)。
开关:vLLM --enable-chunked-prefill,v0.6 起默认开启;chunk 大小由 max_num_batched_tokens 控制。
关键技术点 3:PD 分离(Disaggregated Prefill-Decode)
Chunked Prefill 治标不治本:prefill 和 decode 仍共享同一组 GPU,扩缩容耦合。DistServe(OSDI'24)和 Splitwise(ISCA'24)提出物理拆分。
架构:① Prefill 集群:高算力卡(H100/H200),追求 TTFT,TP 较大、batch 较小。② Decode 集群:可以用算力略低但显存大的卡,追求吞吐和 TPOT,batch 大、KV 多。③ KV 传输:prefill 完后通过 NVLink/RDMA 把整段 KV 传给 decode 节点;H100 NVLink 900GB/s、CX-7 IB 400Gb/s,10k token Llama-70B 的 KV ~1.4GB,传输 < 5ms。
关键工程问题:① 路由层要根据 prompt 长度和当前两端负载决定走哪个 prefill 节点;② KV layout 跨节点要兼容,常用 NVSHMEM 或自研 RDMA 库;③ decode 节点要能接收 streaming KV,第一块到了就能开始 decode 第一个 token,进一步压低 TTFT。
vLLM/SGLang 实现:vLLM v0.6+ 实验性支持 disaggregated serving;DeepSeek/月之暗面/Mooncake 都是 PD 分离生产实践。
关键技术点 4:投机解码(Speculative Decoding)
Decode 是 memory-bound,瓶颈在权重从 HBM 读到 SM。一次 forward 验证多个 token 几乎不增加权重读取,是无损加速的关键洞察。
原理:用便宜的 draft 模型生成 K 个候选 token,大模型对 K+1 个位置并行做一次 forward,得到大模型在每个位置的真实分布;按拒绝采样接受最长前缀,第一个被拒绝的位置用大模型分布重采样。数学上等价于直接从大模型采样,无损。
变体:
- Draft model:用一个小模型(如 Llama-1B 配 Llama-70B),简单但 draft 也要算 forward。
- Medusa:在大模型 last hidden 上接 N 个独立 head 直接预测后 N 个 token,免 draft 模型,但精度依赖 head 训练质量。
- EAGLE / EAGLE-2:把大模型的 hidden state 也喂给 draft,接受率显著高于普通 draft;当前最常用。
- Lookahead Decoding:用 Jacobi 迭代生成 N-gram pool,命中即接受,无需训练。
陷阱:① 接受率低(< 0.5)反而变慢;② batch 越大越没收益(GPU 已 compute-bound);③ 实现复杂,KV 要支持回滚被拒绝位置。
关键技术点 5:MoE 推理与 EP
DeepSeek-V3、Qwen2.5-MoE、Mixtral 8x22B 推动 MoE serving 成为 2025-2026 核心战场。
瓶颈:
- 路由不均:top-k 路由让部分专家成为热点,整 batch 跟着最慢专家走。训练侧用 aux loss 平衡,推理侧用 redundant experts(热门专家放 2 份)。
- all-to-all:每层 2 次 all-to-all(dispatch + combine),跨机 IB 是瓶颈;DeepEP 用 NVLink 做机内、IB 做机间,一次只发非零 token,比 NCCL all-to-all 快 3 倍。
- 显存:专家多激活少,纯 TP 把每个专家都切让 GEMM 太小;EP 每个专家完整放在一卡,配 grouped GEMM 一次算多个专家。
典型部署:DeepSeek-V3 671B 用 Attention DP=32 + Expert Parallel=32(一台 8 卡 H800 跑 8 个专家),prefill 节点和 decode 节点各跑独立 EP 集群。
计算与通信 overlap:每层 attention 算完先发 dispatch all-to-all,同时算下一组的 attention;DeepSeek DualPipe 在训练用,推理也有类似思路。
关键技术点 6:Prefix Cache 与 RadixAttention
多轮对话、Agent、few-shot prompt 有大量共享前缀。Prefix Cache 把相同前缀的 KV 块跨请求复用。
vLLM Prefix Cache:对每个完整 block 做 hash(block_size token 内容 + 前一块 hash),相同 hash 的物理块共享;命中时跳过这些 token 的 prefill 计算。开关 enable_prefix_caching。
SGLang RadixAttention:把所有活跃 KV 块组织成 radix tree(基数树),路径即 token 序列。新请求来时按 token 在树上匹配最长前缀,命中部分直接复用,未命中部分新建子节点。LRU 淘汰叶子;命中粒度比 vLLM 的 block hash 更细,多轮对话场景命中率显著更高。
命中率优化:路由层按 prompt prefix hash 把请求路由到同一实例,命中率从 30% 拉到 80%+;系统提示词命中后 TTFT 几乎为 0。
关键技术点 7:KV 量化(FP8 / INT8)
BF16 KV → FP8 KV 显存减半,可翻倍 batch 或上下文。
方案:
- per-tensor scale:整个 K 或 V 用一个 scale,简单但动态范围大时精度差。
- per-token scale:每个 token 一个 scale,精度更好,主流方案。
- per-channel scale:对 outlier channel 单独 scale,组合 SmoothQuant 思路。
硬件:FP8 需要 SM89+(Ada L40 / Hopper H100/H800/H200);A100 没有 FP8 但可以走 INT8。
精度回归:① 短上下文一般无损;② > 32k 累计误差需要单独评测;③ 数学/代码任务比对话敏感;④ 用业务真实评测集(不是 MMLU)卡 acc/EM/pass@1。
四大引擎深度对比
| 维度 | vLLM | TensorRT-LLM | SGLang | TGI |
| 核心创新 | PagedAttention + continuous batching | NVIDIA 全栈 kernel + plugin | RadixAttention + 前端 DSL | 工程化 + HF 生态 |
| 调度器 | Python,可读性强,社区活跃 | C++ in-flight batcher,半闭源 | Python,前缀树调度 | Rust router + Python server |
| KV 管理 | Paged,block_size 可调,prefix cache(hash) | Paged,FP8 KV,循环 buffer | Radix tree 自动共享 | Paged(早期版本较弱) |
| 量化 | AWQ/GPTQ/FP8/INT8 | SmoothQuant/FP8/INT4 AWQ 全栈 | AWQ/FP8 | BitsAndBytes/GPTQ |
| 投机解码 | 支持(draft / EAGLE / Medusa) | 支持,性能强 | 支持 EAGLE | 较弱 |
| MoE | 支持,EP 持续完善 | 支持,性能优 | DeepSeek 优化最好 | 有限 |
| 多模态 | 较好 | 需要自己接 | 较好 | 有限 |
| 构建复杂度 | 低,pip 装 | 高,需要 build engine、绑版本 | 低 | 低 |
| 定位 | 通用 OSS 默认选项 | NVIDIA 上的极致性能 | 复杂 prompt / agent / 结构化生成 | HF 生态快速上线 |
Q1: 解释 PagedAttention,为什么提升吞吐?block_size 怎么选?
核心:把 KV Cache 像 OS 虚拟内存一样按 block 管理。
解决什么问题
传统按 max_seq_len 给每个序列预留连续显存,浪费严重(内部碎片 + 预分配碎片),实际利用率常 < 40%,并发上不去。
怎么做
逻辑上按 block_size(如 16)分块,物理上不连续,通过 block table 映射。新 token 满一块再申请下一块。共享前缀用引用计数 + CoW。
block_size 选型
太小(1-4):block table 大、attention kernel 访存不友好、调度开销升高。太大(>64):内部碎片回到老问题,prefix 共享粒度变粗。vLLM 默认 16,是 kernel 性能与碎片率的折中。
PagedAttention 把显存利用率从 ~40% 提到 >90%,吞吐提升来自更高的 batch size。
Q2: Continuous Batching 与 Static Batching 区别?
核心:调度粒度从 request 级降到 iteration(token)级。
Static
整批一起进入、一起出去。最长那条没结束全 batch 都得等,GPU 大量空转。
Continuous(Orca / vLLM)
每个 forward step 重新组 batch:完成的立即返回,等待的立即加入。配 PagedAttention,无需 padding 到同长。
瓶颈
batch 打满 token budget 后再加请求触发 preemption,max_num_batched_tokens 要按显存和 SLA 调。
continuous batching 让 GPU 永远在干活,吞吐通常 5-20 倍提升。
Q3: Prefill 和 Decode 一起跑会有什么问题?Chunked Prefill 和 PD 分离怎么解?
核心:两阶段计算特性完全不同,混跑互相伤害。
冲突
Prefill compute-bound,单条长 prompt 把 GPU 占满几百毫秒,期间 decode TPOT 卡顿。Decode memory-bound,单独跑 GPU 利用率低。
Chunked Prefill
把长 prompt 切 chunk,每个 step 拼一段 prefill + 多个 decode 进同一 batch,TPOT 抖动从几百 ms 降到几十 ms。
PD 分离
物理拆两个集群:Prefill 节点专跑首 token,Decode 节点专跑生成;KV 通过 NVLink/RDMA 传输。可独立扩缩容,TTFT 和 TPOT 解耦。
在线服务多用 chunked prefill;超大规模或 SLA 严苛用 PD 分离。
Q4: 投机解码原理?为什么能加速且不损精度?
核心:用便宜 draft 猜 K 个,大模型一次 forward 验证。
原理
Draft 生成 K 个候选 token,大模型对 K+1 个位置并行 forward,按拒绝采样接受最长前缀,第一个被拒位置用大模型分布重采样。数学上等价于直接采样,无损。
为何变快
Decode memory-bound,瓶颈是权重从 HBM 读到 SM。一次 forward 验证 K 个 token 几乎不增权重读取,TPOT 接近降为 1/K(接受率高时)。
变体
Draft model(Llama-1B + 70B);Medusa(多头预测,免 draft);EAGLE(在 hidden state 上 draft,接受率高);Lookahead(Jacobi 迭代)。
提升 1.5-3x 不损精度,但接受率低反而变慢,且 batch 越大收益越小。
Q5: 设计 1k QPS、p99 TTFT < 500ms 的 70B serving 集群
核心:容量估算 + 分层架构 + SLO 拆分。
容量
70B BF16 ≈ 140GB,TP=4 在 4×A100-80G 或 2×H100-80G 跑得动。假设输入 1k、输出 256,单实例 ~30 QPS,需要 ~40 实例 + 余量。
分层
① 接入:LB + 鉴权 + 限流;② 路由:按 prefix hash 路由提高 cache 命中;③ 推理:vLLM 池,开 chunked prefill;④ 长 prompt 独立集群走 PD 分离;⑤ 监控 TTFT/TPOT/queue/preempt/cache hit。
达成 p99 TTFT
chunked prefill 控 chunk size,限单 step token 预算;超长请求隔离独立队列;预留 20% headroom;prefix cache 命中干掉系统提示词的 prefill。
容灾
多 AZ;权重持久化;KV swap 防 OOM;慢节点剔除;金丝雀升级。
设计题给分点:容量、SLO 拆分、瓶颈识别、可观测、容灾,缺一不可。
Q6: vLLM、TensorRT-LLM、SGLang 怎么选?
核心:workload + 硬件 + 团队能力三维决策。
vLLM
OSS 生态最活、上手最快、模型支持最全,适合大多数在线服务和团队,是默认选项。
TensorRT-LLM
纯 NVIDIA GPU、追求极致延迟和吞吐、能接受 build engine 的工程成本,适合大厂自营核心业务。
SGLang
有大量共享前缀、做结构化输出、tool calling、Agent 多轮,RadixAttention 命中红利明显;DeepSeek MoE 部署事实标准。
TGI
团队深度依赖 HF 生态、追求快速上线、性能要求不极致。
先问场景再选引擎,benchmark 永远要在自己 workload 上跑。
Q7: KV Cache 量化收益与风险?
核心:显存换精度。
收益
BF16→FP8 KV 显存减半,可翻倍 batch 或上下文长度;H100 attention kernel 原生支持 FP8。
风险
长上下文(>32k)累计误差放大;数学/代码任务敏感;动态范围大的层要 per-token / per-channel scale。
工程要点
校准集覆盖目标分布;和 weight 量化一起评估;上线前用业务评测集卡精度回归。
FP8 KV 是当前性价比最高的显存优化之一,但要做精度回归。
Q8: MoE 推理瓶颈?EP 怎么部署?
核心:路由不均 + all-to-all 通信。
瓶颈
① 路由不均,热门专家拖累整 batch;② all-to-all 跨机带宽是上限;③ 显存 — 专家多激活少,纯 TP 让 GEMM 太小。
部署
Attention 用 DP+TP,FFN/MoE 用 EP;DeepSeek-V3 671B 用 Attention DP=32 + EP=32。DeepEP 用 NVLink+IB 混合 all-to-all 比 NCCL 快 3x。
优化
专家亲和路由、训练时 aux loss 均衡、热点专家冗余副本、计算与通信 overlap。
MoE serving 是 2025-2026 AI Infra 核心战场,DeepSeek/Qwen/Mixtral 推动 EP 成熟。
Q9: TTFT 高怎么排查?
核心:从入口往后逐层切。
路径
① 网关时延(trace 接入层);② 队列等待(queue depth、是否 waiting);③ Prefill 时长(输入长度、是否 chunk、是否被抢占);④ KV 是否重算(recompute);⑤ Prefix cache 是否命中;⑥ GPU 是否在做别的请求。
指标
vllm:time_to_first_token_seconds、vllm:request_queue_time_seconds、vllm:num_preemptions_total、vllm:gpu_prefix_cache_hit_rate。
TTFT 排查 = 队列 + prefill + 抢占 + 缓存命中四件事。
Q10: vLLM preempt-by-recompute vs preempt-by-swap?
核心:显存不够时怎么腾位置。
Recompute
丢 KV,恢复时重跑 prefill。简单、不占 CPU 内存;长 prompt 重算贵。
Swap
KV 拷到 CPU pinned memory,恢复时拷回。长 prompt 友好;PCIe 带宽是瓶颈,CPU 内存要够。
选择
短 prompt 高吞吐用 recompute;长 prompt 低抢占率用 swap;vLLM 默认 recompute。
理解状态机就理解了 vLLM 调度器一半。
面试自查清单
① PagedAttention 块管理与 CoW;② Continuous batching 状态机;③ Chunked prefill 与 PD 分离的取舍;④ Prefix cache / RadixAttention 命中机制;⑤ 投机解码原理与变体;⑥ TP/PP/EP/SP 切分与通信开销;⑦ KV 量化的精度风险;⑧ MoE 路由与 all-to-all 优化;⑨ vLLM scheduler 状态机与 preemption 策略;⑩ FlashAttention v3 在 H100 上的关键优化(warp specialization、TMA、async);⑪ CUDA Graphs 在 decode step 的收益;⑫ 服务化指标体系与 SLO 分解;⑬ 千卡集群的请求路由、KV 迁移、容灾。
关联模块
GPU 硬件与资源共享:提供 SM、HBM、NVLink、MIG/MPS、利用率诊断等底层直觉。LLM 推理系统:提供 Prefill/Decode、KV Cache、Serving Engine 和推理优化语境。Kubernetes 核心:提供调度、资源模型、控制器和扩展机制。分布式训练 / 调度与集群:提供多卡通信、队列、公平性、拓扑和容错背景。