执行摘要
- 一句话:Voyage 模型改用 AutoWeightsLoader
- 推荐动作:值得精读,展示了如何将手动融合逻辑迁移到 AutoWeightsLoader。其他模型维护者可参考此模式,理解 packed_modules_mapping 和组合子模块的用法。
功能与动机
遵循 issue #15697 的要求,将 Voyage 模型迁移至 AutoWeightsLoader 以实现复合模型加载。原来手动融合 QKV 和 MLP 权重的逻辑容易出错且难以维护,标准化为 AutoWeightsLoader 后可以减少模型实现中的重复代码。
实现拆解
- 结构调整:将
VoyageQwen3BidirectionalEmbedModel 从继承 Qwen3Model 改为组合 nn.Module,并添加 self.model 作为 Qwen3Model 子模块。这样避免了继承复杂性,并允许 AutoWeightsLoader 递归遍历子模块。
- 移除手动融合:删除
_fuse_qkv_proj、_fuse_gate_up_proj 方法及相关的 WeightsMapper 和正则表达式。这些融合操作由 AutoWeightsLoader 和 packed_modules_mapping 自动完成。
- 添加 packed_modules_mapping:在类上定义
packed_modules_mapping,映射 qkv_proj -> ['q_proj', 'k_proj', 'v_proj'] 和 gate_up_proj -> ['gate_proj', 'up_proj'],指导 AutoWeightsLoader 如何从 checkpoint 中查找并融合权重。
- 重写 load_weights:使用
AutoWeightsLoader(self) 并调用其 load_weights(weights),不再需要手动处理前缀和融合。
- 适配新结构:更新
__init__、forward 和添加 embed_input_ids 方法,委托给 self.model,保持接口一致。
关键文件:
vllm/model_executor/models/voyage.py(模块 模型层;类别 source;类型 core-logic;符号 VoyageQwen3BidirectionalEmbedModel, init, forward, _fuse_qkv_proj): 唯一修改的文件,包含 Voyage 模型的全部变更:从手动融合到 AutoWeightsLoader 的迁移。
关键符号:VoyageQwen3BidirectionalEmbedModel.init, VoyageQwen3BidirectionalEmbedModel.forward, VoyageQwen3BidirectionalEmbedModel.load_weights, VoyageQwen3BidirectionalEmbedModel.embed_input_ids, VoyageQwen3BidirectionalEmbedModel._fuse_qkv_proj (removed), VoyageQwen3BidirectionalEmbedModel._fuse_gate_up_proj (removed)
评论区精华
风险与影响
- 风险:主要风险在于
AutoWeightsLoader 对 Voyage checkpoint 键的解析是否正确。Checkpoint 前缀 'model.' 通过 maybe_prefix(prefix, 'model') 处理,但若 packed_modules_mapping 键名与 Qwen3Model 内部 fused 层名不一致,将导致权重加载异常。另外,组合结构下子模块路径变化可能影响权重键匹配,但经由 load_weights 的自动遍历应无问题。
- 影响:影响范围局限于
VoyageQwen3BidirectionalEmbedModel 一个模型。用户需重新加载权重,但语义应保持一致。此 PR 作为 AutoWeightsLoader 推广的示例,有助于后续迁移其他模型。无性能回退,因为 AutoWeightsLoader 内部仍调用相同的 weight_loader。
- 风险标记:AutoWeightsLoader 依赖 packed_modules_mapping, 组合结构可能改变权重路径, 主分支 CI 不稳定影响验证
关联脉络
参与讨论