Prhub

#22715 [Bug Fix] Fix RunAI streamer: corrupted weights, missing quant init, and broken URIs for multimodal models

原始 PR 作者 junliu-mde 合并时间 2026-05-07 10:20 文件变更 4 提交数 11 评论 12 代码增减 +14 / -6

执行摘要

修复 RunAI 对象存储 URI 在多模态处理器中的解析

关联 Issue #22701 报告了三类 RunAI 流加载器 bug。其中一类是 get_processor() 未处理对象存储 URI,导致多模态模型加载时直接将原始 az:// 等路径传给 HuggingFace,引发崩溃。get_config()get_tokenizer() 已有 URI 解析逻辑,但 get_processor() 缺失,造成不一致。

值得精读。该 PR 展示了如何通过提取公共函数统一多个辅助函数的 URI 处理逻辑,避免重复代码和遗漏。同时也体现了代码审查中发现模式、建议抽象的良好协作。

讨论亮点

Reviewer alexnails 建议将重复的 URI 检查提取为 helper 函数(原评论:"can we make this a helper? it is called many times in this file."),作者采纳并在 common.py 中新增了 resolve_runai_obj_uri。此外,alexnails 还建议为 RunAI loader 添加单元测试以防回归,作者最初添加了测试但后续因冲突移除(相关修复已由 PR #23850 覆盖),最终本 PR 未包含测试。

实现拆解

  1. 提取公共函数:在 common.py 中新增 resolve_runai_obj_uri(model_name_or_path: str) -> str,封装 is_runai_obj_uri 检测和 ObjectStorageModel.get_path 转换逻辑。

  2. 重构 config 和 tokenizer:在 config.pyget_config()tokenizer.py_resolve_tokenizer_name() 中,将原有的内联 if is_runai_obj_uri: … 替换为调用 resolve_runai_obj_uri(),同时将导入从 runai_utils 改为从 common 导入,减少跨模块依赖。

  3. 补全 processor:在 processor.pyget_processor() 函数开头添加 tokenizer_name = resolve_runai_obj_uri(tokenizer_name),使处理器路径也能正确解析对象存储 URI,与 config 和 tokenizer 保持行为一致。

文件 模块 状态 重要度
python/sglang/srt/utils/hf_transformers/common.py HF 工具层 modified 6.49
python/sglang/srt/utils/hf_transformers/config.py 配置加载 modified 5.47
python/sglang/srt/utils/hf_transformers/tokenizer.py 分词器加载 modified 5.47
python/sglang/srt/utils/hf_transformers/processor.py 处理器加载 modified 5.39

关键符号

resolve_runai_obj_uri

关键源码片段

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

核心修复:get_processor 之前缺少 URI 解析,现补全,使多模态模型加载从对象存储可用。

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",
    **kwargs,
):
    # ... 前面可能有一些处理
    revision = kwargs.pop("revision", tokenizer_revision)
    # 新增:在传递给 HuggingFace 前解析 RunAI 对象存储 URI,
    # 避免将原始 az:// 等路径传给 AutoProcessor 导致崩溃
    tokenizer_name = resolve_runai_obj_uri(tokenizer_name)
    # 后续处理与 config / tokenizer 一致(省略)
    if is_mistral_model(tokenizer_name):
        config = load_mistral_config(...)
    ...

评论区精华

建议提取 URI 解析为 helper 函数 设计

Reviewer alexnails 在 `hf_transformers_utils.py` 的评论中建议:"can we make this a helper ? it is called many times in this file."

结论:作者采纳并新增 `resolve_runai_obj_uri` 函数,统一 URI 解析逻辑。 · 已解决

建议为 RunAI loader 添加单元测试 测试

Reviewer alexnails 在 `loader.py` 的评论中建议:"could you add unit test in /registered so this regression does not happen again?"

结论:作者最初添加了测试,但后续因冲突移除(相关修复已由 PR #23850 覆盖),最终本 PR 未包含测试。 · unresolved

风险与影响

风险较低:resolve_runai_obj_uri 的语义与先前内联代码完全一致,config 和 tokenizer 的行为未改变;processor 新增的 URI 解析修正了此前缺失的逻辑。主要风险是 processor 路径缺乏单元测试覆盖(原本 PR 包含的测试因冲突被移除),未来若重构 URI 解析可能回归。建议后续补充对 get_processor 使用对象存储 URI 的测试。

影响范围集中于使用 RunAI 模型流加载器(load_format="runai_streamer"az:///s3:///gs:// 路径)且采用多模态模型的用户。修复后这些用户可以正常加载模型,不再因处理器崩溃而失败。对仅使用本地或 HuggingFace 路径的用户无影响。

缺少处理器单元测试

关联 Issue

#22701 [Bug] RunAI streamer (#17948): corrupted weights, missing quant init, and broken object-storage URIs for multimodal models

完整报告

参与讨论