Prhub

#1949 [docker] fix sglang pd prefill abort request

原始 PR 作者 zhuzilin 合并时间 2026-05-26 21:56 文件变更 2 提交数 1 评论 0 代码增减 +62 / -10

执行摘要

修复 sglang PD prefill 超时 abort 与 KV 同步失败处理

在分解式(disaggregated)推理架构中,当预填充阶段出现超时或 KV 传输失败时,系统应能优雅地 abort 请求,避免继续处理无效请求导致状态不一致。此 PR 旨在增强系统的健壮性。

该 PR 是关键的健壮性修复,建议合并。对于生产环境,建议根据实际网络状况调整超时配置。

讨论亮点

无 review 评论。

实现拆解

  1. prefill.pyPrefillBootstrapQueue.process_disagg_prefill_inflight_queue
    • 引入 bootstrap_timeout 环境变量(默认 600s),在轮询请求状态时检测超时,超时则构造错误消息并调用 prepare_abortstream_output,将请求从队列中移除。
    • PrefillBootstrapQueue 中新增 release_memory_occupationresume_memory_occupation 方法,用于在暂停引擎时释放和重新注册 KV 缓存。
    • prefill 侧的 fill_batch 方法中,在遍历请求时提前检查 req.finished(),若已 abort 则立即释放 KV 缓存并跳过后续处理。
  2. prefill.py 的 KV 传输逻辑中
    • 在发送 extra state chunk 后检查返回值,若 ret != 0 则记录失败并同步状态至 decode 端。
  3. sglang.patch
    • 对应更新 sglang 源码中的 _pause_engine 函数,确保在 pause/resume 过程中能正确处理 abort 请求。
  4. 版本号更新
    • docker/version.txtnightly-dev-20260525a 更新为 nightly-dev-20260526a
文件 模块 状态 重要度
docker/patch/latest/sglang.patch sglang modified 6.88
docker/version.txt Docker modified 1.32

关键符号

_pause_engine process_disagg_prefill_inflight_queue fill_batch release_memory_occupation resume_memory_occupation

关键源码片段

docker/patch/latest/sglang.patch bugfix

该 patch 包含对 sglang 源码的多个关键修改:超时 abort、KV 传输失败处理、`_pause_engine` 增强,是本次 PR 的核心变更。

def process_disagg_prefill_inflight_queue(self, rids_to_check=None):
    # 设置 bootstrap 超时时间,可通过环境变量 SGLANG_DISAGGREGATION_TRANSFER_TIMEOUT 配置,默认 600 秒
    bootstrap_timeout = float(
        os.environ.get("SGLANG_DISAGGREGATION_TRANSFER_TIMEOUT", "600")
    )
    now = time.perf_counter()
    for i, (req, poll) in enumerate(zip(self.queue, polls)):
        if rids_to_check is not None and req.rid not in rids_to_check:
            continue
        if poll == KVPoll.WaitingForInput:
            # 检测超时,若当前时间与启动时间之差超过超时值,则触发 abort
            if now - req.disagg_kv_sender.start_time > bootstrap_timeout:
                error_message = (
                    f"Prefill bootstrap timeout (> {bootstrap_timeout}s) "
                    f"for request rank={self.tp_rank} "
                    f"{req.rid=} {req.bootstrap_room=}"
                )
                logger.error(error_message)
                prepare_abort(req, error_message, status_code=HTTPStatus.GATEWAY_TIMEOUT)
                self.scheduler.stream_output([req], req.return_logprob)
                indices_to_remove.add(i)
                failed_reqs.append(req)
                if self.scheduler.enable_metrics:
                    self.scheduler.metrics_collector.increment_bootstrap_failed_reqs()
            continue
        elif poll == KVPoll.Failed:
            # 处理 bootstrap 失败的情况
            ...

(注:以上为简化示意,完整代码见 patch 文件)

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. 超时时间硬编码风险SGLANG_DISAGGREGATION_TRANSFER_TIMEOUT 默认 600s,若网络较慢可能误 abort。
  2. 中断循环风险:在 process_disagg_prefill_inflight_queue 中,超时 abort 后 continue 跳过后续处理,但可能遗漏其他状态的请求处理流程。
  3. 状态覆盖风险:已 abort 的请求仍可能被后续逻辑误判为成功。
  • 用户影响:增强预填充阶段异常处理的可靠性,减少因超时或传输失败导致的用户无响应问题。
  • 系统稳定性:改善分解式架构在异常条件下的稳定性。
  • 维护影响:patch 文件变更与上游 sglang 版本同步,需在每次更新 sglang 时验证。
核心路径变更 缺少测试覆盖

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论