SGLang 推理框架核心组件解析:请求、内存与缓存的协同工作

在当今大语言模型(LLM)服务的浪潮中,高效的推理框架是决定服务质量与成本的关键。SGLang 作为一个高性能的 LLM 推理和部署库,其内部精巧的设计确保了高吞吐量和低延迟。为了实现这一目标,SGLang 在其核心调度与内存管理机制中,通过一系列紧密协作的对象来处理用户请求和优化计算资源,特别是对 KV 缓存的管理。在 SGLang 的调度批次(ScheduleBatch)中,reqsreq_to_token_pooltoken_to_kv_pool_allocatortree_cache 这四个关键字段,分别代表了从请求到底层缓存管理的不同层面,它们之间的协同关系构成了 SGLang 高效推理的基石。

请求的表示:Req 对象

一切处理始于请求。在 SGLang 中,每一个进入系统的用户请求都被封装成一个 Req 对象(位于 managers.schedule_batch.Req)。这个对象是请求在系统内流转的基本单位,包含了与该请求相关的所有信息,例如请求的唯一标识符(rid)、输入的文本序列(prompt)、生成的配置参数(如温度、最大新 token 数)以及请求当前的状态(如等待中、运行中、已完成)。

ScheduleBatch 中,reqs 字段是一个列表,容纳了当前批次中所有正在被处理的 Req 对象。调度器根据一定的策略(如先到先服务、最长前缀匹配等)从等待队列中挑选 Req 对象,将它们组合成一个 ScheduleBatch 进行统一处理。因此,reqs 字段是整个推理流程的入口,后续所有的内存分配和计算都围绕着这个列表中的请求展开。

两级内存池:从请求到物理内存的映射

为了高效管理 GPU 内存,尤其是占用巨大的 KV 缓存,SGLang 采用了一种精巧的两级内存池机制。req_to_token_pooltoken_to_kv_pool_allocator 正是这一机制的核心体现。

首先是 ReqToTokenPool(请求到 Token 池的映射)。这个组件在 ScheduleBatch 中表现为 req_to_token_pool 字段,其核心作用是建立每个请求(Req)与其包含的 token 在逻辑缓存池中位置的映射关系。它本质上可以理解为一个二维表,第一维由请求的池索引(req_pool_idx)确定,第二维则是该请求内部 token 的序列位置。表中的值是一个逻辑索引(out_cache_loc),指向该 token 在全局 Token 缓存池中的具体位置。通过这种方式,系统无需关心每个请求的具体 token 内容,只需通过索引就能快速定位其缓存信息。

比如下面这个就是一个ScheduleBatch批次有两个Req请求时的情况(batch_size最大为48,但当前batch_size=2):
req_to_token字段的张量形状:torch.Size([48, 131076])

{   'size': 48, 'max_context_len': 131076, 'device': 'cuda', 'req_to_token': tensor([[1, 2, 3,  ..., 0, 0, 0],[1, 8, 9,  ..., 0, 0, 0],[0, 0, 0,  ..., 0, 0, 0],...,[0, 0, 0,  ..., 0, 0, 0],[0, 0, 0,  ..., 0, 0, 0],[0, 0, 0,  ..., 0, 0, 0]], device='cuda:0', dtype=torch.int32), 'free_slots': [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]}

接下来是 TokenToKVPoolAllocator(Token 到 KV 缓存池的分配器)。req_to_token_pool 提供的仅仅是逻辑位置,而 token_to_kv_pool_allocator 则负责将这个逻辑位置与 GPU 上的物理内存块对应起来。它管理着一个巨大的、为所有请求共享的物理 KV 缓存池。当一个 token 需要被存储时,token_to_kv_pool_allocator 会为其分配具体的内存地址。这个物理缓存池通常是三维或四维的结构,维度包括模型层数、注意力头数量和头维度等。当 req_to_token_pool 将一个请求的 token 映射到一个逻辑索引后,token_to_kv_pool_allocator 就利用这个索引,在物理池的相应位置存取实际的 Key-Value 向量数据。

