g
gcw_coj3XaOd/vocos-mel-24khz
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

Vocos-mel-24kHz NPU 适配 (Ascend 910)

将 Vocos 声码器模型适配到华为昇腾 Ascend 910 NPU 上运行。

模型信息

项目说明
模型名称Vocos-mel-24kHz
模型来源pengzhendong/vocos-mel-24khz (ModelScope)
模型类型声码器 (Vocoder):Mel 频谱图 → 音频波形
参数量13.53M
采样率24000 Hz
输入Mel 频谱图 (B, 100, T)
输出音频波形 (B, T×256)
原始框架PyTorch

环境要求

依赖版本
OSUbuntu 22.04 LTS
Python3.11+
PyTorch2.9.0
torch_npu2.9.0.post1
CANN8.5.1
vocos0.1.0
scipy1.17+ (音频保存 fallback)
NPUAscend 910 (9362)

适配说明

问题

Vocos 模型在 NPU 上运行时,torch.istft 和 nn.functional.fold 算子不可用:

  • torch.istft 内部调用 nn.functional.fold → col2im → aclnnUnfoldGrad,NPU 不支持
  • nn.functional.fold 直接调用 aclnnIm2colBackward,NPU 不支持

解决方案

用纯 PyTorch 手动实现 ISTFT 的 overlap-add 算法,替代 torch.istft:

  1. IRFFT: 使用 torch.fft.irfft(NPU 原生支持)
  2. 加窗: 对逆 FFT 结果加分析窗
  3. 手动 overlap-add: 用 for 循环逐帧叠加(替代 nn.functional.fold)
  4. 归一化: 用窗函数平方包络归一化
  5. 修剪: 对 center padding 模式从两端各修剪 n_fft//2 个样本

核心适配代码

  • vocos_npu.py:ISTFT 手动实现 + 模型 monkey-patch 加载
  • _patch_istft_head():替换 ISTFT.forward 为 NPU 兼容版本
  • istft_center():center padding 模式的手动 ISTFT
  • istft_same():same padding 模式的手动 ISTFT

适配原理

Vocos 的 ISTFTHead 调用 ISTFT 类的 forward,内部使用 torch.istft。通过 monkey-patch 替换 ISTFT.forward 为手动 overlap-add 实现,无需修改原始 vocos 库代码。

快速开始

安装依赖

pip install vocos torch_npu torchaudio scipy modelscope

下载模型

python3 -c "from modelscope import snapshot_download; snapshot_download('pengzhendong/vocos-mel-24khz')"

Python 推理

import torch
import torch_npu
from vocos_npu import load_vocos_model, decode

# 加载模型到 NPU
model = load_vocos_model("npu:0")

# 准备 mel 频谱图 (B, 100, T)
mel = torch.randn(1, 100, 256, device="npu:0")

# 推理
with torch.no_grad():
    audio = decode(model, mel)

print(f"输出音频: {audio.shape}, 设备: {audio.device}")

命令行推理

# 生成 5 秒随机音频
python3 inference.py --generate --duration 5.0 --output output.wav

# 从 mel 频谱图文件生成
python3 inference.py --input mel.pt --output output.wav

# 指定设备
python3 inference.py --generate --duration 3.0 --device npu:0 --output output.wav

推理正常输出证据

以下为 NPU 上的实际推理输出(Ascend 910_9362,PyTorch 2.9.0 + torch_npu 2.9.0.post1):

============================================================
  Vocos-mel-24kHz NPU 推理
============================================================

  NPU 设备:  Ascend910_9362
  输入:      Mel 频谱图 shape=torch.Size([1, 100, 937])
  输出:      音频波形 shape=torch.Size([1, 239616])
  时长:      9.98s
  范围:      [-0.106428, 0.094721]

  ✅ 推理成功
  ✅ 已保存到 output.wav
============================================================
============================================================
  Vocos-mel-24kHz NPU 适配验证报告
============================================================

【环境信息】
  PyTorch:    2.9.0+cpu
  torch_npu:  2.9.0.post1+gitee7ba04
  NPU 可用:   True
  NPU 设备:   Ascend910_9362
  NPU 数量:   2

【1. CPU 参考推理 (torch.istft)】
  输入 shape:  torch.Size([1, 100, 256])
  输出 shape:  torch.Size([1, 65280])
  输出范围:    [-0.141037, 0.103343]
  输出均值:    -0.002615
  输出标准差:  0.021002

【2. NPU 推理 (手动 overlap-add 替代 torch.istft)】
  输入 shape:  torch.Size([1, 100, 256])
  输出 shape:  torch.Size([1, 65280])
  输出范围:    [-0.141131, 0.103346]
  输出均值:    -0.002614
  输出标准差:  0.021002

