本文档记录 bigvgan_v2_22khz_80band_256x 在华为昇腾 NPU (Ascend 910B) 上的适配与推理验证结果。
BigVGAN 是由 NVIDIA 提出的通用神经声码器,基于抗锯齿周期激活函数(Snake / SnakeBeta)的 GAN 架构,可将 mel 频谱转换为高质量波形。本验证确认该模型可在昇腾 NPU 上通过原生 PyTorch 完成推理,无需 CUDA 专属算子或自定义 kernel。
相关获取地址:
| 组件 | 版本 |
|---|---|
CANN | 8.5.1 |
torch | 2.9.0+cpu |
torch-npu | 2.9.0.post1+gitee7ba04 |
librosa | 0.11.0 |
scipy | 1.17.1 |
numpy | 1.26.4 |
1 × Ascend 910B4./bigvgan_generator.ptexport HF_ENDPOINT=https://hf-mirror.com
pip install huggingface-hub
huggingface-cli download nvidia/bigvgan_v2_22khz_80band_256x \
--local-dir ./bigvgan_v2_22khz_80band_256x \
--include "bigvgan_generator.pt" "config.json"pip install modelscope
modelscope download --model nvidia/bigvgan_v2_22khz_80band_256x \
--local_dir ./bigvgan_v2_22khz_80band_256x# 安装核心依赖
pip install torch==2.9.0 torch-npu==2.9.0.post1
pip install librosa scipy numpy tqdm
# 确认 NPU 可用
python -c "import torch; import torch_npu; print(torch_npu.npu.is_available())"将以下代码保存为 infer_npu.py,与模型权重置于同一目录:
#!/usr/bin/env python3
import os, sys, json, time
import torch
import numpy as np
# 自动检测 NPU
try:
import torch_npu
DEVICE = torch.device("npu:0") if torch_npu.npu.is_available() else torch.device("cpu")
except Exception:
DEVICE = torch.device("cpu")
import bigvgan
from meldataset import get_mel_spectrogram
from env import AttrDict
def load_model(model_dir: str, device: torch.device):
with open(os.path.join(model_dir, "config.json")) as f:
h = AttrDict(json.load(f))
model = bigvgan.BigVGAN(h, use_cuda_kernel=False)
ckpt = torch.load(os.path.join(model_dir, "bigvgan_generator.pt"), map_location="cpu")
try:
model.load_state_dict(ckpt["generator"])
except RuntimeError:
model.remove_weight_norm()
model.load_state_dict(ckpt["generator"])
model.remove_weight_norm()
model = model.eval().to(device)
return model, h
# 加载模型
model, h = load_model(".", DEVICE)
# 方式 A:从随机 mel 生成
mel = torch.randn(1, h.num_mels, 100, device=DEVICE)
with torch.inference_mode():
wav_gen = model(mel)
print("Output shape:", wav_gen.shape) # [1, 1, T]
# 方式 B:从音频文件端到端生成
import librosa
wav, sr = librosa.load("input.wav", sr=h.sampling_rate, mono=True)
wav_tensor = torch.FloatTensor(wav).unsqueeze(0)
mel = get_mel_spectrogram(wav_tensor, h).to(DEVICE)
with torch.inference_mode():
wav_gen = model(mel)
# 保存结果
audio = wav_gen.squeeze().cpu().numpy()
audio = np.clip(audio, -1.0, 1.0)
audio = (audio * 32767.0).astype("int16")
from scipy.io.wavfile import write
write("output_npu.wav", h.sampling_rate, audio)python infer_npu.py| 检查项 | 结果 |
|---|---|
| 模型加载 | 通过 |
| 随机 mel 前向推理 | 通过 |
| 真实音频端到端推理 | 通过 |
| 权重 norm 移除 | 通过 |
以相同随机 mel 输入分别执行 NPU 与 CPU 推理,对比输出波形:
| 指标 | 数值 |
|---|---|
| Max Absolute Diff | 7.38e-02 |
| Mean Absolute Diff | 7.65e-03 |
| RMSE | 1.05e-02 |
差异来源于 NPU 与 CPU 浮点运算顺序不同,对声码器任务属于正常范围,主观听感无异常。
测试条件:batch_size=1,warmup=5,runs=20。
| Mel Frames | 输出音频时长 | 平均延迟 | 实时因子 (RTF) |
|---|---|---|---|
| 50 | ~0.58 s | 130.59 ms | 4.45x |
| 100 | ~1.16 s | 208.90 ms | 5.56x |
| 200 | ~2.33 s | 371.07 ms | 6.26x |
| 500 | ~5.82 s | 865.88 ms | 6.70x |
433 MB(分配)/ 662 MB(预留)CUDA Kernel 禁用:BigVGAN 官方提供可选的 CUDA fused kernel(use_cuda_kernel=True)用于加速推理。昇腾 NPU 不支持该 CUDA kernel,推理时必须显式设置 use_cuda_kernel=False(默认即为 False)。
无算子适配:模型主体为 PyTorch 标准算子(Conv1d、ConvTranspose1d、Snake 激活等),无需自定义算子替换即可在 NPU 上直接运行。
Mel 频谱计算:torch.stft 在部分 CANN 版本中存在限制。若遇到 mel 提取失败,可将 get_mel_spectrogram 放在 CPU 上执行,仅模型推理放在 NPU:
mel = get_mel_spectrogram(wav_tensor, h) # CPU
mel = mel.to(DEVICE) # 搬运到 NPU
wav_gen = model(mel) # NPU 推理分布式训练:config.json 中默认 dist_backend 为 nccl,若需在昇腾上进行多卡训练,应修改为 hccl。
音频保存:输出波形取值范围为 [-1, 1],保存为 16-bit PCM 前请先 clip,防止 int16 溢出。