2026-09-16
NPU Dockerfile 默认工作目录改到仓库根目录
不建议为此 PR 投入深度精读——它就是一行 `WORKDIR` 修正加一行注释,读完 patch 即可理解全部语义;真正值得略作停留的是两个设计层面的信号:(1) 参照同文件里 `TARGETARCH` 的 fail-fast 校验,是否应为 workdir 增加一个轻量断言(例如构建期检查 clone 目录存在),避免 `WORKDIR` 静默创建空目录这一失败模式;(2) 其他 Dockerfile(`docker/Dockerfile`、各平台镜像)是否也应统一到 `/sgl-workspace/sglang`,否则不同镜像的 CWD 约定会继续分叉,给文档和 CI 脚本带来长期维护成本。另外建议关注 `Latest PR Test (Extra)` 的那次失败是否有后续 issue 跟踪。
修复始终失败的覆盖率 Job,新增按 GPU 数统计视图
值得精读,尤其是长期维护 CI 的人。重点看两处设计决策:一是用 `set -o pipefail` + `|| echo` 把「非门禁」从意外行为改成显式契约,以及随之而来的问题发现责任转移;二是 `_SUITE_ACCEL_COUNT_RE` 用 `(?:^|-)` / `(?:-|$)` 锚定来区分 runner 规模与 `-tp4`、`qwen3-235b` 这类同名数字,这类「从命名反解元数据」的做法在新增套件命名不规范时会静默失真,建议后续补一个覆盖 `stress`、`mm-gen-*`、`-tp4` 等边界的单测。可略读 `by-gpu-count` job 与 JSON 字段部分,属机械扩展。
路由器按请求强制与注入采样契约,拒绝码与指标落地
值得精读,尤其是三处设计决策:(1) `ProbedValue` 三态把「省略 / 可读数字 / 读不出」在反序列化期一次定形,避免了在每次请求上物化客户端大小的 `serde_json::Value`;(2) `parse_as_engine_number` 的注释解释了为什么不能靠推导 pydantic 规则写这个函数(Python 数字字面量规则与 pydantic 在 `1._5`、`1e_5`、`-_1` 上不一致),以及为什么 `reject` 选择 fail-closed;(3) 采样键 last-wins、路由键重复即 400 的非对称设计,理由是「让契约比较的值与引擎真正采样用的值一致」。建议重点关注:注入语义对客户端的影响评估、`Unusable` 误拒的线上可观测性、以及 stack 3 是否真的消除了 `build_outgoing_body` 的额外解析开销。适合作为「如何为跨 fleet 的强制契约编写 fail-closed 守卫、并为灰度准备指标」的工程范例。
为 Router 新增优雅关闭排空配置面与启动校验、告警
值得精读,但**只推荐给关心 router 部署形态与滚动升级语义的人**(k8s / 平台 / Router owner);对模型、内核方向的工程师,读执行摘要即可,因为本 PR 没有任何运行期行为变化。精读时建议关注四个设计决策:① `shutdown_drain_advisory` 的 `>=` 边界与 `grace_declared` 字段(前者决定「drain 正好等于 grace」是否告警,后者决定同一告警是否能被日志聚合去重);② 把秒 → `Duration` 的转换从 `main.rs` 收进 `ServerConfig::shutdown_drain()` 的理由;③ 软 advisory 与硬 `MAX_SHUTDOWN_DRAIN_SECS` 的职责切分,以及它留下的「drain > grace 仍可启动」空隙是否可接受;④ `Default` impl(服务测试)与穷举 `into_config`(约束生产)并存这一对取舍。同时把 #39016 一起拉出来读,才能真正判断这套配置面是否够用。
为 Router e2e worker 限定显存预算并禁用 prefill 图,消除启动 OOM
建议精读,但重点不在 diff(只有 22 行、单一测试基建文件),而在 PR body 的诊断链路。值得关注三点:一是「KV 池按卡容量分配、slack 却被激活预留独占」这条内存计费缺陷的完整账本,它解释了许多人遇到过的‘小模型反而更容易 CUDA graph OOM’现象;二是把测试夹具参数收敛成单个 `CI_WORKER_ARGS` 常量、复用既有 `worker_args` 契约而不改读侧的设计手法;三是作者主动标注的后续动作——应针对 memory profiler 开 issue,让 KV sizing 为 graph capture 预留额度。评审/维护者后续应确认两件事:新增 e2e spec 是否强制携带 `CI_WORKER_ARGS`,以及在更大显存或非 H100 runner 上 0.6 这个比例是否仍然合适。
Router 新增在途 HTTP 计数,随响应体结束才释放
值得精读,但只需聚焦两个文件:`src/server/inflight.rs`(计数原语与 RAII 守卫的设计,全文是标准「streaming 会计」范式)与 `src/server/app.rs` 的 `count_requests`(唯一的接线点,一行 `resp.map(...)` 承载了全部语义)。阅读时重点回答三个问题:(1) 为什么守卫必须挂在响应体而不是 handler future;(2) 为什么必须是 `Drop` 而不是显式 decrement(客户端中途断开);(3) 为什么 `Relaxed` 足够。测试部分值得看的是「非空性验证」思路 —— 作者通过把守卫改回 handler 出口释放来证明测试不是空断言,这种自我证伪值得借鉴。追 #39016 时建议回看本 PR,确认 drain 的等待条件确实基于这条 gauge,并补充 gzip / timeout 层下的在途观测。夹带的 `pd_protocol_binding.rs` 修复可略读。
Router 双端支持 h2c:入站同端口协商、出站按 worker 选协议转发
值得精读,尤其适合关注路由层网络栈的工程师。推荐关注三个设计决策:其一,客户端对象在构造期分裂并在热路径做纯选择,这是把“per-worker 属性”落到共享代理对象上的通用解法,可直接迁移到其他按 worker 差异化的配置项;其二,`admin_client()` 把“扇出型流量不属于任何 worker”这一语义显式编码进 API,而不是让调用点随便借一个 worker 的协议;其三,测试用“只讲 HTTP/2 的 mock”与“只讲 HTTP/1.1 的 mock”制造互斥,让错误绑定在线上失败而不是在断言里失败,这套手法比断言“传进去的值是 X”强得多。阅读时建议同时看 #39004(解析规则与 `dials_cleartext` 的 URL 归一化陷阱)以及 `Cargo.toml` 中 `http2` feature 的存在理由,否则容易误以为 `WireProtocol::Http1` 在 TLS 上也只讲 HTTP/1.1。
新增采样契约配置面:类型、解析与启动校验
值得精读。本 PR 展示了一个高质量的「配置面先行、请求路径后置」的分层实现策略,手写解析器、有序 entries 解码、编译期 `ALL`/`index` 一致性断言、启动即失败(fail fast)的运维理念都很有参考价值。重点关注 `sampling.rs` 的解析与校验架构,以及它如何为 Stack 2/3 的注入与拒绝逻辑预留清晰的接口边界。