【6. 推理正常输出证据】
  NPU 推理成功!
  输入:  Mel 频谱图 shape=torch.Size([1, 100, 937])
  输出:  音频波形 shape=torch.Size([1, 239616])
  时长:  9.98s
  范围:  [-0.106428, 0.094721]

CPU vs NPU 精度对比

端到端对比 (CPU torch.istft vs NPU 手动 overlap-add)

CPU 和 NPU 使用相同输入 Mel 频谱图,分别用 torch.istft 和手动 overlap-add 做 ISTFT 重建:

【3. CPU vs NPU 精度对比 (torch.istft vs 手动 overlap-add)】
  最大绝对误差:  0.001573
  平均绝对误差:  0.000144
  MSE:           0.0000000381
  PSNR:          74.19 dB
  余弦相似度:    0.99995840
  allclose(1e-2): ✅ 通过
  allclose(1e-3): ❌ 未通过

不同序列长度 CPU vs NPU 精度对比

T (帧数)音频时长最大误差平均误差PSNR (dB)余弦相似度allclose(1e-2)
640.67s0.0010030.00014274.420.99996102✅ 通过
1281.35s0.0014360.00014274.340.99995863✅ 通过
2562.72s0.0014990.00015373.850.99995553✅ 通过
5125.45s0.0013480.00015573.750.99995470✅ 通过
102410.91s0.0020670.00015773.600.99995363✅ 通过

结论: 所有长度 allclose(atol=1e-2) 均通过,PSNR > 73 dB,余弦相似度 > 0.99995。误差来源于 Conv1d 等 FP32 算子在 CPU/NPU 上的浮点实现微小差异,不影响音频质量。

ISTFT 算子级精度 (torch.istft vs 手动 overlap-add)

仅对比 ISTFT 算子本身(排除模型其他层的影响):

测试用例最大误差PSNR (dB)allclose
n_fft=1024 T=640.000000inf✅
n_fft=1024 T=1280.000000inf✅
n_fft=1024 T=2560.000000inf✅
n_fft=1024 T=5120.000000inf✅

ISTFT 算子级对比完美匹配(误差为零),说明手动 overlap-add 实现与 torch.istft 完全等价。

运行精度评测

python3 benchmark_accuracy.py

CPU vs NPU 性能对比

推理性能 (T=468, 约5s音频)

【5. CPU vs NPU 性能对比 (T=468, 约5s音频)】
  音频时长:      4.99s
  CPU 推理均值:  246.4ms  RTF=0.0494
  NPU 推理均值:  53.5ms   RTF=0.0107
  加速比:        4.60x
指标CPU (torch.istft)NPU (手动 overlap-add)对比
推理延迟246.4ms53.5msNPU 快 4.60x
RTF0.04940.0107NPU 快 4.60x
实时倍率20.2x93.5xNPU 快 4.60x

NPU 不同长度推理延迟

T (帧数)音频时长均值 (ms)P50 (ms)P95 (ms)RTF实时倍率
640.67s7.857.778.050.011785.6x
1281.35s12.8812.8613.030.0095105.2x
2562.72s23.5323.5823.810.0087115.6x
5125.45s45.0044.9745.220.0083121.1x
102410.91s83.7785.7386.690.0077130.3x
  • 平均 RTF: 0.0092 (109.2x 实时)
  • 峰值显存占用: 99.2 MB

运行性能评测

python3 benchmark_performance.py

验证测试

# 完整验证 (环境检查 + 推理 + 精度对比 + 多长度测试)
python3 vocos_npu.py

# 快速 NPU 验证
python3 test_npu.py

文件结构

vocos-mel-24khz-npu/
├── README.md                # 部署文档
├── vocos_npu.py             # 核心适配代码 (ISTFT 手动实现 + 模型加载)
├── inference.py             # 命令行推理脚本
├── benchmark_accuracy.py    # 精度评测脚本
├── benchmark_performance.py # 性能评测脚本
└── test_npu.py              # NPU 验证测试

已知限制

  1. torchaudio.save 在当前环境因 torchcodec 缺少 libnvrtc 而失败,推理脚本已添加 scipy fallback
  2. 首次推理耗时较长(含 warmup),后续推理延迟稳定
  3. 手动 overlap-add 使用 Python for 循环,对极长序列 (T > 4096) 可能成为瓶颈,可用 CUDA Graph 或 C++ 扩展优化

许可证

Vocos 原始项目: MIT License
本适配代码: MIT License