已开启
【实践文档】Qwen2.5-VL 插件式 FSDP2 模型开发实践(PR !2776 / #382) #789
jacky_leeie创建于  18 天前
jacky_leeie
18 天前 创建

Qwen2.5-VL 插件式 FSDP2 模型开发实践

任务:#382;代码评审:PR !2776。按 2026-08-04 的评审意见,完整实践提交在 issue;仓内 README 负责操作说明。

1. 接入路线与数据

Qwen2.5-VL 是标准 HF dense VLM。使用 Transformers 4.57.0 的 Qwen2_5_VLForConditionalGeneration,由 ModelHub 加载 HF config/权重;插件注册名为 qwen2_5_vl。复用 huggingface dataset、template=qwen2vl 和 collate_param.model_name=qwen3vl(实际注册的是 DataCollatorForQwen2vl)。图像数据采用 messages/images 格式。

分片及重计算路径由 HF 4.57.0 的模块树确定:model.visual.blocks.{*}、model.visual.merger、model.language_model.embed_tokens、model.language_model.layers.{*}、lm_head 等。模型没有稀疏专家,不配置 EP。

2. 评审后的模型改造

原来只注册 HF 类,开启框架 Chunk Loss 会把 lm_head 的接口变成 (hidden_states, loss_func, labels),与 HF 的普通 logits 调用不匹配。本轮用一个小型子类保留非 chunk 分支的 HF forward,chunk 分支调用同一个 HF 多模态 backbone,然后把 hidden_states、训练引擎注入的 loss_function 和 labels 交给 chunk head;避免产生完整 logits。

  • 保留图像/视频处理、mRoPE 和 HF state_dict 键;不复制整份 modeling。
  • chunk 模式要求 labels、logits_to_keep=0、关闭 KV cache;loss_type=raw 与 chunk 模式组合提前报错。
  • ViT 默认不冻结;需要冻结时设置 model.freeze: [model.visual]。此前冻结 ViT 只是小显存 E2E 配置选择,不是模型限制。
  • 通用 chunk MBS 对 hidden_states 与 mRoPE 的 batch 维不一致,当前明确不支持并提前报错,避免照抄 MoE 配置。
  • NPU patch 使用延迟依赖、CPU/GPU 原实现回退和重复调用保护;RMSNorm、视觉 RoPE、文本 SwiGLU 按张量设备选择融合路径,文本 mRoPE 保持原实现。

3. 配置及启动

规范入口为 examples/qwen2.5vl/qwen2_5_vl_3b_config_v1.yaml 和 finetune_qwen2_5_vl_3b_v1.sh,操作手册为该目录的 README_v1.md。原 plugin 路径保留兼容入口,不作为推荐入口。

bash examples/qwen2.5vl/finetune_qwen2_5_vl_3b_v1.sh

配置 HF 权重、图像目录、训练 JSON 和 cache 路径后启动。默认直接加载 HF 权重,training.load: "";meta 初始化或恢复训练时按 README 配置 DCP load 与 optimizer/RNG 开关。checkpoint 保存、profiler 和 memory 参数已补齐;显存特性逐项验证后开启。

4. 本轮真实验证(CPU,2026-10-13)

Python 3.12 / torch 2.8.0a0+5228986c39.nv25.05 / Transformers 4.57.0。当前机器没有 NPU/GPU;本轮不宣称完成昇腾端训练或性能复测。CPU 执行时仅替代 launcher 的环境初始化、MindSpeed logging/名称匹配和 CP 通信环境;模型、图像 forward、分块 loss、自定义 autograd、反向传播、AdamW 和重计算使用真实实现。

tests/ut_fsdp/models/test_qwen2_5_vl.py:20 项 CPU 回归通过;1 项昇腾 BF16 FA + Chunk Loss 专项测试因缺少硬件跳过。

  • 文本/图文、不同 chunk_size、default/per_sample_loss:loss 及所有有梯度参数对齐。
  • Chunk Loss + 重计算组合:loss/梯度对齐。
  • ViT 冻结时无梯度,不冻结时有有限非零梯度。
  • SDPA 与 eager 对齐;tuple 输出、动态 chunk 路由和非法组合检查通过。
  • 固定随机种子 42 的小型随机图文模型、同一合成 batch、30 次 AdamW 更新:基线 loss 4.214021 → 3.405616;Chunk Loss 对照最大绝对差 4.76837158203125e-7,最大相对差 1.223798998846753e-7。

在已安装完整 MindSpeed-MM 依赖的环境中:

NON_MEGATRON=true QWEN25VL_DISABLE_NPU_FUSION=1 \
  python -m pytest tests/ut_fsdp/models/test_qwen2_5_vl.py -k 'not npu' -q

昇腾专项入口(须使用真实 NPU 与完整框架 bootstrap):

NON_MEGATRON=true python -m pytest \
  tests/ut_fsdp/models/test_qwen2_5_vl.py -k npu -q

CPU 的小模型数值验证不等同于完整 3B 模型的 NPU FSDP2/HCCL 验证。

5. 历史 E2E 与后续验证范围

原 PR 于 7 月记录了 2×Ascend 910 / CANN 9.0.0 / torch 2.7.1 / torch_npu 2.7.1.post6 / Transformers 4.57.0 的 30 步 3B E2E,使用冻结 ViT、SDPA 和重计算。本轮没有重新访问原始训练日志,不将这组旧结果当作当前提交通过 NPU 验证的依据。

FA 的接入路径存在:HF attention 接口经 NON_MEGATRON bootstrap 注册到框架 NPU fusion attention;当前默认保留 SDPA,FA、NPU Chunk Loss、activation offload 和新默认不冻结 ViT 的完整分布式训练仍需目标环境验证。性能实践另以 issue 提交,并提供历史观测点图与本轮 CPU 对比图。

本轮代码提交:53639ea。

likedislike
Jjacky_leeie
18 天前 修改了issue 的描述
yeqm成员
18 天前 评论:

您好,感谢您提交 Issue。关于【实践文档】Qwen2.5-VL 插件式 FSDP2 模型开发实践(PR !2776 / #382),我们会结合相关信息进一步核查。

该问题可能与正在跟进中的 #790 为相似问题,可关注相关 Issue 的进展。

有进展我们会在本 Issue 中同步。感谢您的支持!

likedislike
Yyeqm成员
18 天前 关联了里程碑:MindSpeed 26.3.0