什么是 SGLang:给 LLM 程序一台「会复用前缀」的高速运行时

SGLang 概念全解析:Structured Generation Language 的前端 DSL 与 RadixAttention 运行时、为什么多轮/Agent/RAG 特别吃树状 KV 缓存、和 vLLM 怎么选、DeepSeek 为何推荐它,以及一行命令拉起 OpenAI 兼容服务。

  • AI
  • SGLang
  • LLM
  • 推理引擎
  • RadixAttention
  • vLLM
  • DeepSeek
  • LMSYS

前几篇把 Agent 的编排层讲了不少:DeepSeek Harness 是身手,LangGraph 是图,RAG 是外接知识。 但模型真正吐 token 的那一层——推理引擎——还没单独拆开过。2026 年你要自建 DeepSeek、Qwen、Kimi 这类开源模型, 几乎一定会碰到一个名字:SGLang。这篇把它是什么、凭什么快、和 vLLM 怎么选,一次讲清楚。

一、它是什么:一门小语言,外加一台高速运行时

SGLang 的全称是 Structured Generation Language,结构化生成语言。 2024 年 1 月由 LMSYS(就是做 Chatbot Arena / Vicuna 的那拨人)发布,论文SGLang: Efficient Execution of Structured Language Model Programs后来进了 NeurIPS 2024。一作是 Lianmin Zheng,和 Ying Sheng 等人一起,把「怎么写 LLM 程序」和「怎么跑 LLM 程序」绑在同一套设计里。

官方现在的定位已经很直白:

High-performance serving framework for large language and multimodal models.面向大语言模型和多模态模型的高性能服务框架,从单卡到分布式集群,冲着低延迟、高吞吐的生产推理。

但名字里的「Language」不是装饰。SGLang 从一开始就是前后端合在一起的系统

是什么解决什么
前端语言嵌在 Python 里的 DSL:gen / fork / regex把多步生成、并行分支、JSON 约束写成普通函数,而不是一串裸 prompt
运行时带 RadixAttention 的推理引擎,OpenAI 兼容 HTTP 服务自动复用 KV cache、连续批处理、把 GPU 打满

今天 90% 的人用它,其实只碰运行时:python3 -m sglang.launch_server 拉起一个/v1/chat/completions,用 OpenAI SDK 对着打。前端语言还在,适合 Agent、多维评判、带 schema 的抽取; 但生态重心已经从「一门新语言」变成「一台能扛生产流量的引擎」。

一组官方数字方便建立量级(来自 docs.sglang.io 与仓库 README,2026 年 8 月): 托管在非营利组织 LMSYS 下;自称全球超过 40 万张 GPU 在跑, 每天生产环境产生数万亿 token;GitHub sgl-project/sglang约 3.2 万 star;PyPI 当前稳定版 0.5.17。采用名单里能看到 xAI、NVIDIA、AMD、Cursor、LinkedIn, 以及 AWS / Azure / GCP。数字是项目自己报的,当量级看,不必当成审计结果。

二、为什么需要它:LLM 早就不是「一问一答」了

2023 年之前,推理引擎的默认假设很简单:来一条 prompt,算出 KV cache,生成完,把 KV 扔掉。 下一条请求哪怕和上一条共享同一段系统提示,也从头 prefill 一遍。

真实工作负载早就不是这样:

  • 多轮聊天:系统提示 + 历史原封不动,每轮只多几句;
  • Few-shot / RAG:同一组例题或同一段检索到的文档,后面挂不同问题;
  • Agent / ReAct / Tree-of-Thought:一次任务里多次调用模型,工具说明、思考前缀反复出现;
  • 结构化输出:要 JSON、要枚举、要正则,而不是自由散文。

这些程序有两个系统级痛点。第一,前缀明明一样,计算却不共享——GPU 时间浪费在重复 prefill 上, 首 token 延迟也被拖高。第二,控制生成很难——你想要合法 JSON,就得在解码时屏蔽不合法 token; 朴素做法一步只能进一个 token,JSON 一长就慢。

SGLang 的答案对应两刀:运行时用 RadixAttention 自动复用 KV; 前端用约束解码(压缩有限状态机)让合法的多 token 路径可以一步走完。 论文里在 Llama-7B / Mixtral-8x7B 上,对当时的 Guidance、vLLM、TGI,吞吐最高到约 5×~6.4×。 那是 2024 年初的基线,vLLM 后来也补了前缀缓存;数字不能直接拿到 2026 年用,但问题定义没过时。

三、核心发明:RadixAttention,把 KV cache 当成一棵树

普通引擎把每次请求的 KV cache 当成这份请求的私有内存:做完就释放。 RadixAttention 换了个看法:KV cache 是可以按前缀检索的缓存,结构是一棵radix tree(基数树)