比如上面两个批次的ScheduleBatch对应的TokenToKVPoolAllocator内容如下:
free_slots字段表示未分配的token缓存,形状为:torch.Size([154788])

ipdb> batch.token_to_kv_pool_allocator.__dict__
{'size': 154801, 'dtype': torch.float16, 'device': 'cuda', 'page_size': 1, 
'free_slots': tensor([    15,     16,     17,  ..., 154800, 154801,      7], device='cuda:0'), 
'is_not_in_free_group': True, 'free_group': [], 
'_kvcache': <sglang.srt.mem_cache.memory_pool.MHATokenToKVPool object at 0x7f3cdde850d0>}
前缀共享的利器:RadixCache

在多用户、多请求的服务场景中,不同请求的输入(prompt)往往有重叠的前缀。例如,多个用户可能都在进行相似主题的问答。如果能复用这些相同前缀的 KV 缓存,将极大减少重复计算,提升系统吞吐量。这正是 RadixCache(基数缓存,在 ScheduleBatch 中体现为 tree_cache 字段)发挥作用的地方。

RadixCache 采用树状结构(Trie Tree 或称前缀树)来组织和存储所有处理过的 token 的 KV 缓存。树的每条边代表一个 token ID,从根节点到任意节点的路径就构成了一个 token 序列(即前缀)。每个节点则存储着对应 token 的 KV 缓存的逻辑索引(out_cache_loc)。

当一个新的请求进入系统时,SGLang 会利用 RadixCache 查找其输入序列的最长公共前缀。一旦找到匹配的前缀,该前缀对应的所有 token 的 KV 缓存就可以被直接复用,无需重新计算。系统只需从前缀结束的位置开始进行新的计算。这个过程涉及到与 ReqToTokenPoolTokenToKVPoolAllocator 的紧密交互:RadixCache 负责找到可复用的 token 及其逻辑索引,然后更新 req_to_token_pool,将当前请求的相应 token 位置指向这些已存在的逻辑索引。TokenToKVPoolAllocator 则根据这些逻辑索引提供对底层物理内存的访问。

对于新生成的 token,RadixCache 也会将其插入到树中,并由 TokenToKVPoolAllocator 为其分配新的缓存空间,从而不断扩充可供复用的缓存池。

协同工作的流程

这四个组件在 ScheduleBatch 中的关系可以总结为一个清晰的流程:

  1. 请求聚合:调度器将多个 Req 对象收集到 ScheduleBatchreqs 字段中。
  2. 前缀匹配与复用:系统利用 tree_cache (RadixCache) 对 reqs 列表中的每个请求进行前缀匹配。对于匹配到的公共前缀,直接复用其在 RadixCache 中已有的 KV 缓存信息。
  3. 逻辑映射建立tree_cache 将找到的或新创建的 token 的逻辑缓存索引(out_cache_loc)填充到 req_to_token_pool 中,从而建立了每个请求与其 token 逻辑缓存位置的映射。
  4. 物理内存分配与访问:当模型需要进行注意力计算时,它会通过 req_to_token_pool 获取到所需 token 的逻辑索引,再由 token_to_kv_pool_allocator 将这些逻辑索引转换为 GPU 上的物理内存地址,最终读取或写入实际的 Key-Value 数据。

通过 Req 对象对请求进行封装,再经由 RadixCache 实现高效的前缀共享,最后通过 ReqToTokenPoolTokenToKVPoolAllocator 这两级内存池完成从逻辑请求到物理内存的精确映射与管理,SGLang 构建了一个强大而高效的推理引擎。这四个组件环环相扣,共同确保了 GPU 资源的最大化利用和推理服务的高性能表现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/915118.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/915118.shtml
英文地址,请注明出处:http://en.pswp.cn/news/915118.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React学习笔记——Day2打卡

