SGLang Zero-Overhead 调度器与 GPU 显存管理CPU/GPU 重叠调度与三大内存池LLM 推理框架的吞吐量不只取决于 GPU 算力。CPU 端的调度开销和显存的分配策略同样关键。SGLang 在这两个维度上分别做了针对性设计Zero-Overhead Scheduler 让 CPU 调度延迟对 GPU 执行时间零暴露三大内存池则把 GPU 显存按职责切分为独立区域各自可调可控。串行调度的代价传统推理框架中CPU 调度和 GPU 计算是串行执行的。CPU 先完成一轮调度选择请求、前缀匹配、分配显存、排列 batch然后把组好的 batch 交给 GPU 执行前向传播。GPU 算完当前 batch 后又要等 CPU 准备下一个 batch。这段 GPU 空闲等待的时间被称为调度空泡Bubble。在 Decode 阶段这个问题尤其严重。每次前向传播只处理 1 个 tokenGPU 的计算时间很短但 CPU 的调度时间是固定的。实测中CPU 调度延迟占 GPU 单次执行时间的比例可达 10-20%。换句话说GPU 有接近五分之一的算力浪费在等 CPU 上。OverlapThread让 CPU 和 GPU 各干各的SGLang 用一个后台线程 OverlapThread 解决这个问题。核心思路是流水线重叠GPU 执行当前 batch 的同时CPU 在后台准备下一个 batch。GPU: [batch A 计算][batch B 计算][batch C 计算][batch D 计算] CPU: [准备 batch B] [准备 batch C] [准备 batch D] [准备 batch E]当 GPU 正在跑 batch A 的前向传播时OverlapThread 并行完成 batch B 的全部调度工作包括 RadixAttention 前缀匹配、显存分配和请求排序。GPU 算完 A 后直接无缝衔接 B中间没有空泡。这个设计的前提假设是 CPU 的调度耗时不超过 GPU 的单 batch 计算时间。在 Decode 阶段这个条件天然成立GPU 即使只算 1 个 token 的前向传播也涉及整个模型权重的矩阵运算耗时远大于 CPU 的调度逻辑。实测中OverlapThread 带来约 1.1 倍的吞吐提升。Chunked Prefill 与缓存感知负载均衡除了重叠调度SGLang 还有两项配套的调度优化。Chunked Prefill 处理长 prompt 的问题。一个很长的 prompt 进入 Prefill 阶段时一次性计算全部 token 的 KV Cache 会长时间独占 GPU阻塞同一 batch 中的 Decode 请求。分块预填充把长 prompt 切成多个 chunk每个 chunk 只算一部分 token让 Decode 请求能穿插执行。分块大小通过--chunked-prefill-size控制值越小 Decode 延迟越平稳但 Prefill 的总耗时会增加。Cache-aware Load Balancing 面向多实例部署场景。多个 SGLang 实例并行服务时各自的 RadixCache 缓存了不同的前缀。新请求到来后系统优先把它路由到已缓存对应前缀的实例上最大化缓存命中率。这项优化在 v0.4 版本引入带来了 1.9 倍吞吐提升和 3.8 倍缓存命中率提升。GPU 显存的三池划分调度解决了时间上的效率显存管理解决空间上的效率。SGLang 把 GPU 显存划分为三个独立的池。模型权重池Model Weights存储模型参数。大小由模型参数量和量化精度决定启动后固定不变。Llama-3 70B 的 BF16 权重约 140GBFP8 量化后约 70GB。KV 缓存池KV Cache Pool存放所有活跃请求和已缓存节点的 KV tensor。这是显存中占比最大也最动态的部分。SGLang 用--mem-fraction-static参数控制它占可用显存的比例默认 0.9即 KV 缓存池拿走模型权重池之后剩余显存的 90%。激活值内存Activation Memory存放前向传播过程中的中间计算结果。它的大小是 KV 缓存池分配后的剩余空间。正常情况下不需要手动干预但如果 KV 缓存池占比过高留给激活值的空间不足就会在长 prompt 的 Prefill 阶段触发 OOM。两个核心 Pool 对象源码层面SGLang 用两个 Pool 对象维护显存中的映射关系。req_to_token_pool维护请求到 token 的映射。给定一个请求 ID通过它可以查到该请求当前所有的 token ID 列表。token_to_kv_pool维护 token 到 KV tensor 的映射。给定一个 token ID通过它定位这个 token 在 GPU 显存中的 KV Cache 存储位置这是 Radix Tree 底层存储的基础。两个 Pool 串联起来构成请求、token、KV tensor 三级寻址链路请求 ID 查 token 列表token ID 查 KV tensor 的显存地址。RadixAttention 的最长前缀匹配最终就是通过这条链路找到可复用的 KV 数据。关键调优参数--mem-fraction-static控制 KV 缓存池占可用显存的比例默认 0.9。遇到 OOM 时把它降到 0.85给激活值内存腾出更多空间。这是最常需要调整的参数。--chunked-prefill-size控制分块预填充每块的 token 数默认由系统自动计算。长上下文场景下prompt 超过数千 token手动设一个较小的值如 4096可以防止单次 Prefill 的激活值峰值撑爆显存。--enable-deterministic-inference开启后保证相同输入产生相同输出适用于需要结果可复现的场景如回归测试。关闭状态下性能略好。一个可迁移的工程判断方法当你在部署 SGLang或任何基于 KV Cache 的推理框架时遇到 OOM可以按这个思路定位瓶颈。先看 OOM 发生在哪个阶段。Prefill 阶段报错大概率是激活值内存不够降低--mem-fraction-static让 KV 缓存池让出空间给激活值。Decode 阶段报错大概率是 KV 缓存池本身容量不足需要降低并发请求数或减小--mem-fraction-static来压缩缓存总量。如果 OOM 发生在长 prompt 的 Prefill 期间配合调小--chunked-prefill-size限制单次激活值峰值。这个方法的本质是把显存看作两个池的博弈KV 缓存池越大能缓存越多请求激活值内存越大能支撑越长的单次计算。OOM 是两者边界失衡的信号调参就是在重新划定这条边界。这个判断框架不局限于 SGLang对 vLLM、TensorRT-LLM 等同类框架同样适用。