基数树是前缀树的省空间版:边上可以挂一整段 token,不必一个字符一个节点。 树上每个节点对应「这段 token 序列已经算好的 KV」。新请求带着完整 prompt 进来, 运行时做前缀匹配:命中的那段直接复用,只对后缀做 prefill。前端不用标记「这段请缓存」—— 共享系统提示、共享 few-shot、共享聊天历史,形状各不相同,树都能接住。

RadixAttention · KV cache 是一棵会分享的树请求带完整 prompt,运行时自己做前缀匹配系统提示(共享根)You are a helpful assistant对话 A · 第 1 轮Hello → Hi对话 B · 第 1 轮另一段聊天Few-shot 题干共享例题前缀对话 A · 第 2 轮只算新增 token题目 1同一套例子题目 2分叉蓝框是可复用的 KV:多轮聊天、few-shot 例题、Agent 的固定工具说明,都不必重新 prefillGPU 内存不够时按 LRU 从叶子往上赶:最近还在聊的前缀留下,冷会话腾地方这就是 SGLang 相对「每条请求算完就丢掉 KV」的旧运行时,吞吐能拉开的原因
图 1 · RadixAttention:系统提示是树根,多轮对话和 few-shot 从公共前缀分叉;GPU 不够就按 LRU 从叶子往上腾

和「只缓存整段完全相同的 prompt」相比,树结构多做了三件事:

  1. 多级共享:A、B 两路对话可以只共享系统提示,few-shot 的十道题可以只共享例题段;
  2. 感知缓存的调度:优先调度更容易命中前缀的请求,命中率再抬一截;
  3. LRU 逐出:GPU 显存有限,从最近最少用的叶子往上赶,正在聊的会话前缀留下。

物理存储仍然是分页的(和 vLLM 的 PagedAttention 同一类思路,论文也写明兼容 continuous batching 与 paged attention)。 创新不在「KV 分页」,而在把分页后的 KV 组织成可检索的树,并且默认常开——消融实验显示即便没有 cache hit,开着也几乎没有额外开销。

这就是为什么 Agent、多轮客服、RAG、「同一系统提示打一万个用户」这类流量,SGLang 往往好看:工作负载本身就是一棵树,运行时终于按树来管内存了。

四、前端语言:把「多次生成」写成普通 Python 函数

运行时解决「怎么跑得快」。前端解决「怎么把复杂生成程序写清楚」。语法受 Guidance 启发,多了并行和批处理原语。 一个最小问答是这样:

@function
def basic_qa(s, question):
    s += system("You are a helpful assistant.")
    s += user(question)
    s += assistant(gen("answer", max_tokens=512))

state = basic_qa("List 3 countries and their capitals.")
print(state["answer"])

几个真正让它不像「prompt 字符串拼接」的点:

  • gen("name"):一次生成,结果存进状态机里的变量。调用默认非阻塞, 同一个函数里可以同时挂多路生成;
  • fork:把当前 prompt 状态复制成几份并行往下走,适合「同一篇文章从多个维度打分再合并」 (论文里的 branch-solve-merge);
  • choices / regex:生成必须落在枚举里,或符合正则 / JSON schema。 这就是结构化输出——Agent 要的 tool call、抽取要的字段,靠解码约束而不是事后正则抢救;
  • 普通 Python 控制流if s["tool"] == "calculator" 这种分支可以直接写, 解释器负责同步;也可以把程序 trace 成数据流图再交给编译器做调度。

后端不一定是本地 GPU。同一套函数可以打到 OpenAI / Anthropic / Gemini,也可以打到本机 SGLang 服务。 多数生产部署不会用 DSL 重写整套业务,而是 HTTP + 约束解码;但理解这层很重要:SGLang 当初不是为了再做一个 vLLM,而是为了让「LLM 程序」成为一等公民。运行时的 RadixAttention,正是被这些多调用、多分叉的程序形状逼出来的。

五、2026 年的 SGLang:生产引擎清单

两年半里它从「论文系统」长成了完整的推理栈。和今天部署相关的能力,可以按层看:

有什么
调度与缓存RadixAttention、连续批处理、chunked prefill、zero-overhead CPU scheduler、HiCache(分层 KV,可热插拔存储后端)
并行张量 / 流水线 / 数据 / 专家并行(EP)、DP Attention(MLA 类模型避免 KV 被 TP 放大)、Decode Context Parallelism
拆分与投机Prefill–Decode 分离(PD disaggregation)、EPD、投机解码(含面向 DeepSeek 的 MTP / EAGLE 路径)
精度与适配FP4 / FP8 / INT4 / AWQ / GPTQ、量化 KV、多 LoRA 批处理
接口OpenAI、Anthropic Messages、Ollama 兼容 API;离线 sgl.Engine;原生 /generate
硬件NVIDIA(含 GB200 / GB300)、AMD MI300/MI355、Intel Xeon、Google TPU、昇腾 NPU、部分 XPU / Apple Silicon
模型面Llama / Qwen / DeepSeek / Kimi / GLM / GPT-OSS / Gemma / Mistral,以及 embedding、reward、部分扩散模型

