Prhub

#25725 Fix the misnamed request finish-check method to reflect its mutating semantics

原始 PR 作者 fzyzcjy 合并时间 2026-05-19 09:22 文件变更 8 提交数 1 评论 1 代码增减 +14 / -14

执行摘要

重命名 check_finished 为 update_finish_state 以澄清语义

方法原名 check_finished 从命名上看像是只读谓词,但实际上它具有 state-advancing 副作用:会修改 finished_reason、finished_len、to_finish 等字段,甚至通过 _check_vocab_boundary_finish 覆盖 output_ids。返回值为 None,真正的完成状态需要后续通过 req.finished() 方法获取。同名的 finished() 方法已经是真正的谓词,导致同一词根但语义相反的命名冲突。因此重命名为 update_finish_state,使动词 'update' 和名词 'state' 都明确表达该方法的变更语义。

推荐开发者在类似场景中遵循命名约定:对副作用的修改操作使用动词(update/set/reset),对只读查询使用谓词(is_/has_/finished)。该 PR 虽小但体现了代码清晰度的重要性。

讨论亮点

该 PR 没有引发讨论,变更直观且机械。

实现拆解

  1. 方法定义重命名:在 python/sglang/srt/managers/schedule_batch.py 的 Req 类中,将 check_finished 方法定义重命名为 update_finish_state,签名保持不变(new_accepted_len: int = 1)。

  2. 批处理处理器调用点更新:在 python/sglang/srt/managers/scheduler_components/batch_result_processor.py 的四处位置(process_batch_result_prebuiltprocess_batch_result_prefill 两处、process_batch_result_decode)将 req.check_finished(...) 替换为 req.update_finish_state(...),同时更新了相关的注释文字。

  3. DLLM 调度器调用点更新:在 python/sglang/srt/dllm/mixin/scheduler.py 的 process_batch_result_dllm 中替换调用。

  4. 投机解码验证阶段更新:在 python/sglang/srt/speculative/eagle_info.py(两处)、dflash_info.py 和 ngram_info.py 中替换调用。

  5. 注释更新:在 python/sglang/srt/disaggregation/decode_schedule_batch_mixin.py 和 python/sglang/srt/managers/schedule_policy.py 中更新了描述性注释,将 check_finished 替换为 update_finish_state

  6. 无测试变更:所有改动均为纯文本替换,不涉及行为变化,因此未修改测试文件。

文件 模块 状态 重要度
python/sglang/srt/managers/schedule_batch.py 调度器 modified 5.35
python/sglang/srt/managers/scheduler_components/batch_result_processor.py 调度器 modified 5.21
python/sglang/srt/dllm/mixin/scheduler.py DLLM 调度 modified 4.13
python/sglang/srt/speculative/eagle_info.py 投机解码 modified 4.1

关键符号

update_finish_state

关键源码片段

python/sglang/srt/managers/schedule_batch.py core-logic

重命名核心方法定义,是所有调用的源头。

def update_finish_state(self, new_accepted_len: int = 1):
    """
    更新请求的完成状态,而非仅仅检查。
    这是对原 check_finished 的重命名,以反映其修改语义。
    """
    # 如果已经完成则直接返回
    if self.finished():
        return
​
    # 处理通过 to_finish 提前设置的终止原因
    if self.to_finish:
        self.finished_reason = self.to_finish
        self.to_finish = None
        return
​
    # 检查是否达到最大新 token 数
    if len(self.output_ids) >= self.sampling_params.max_new_tokens:
        self.finished_reason = FINISH_LENGTH(
            length=self.sampling_params.max_new_tokens
        )
        self.finished_len = self.sampling_params.max_new_tokens
        return
​
    # 检查 grammar 是否终止
    if self.grammar is not None:
        if self.grammar.is_terminated():
            self.finished_reason = FINISH_MATCHED_TOKEN(matched=self.output_ids[-1])
            return
​
    new_accepted_tokens = self.output_ids[-new_accepted_len:]
​
    # 依次检查多种终止条件
    if self._check_token_based_finish(new_accepted_tokens):
        return
    if self._check_vocab_boundary_finish(new_accepted_tokens):
        return
    if self._check_str_based_finish():
        return
python/sglang/srt/managers/scheduler_components/batch_result_processor.py core-logic

最主要的调用者,包含四处调用点和多处注释更新。

# process_batch_result_prebuilt 中的调用示例
for req in batch.reqs:
    req.time_stats.set_decode_prebuilt_finish_time()
    # 原为 req.check_finished(),重命名以反映其修改完成状态的语义
    req.update_finish_state()
    if req.finished():
        req.time_stats.set_quick_finish_time()
        if self.server_args.enable_hisparse:
            self.hisparse_coordinator.request_finished(req)
        release_kv_cache(req, self.tree_cache)# process_batch_result_prefill 中的调用示例
for i, (req, next_token_id) in enumerate(zip(batch.reqs, next_token_ids)):
    if req.finished() or req.is_retracted:
        continue
    if req.inflight_middle_chunks <= 0:
        req.time_stats.set_prefill_finished_time()
        req.output_ids.append(next_token_id)
        self._maybe_update_reasoning_tokens(req, next_token_id)
        # 原为 req.check_finished()
        req.update_finish_state()
        if req.finished():
            self._maybe_collect_routed_experts(req)
            self._maybe_collect_indexer_topk(req)
            release_kv_cache(req, self.tree_cache)
            req.time_stats.set_completion_time()
        elif not batch.decoding_reqs or req not in batch.decoding_reqs:
            maybe_cache_unfinished_req(req, self.tree_cache)

评论区精华

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

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

风险与影响

风险极低:所有改动均为纯机械重命名,不涉及逻辑变更。但需确认没有遗漏调用站点;由于改动文件覆盖了主要调度路径和投机解码路径,遗漏可能性较小。如果有外部代码依赖原始方法名(如自定义插件或 fork),可能会中断,但仓库内部已完全覆盖。

对用户无影响。对开发者提升了代码可读性,消除了命名歧义,降低了将变体方法误当作谓词使用的风险。未来维护者能更直观地理解该方法会修改状态。

低风险 纯重命名

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论