/label add good-first-issue


认领这个任务


认领这个任务
@hazhang94
欢迎认领任务,请参考https://gitcode.com/Ascend/MindSpeed-MM/issues/356 社区任务池明确该任务的:
- 完成的截止日期
- 开发进展反馈
- 微信答疑群
- 任务交付注意事项
等信息。如果您同时认领了多项任务,但无法都能进行投入,可以在部分任务中回复退出.
麻烦您加入到对应微信群,群备注名修改为"社区任务+您的gitcode账号", 后续有相关消息和问题都可以在微信群咨询答疑。 等您加入到微信群后,我这边会在社区任务池里面登记任务责任人。


认领这个任务
欢迎参加认领社区任务,当前一个任务只分配一个开发,根据评论认领时间确定,您可以后续观察该任务是否被释放退出,或者认领其他任务 https://gitcode.com/org/Ascend/discussions/4


认领这个任务


@Ronald1995 已提交PR
VoxCPM2 适配与调优实践(MindSpeed-MM FSDP2) 实践文档
VoxCPM2 是 OpenBMB 的 tokenizer-free 连续隐变量 TTS 模型(MiniCPM4 主干 + Local
Encoder + Local DiT + AudioVAE),仅开放权重/推理代码、无训练管线。本文记录将其
以插件方式接入 MindSpeed-MM 新版 FSDP2 训练后端,并在 Ascend 910C 上完成全参/LoRA
微调、收敛验证与 MFU 评估的全过程。
目录结构
mindspeed_mm/fsdp/models/voxcpm2/:模型插件(@model_register("voxcpm2")包装类- vendoring 的上游 modeling 子集 +
npu_patch.py)
- vendoring 的上游 modeling 子集 +
mindspeed_mm/fsdp/data/datasets/voxcpm2/:数据插件(@data_register("voxcpm2")+collate_fn)mindspeed_mm/fsdp/tools/flops_tool/flops_voxcpm2.py:MFU/FLOPs 估算工具examples/voxcpm2/:YAML 配置、启动脚本、离线预处理脚本preprocess.py、收敛验证脚本eval_loss.py
适配要点
- 自定义模型路径:VoxCPM2 的
config.json缺少 HF 的model_type/architectures,
ModelHub.build自动回退到自定义构建器,调用包装类的from_pretrained(ModelArguments)。
包装类同时继承nn.Module与BaseModel,实现from_pretrained(加载真实权重)与
_from_config(meta/随机初始化)。 - loss 契约:
features.loss_cfg.loss_type=raw时 trainer 直接取forward返回对象的
.loss。包装类把上游loss/diff、loss/stop按权重求和后输出,同时保留两项明细。 - 设备管理:上游模型内部含
.to(self.device),包装类在forward入口将
self.model.device指向输入张量所在设备,使其变为 no-op,避免与 FSDP 设备搬运冲突。 - 裁剪推理态结构:训练不使用自回归 KV cache,构造后置空;离线预计算 latent 后删除
audio_vae子模块,避免 FSDP2 对 weight_norm 参数化的分片并节省显存。 - 数据契约:dataset 自带
collate_fn,产出与forward完全对齐的扁平张量
(text_tokens/text_mask/audio_feats/audio_mask/loss_mask/position_ids/labels)。
性能优化(面向 MFU)
- 离线预计算 AudioVAE latent(主优化):
preprocess.py将每条音频一次性编码为 latent
存盘,训练步彻底移除 VAE 编码。dataset 只消费 latent,不再依赖 librosa/AudioVAE。 - NPU 融合算子:
npu_patch.py把 MiniCPM4 的RMSNorm、SwiGLU MLP替换为torch_npu
融合实现。base_lm/residual_lm/encoder/dit 均复用 MiniCPM4,单点 patch 即覆盖全部重算子。 - bf16 RoPE:参考实现把 q/k 先 upcast 到 fp32 再做 rotate-half,profiler 显示这是每层
大块 Cast 算子且使激活峰值翻倍。npu_patch.py改为在 bf16 计算 RoPE(数值与基线一致,
rel<1e-2),实测长序列稳态单步 1069ms → 987ms(-7.7%),MFU 22.7% → 24.6%。
(注:CANN 的npu_rotary_mul融合在此 BNSD/B*N规模下 tiling 失败,故保留 rotate-half 形式。) - 混合精度:
param_dtype=bf16+reduce_dtype=fp32。 - 显存充裕时默认关闭重计算以保住 MFU;显存吃紧再开启
recompute(注意会降低 MFU)。
数据准备
以单说话人英文 TTS 数据集 ylacombe/jenny-tts-6h 为例(任意 {audio, text} 数据集均可):
export HF_ENDPOINT=https://hf-mirror.com # 视网络环境
hf download ylacombe/jenny-tts-6h --repo-type dataset \
--include "data/train-00000-of-00003.parquet" --local-dir /workspace/data/jenny
# 解析 parquet -> 写出 {audio,text} 原始 manifest(见内部文档示例),再离线编码为 latent:
python examples/voxcpm2/preprocess.py \
--model_path /workspace/models/openbmb/VoxCPM2 \
--input_manifest /workspace/data/jenny/raw.jsonl \
--output_manifest /workspace/data/jenny/train.jsonl \
--feat_dir /workspace/data/jenny/feats --device npu
- 输入 JSONL:每行
{"audio": "<wav/flac>", "text": "..."[, "ref_audio": "..."]} - 输出 JSONL:每行
{"feat": "<.pt latent [T',64]>", "text": "..."[, "ref_feat": "..."]}
训练
# 全参微调(修改 voxcpm2_config.yaml 的 dataset_dir / model_name_or_path)
NPUS_PER_NODE=2 bash examples/voxcpm2/finetune_voxcpm2.sh
# LoRA 微调(框架原生 PEFT,仅训练注入到 q/k/v/o_proj 的低秩适配器)
NPUS_PER_NODE=2 bash examples/voxcpm2/finetune_voxcpm2_lora.sh
测试 / 收敛验证
关键说明:VoxCPM2 的每步训练 loss 由 flow-matching(CFM)diff_loss 主导,每步都会
重采样时间步 t 与高斯先验,其期望等于不可约的条件方差,因此原始逐步 loss 即使模型在
学习也基本持平——它不是可靠的收敛信号。
eval_loss.py 固定随机种子(使 t 与噪声在每次评估中完全一致),在固定验证批上评估 loss,
消除方差后即可看出真实下降趋势;带 --train_steps 时还会做一段在线 AdamW 训练并周期性评估:
python examples/voxcpm2/eval_loss.py \
--model_path /workspace/models/openbmb/VoxCPM2 \
--manifest /workspace/data/jenny/train.jsonl \
--train_steps 400 --eval_every 50
实测结果(Ascend 910C × 2 die,bf16)
1) 全参 5000 步(真实 Jenny 数据,mbs=2 / gbs=4,lr=5e-5)
- 稳态单步 ≈ 188 ms,吞吐 ≈ 21.2 samples/s,全程稳定无 NaN/发散。
- 原始逐步 loss 平滑后约 0.838 → 0.836(持平,符合上文 CFM 解释)。
2) 确定性收敛验证(eval_loss.py,固定种子)
| step | total | diff | stop |
|---|---|---|---|
| 0 | 0.8125 | 0.7773 | 0.0359 |
| 100 | 0.7539 | 0.7422 | 0.0128 |
| 250 | 0.7461 | 0.7344 | 0.0125 |
| 350 | 0.7500 | 0.7344 | 0.0156 |
去除采样方差后,total 0.812 → 0.75、diff 0.777 → 0.734、stop 0.036 → 0.015,loss 正常下降。
3) MFU(flops_voxcpm2.py)
单 die 峰值按本机芯片 Ascend910_9382(910C die)官方规格计算:由 CANN 平台配置
cube_core_cnt(24) × (16×16×16 MAC) × 2 × cube_freq(1.8GHz) = 353.9 TFLOPS(BF16 dense)。
FLOPs 按各塔真实计算的(含 padding)序列长度统计:base/residual_lm L=830,encoder T=830,
LocDiT 每帧 T=830 个内序列、内长 mu(2)+t(1)+cond(4)+x(4)=11。
| 场景 | 序列 | batch | 单步 | 单 die 吞吐 | MFU |
|---|---|---|---|---|---|
| 真实长序列(fp32 RoPE 基线) | L=830 | mbs=4 / gbs=8 | 1.069s | 80.4 TFLOP/s | 22.7% |
| 真实长序列(bf16 RoPE,本工作) | L=830 | mbs=4 / gbs=8 | 0.987s | 87.1 TFLOP/s | 24.6% |
长序列稳态取 180 步中后 150 步中位数(min 982ms,极稳),loss/grad 与基线逐位一致。
优化与瓶颈分析:profiler(level1)显示设备约 99% 繁忙,matmul 42% + FlashAttention 26%
(均已是最优融合算子),其余为 RoPE/逐元素/拷贝。可行且有正收益的优化只有 bf16 RoPE;
以下尝试经实测无正收益已回退:增大 batch(mbs≥6 OOM,单 die 61GB 显存饱和)、
activation_offload/recompute(换显存上 batch 反而拉低 MFU)、enable_gqa(NPU FA dense 路径更快)、
npu_add_rms_norm(无反向核,训练不可用)。
LoRA
voxcpm2_lora_config.yaml 启用 training.lora,注入 q/k/v/o_proj,冻结基座仅训练适配器。
最小 E2E 实测显存约 14GB(全参约 22GB)。


