SGLang 专项:36 道面试题与系统设计
白话导读:SGLang 方向的 36 道题:执行基础、KV 正确性与分层缓存、分布式与系统设计。
- 重点题:PagedAttention 与 RadixAttention 的区别、完整命中后是否还要计算、MLA 与 Mamba 的缓存差异。
- 与专家深挖问答重叠的题,以深挖问答为主答案。
复杂模型相关题配合复杂模型与 KV 存储阅读。
回答结构建议:结论 → 原理 → 适用条件 → 验证方法。涉及版本支持时,区分算法能力、框架能力和当前引擎 connector 的能力。
一、推理与执行基础
1. Prefill 与 Decode 有什么区别?
Prefill 处理输入序列并产生历史 KV,通常也产生首个输出 token 所需 logits;Decode 基于已有 KV 继续逐步生成。
两者的矩阵形状、算术强度、资源访问和延迟特征不同。Prefill 常有较高计算效率,小 batch Decode 常受读取带宽限制,但实际瓶颈需要 profiling。
追问:首 token 是否需要额外 Decode?通常 Prefill 已提供所需 logits,不能统一多算一步。
2. Decode 为什么经常受带宽限制?
每步只为每个请求产生少量新 token,却需要读取大量模型权重和历史 KV,FLOPs/byte 较低。提高 batch 可摊薄权重读取,但也增加 KV 流量和计算。
大 batch、长上下文、量化或多卡通信会改变主导瓶颈。不能用“Decode 永远 memory-bound”代替测量。
3. 为什么缓存 K/V,通常不缓存 Q?
未来位置的 Query 要读取历史 K/V,历史 Query 通常不再用于未来 Attention。在因果模型中,新增后续 token 不会改变历史 K/V。
这不代表未来 token 无需计算 Attention;它仍要生成自己的 Q/K/V 并读取历史状态。
4. 如何估算 KV 显存?
标准 Full Attention 用:
2 × 层数 × KV heads × head dimension × 每元素字节数 × 总缓存 token 数。
要区分 KV heads 与 Query heads,考虑共享物理前缀、分页、scale、混合状态和并行切分。每 rank 用其实际持有的数据计算。
例子:32 层、8 KV heads、128 维、BF16,每 token 128 KiB,8192 token 约 1 GiB。
5. FlashAttention 为什么快?
通过分块和在线 softmax 等手段降低 HBM 访问,避免完整 Attention 中间矩阵落地,提升数据复用。
它在数学上保持原 Attention,但浮点顺序变化不保证 bitwise 一致。具体速度取决于 shape、硬件、dtype 与 backend。
6. PagedAttention 与 RadixAttention 有什么区别?
PagedAttention 重点是动态 KV 的分页管理与访问;RadixAttention 重点是用前缀树查找和复用已有 KV。
两者分别处理物理组织与逻辑复用,可以结合。不能因为一个系统采用 radix tree 就认为它不需要分页或 slot 分配。
7. Continuous batching 的收益是什么?
在迭代边界加入新请求、移除已完成请求,减少静态 batch 因长度不同造成的空闲。
收益受请求供给、KV 容量、调度预算和模型效率影响;还需兼顾公平性、排队和尾延迟。
8. Chunked prefill 越小越好吗?
不一定。小 chunk 缩短一次 Prefill 对 GPU 的占用,降低 Decode 被阻塞时间,但增加调度与 kernel 开销,可能降低矩阵计算效率。
应使用混合负载扫描 chunk size,以满足 ITL/TTFT SLO 的 Goodput 判断。
9. 重叠调度能消除自回归依赖吗?
不能。它让 CPU 准备、结果处理和 GPU 执行等工作重叠,仍需遵守 token 依赖、stream/event 同步和内存生命周期。
回答源码时,可对照 event_loop_normal 与 event_loop_overlap,说明结果队列与同步边界,而不是仅说“异步所以快”。
10. CUDA Graph 为什么可能不加速?
如果大 kernel 或通信主导,launch 开销比例小;shape 变化、padding、capture 资源和不支持的控制路径也限制收益。
验证时比较 GPU 空隙、CPU launch 时间、额外内存和端到端性能,不能只看是否开启开关。
11. 为什么 Radix 节点需要拆分?
压缩节点可能包含多个 token。新请求在节点中间结束或发生分叉时,需要显式建立公共边界,才能正确表示共享前缀和不同后缀。
拆分还要正确更新物理索引、父子关系、引用和组件状态。
12. 请求结束为什么不立即释放所有 KV?
请求结束只是活跃使用结束,KV 仍可能作为前缀缓存为未来请求复用。应释放请求引用和私有资源,再由缓存策略决定何时回收。
仍在执行的计算或 I/O 引用也必须保留到安全边界。
二、KV 正确性与分层缓存
13. 文本相同是否一定能命中?
不一定。需要比较实际 token IDs、前文、位置和模型计算语义。模板、空白、分词、多模态输入和 LoRA 都可能改变状态。
即使语义兼容,页面边界、淘汰、命名空间和数据未就绪也会影响命中。
14. 完整 Prompt 命中后是否完全不用计算?
不一定。系统通常保存 KV,未必保存末位置 hidden state 或 logits,可能需要重算最后一个 token 来取得输出分布。
页面对齐、组件有效性和具体实现也会导致部分尾部重算。要看真实执行与少算 token 数。
15. 分布式缓存 key 应包含什么?
需要覆盖模型与前缀计算身份、格式兼容性和隔离域。常见方式是带历史信息的链式 hash 加命名空间。
重点考虑模型版本、token/位置语义、适配器、多模态状态、dtype、layout、分块与并行兼容性。只 hash 当前文本块不够。
命名空间不代替认证与访问控制。
16. RAG 文档块能否放在任意位置复用 KV?
标准因果 Attention 下,块的状态依赖前文和位置,不能直接保证等价复用。
需要专门的计算机制或选择性重算,例如研究 CacheBlend,并单独验证任务质量、模型和引擎支持。不能把非前缀复用当成普通 prefix caching。
17. GQA 为什么减少 KV?
多个 Query heads 共用较少 KV heads,降低缓存容量和读取量。
实际加速取决于 kernel、并行复制和其他瓶颈。计算容量时应使用 KV head 数。
18. MLA 能直接套 GQA 的公式吗?
不能。MLA 可能缓存压缩 latent 和位置相关分量,需要按实际物化 pool 的 shape、dtype 与 rank 分布估算。
部分实现中状态会在 attention TP ranks 间复制,所以不能盲目除以 TP size。
19. Mamba 缓存与普通 KV 有何区别?
Mamba/SSM 主要维护递归状态,分支恢复涉及 checkpoint 和 COW,生命周期与 Full Attention 逐 token KV 不同。
混合模型恢复前缀时,Full、SWA、SSM 等相关状态都必须满足有效性条件。
20. KV FP8 一定更快吗?
不一定。容量与读取字节减少,但 scale、转换、kernel 支持和数值误差可能抵消收益。
应同时测任务质量、显存、吞吐和尾延迟;不能仅按理论压缩倍率给速度结论。
21. HiCache 如何提高复用?
把可复用缓存从 GPU 扩展到 Host 与外部后端,增加可保留前缀的容量,并通过预取和异步传输争取隐藏加载时间。
收益取决于命中、实际少算的计算、查找与传输成本,以及并发争用。
22. 同机两个 SGLang 实例共享 HiCache L2 吗?
常规 HiCache L2 属于实例私有 Host 内存,不会自动共享。
跨实例复用需要配置共享后端,并保证命名空间、模型与 KV 格式兼容。增大 ratio 不是把其他机器的内存变成自己的 L2。
23. Mooncake Transfer Engine 与 Store 有何区别?
TE 负责已知内存区域间的高效传输;Store 负责对象查找、放置、副本、租约、淘汰等,并使用传输层搬运数据。
PD 可以只用 TE;部署 TE 不等于已经具备跨请求共享缓存。
24. LMCache 与 Mooncake 是竞争关系吗?
部分能力有交集,但所处层次不同。LMCache 是缓存中间件与服务,Mooncake 提供传输和分布式存储基础设施。
LMCache 可以用 Mooncake Store 后端。应画清所选路径,避免双重管理和错误配置。
三、系统、性能与工程判断
25. 当前 SGLang 能同时开 HiCache 与 LMCache 吗?
本手册对应工作区明确互斥。
当前 LMCache 集成还限制投机解码、Attention DP、DCP>1、streaming session、PD 等组合。答案应附版本范围,以实际校验代码为准,而非把它说成永久限制。
26. 命中率提高,TTFT 为什么变差?
远端查询、排队、传输、H2D、布局转换和同步可能超过省下的计算;也可能存在无效预取、队头阻塞或争用。
分层统计命中来源、少算 token、传输字节和关键路径时间。缓存收益不应只用命中率衡量。
27. 200 Gb/s 传 1 GiB 至少多久?
理论带宽 25 GB/s,约 43 ms,尚未计协议、排队、H2D 与同步。
Gb/s 与 GB/s 相差 8 倍,还要区分 GB 和 GiB。实际测量应使用有效带宽和暴露在关键路径的时间。
28. 什么情况下适合 PD 分离?
Prefill/Decode 干扰明显、阶段 SLO 和资源配置不同、互联足够好时值得考虑。
短输入、低负载、小模型或弱网络下,新增传输和编排可能超过收益。需要相同总 GPU 预算的对照实验。
29. 缓存节点故障怎么办?
对可重算的输入前缀,可将不可用缓存视为 miss 并重算,但具体自动降级能力要核对实现。
不能使用不完整或版本不匹配的数据。活跃 Decode 状态丢失可能需要重放或终止,不能一概按普通 cache miss 处理。
30. 异步回写有哪些正确性风险?
源 buffer 提前复用、目标未写完就发布、取消后悬挂引用、旧会话继续写入新 buffer、版本命名空间污染。
需要明确所有权、引用、完成状态、原子可见性、幂等与超时清理。提交成功不等于目标已可读。
31. TP 与服务副本 DP 如何选择?
TP 解决单模型容量和部分计算,但增加通信;服务副本 DP 提高整体吞吐,但复制权重并分散缓存。
要结合模型容量、单请求 SLO、吞吐、缓存局部性和拓扑选择。另需区分 Attention DP 等模型内部并行。
32. MoE 激活参数少,为什么可能仍然慢?
专家权重驻留、路由不均、较小专家 GEMM、dispatch/combine 与 All-to-All 可能成为瓶颈。
同时分析激活计算、总权重、专家负载、通信和拓扑,不仅看 active parameter 数。
33. GPU 利用率低如何排查?
先确认请求供给和客户端限流,再看 Tokenizer、CPU 调度、kernel 间隙、拷贝、通信、同步和缓存加载。
先复现、分阶段测量,再做单变量实验。GPU 利用率本身不能证明具体瓶颈。
34. 开缓存后输出错误如何定位?
固定输入、版本与配置,对比无缓存路径。检查 key、token、位置、dtype/layout、LoRA、混合状态和异步生命周期。
必要时比较分层输出或 logprob,定位首次分歧。考虑浮点误差,但不能以“数值误差”掩盖系统性错位或旧缓存复用。
35. SGLang 一定比 vLLM 快吗?
不存在脱离 workload 的统一结论。需要固定模型、硬件、精度、并行、缓存状态、长度分布、到达率和 SLO。
比较端到端性能、质量、功能与资源成本,解释适用条件。不同框架或版本的默认设置不一定等价。
36. 如何设计长上下文 RAG 推理集群?
先定义输入/输出分布、复用率、峰值到达率与 SLO,再估算权重、KV 与传输成本。
设计稳定前缀、缓存感知路由、分层缓存与可选 PD;补齐限流、隔离、超时、取消、降级和可观测性;用冷、热、突发和故障场景验证 Goodput。
四、系统设计题的完整回答顺序
题目示例:为长上下文 RAG 和多轮 Agent 服务设计推理集群,要求控制首 token 与流式延迟。
1. 澄清 workload
- 输入和输出的 p50/p95/p99 长度。
- 到达率、突发性与并发。
- 公共系统提示词、文档和多轮历史的复用比例。
- 模型、精度、LoRA、多模态与租户要求。
2. 明确 SLO 与预算
- TTFT、ITL 或 TPOT 的测量边界与分位数目标。
- 错误率、拒绝率与超时。
- GPU、Host 内存、网络和成本约束。
3. 建立容量模型
- 权重、KV、workspace、Graph 与通信内存。
- 给定长度下的可容纳请求数。
- 每个请求取回或移交多少 KV。
- 网络是否能支持目标请求率。
4. 选择执行与并行
- 单体 serving 是否已满足目标。
- 是否存在需要 PD 解决的干扰。
- TP、服务副本、EP 等如何放置。
- P/D 资源比例如何随负载调整。
5. 设计缓存
- GPU、Host、外部容量与页面大小。
- 模型版本、格式和租户命名空间。
- 写入、预取、超时与淘汰策略。
- 什么情况下直接重算。
6. 设计路由
兼顾缓存局部性与排队。请求全挤到命中率最高的节点可能导致更差的 TTFT。需要考虑预计等待、加载、剩余计算与会话需求。
7. 设计失败路径
- 外部缓存 miss、超时或不可用。
- 在途传输时取消。
- Worker 退出与活跃状态丢失。
- 模型升级与旧缓存清理/隔离。
- 重试、配额、背压和拒绝。
8. 验证
固定对照组,测试冷启动、稳态、热点变化、突发与故障,报告 Goodput、质量和成本,不只报平均 token/s。
五、项目讲述模板
我先定位了特定输入和负载下的瓶颈,再通过源码确认调度与缓存路径,设计控制变量实验。结果显示某项配置在特定复用比例和并发下改善了 TTFT 或 Goodput;另一种负载下因为传输或排队成本增加,收益消失。我据此给出适用条件、容量预算与回退方案。
每个“结果”都应由实际完成的实验支持。没有执行的部分,应明确说成设计或推演。
六、最后的易错点速记
- Request finished 不等于 KV 全部释放。
- Cache lookup hit 不等于 GPU ready。
- 命中 token 比例不等于 Prefill 时间节省比例。
- Zero-copy 不等于零带宽或零 CPU 开销。
- HiCache L2 不自动跨实例共享。
- LMCache 的 L1 与 HiCache 的 L1 命名不同。
- Mooncake TE 不等于 Mooncake Store。
- 算法支持不等于当前 connector 支持。
- 更高吞吐不一定意味着更高 SLO Goodput。
- 论文收益不是自己部署的性能承诺。