Prhub

#41448 Refractor longcat loading to use AutoWeightsLoader

原始 PR 作者 Yuyi-Ao 合并时间 2026-05-01 17:07 文件变更 1 提交数 3 评论 5 代码增减 +82 / -73

执行摘要

LongcatFlash 权重加载迁移至 AutoWeightsLoader

为标准化复合模型的权重加载方式,减少重复代码。参见 Issue #15697。原作者提到当前只有部分语言骨干实现了 load_weights,希望通过 AutoWeightsLoader 统一所有模型。

值得精读,展示了 AutoWeightsLoader 的标准使用模式,可作为其他模型从手动加载迁移到统一委托的参考。同时关注 review 中对死代码的监督,保持代码整洁。

讨论亮点
  • get_expert_mapping 死代码问题:gemini-code-assist[bot] 指出新 LongcatFlashForCausalLM 中的 get_expert_mapping 是死代码,建议删除。作者回应已将其改为委托给 FlashModel.get_expert_mapping,匹配其他 MoE 模型模式(如 Qwen2MoeForCausalLM),避免重复加载逻辑。
  • DCO 修复:DarkLight1337 要求修复 DCO,作者确认修复。

实现拆解

  1. 导入 AutoWeightsLoader:在 longcat_flash.py 中从 .utils 新增导入 AutoWeightsLoader
  2. FlashModel 增强:在 FlashModel.__init__ 中增加 self.quant_config = quant_config,并将原 LongcatFlashForCausalLM.load_weights 中的 MoE 权重加载逻辑移入 FlashModel,同时实现 get_expert_mapping
  3. 重写 LongcatFlashForCausalLM:删除旧类,在文件末尾重新定义,__init__ 中通过 FlashModel 初始化并单独处理 lm_headlogits_processor
  4. 新加载函数:LongcatFlashForCausalLM.load_weights 使用 AutoWeightsLoader(self) 递归加载所有子模块权重,FlashModel.load_weights 自动被调用处理 MoE 及通用层权重。
  5. 委托 get_expert_mapping:将 LongcatFlashForCausalLM.get_expert_mapping 改为调用 self.model.get_expert_mapping(),避免重复逻辑。
  6. 测试配套:本地通过模型注册、编译和 GPU 初始化测试,但未新增独立测试文件。
文件 模块 状态 重要度
vllm/model_executor/models/longcat_flash.py 权重加载 modified 8.75

关键符号

LongcatFlashForCausalLM.load_weights FlashModel.load_weights LongcatFlashForCausalLM.__init__ FlashModel.__init__

关键源码片段

vllm/model_executor/models/longcat_flash.py core-logic

唯一变更文件,重构了 LongcatFlashForCausalLM 和 FlashModel 的权重加载架构。

# -*- coding: utf-8 -*-
# 关键变更:LongcatFlashForCausalLM 使用 AutoWeightsLoader 委托加载from .utils import AutoWeightsLoader # 新增导入class FlashModel(nn.Module):
    # ... 
    def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""):
        # ...
        self.config = config
        self.quant_config = quant_config # 新增,供 load_weights 使用
        # ...
​
    def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
        """包含 MoE 专家权重和通用层权重的加载逻辑。原 LongcatFlashForCausalLM.load_weights 移入此处。"""
        params_dict = dict(self.named_parameters())
        loaded_params: set[str] = set()
        for name, loaded_weight in weights:
            # 子层权重由子模块自身加载,不在此处理
            param = params_dict.get(name)
            if param is not None:
                weight_loader = getattr(param, "weight_loader", default_weight_loader)
                weight_loader(param, loaded_weight)
                loaded_params.add(name)
        # 处理 MoE 专家权重(量化感知)
        for layer_id in range(self.config.num_hidden_layers):
            for i in range(2):
                if isinstance(self.layers[layer_id], PPMissingLayer):
                    continue
                self_attn = self.layers[layer_id].self_attn[i]
                if hasattr(self.quant_config, "weight_block_size"):
                    expert_mapping = self.get_expert_mapping()
                    # ...(具体专家权重加载循环)
        return loaded_params
​
    def get_expert_mapping(self) -> list[tuple[str, str, int, str]]:
        # 与原来相同的专家参数映射
        # ...class LongcatFlashForCausalLM(nn.Module, SupportsLoRA, SupportsPP):
    # ... __init__ ...
    def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
        # AutoWeightsLoader 自动递归调用子模块(如 model)的 load_weights
        loader = AutoWeightsLoader(self)
        return loader.load_weights(weights)
​
    def get_expert_mapping(self):
        # 委托给 FlashModel,避免重复封装
        return self.model.get_expert_mapping()

评论区精华

get_expert_mapping 方法是否死代码 设计

gemini-code-assist[bot] 指出新类 LongcatFlashForCausalLM 中的 get_expert_mapping 是死代码,因为权重加载已由 AutoWeightsLoader 委托给 FlashModel。

结论:作者按建议将方法改为委托实现,匹配其他 MoE 模型模式。 · 已解决

DCO 修复 other

DarkLight1337 要求修复 DCO(提交签名),作者确认修复。

结论:已修复 DCO。 · 已解决

风险与影响

重构不改变模型行为,风险较低。但存在以下潜在风险:

  • AutoWeightsLoader 的递归加载行为若未覆盖所有子模块,可能导致某些权重未被加载(如 lm_head 需额外处理,但已保留)。
  • get_expert_mapping 最初残留为死代码,虽已修复,但类似遗漏可能影响权重正确性。
  • 缺少端到端测试验证权重加载后的精度一致性(仅测试初始化)。
  • 用户:无直接影响,模型推理行为不变。
  • 系统:便于后续其他模型迁移至 AutoWeightsLoader,统一加载模式。
  • 团队:贡献了标准化重构的参考实现,降低维护成本。
缺少测试覆盖 旧路径残留清理不彻底(get_expert_mapping 最初遗留)

关联 Issue

#15697 [Feature]: Composite model loading using `AutoWeightsLoader` for all models

完整报告

参与讨论