SGLang 可以理解为两部分:用于编写复杂 LLM 程序的前端语言 ,以及负责高吞吐、低延迟推理的运行时 SRT(SGLang Runtime)。两者可以独立使用;现在大多数部署场景主要使用 SRT,通过 OpenAI 兼容接口提供模型服务,并不需要使用前端 DSL。
一、整体结构
一次文本推理请求,大致经过下面的链路:
text
客户端
│ HTTP / OpenAI API / Python Engine
▼
API Server
│ 参数解析、Chat Template、请求校验
▼
TokenizerManager
│ 文本 Tokenize、多模态预处理、请求状态管理
▼
Data Parallel Controller(可选)
│ 在多个推理副本之间分发请求
▼
Scheduler
│ 排队、前缀匹配、显存评估、动态组 Batch
▼
TP Worker / ModelRunner
│ 组织模型前向计算、CUDA Graph、分布式通信
▼
模型层 + Attention / MoE / Quantization + KV Cache
│ GPU Kernel:FlashInfer、Triton、sgl-kernel 等
▼
输出 Token
│
▼
DetokenizerManager
│ 增量解码为文本
▼
流式返回客户端
经典 Python 运行时的三个核心组件就是 TokenizerManager、Scheduler、DetokenizerManager:TokenizerManager 负责请求输入和结果聚合,Scheduler 在子进程中调度模型计算,DetokenizerManager 将输出 Token 转回文本,组件之间通过 IPC 通信。
二、源码目录与模块对应关系
| 源码位置 | 主要职责 |
|---|---|
python/sglang/lang/ |
前端 DSL,如 gen、fork、多步生成程序 |
python/sglang/srt/entrypoints/ |
HTTP Server、离线 Engine 等入口 |
python/sglang/srt/managers/ |
Tokenizer、Scheduler、Detokenizer、DP 控制器 |
python/sglang/srt/mem_cache/ |
RadixCache、KV Cache 池、分层缓存 |
python/sglang/srt/model_executor/ |
ModelRunner、模型执行和 CUDA Graph |
python/sglang/srt/models/ |
Llama、Qwen、DeepSeek 等模型实现 |
python/sglang/srt/layers/ |
Attention、MoE、量化、采样等基础层 |
python/sglang/srt/speculative/ |
投机解码相关实现 |
python/sglang/multimodal_gen/ |
图像、视频等 Diffusion 生成 |
sgl-kernel/ |
高性能 CUDA/C++ 计算内核 |
sgl-router/、sgl-model-gateway/ |
多实例路由、负载均衡和网关 |
rust/ |
部分高性能 Rust 扩展 |
前端 DSL 与核心运行时代码分别位于 lang/ 和 srt/,这也是阅读源码时最清晰的边界。
三、最核心的工作原理
1. Prefill 与 Decode 两阶段
自回归 Transformer 的推理由两个阶段组成:
- Prefill(预填充):一次性处理输入 Prompt,计算每个位置的 Key、Value,并写入 KV Cache。输入越长,首 Token 延迟通常越高。
- Decode(解码):根据已有 Token 和 KV Cache 逐步生成后续 Token。每生成一个 Token,就把新的 KV 加入缓存,避免重复计算整段历史。
因此:
- Prefill 更偏向大规模并行计算;
- Decode 更依赖显存容量、显存带宽和调度效率;
- SGLang 的很多优化都围绕"少做重复 Prefill、提高 Decode 批量、降低调度开销"展开。
2. RadixAttention:跨请求复用 KV Cache
这是 SGLang 最有代表性的设计。
假设很多请求都以同一段系统提示词开头:
text
请求 A:系统提示词 + 问题 A
请求 B:系统提示词 + 问题 B
请求 C:系统提示词 + 问题 C
普通做法是每个请求都重新计算"系统提示词"的 KV。RadixAttention 则将 Token 前缀组织成一棵基数树(Radix Tree),树节点关联相应的 KV Cache:
text
系统提示词
├── 问题 A
├── 问题 B
└── 问题 C
新请求到来时:
- 在树中查找最长匹配前缀;
- 直接复用该前缀的 KV Cache;
- 只对不匹配的后缀执行 Prefill;
- 请求结束后,可将可复用 KV 留在树中;
- 缓存不足时,通过 LRU 等策略淘汰不再需要的节点。
这不仅适用于固定系统提示词,也适用于多轮对话、少样本模板、Agent 重复上下文和树状分支生成。其论文设计就是在 Radix Tree 中保留 KV Cache,并配合缓存感知调度提高命中率。
3. Continuous Batching:持续动态组批
静态 Batch 必须等整批请求全部结束,长请求会拖累短请求。SGLang 的 Scheduler 则以模型迭代为粒度调整运行中的 Batch:
- 完成的请求立即退出;
- 新请求在显存允许时加入;
- 不同请求可以处于不同生成长度;
- 尽量让 GPU 每一轮都有足够多的工作。
同时,Scheduler 不只是"先来先服务",还可以考虑:
- 请求能复用多长的已有前缀;
- 当前 KV Cache 剩余空间;
- 输入和输出长度;
- Prefill 与 Decode 的混合比例;
- 请求优先级及公平性。
缓存感知调度会倾向于让能够复用相同前缀的请求相邻执行,减少缓存抖动和重复计算。
4. Chunked Prefill:拆分长 Prompt
如果一个很长的 Prompt 一次性执行 Prefill,可能长时间阻塞其他请求的 Decode。
Chunked Prefill 将其拆成多个块:
text
长 Prompt Prefill
→ Chunk 1
→ Chunk 2
→ Chunk 3
→ 开始 Decode
调度器可以在块之间安排其他请求的 Decode,从而在以下目标之间取得平衡:
- 长 Prompt 的首 Token 延迟;
- 其他请求的 Token 间延迟;
- 整体吞吐量。
5. ModelRunner 与高性能 Kernel
Scheduler 决定"这一轮算什么",ModelRunner 负责"怎样在 GPU 上高效执行"。
这一层通常包括:
- 加载模型权重和模型结构;
- 准备 Attention 元数据及 KV Cache 索引;
- 选择 FlashInfer、Triton 等 Attention 后端;
- 执行量化、MoE、采样等算子;
- 使用 CUDA Graph 减少重复 Kernel Launch 和 CPU 调度开销;
- 将 CPU 侧调度与 GPU 计算尽可能重叠。
简单说,Scheduler 优化宏观执行顺序,Kernel 和 CUDA Graph 优化单次执行效率。
四、多卡与分布式原理
SGLang 支持多种并行方式,它们解决的问题不同:
| 并行方式 | 原理与用途 |
|---|---|
| TP:张量并行 | 将单层矩阵计算切到多张 GPU,解决单卡放不下模型的问题 |
| PP:流水线并行 | 将不同 Transformer 层放到不同 GPU/节点 |
| DP:数据并行 | 启动多个模型副本,不同副本处理不同请求,提高吞吐 |
| EP:专家并行 | 将 MoE 的不同专家分布到不同 GPU |
| PD 分离 | Prefill 和 Decode 使用不同资源池,通过 KV 传输衔接 |
TP/PP/EP 主要解决模型如何分布 ,DP 主要解决请求如何扩展 ,PD 分离主要解决两种推理阶段的资源特征不同。
五、结构化输出与投机解码
结构化输出
对于 JSON Schema、正则表达式等约束,SGLang 可以将约束转换为状态机或文法状态。在每步采样前,计算当前允许出现的 Token,并屏蔽不合法 Token 的 Logits,从而保证输出符合格式,而不只是依赖 Prompt 提醒模型。
投机解码
投机解码使用较小的 Draft 模型或草稿机制,一次提出多个候选 Token,再由目标模型批量验证:
text
Draft:提出 t1、t2、t3、t4
Target:并行验证
结果:接受连续正确的 Token,拒绝并修正第一个错误 Token
它减少的是目标模型的串行 Decode 步数,但是否加速取决于草稿接受率及额外计算成本。
六、推荐的源码阅读顺序
如果准备结合源码深入理解,可以按下面的顺序:
text
entrypoints/engine.py
↓
managers/tokenizer_manager.py
↓
managers/scheduler.py
↓
managers/schedule_policy.py
managers/schedule_batch.py
↓
managers/tp_worker.py
↓
model_executor/model_runner.py
↓
mem_cache/radix_cache.py
↓
models/ 与 layers/
概括:SGLang 的核心不是某一个单独算子,而是把前缀缓存、请求调度、动态组批、显存管理、模型执行和分布式通信联合设计,以减少重复计算并持续保持 GPU 高利用率。