和 DeepSeek 的关系尤其值得单独说。DeepSeek-V3 / R1 发布时,官方 README 把 SGLang 列为推荐推理引擎;MLA(Multi-head Latent Attention)有 FlashAttention3、FlashMLA、CutlassMLA 等多套后端, 还有专门的 DP Attention,避免张量并行把 KV 在每张卡上各存一份。2026 年 4 月还有DeepSeek-V4 Day 0 的推理与 RL 合作博客。 你在国内集群上跑 DeepSeek 类 MoE,SGLang 通常是默认选项,不是因为品牌,而是因为 MLA + 专家并行这条路径被共同打磨过。

另一条正在变粗的线是后训练 / RL。README 把它写成许多前沿模型的 rollout 后端, 原生接 AReaL、Miles、slime、Tunix、verl。推理引擎不再只服务「聊天产品」,也服务「训练时要高速采样」的闭环。

六、和 vLLM 怎么选

这是部署时最常被问的一句。两者都是开源、都接 Hugging Face、都提供 OpenAI 兼容服务,都用分页 KV。 差别在重心。

SGLangvLLM
成名作RadixAttention(树状前缀复用)+ 结构化生成语言PagedAttention(把 KV 当虚拟内存分页)
更吃香的流量多轮、Agent、RAG、共享系统提示、要 JSON/工具约束prompt 彼此不太像的混合流量、要最大模型覆盖面
DeepSeek / MLA / 大 EPDay-0 深、官方推荐过,PD + 大规模专家并行案例多能跑,生态也在追,历史包袱更偏通用 Transformer
编程面自带前端 DSL;也能当纯 HTTP 服务以服务和引擎 API 为主
硬件广度NVIDIA / AMD / TPU / 昇腾等都有路径贡献者和「新架构第二天能跑」的惯性往往更大

实用建议:先看工作负载像不像一棵树。客服、Agent、同一套工具 schema 打海量请求,优先拿 SGLang 压吞吐; 模型清单很杂、要跟新架构 Day-1、流量前缀很散,vLLM 往往省心。TensorRT-LLM 仍是「绑死 NVIDIA、愿意用引擎换极致延迟」的第三条路。 三者都在互相吸收对方的技巧,2026 年已经没有「谁完胜」——有的是默认选项不同

七、怎么跑起来

官方推荐用 uv 装(需要 Python 3.10+,NVIDIA 上一般是 sm80 及以上):

uv pip install --prerelease=allow sglang

拉起服务,等终端打出 The server is fired up and ready to roll!

python3 -m sglang.launch_server \
  --model-path Qwen/Qwen2.5-7B-Instruct \
  --host 0.0.0.0 --port 30000

然后它就是一个 OpenAI 兼容端点。已有业务改 base_url 即可:

import openai

client = openai.Client(base_url="http://127.0.0.1:30000/v1", api_key="None")
print(client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[dict(role="user", content="用一句话解释 RadixAttention")],
).choices[0].message.content)

离线批处理不必起 HTTP,直接 sgl.Engine(model_path=...)generate。 Docker 镜像在 lmsysorg/sglang,生产可用更小的 latest-runtime。 多卡加 --tp-size;DeepSeek 类 MoE 再叠加专家并行和(需要时)PD 分离——那是另一篇调参文的长度, 官方 cookbook 比任何二手清单都准。

小结

SGLang 可以记成三句话:

它是 LLM 程序的运行时,不只是「再做一个 vLLM」。 核心不变量是 RadixAttention:KV 按前缀长在树上,复杂程序的重复计算被结构消掉。 2026 年它已经是开源模型、尤其是 DeepSeek 系 MoE 的默认高速引擎之一。

  1. 名字里的 Language 和 Serving 是同一件事的两面——前端让你把多步生成写成函数, 后端让这些函数共享 KV。只用 HTTP 也能享受树缓存,但理解前端,才知道这棵树为什么长这样。
  2. 快,首先快在「别做重复 prefill」——分页、CUDA Graph、投机解码大家都有; 把多轮 / Agent / few-shot 的共享前缀当成一等缓存,是 SGLang 的原教旨。
  3. 选引擎看流量形状——前缀树密集走 SGLang,模型杂、前缀散走 vLLM。DeepSeek 官方推过它,不是广告,是 MLA 和 EP 被一起打磨过。

站在本站的主线上:Harness 决定 Agent 怎么动手,SGLang 决定模型怎么把 token 吐得够快、够便宜。 没有后者,前者的「一切皆插件」只会在 GPU 上空转。想继续往下,官方入口是docs.sglang.io,论文在arXiv:2312.07104, 2024 年那篇把 RadixAttention 讲明白的博客在LMSYS