认领这个任务


@hazhang94
请您在完成任务后填表登记:MM社区任务管理 https://www.kdocs.cn/l/cdATVWqoh385,并将pr关联此issue,并确保pr的ci通过


@hazhang94 您好!
MindSpeed-MM 邀请您参加 2026-08-20 16:00 召开的WeLink会议
会议主题:MindSpeed MM 社区例会
会议内容:
1.社区关键issue解答
2.代码合入评审
会议链接:https://meeting.huaweicloud.com:36443/#/j/980887584
会议纪要&签到链接:https://etherpad.ascend.osinfra.cn/p/sig-MindSpeed-MM


任务描述
基于MindSpeed MM开放仓库的FSDP2源码,补齐模型的端侧功能。
本期任务的具体信息如下:
(1)模型名称:VoxCPM2(https://github.com/OpenBMB/VoxCPM/blob/main/scripts/train_voxcpm_finetune.py)
(2) MindSpeed MM开放仓库的模型源码链接:
https://gitcode.com/Ascend/MindSpeed-MM
(3) 开发平台:Atlas 800T A2或者A3
验收标准
一、任务交付件
本期任务为基于MindSpeed MM开放仓库代码进行功能扩展,请合入开发代码。主要开发点如下:
(1) 模型适配
(2) 模型优化实现
二、验收标准:
1)精度/性能要求
精度:
训练5000步loss正常下降
性能:
MFU 不低于24
2)实践文档:
模型适配调优文档1篇
3)任务完成标准
本次任务完成标准为:
精度/性能(根据实际要求)达标,PR完成合入,实践文档提交到仓库issue。
PR 合入
本地完成测试验证后,向MindSpeed-MM的main分支发起PR。
对接人
待补充
欢迎加入社区,感谢您对社区的贡献 🎉!