# PR #33671 完整报告

- 仓库：`sgl-project/sglang`
- 标题：[Bugfix] Treat unsharded model.safetensors as HF weights in Mistral-native format detection
- 合并时间：2026-08-05 16:54
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/33671

---

# 执行摘要

- 一句话：修复未分片 HF 权重未被识别导致的 Mistral 加载崩溃
- 推荐动作：值得精读。改动虽小（1 文件 9 行），但位于权重加载格式自动检测的核心决策点，修复了 Mistral 双子模型开箱即崩的问题。值得关注的设计点：一是 AUTO 加载路径与 filter_duplicate_safetensors_files 去重配合，实现检测翻转后自动选择正确权重文件；二是 HF-API 分支用根目录限定避免子目录误判，保持与本地 glob 语义一致。若团队后续维护 Mistral 系新模型，建议为该检测逻辑补充单元测试，避免回归。

# 功能与动机

PR body 明确指出：Shieldstral-1.0-3B 和 Ministral-3-3B-Instruct-2512 仓库同时携带未分片 HF model.safetensors 与 Mistral-native consolidated.safetensors/params.json/tekken.json，而 _is_mistral_native_format() 仅按分片模式 model-*.safetensors 判定 'HF weights present'，未分片单文件 checkpoint 不被识别，于是自动设置 load_format=mistral，加载器读取 Mistral-native 权重名，最终在 Mistral3ForConditionalGeneration.load_weights 中因找不到 layers.0.attention.wk.weight 或 layers.0.attention.k_fake_quantizer.qscale_act 而崩溃。

# 实现拆解

1. 定位检测入口：server_args.py 的 _is_mistral_native_format()（约 7328 行）通过 _check_format(has_params, has_consolidated, has_hf_weights) 决定是否强制 load_format=mistral；其设计意图是当同一 checkpoint 同时存在两种权重格式时优先 HF 路径。
2. 本地目录分支：将 has_hf_weights 的 glob 匹配从 model-*.safetensors 改为 model*.safetensors，使未分片 model.safetensors 也能命中，从而让 _check_format 返回 False。
3. HF-API 分支：将文件匹配从 startswith('model-') 放宽为 startswith('model')，并新增 '/' not in f 条件限定仓库根目录，与本地 glob 语义保持一致，避免子目录内同名 safetensors 误判为 HF 权重。
4. 配套与验证：同步更新函数 docstring 中的模式描述；未新增自动化测试（checklist 未勾选测试项），改为在 4x H200 上对 Mistral 家族 8 个仓库做检测翻转矩阵验证；检测翻转后 AUTO 加载路径会同时 glob 两类文件，由既有的 filter_duplicate_safetensors_files 两文件去重逻辑优先选择 model.safetensors，保证权重名与 HF 架构匹配。

关键文件：
- `python/sglang/srt/server_args.py`（模块 加载格式；类别 source；类型 core-logic；符号 _is_mistral_native_format, _check_format）: 修改 _is_mistral_native_format() 的 HF 权重识别逻辑，是本次修复的核心；本地 glob 与 HF-API 两处匹配同时放宽并保持语义一致。

关键符号：_is_mistral_native_format, _check_format

## 关键源码片段

### `python/sglang/srt/server_args.py`

修改 _is_mistral_native_format() 的 HF 权重识别逻辑，是本次修复的核心；本地 glob 与 HF-API 两处匹配同时放宽并保持语义一致。