1、React表单控制 1.1 受控绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 完整示例&#xff1a; function App(){/* 1. 准备一个React状态值 */ const [value, setValue] useState()return (/* 2. 通过value属性绑定状态&#x…

用例测试方法5,6:状态迁移图和因果图

状态迁移图通过描绘系统的状态及引起状态转换的事件&#xff0c;来表示系统的行为例如&#xff1a;订机票l向航空公司打电话预定机票—>此时机票信息处于“完成”状态顾客支付了机票费用后—>机票信息就变为“已支付”状态旅行当天到达机场后&#xff0c;拿到机票后—>…

linux 脚本解释

if [ $? -ne 0 ]; thenecho "错误: 无法关闭现有 Tomcat 实例&#xff0c;终止启动流程!" >&2exit 1fi$? 是shell中的特殊变量&#xff0c;表示上一个命令的退出状态码-ne 0 表示"不等于0"(在Unix/Linux中&#xff0c;0通常表示成功&#xff0c;非…

Glary Utilities(系统优化工具) v6.20.0.24 专业便携版

GlaryUtilities 允许你清理系统垃圾文件&#xff0c;无效的注册表&#xff0c;上网记录&#xff0c;删除插件&#xff0c;查找重复文件&#xff0c;优化内存&#xff0c;修理或删除快捷方式&#xff0c;管理windows启动程序&#xff0c;卸载软件&#xff0c;安全删除文件&#…

VScode链接服务器一直卡在下载vscode服务器/scp上传服务器,无法连接成功

终极方案&#xff08;强力推荐&#xff0c;亲测有效&#xff0c;链接只需5秒钟&#xff09;&#xff1a;本地下载复制到mkdir -p ~/.vscode-server/bin/<commit_hash>里面 <commit_hash>可以从帮助->关于里面找到&#xff0c;如下所示 版本: 1.96.2 提交: fa…

基于Spring Boot的农村农产品销售系统设计与实现

随着现代农业的快速发展,传统农产品的销售模式逐渐暴露出信息闭塞、流通效率低和中间环节多等问题。为了打破这些瓶颈,我基于Spring Boot框架开发了一套农产品销售系统,旨在构建一座连接农民与消费者之间的数字桥梁,让优质农产品更高效地直达用户餐桌。 一、项目背景与目标…

Mysql默认存储引擎InnoDB和底层数据结构

在黑马点评项目实战中&#xff1a;谈到了为什么不推荐使用mysql的字段自增作为订单id传递给客户端&#xff0c;让我想到了Mysql的​​存储引擎​​和​​底层数据结构​​究竟是什么&#xff1f;它是如何实现自增的&#xff1f;本文主要是深度解析 MySQL 默认存储引擎 InnoDB 与…

原点安全签约金网络数科,共建一体化数据安全防护体系

金网络正式携手原点安全&#xff0c;基于原点安全一体化数据安全平台&#xff08;uDSP&#xff09;&#xff0c;启动企业数据安全平台建设项目&#xff0c;围绕数据资产盘点、敏感数据识别与分类分级、数据访问权限管控、数据动态脱敏、数据安全审计与风险监测等关键能力建设&a…

mix-blend-mode的了解使用

mix-blend-mode 是 CSS 的一个属性&#xff0c;用于控制元素的内容&#xff08;如文本、图像、背景等&#xff09;如何与其 父元素 或 背景 进行混合。它类似于图形设计软件&#xff08;如 Photoshop&#xff09;中的图层混合模式&#xff0c;可以实现各种视觉效果&#xff1b;…

vue自定义指令bug

问题描述&#xff1a;页面加载时&#xff0c;报已下错误。同时&#xff0c;页面数据不显示环境介绍&#xff1a;已经添加了vue自定义指令permission&#xff0c;实现如下&#xff0c;用以控制元素显示权限app.directive(permission, (el, binding) > {if (!store.hasPermiss…

Vue3 + WebSocket

