已开启
【Feature】VoxCPM2模型支持 #355
Ronald1995创建于  5月18日
Ronald1995
5月18日 创建

任务描述

基于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。

对接人

待补充

欢迎加入社区,感谢您对社区的贡献 🎉!

likedislike
RRonald1995
5月18日 修改了issue 的描述
RRonald1995
5月18日 修改了issue 的描述
js1234567成员
5月18日 评论:

👋 您好,欢迎向 MindSpeed MM 提交 Issue!

我们已收到您的反馈,感谢你对开源社区的支持。🎉

📅 处理时效: 维护团队将在 24 小时内 查看并回复您的问题(工作日)。

🚨 紧急联系: 如果您的问题非常紧急,可通过以下方式联系我们:

💬 微信: WeChat

请确保 Issue 描述清晰,包含复现步骤和日志,这将帮助我们更快定位问题。谢谢!

likedislike
Ronald1995
6月11日 评论:

/label add good-first-issue

likedislike
ascend-robotascend-robot成员
6月11日 添加了label:good-first-issue
hazhang94
6月25日 评论:

认领这个任务

likedislike
gcw_FeESPmVU
6月25日 评论:

认领这个任务

likedislike
Ronald1995
6月26日 评论:

认领这个任务

@hazhang94
欢迎认领任务,请参考https://gitcode.com/Ascend/MindSpeed-MM/issues/356 社区任务池明确该任务的:

  • 完成的截止日期
  • 开发进展反馈
  • 微信答疑群
  • 任务交付注意事项

等信息。如果您同时认领了多项任务,但无法都能进行投入,可以在部分任务中回复退出.

麻烦您加入到对应微信群,群备注名修改为"社区任务+您的gitcode账号", 后续有相关消息和问题都可以在微信群咨询答疑。 等您加入到微信群后,我这边会在社区任务池里面登记任务责任人。

likedislike
Ronald1995
6月26日 评论:

认领这个任务

@gcw_FeESPmVU

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

likedislike
gcw_MTeIQk9o
6月29日 评论:

认领这个任务

likedislike
hazhang94
6月29日 评论:

@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)
  • 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

适配要点

  1. 自定义模型路径:VoxCPM2 的 config.json 缺少 HF 的 model_type/architectures,
    ModelHub.build 自动回退到自定义构建器,调用包装类的 from_pretrained(ModelArguments)。
    包装类同时继承 nn.Module 与 BaseModel,实现 from_pretrained(加载真实权重)与
    _from_config(meta/随机初始化)。
  2. loss 契约:features.loss_cfg.loss_type=raw 时 trainer 直接取 forward 返回对象的
    .loss。包装类把上游 loss/diff、loss/stop 按权重求和后输出,同时保留两项明细。
  3. 设备管理:上游模型内部含 .to(self.device),包装类在 forward 入口将
    self.model.device 指向输入张量所在设备,使其变为 no-op,避免与 FSDP 设备搬运冲突。
  4. 裁剪推理态结构:训练不使用自回归 KV cache,构造后置空;离线预计算 latent 后删除
    audio_vae 子模块,避免 FSDP2 对 weight_norm 参数化的分片并节省显存。
  5. 数据契约:dataset 自带 collate_fn,产出与 forward 完全对齐的扁平张量
    (text_tokens/text_mask/audio_feats/audio_mask/loss_mask/position_ids/labels)。

性能优化(面向 MFU)

  1. 离线预计算 AudioVAE latent(主优化):preprocess.py 将每条音频一次性编码为 latent
    存盘,训练步彻底移除 VAE 编码。dataset 只消费 latent,不再依赖 librosa/AudioVAE。
  2. NPU 融合算子:npu_patch.py 把 MiniCPM4 的 RMSNorm、SwiGLU MLP 替换为 torch_npu
    融合实现。base_lm/residual_lm/encoder/dit 均复用 MiniCPM4,单点 patch 即覆盖全部重算子。
  3. 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 形式。)
  4. 混合精度:param_dtype=bf16 + reduce_dtype=fp32。
  5. 显存充裕时默认关闭重计算以保住 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)。

likedislike
ascend-robotascend-robot成员
7月3日 关联了看板:MindStudio ISSUE管理
Robin
Robin
7月4日 评论:

认领这个任务

likedislike
young256young256成员
7月8日 关联了里程碑:MindSpeed 26.2.0
且奏长歌
且奏长歌成员
8月3日 评论:
likedislike
且奏长歌
且奏长歌成员
8月19日 评论:

@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

likedislike
且奏长歌且奏长歌成员
18 天前 关联了里程碑:MindSpeed 26.3.0