```python
def _is_mistral_native_format(self) -> bool:
    """判断 checkpoint 是否必须使用 load_format=mistral。

    只要检测到 HF 权重（model*.safetensors），就优先走 HF 加载路径，
    避免把 Mistral-native 命名的权重加载进 HF 命名架构。
    """
    _MISTRAL_NATIVE_PATTERNS = (
        'mistral-large-3',
        'mistral-small-4',
        'leanstral',
    )
    # 名称覆盖：这几类模型家族无论本地文件如何，只要存在 params.json 就按 native 处理
    name_matches = any(
        p in str(self.model_path).lower() for p in _MISTRAL_NATIVE_PATTERNS
    )

    def _check_format(has_params, has_consolidated, has_hf_weights) -> bool:
        # 家族名命中且存在 params.json 时，强制走 Mistral-native 加载
        if has_params and name_matches:
            return True
        # 其他情况：只有存在 consolidated 权重且没有 HF 权重时才返回 True，
        # 即“双格式仓库优先选 HF 路径”
        return has_consolidated and not has_hf_weights

    if os.path.isdir(self.model_path):
        # 本地目录分支用 glob 匹配 model*.safetensors，同时覆盖分片与未分片
        return _check_format(
            has_params=os.path.exists(os.path.join(self.model_path, 'params.json')),
            has_consolidated=bool(
                glob.glob(os.path.join(self.model_path, 'consolidated*.safetensors'))
            ),
            has_hf_weights=bool(
                glob.glob(os.path.join(self.model_path, 'model*.safetensors'))
            ),
        )

    try:
        from huggingface_hub import HfApi

        files = {s.rfilename for s in HfApi().model_info(self.model_path).siblings}
        return _check_format(
            has_params='params.json' in files,
            has_consolidated=any(
                f.startswith('consolidated') and f.endswith('.safetensors')
                for f in files
            ),
            has_hf_weights=any(
                f.startswith('model')
                and f.endswith('.safetensors')
                and '/' not in f  # 只统计 repo 根目录的权重文件，子目录同名文件不参与判定
                for f in files
            ),
        )
    except Exception:
        # HfApi 查询失败（无网络或仓库不存在）时按非 native 处理，交由 AUTO 路径兜底
        return False

```

# 评论区精华

该 PR 没有任何 inline 评论或线程讨论，reviewer JustinTong0323 直接给出 APPROVED 并附言 'LGTM'。关键设计权衡记录在 PR body 中：检测翻转只作用于「consolidated + 未分片根目录 model.safetensors」这一原先必崩的仓库类；native-only、分片双格式、mistral-large-3/mistral-small-4/leanstral 名称覆盖以及显式 --load-format mistral 的路径均不受影响。

- 整体审阅 (other): 无未解决疑虑，批准合并。

# 风险与影响

- 风险：回归面：变更局限于 _is_mistral_native_format() 的匹配宽度，native-only 仓库 has_hf_weights 仍为 False，分片双格式仓库仍为 True，名称覆盖分支提前返回，因此只有原本崩溃的「未分片 HF + consolidated」组合发生行为翻转，回归风险低。
误判风险：startswith('model') + 根目录限定理论上可能将仓库根目录下其他以 model 开头、以 .safetensors 结尾的非权重文件误判为 HF 权重，实际概率很低；本地 glob 同样放宽，存在同类理论风险。
测试缺口：PR 未新增自动化测试，仅靠 4x H200 手动矩阵验证，后续 Mistral 新模型缺少针对该检测逻辑的回归保护，这是主要风险点。
已知无关问题：Mistral-Small-3.2-24B-Instruct-2506 缺少 HF preprocessor_config.json/tokenizer_config.json，在处理器初始化阶段即失败，与本次权重检测无关（PR body 已说明）。

- 影响：对用户：Shieldstral-1.0-3B、Ministral-3-3B-Instruct-2512 等双格式未分片仓库可开箱加载，无需手动 --load-format 纠偏。对系统：仅影响 ServerArgs 加载格式自动判定，不触及推理、调度、KV 管理等运行时路径。对团队：为 Mistral3ForConditionalGeneration 类新模型铺平加载基础，配合 AUTO 加载与 filter_duplicate_safetensors_files 去重形成闭环；整体影响面中等偏小。
- 风险标记：核心路径变更 , 缺少测试覆盖 , 匹配规则放宽

# 关联脉络

- PR #33392 [Refactor] Keep chat template validation out of ServerArgs dispatcher: 同文件 server_args.py 的近期重构，反映 ServerArgs 参数检测 / 校验逻辑正在持续整理；本次修复与其同处一个文件的相邻区域。
- PR #33545 Allow optimistic prefill with L2 hierarchical cache and write-back policy: 同样修改 server_args.py，涉及加载格式相关校验路径，与本次加载格式检测存在间接交集。