SGLang 回答慢,时间究竟花在了哪里?

SGLang 回答慢,时间究竟花在了哪里

场景:SGLang 推理服务上线后用户反馈"答得慢"。结论:两种"慢"是不同阶段的问题,需要分别看 prefill 前 / decode 后 / 链路后端三类观察点。产出:一份可复查的排障记录模板和一张症状-核对项对照表。 适用版本:SGLang v0.5.x(2026 年 9 月前后的稳定版;最新发布 v0.5.19,2026-09-05)。

TL;DR

  • 场景:用户报告"首段迟迟不来"和"开头快、后面断断续续"两类慢请求;GPU 利用率看不出问题。
  • 结论:两种症状分别指向不同阶段------首段慢优先看调度队列与实际输入长度(含 prefill 缓存命中),后续断流优先看 decode 阶段并发与转发链。
  • 产出:5 行核对表(症状 → 接下来核对什么)、6 张可复用配图、1 张可填写记录模板。

版本矩阵

功能 状态 说明
SGLang 官方 Production Metrics 页 ✅ 已验证 https://docs.sglang.io/docs/references/production_metrics 返回 200,文档可访问
--enable-metrics 启动参数 ✅ 已验证 官方文档明确通过该参数暴露 Prometheus 指标
SGLang scheduler 源码(python/sglang/srt/managers/scheduler.py ✅ 已验证 GitHub 链接 commit febb3605 有效;批次调度与执行逻辑可追踪
SGLang 流式 Quickstart 示例 ✅ 已验证 docs.sglang.io/docs/get-started/quickstart#streamingstream=True + for chunk in response 写法可访问
SGLang 最新稳定版本 ✅ 已验证 v0.5.19,发布日期 2026-09-05
官方流式示例能证明"浏览器已显示" ❌ 已驳斥 for chunk in response 只证明客户端能逐段读取,不证明后端及时转发、不证明浏览器已显示
用浏览器总耗时减服务平均值当网络耗时 ❌ 已驳斥 跨机时钟未同步会制造假延迟;正确做法是同进程内时间间隔 + request_id 串联
"看到指标上涨就加并发" ❌ 已驳斥 等待请求数高可能是入口流量增加,也可能是每条请求生成更长答案

文章正文

用户发来一句话,页面过了好一会儿才开始显示;换一个问题,文字马上出现,却一小段一小段地往外挤。这两种"慢",需要查的地方并不相同。

第一种先看首段内容出现之前发生了什么,第二种要看开始生成之后为什么跟不上。沿着一条请求走一遍,比只盯着 GPU 利用率更容易找到方向。

请求到了,并不代表 GPU 已经开始算

应用把消息发送给 SGLang 后,消息还需要按模板组织、转换成 token,并进入执行调度。遇到已有任务占用资源,新请求会等待。

SGLang 的调度器源码可以用来追踪选取批次、执行批次和处理结果的过程。这里的批次,是一次安排在一起计算的一组请求;它不是"某位用户的一整段回答"。具体实现会随版本和运行模式改变,不能把一张串行流程图当作所有部署的进程拓扑。

这一步对排障的意义很直接:请求已经被服务接收,仍可能长时间待在队列里。应用只记录"请求发送"和"最终返回",会把这段等待全算进"模型推理慢"。

首 token 之前,长输入要先被处理

模型要理解输入中的规则、文档和历史。处理输入的阶段通常称为 prefill。如果可复用前缀仍在缓存中,一部分重复计算可以省去;剩余输入仍需处理。

一位用户只问了一句"那第三条呢",不等于这次输入很短。应用可能把整份文档和十轮历史又发了过来。排查时应该保存模型实际接收的输入长度,而不仅是聊天框里新增的那句话。

如果前缀命中增加,但首 token 时间没改善,还要看排队和其他开销。缓存只影响部分计算,不会让已经拥堵的队列自动缩短。

第一段文字出来以后,任务还没有结束

接下来是生成新内容的 decode。常见自回归生成要依据已有上下文逐步继续;输出越长,后续计算也越多。

多个请求的生成过程可以一起被调度,因此某条请求的表现会受同一服务中其他负载影响。"我单独测试很快,上线就慢"需要检查并发请求的输入长度、输出长度和到达节奏。

如果使用结构化输出,还要考虑约束解码;如果启用了特殊推理模式或其他优化,输出处理也可能不同。先保留实际启动参数,才知道你在排查哪条路径。

服务有 token,页面未必立即有文字

生成出的 token 需要转成文字并发送出去。客户端、业务后端和反向代理可能继续缓冲。一个流式响应里的首个事件,也可能只是角色或元信息,而不是用户看得见的内容。

因此,要区分"收到第一个事件"和"收到第一段非空内容"。当服务指标很好、页面仍然停顿时,可以在同一请求上分别记录:服务发出内容、业务后端收到内容、浏览器显示内容的时刻。

跨机器时钟没有同步,直接相减会制造假延迟。优先记录同一进程内的时间间隔,再用请求 ID 串起不同观察点。不要把浏览器总耗时减去某个服务平均值,就当成网络耗时。

用一组症状决定下一步看哪条记录

官方指标页列出了首 token 时间、等待请求数、运行中请求数、缓存命中等指标。启动服务时可以启用 --enable-metrics。这些指标适合观察负载变化,但聚合指标不能单独还原一次请求。

下面这张表是排查顺序,不是已确认的故障结论:

你看到的现象 接下来核对什么
首段迟迟不来,等待请求数持续上升 请求到达速度、并发上限、正在运行的长任务
只有长文问题起步慢 实际输入长度、可复用前缀和 prefill 情况
起步正常,后续文字变慢 输出长度、同时运行的任务、生成阶段资源压力
服务已发出文字,页面仍没显示 后端转发、代理缓冲、浏览器处理
请求偶发消失或提前结束 错误、超时、取消、结束原因与客户端重试

不要看到一个指标上涨就马上改配置。比如等待请求数高,可能是入口流量增加,也可能是每条请求开始生成更长的答案。两种情况下都加并发,未必能解决问题。

留下能够重现的请求,再改一个变量

从慢请求中选一个已脱敏样本,固定模型、模板、输入和生成设置,记录它在低负载下的表现,再逐步恢复当时的并发条件。本文没有执行模型压测,这里给的是定位办法。

你需要的结果不是"模型慢"四个字,而是更具体的描述,例如:"长输入在首 token 之前耗时增加""队列增长后短请求也被拖慢",或者"服务已经流式返回,代理还在攒数据"。

描述能落到具体阶段,改动就能落到相应位置。下一次复测时,也知道该检查哪段等待有没有真的缩短。


错误速查卡

症状 根因 定位 修复
首段迟迟不来,等待请求数持续上升 请求被调度器积压,批次还没轮到当前请求 核对到达速率、并发上限、当前在跑长任务;同一进程内测"请求入队 → 选中执行"间隔 在不改变业务峰值的前提下,调并发上限或拆长任务;先固定一个变量复测
只有长文问题起步慢 实际输入比用户感知的长得多,prefill 阶段耗时长 记录模型实际收到的输入 token 数、命中前缀比例 缩短上下文、复用前缀缓存、减少每轮重发整份文档
缓存命中增加,首 token 没改善 缓存只省部分计算,没解决调度排队与其他开销 同时看排队长度和 prefill 时长 单独看排队、再单独看 prefill,逐项验证
起步正常,后续文字变慢 decode 阶段资源被其他请求挤占,或输出特别长 看运行中请求数、输出 token 数、生成阶段 GPU/带宽指标 限流或拆短输出,先复测同输入短输出
服务指标很好,页面仍停顿 业务后端/代理/浏览器在缓冲,token 没及时落到 UI 同一请求上分别记录:服务发出首段非空内容、业务后端收到、浏览器显示 检查后端是否收齐整段才转发、代理是否有 proxy_buffering、浏览器是否被节流
stream=True 示例跑通就觉得"流式没问题" 官方 for chunk in response 只证明客户端能逐段读 把"收到第一个事件"和"收到第一段非空内容"分开记 同时校验后端转发与浏览器显示两侧
把浏览器总耗时减服务平均值当网络耗时 跨机时钟未同步 在同进程内比对时间戳;用 request_id 串联不同观察点 改为同进程内时间间隔 + request_id 关联
看到等待请求数高就加并发 原因可能是入口流量增大,也可能是每条请求输出变长 看输入/输出分布、达到节奏、生成阶段指标 先判断是入口侧还是生成长度侧,再决定调入口或限流
请求偶发消失或提前结束 错误、超时、取消、客户端重试 在同一进程内记录"结束原因"标签 区分是服务侧主动结束,还是客户端侧主动断开
排查时只盯 GPU 利用率 排队、后端缓冲、浏览器渲染都看不见 拉同请求多观察点 + 聚合指标 把"GPU 利用率"换成"首 token 之前 / decode 之后 / 链路后端"三段观察

作者 :武子康的个人博客 发布日期 :2026-09-11(基于 SGLang v0.5.x,2026 年 9 月) 核查依据 :官方 Production Metrics 页(HTTP 200)、SGLang GitHub 源码(commit febb3605)、官方 Quickstart Streaming 文档;最新发布版本 v0.5.19(2026-09-05)。

相关推荐
派大_星1 小时前
PyTorch CNN图片分类与数据增强实践
人工智能·深度学习·机器学习
超级无敌霹雳大狗熊1 小时前
以最小demo讲解Eino中的graph编排
go·agent
jay神1 小时前
【计算机毕业设计项目】基于 YOLO + ArcFace 的人脸识别检测系统
人工智能·深度学习·计算机视觉·毕业设计·课程设计·计算机毕业设计
2601_962297481 小时前
基于LangChain+LLM大模型+机器学习的恶意域名(流量)智能检测系统
机器学习·langchain·llm·恶意域名·流量检测
长谷深风1111 小时前
Checkpoint设计的三大生死关
大数据·人工智能·ai·大模型·ai智能体·tool·aiagent
DevNo1 小时前
我的旅拍素材整理和剪辑记录
人工智能
程序员cxuan1 小时前
DeepSeek V4.1 Flash 正式发布!
人工智能·后端·程序员
海宇大数据1 小时前
分布式网格实战:基于海宇柠檬查出险-登记证构建自动化车辆合规网关
运维·人工智能·分布式·自动化
mldong1 小时前
AI Agent 不能自己签字:用 Python 工作流引擎给 AI 加一道人类审批闸门
后端·python·agent