Prhub

#25643 fix: get_processor fails when --tokenizer-path lacks model config.json

原始 PR 作者 JINO-ROHIT 合并时间 2026-06-17 01:25 文件变更 4 提交数 14 评论 9 代码增减 +12 / -0

执行摘要

修复 --tokenizer-path 缺少 config.json 时 get_processor 失败

根据 issue #25565,sglang serve 使用多模态模型并指定独立的 --tokenizer-path(不含 config.json)时会崩溃,因为 get_processor 通过 AutoConfig.from_pretrained(tokenizer_path) 读取 model_type,而 tokenizer 路径中没有 config.json 导致失败。需要从 --model-path 获取配置作为回退。

该 PR 修复了一个实际问题,代码清晰且讨论中采纳了更好的设计(if-elif 替代 try-except)。值得精读,尤其是 get_processor 中的 fallback 模式可作为类似场景的参考。

讨论亮点

review 中 ch-wan 提出“能否避免 try-except,使用显式的 if-else 条件?”(评论于 processor.py 的 diff hunk)。作者 JINO-ROHIT 回应“done!”,随后提交了改用 elif 的版本。该讨论已解决,最终代码采用清晰的 if-elif-else 结构,提升了可读性。

实现拆解

  1. 在 get_processor 中添加 model_name 参数processor.py):函数签名新增 model_name: Optional[str] = None,并在配置加载逻辑中插入 elif model_name is not None: 分支,使用 AutoConfig.from_pretrained(model_name, ...) 获取 config,作为 tokenizer 路径无 config 时的回退。
  2. 在 scheduler.py 的 init_tokenizer 中传递 model_name:调用 get_processor 时添加 model_name=server_args.model_path
  3. 在 tokenizer_manager.py 的 _get_processor_wrapper 中传递 model_name:两处调用(初始调用和 fallback 调用)均添加 model_name=server_args.model_path
  4. 在 tp_worker.py 的 init 中传递 model_name:多模态分支调用 get_processor 时添加 model_name=server_args.model_path
    所有改动均在多模态分支内,不影响非多模态或已有 config.json 的场景。
文件 模块 状态 重要度
python/sglang/srt/utils/hf_transformers/processor.py 处理器 modified 5.84
python/sglang/srt/managers/scheduler.py 调度器 modified 4.96
python/sglang/srt/managers/tokenizer_manager.py 分词器管理 modified 4.89
python/sglang/srt/managers/tp_worker.py 工作进程 modified 4.35

关键符号

get_processor init_tokenizer _get_processor_wrapper

关键源码片段

python/sglang/srt/utils/hf_transformers/processor.py core-logic

核心修复:在 get_processor 中添加 model_name 参数和 fallback 分支,是本次变更的枢纽。

# python/sglang/srt/utils/hf_transformers/processor.py (modified)def get_processor(
    tokenizer_name: str,
    *args,
    tokenizer_mode: str = "auto",
    trust_remote_code: bool = False,
    tokenizer_revision: Optional[str] = None,
    use_fast: Optional[bool] = True,
    tokenizer_backend: str = "huggingface",
    model_name: Optional[str] = None, # 新增参数:模型路径(含完整 config.json)
    **kwargs,
):
    # ... 省略前面处理 fastokens 等逻辑
​
    # 获取 config 决定 model_type
    if is_mistral_model(tokenizer_name):
        config = load_mistral_config(tokenizer_name, ...)
    elif model_name is not None:
        # 当 tokenizer 路径缺少 config.json 时,使用 model_path 加载
        config = AutoConfig.from_pretrained(
            model_name,
            trust_remote_code=trust_remote_code,
            revision=revision,
            **kwargs,
        )
    else:
        config = AutoConfig.from_pretrained(
            tokenizer_name,
            trust_remote_code=trust_remote_code,
            revision=revision,
            **kwargs,
        )
    # ... 后续根据 config.model_type 处理不同类型的 processor

评论区精华

使用 if-elif 替代 try-except 实现 fallback 设计

ch-wan 建议避免使用 try-except,改用显式的 if-else 条件,使逻辑更清晰。

结论:作者接受建议,将实现从 try-except 改为 if-elif-else。 · 已解决

风险与影响

  1. 配置不匹配风险:当 tokenizer 路径无 config 时,回退从 model_path 加载 config。若 model_path 也不存在或模型类型不匹配,仍可能失败,但至少提供了合理的 fallback。
  2. 回归风险低:改动集中在多模态分支的 get_processor 调用处,非多模态路径未受影响。
  3. 缺少测试覆盖:当前 PR 未添加新测试,若未来修改相关逻辑可能引入回归。

用户影响:修复了使用独立 tokenizer 路径的多模态模型启动崩溃,用户无需再为 tokenizer 目录放置 config.json。
系统影响:get_processor 函数增加一个可选参数,调用者均需传递 model_path,但用于多模态场景,不影响其他功能。
团队影响:改动小且集中,审查和合并不复杂。

缺少测试覆盖 fallback 可能隐藏配置不匹配

关联 Issue

#25565 [Bug] `sglang serve` failed with multimodal model when using a standalone `--tokenizer-path`

完整报告

参与讨论