[控场AI]
· 4 分钟阅读· 2,388 字

从第一性原理理解vLLM与SGLang:推理引擎核心技术拆解

从第一性原理理解vLLM与SGLang:推理引擎核心技术拆解

从内存管理与调度第一性原理对比vLLM与SGLang的架构差异与选型逻辑。

文章从第一性原理出发,剖析vLLM与SGLang两大推理引擎的底层机制。首先指出自回归生成的真正瓶颈是KV缓存被浪费而非容量不足。vLLM以PagedAttention借鉴操作系统分页思想,将KV缓存切块按需分配,配合连续批处理实现时空双重优化,主打通用高吞吐服务。SGLang则以RadixAttention用基数树做细粒度前缀复用,并通过前端DSL把复杂生成流程编译为执行计划,在结构化输出与agent负载中更灵活。两者并非替代关系,选型应基于业务负载对控制流和前缀复用的需求,理解底层机制比记忆benchmark更有长期价值。

在LLM应用落地的过程中,推理引擎的选择往往决定了服务的吞吐、延迟与成本。vLLM和SGLang作为当前最受关注的两个开源推理框架,常被拿来比较,但真正理解它们“为什么快”“差异在哪”的开发者并不多。社区中一则关于“从第一性原理讲解vLLM与SGLang”的视频讨论,恰好切中了这个痛点——不从API用法出发,而是回到内存管理、调度与执行模型这些底层机制。

reddit source: How does VLLM and SGLANG work from first principles? An Armature Video

推理引擎的性能瓶颈到底在哪

要理解这两个框架,先得理解它们共同要解决的问题。自回归生成意味着每生成一个token,都要把全部历史token重新送入模型做注意力计算。如果每次都重新分配KV缓存,显存会迅速碎片化,长上下文场景下尤其明显。

传统做法是预分配最大长度的连续显存块,利用率极低。第一性原理的视角下,真正的问题不是“缓存不够大”,而是“缓存被浪费了”。vLLM和SGLang的很多设计,本质上都是在对抗这种浪费。

KV缓存(Key-Value Cache) 是自回归生成中避免重复计算的核心机制。Transformer的注意力层在生成每个token时,需要用到此前所有token的Key和Value向量。若不缓存,每步都要对全部历史token重算K/V投影,计算量随序列长度平方增长。KV缓存把这些中间结果存下来,使每步只需计算新token的K/V,再与缓存拼接做注意力。代价是显存占用随批大小和序列长度线性增长——一个70B模型在长上下文、大batch下,KV缓存可达数十GB,往往比模型权重本身还占显存。这也是推理引擎必须在内存管理上做文章的根本原因:缓存命中率与碎片率直接决定能同时服务多少请求。

vLLM:用分页思想重写KV缓存

vLLM最核心的贡献是PagedAttention。它借鉴操作系统虚拟内存分页的思路,把KV缓存切分成固定大小的block,按需分配、非连续存储,再用块表完成逻辑地址到物理地址的映射。带来的直接收益是显存碎片大幅减少,批处理规模可以显著提升。

另一个常被忽略的点是连续批处理(continuous batching)。请求不再需要等待整批结束才释放资源,而是逐token调度,短请求完成后立即让出位置。PagedAttention解决“空间”问题,连续批处理解决“时间”问题,两者叠加才构成vLLM的吞吐优势。提一嘴,分页会带来额外的块表查找开销,在极短序列场景下优势并不明显。

连续批处理(Continuous Batching),也称迭代级调度(iteration-level scheduling),与传统静态批处理的关键区别在于调度粒度。静态批处理要求一个batch内所有请求全部生成完毕才释放资源,短请求被迫等待长请求,GPU出现空转。连续批处理在每个解码步结束后重新评估:已完成的请求立即退出并释放KV块,新请求随即填入空位。这样GPU始终维持高负载,吞吐可提升数倍。它与PagedAttention是互补的——分页让KV块可以非连续分配和回收,连续批处理才能灵活地在任意时刻增删请求而不触发显存整理。

SGLang:把调度抽象成可编程的执行计划

SGLang走的是另一条路。它的出发点不只是“更好地管理缓存”,而是“让复杂的生成流程能被高效表达和执行”。其核心是RadixAttention,用基数树管理多请求共享的前缀,前缀复用做得更细。在多轮对话、few-shot、树状推理等场景下,共享前缀的命中率更高。

更关键的是SGLang的前端DSL设计。开发者可以用类似编程的方式描述多步生成、分支、并行和约束解码,编译器再把这些逻辑转换成高效的执行计划。这种“调度即程序”的思路,让SGLang在结构化输出和agent类负载中更有优势。不过这也意味着它的上手曲线比vLLM更陡,简单场景下未必需要这套抽象。

基数树(Radix Tree) 是一种压缩前缀树,把相同前缀的路径合并存储。RadixAttention用它管理KV缓存:多个请求若共享相同的token前缀(如相同的system prompt),其KV块在树中只存一份,后续请求直接挂载到已有节点上复用,无需重算。相比按请求独立分配缓存,这种结构天然支持前缀的插入、查找与淘汰,且能精确识别最长公共前缀。在多轮对话、few-shot示例、思维树等前缀高度重复的负载中,缓存命中率显著提升,直接转化为更低的prefill开销和延迟。

两者如何选择

综合来看,vLLM更偏向通用高吞吐服务,生态成熟、集成广泛,适合作为标准推理后端;SGLang在需要复杂控制流、强前缀复用和结构化生成的场景中表现更灵活。两者并非替代关系,很多团队会按业务负载分别选型。

从第一性原理出发理解这些机制,比记住benchmark数字更有价值——因为负载在变,只有理解调度和内存模型,才能判断某个框架是否适合自己的场景。

约束解码(Constrained Decoding) 指在生成过程中强制输出满足特定语法或格式(如JSON Schema、正则表达式)的技术。常见做法是在每个解码步对词表施加掩码,把违反约束的token概率置零,只允许合法token被采样。这对结构化输出、函数调用等场景至关重要,但掩码计算本身有开销,且复杂语法会拖慢解码。SGLang的DSL能将这类约束编译进执行计划,与调度和前缀复用协同优化,因此在agent、工具调用等高结构化负载中更具优势。

#vLLM#SGLang#PagedAttention#推理引擎#KV缓存#连续批处理#RadixAttention#LLM推理优化
分享:

相关推荐