已关闭
【实践文档】:glm4.5v开发模型实践 #560
SuperKoalaKing创建于 8月4日关闭于 9月15日
8月4日 修改了issue 的描述
yeqm
8月21日 评论:
8月21日 评论:
👋 您好,欢迎向 MindSpeed MM 提交 Issue!
我们已收到您的反馈,感谢你对开源社区的支持。🎉
📅 处理时效: 维护团队将在 24 小时内 查看并回复您的问题(工作日)。
🚨 紧急联系: 如果您的问题非常紧急,可通过微信联系我们。
请确保 Issue 描述清晰,包含复现步骤和日志,这将帮助我们更快定位问题。谢谢!


9月15日 issue状态由 TODO 改变为 DONE
9月15日 关闭了 issue
9月15日 添加了label:resolved
MindSpeed MM FSDP2 模型迁移实践(GLM-4.5V,megatron 后端 → 纯 FSDP2 后端)
概述
本文记录将 GLM-4.5V(106B MoE 多模态理解模型) 从 MindSpeed MM 的 megatron-FSDP2 路径
(
mindspeed_mm/models/transformers/glm4v_moe/+pretrain_transformers.py)迁移到插件式纯 FSDP2 后端(
mindspeed_mm/fsdp/+trainer.py)的完整过程与验证方法(对应 issue #370)。
本文不重复共性内容,聚焦 GLM-4.5V 的差异点、双后端等价性验证方法与实测踩坑。
源模型结构与迁移重点
GLM-4.5V 的参考实现为 Transformers(≥4.57)原生
Glm4vMoeForConditionalGeneration:mindspeed_mm/fsdp/models/glm4_5v/modeling_glm4_5v.py(注册 id:glm4v_moe)huggingface数据集 + templateglm4v_moe+ collatorqwen3vlmm-convert ExpertMergeDcpConverter,转换脚本examples/glm4.5v/convert_glm4_5v_ckpt.shexamples/glm4.5v/glm4_5v_full_sft_106B.yaml+finetune_glm4_5v_106B_fsdp.sh模型接入采用薄封装继承 HF 原生类:
__init__内将 RMSNorm、多模态/视觉 RoPE、视觉 embeddings替换为 NPU 融合版(自已验证的 megatron 侧实现移植并去除 Megatron 依赖),支持 chunk-loss 前向,
非 NPU 环境自动回退原生实现。
差异点一:MoE 专家权重布局
同一个模型在两个后端需要两种专家布局,这是 GLM-4.5V 迁移与 Qwen3-VL 接入最大的不同:
(E*in, out)glm_4v_moe_text实现的契约(E, in, out)Shard(0)切分 +npu_grouped_matmul融合前向的契约(同Qwen3VLMoeTextExperts)共享转换器
checkpoint/vlm_model/converters/moe_expert.py据此做成环境变量门控:默认保持上游 2D 展平(megatron 侧转换不受影响),
GLM4V_DCP_3D=1时输出 3D(
convert_glm4_5v_ckpt.sh已内置)。若把 3D 做成无条件默认,会直接破坏 megatron侧的既有转换——我们在实测中踩过这一回归(加载报
Size mismatch saved (8,4096,2816) vs current (32768,2816)),迁移同类双后端共存模型时务必注意。3D 布局契约可零卡时静态验证:
python examples/glm4.5v/verify_expert_layout.py(转换器输出形状 == 模型参数形状,且堆叠前向与 HF 逐专家前向数值等价,实测 max_err ≈ 2.9e-6)。
差异点二:DCP 键前缀
DCP checkpoint 的键 = Stateful 包裹前缀 + 模块 FQN,而两个后端的包裹层数不同:
model.+ FQN →model.model.language_model.*(两层)--dcp_prefix ""model.+model.(TransformersModel 包装) + FQN → 三层model.model.model.*两个必须养成的习惯:
from torch.distributed.checkpoint import FileSystemReader md = FileSystemReader("<dcp_dir>/release").read_metadata() # 检查键前缀层数、experts 形状维度是否符合目标后端training.load_strict: true:键不匹配立即报错。默认宽松模式下键全 miss会静默随机初始化起训,loss 曲线看起来完全正常,是最难发现的一类错误。
同理,
load_format: hf/from_pretrained路线务必检查日志无newly initialized告警(我们实测过:对堆叠布局模型用逐专家布局的原始 HF 权重from_pretrained,全部 experts 被静默随机初始化且不报错)。
meta-device 初始化(
init_model_with_meta_device: true)下权重只从training.load加载,
model.model_name_or_path仅提供 config——yaml 里漏掉load字段同样表现为静默随机起训。差异点三:MoE 融合的开关位置
纯 FSDP2 后端中,模型内没有 MoE 融合开关:融合(grouped-GEMM)由框架专家并行在
EP≥2 时替换 experts 前向提供,EP=1 时走模型自带的逐专家循环。因此融合/非融合的有效 A/B 是
parallel.expert_parallel_size: 2(含 ep_plan)vs1(删 ep_plan),而不是模型配置里的任何布尔开关(megatron 侧的
use_npu_fused_moe在纯 FSDP2 侧无消费者)。双后端等价性验证方法
精度验收(与 megatron 基线对拍 <2%)的前提是逐级排除变量,我们采用四级验证链,
每级都有对应工具,全部随迁移代码提供:
load_format: hf),确定性模式比逐步 losscompare_runs.py(解析两侧日志,自动判精度<2% + 性能≥基线)第 3 级的两个实测要点:
loss_type: default的实现同构(微批内sum(CE)/有效 token → 梯度累积内平均 → DP 组平均),但 megatron 侧样例配置默认
per_token_loss(按 DP 全局平均 token 数归一),两种口径不可由日志事后换算,对拍时须把基线配置临时覆盖为
default。get_batch层的专用入口examples/glm4.5v/dump_entry_megatron.py;纯 FSDP2 侧可用examples/glm4.5v/token_dump.py wrap。训练 YAML 要点(相对 Qwen3-VL 篇的增量)
parallel: fsdp_plan: apply_modules: # 按 GLM 模块树填写 - model.visual - model.visual.blocks.{*} - model.language_model - model.language_model.embed_tokens - model.language_model.layers.{*} - model.language_model.layers.{*}.mlp.experts - lm_head expert_parallel_size: 2 # EP>=2 走框架融合 grouped-GEMM ep_plan: apply_modules: - model.language_model.layers.{*}.mlp.experts training: init_model_with_meta_device: true load: <DCP 目录> # meta 初始化下权重唯一来源,勿漏 load_format: dcp load_strict: true # 强烈建议:杜绝静默随机起训 no_load_optim: true no_load_rng: truefsdp_plan/ep_plan 的模块路径可用
examples/glm4.5v/preflight_check.py零卡时校验(meta 构建模型后逐条模式匹配,避免上卡后才报
[FSDP2] No module named ...)。实测踩坑
training.load或 DCP 键前缀不匹配 → 静默随机起训load_strict: true;上卡前验键名GLM4V_DCP_3DGLM4V_DCP_3D=1 mm-convert moe_expert --style merge得堆叠 safetensors;grepnewly initialized把关preprocessing_num_workers: null走主进程内联MoeTokenUnpermuteGrad ... shape has 0交付与验证状态
小规模验证(tiny 同构模型 + 真实 LLaVA/COCO 图文样本,单卡,token 流逐位一致前提下):
精度以验收原文的 2000 步口径达标——2048 样本 × 2000 步平均相对误差 0.378%(<2%);
性能在 tiny 单卡为持平量级(±2~4%,符号随硬件翻转,非固有回归),权威性能结论待满规模。
数据与复现命令、多组结果详见性能优化实践篇。