Vue3与WebSocket结合能够很好地满足实时通讯的需求。通过合理设计和管理WebSocket连接的生命周期&#xff0c;以及实现必要的重连逻辑和心跳检测机制&#xff0c;可以构建出响应迅速且稳定的实时应用。WebSocketWebSocket允许服务端主动向客户端发送数据&#xff0c;无需客户端…

IPSec和HTTPS对比(一)

IPSec&#xff08;Internet Protocol Security&#xff09;是网络层&#xff08;OSI第3层&#xff09;的加密协议&#xff0c;其核心机制和与HTTPS的区别如下&#xff1a;&#x1f512; ​一、IPSec的核心机制解析​​1. 安全封装结构​┌──────────┬───────…

关于 c、c#、c++ 三者区别

1. 起源与定位语言起源时间开发者定位/特点C1972年Dennis Ritchie面向过程的编程语言&#xff0c;强调底层控制与高效性能C1983年Bjarne Stroustrup在 C 的基础上加入 面向对象编程&#xff08;OOP&#xff09;C#2000年微软&#xff08;Microsoft&#xff09;类似 Java&#xf…

项目总体框架(servlet+axios+Mybatis)

项目总体框架 先暂时这样子&#xff08;后续发现错误的话就改&#xff09; com.hope-tieba/ ← 项目根 ├─ .idea/ ← IDEA 工程配置 ├─ src/ │ ├─ main/ │ │ ├─ java/ │ │ │ └─ com/hope/ │ │ …

RestTemplate 实现后端 HTTP 调用详解

1. 方法签名解析方法名和返回类型说明了这个方法的业务意图和数据结构。Override 表示实现接口方法&#xff0c;利于规范开发和自动检查。Override public List<RobotInfo> listRobots() {这里 RobotInfo 是假设的业务数据结构&#xff0c;实际项目中按你的类名即可。2. …

Python单例模式详解:从原理到实战的完整指南

引言 单例模式是软件设计中最常用的模式之一&#xff0c;它确保一个类只有一个实例&#xff0c;并提供全局访问点。在Python中&#xff0c;实现单例模式有多种优雅的方式&#xff0c;本文将详细讲解6种主流实现方法&#xff0c;包含完整代码示例和注释。 一、模块级单例&#x…

拼团系统中的幂等性防护 , 前置性查询,Redis 库存预判

这段内容涉及两个关键点&#xff1a;幂等性防护 和 拼团目标量判断&#xff0c;下面我将分别解释这两个问题&#xff0c;并重点说明&#xff1a; “如果没有拦截&#xff0c;最终访问数据&#xff0c;也会有数量判断拦截。” 这句话的意思。 ✅ 1. 查询外部交易 outTradeNo 是…

【Python】LEGB作用域 + re模块 + 正则表达式

文章目录一 LEGB作用域二 re&#xff08;Regular Expression&#xff09;预览1. re.match() —— 从字符串开头匹配2. re.search() —— 搜索整个字符串3. re.findall() —— 返回所有匹配的字符串列表4. re.finditer() —— 返回所有匹配的迭代器5. re.sub() —— 替换匹配的字…

JavaSE -- 数据操作流

6. 数据操作流在执行文件存储一个对象的时候&#xff0c;如果该对象只有少量属性需要存储&#xff0c;并且这些属性的类型都是基本数据类型&#xff0c;此时则不需要对象序列化技术。使用数据操作流既可以实现。 DataOutputStreamDataInputStream 注意&#xff1a; 读取数据的时…

GI6E 加密GRID電碼通信SHELLCODE載入

GI6E https://github.com/MartinxMax/gi6e 「它似乎能從特製的音訊信號中提取敏感資訊。」 HEX-GRID CODEX&#xff08;簡稱 HGC&#xff09;是一種自定義的 6 位元結構編碼系統&#xff0c;使用三位元的群組識別碼&#xff08;Group Bits&#xff09;加上三位元的索引識別碼…