本文档记录 DFSMN 回声消除模型的残差抑制网络 (MaskNet) 在昇腾 NPU (Ascend 910B3) 上的迁移适配与精度验证结果。
DFSMN AEC 是达摩院语音团队提出的单通道回声消除模型,包含两个阶段:
libmitaec,暂不在本适配范围)本适配聚焦于 MaskNet 部分的 NPU 迁移。MaskNet 输入 240 维 Fbank 特征(3 帧拼接),输出 321 维相位敏感掩码和逐帧 VAD 预测。
相关获取地址:
参考文档:
| 组件 | 版本 |
|---|---|
CANN | 8.5.1 |
torch | 2.8.0 |
torch_npu | 2.8.0.post4 |
modelscope | 1.37.0 |
numpy | 2.2.6 |
Ascend 910B3,单卡推理conda create -n speech_dfsmn_aec python=3.10 -y
conda activate speech_dfsmn_aec# PyTorch + Ascend NPU 后端
pip install torch==2.8.0 torch_npu==2.8.0.post4 \
-i https://mirrors.huaweicloud.com/repository/pypi/simple \
--trusted-host mirrors.huaweicloud.com
# 模型与工具库
pip install modelscope==1.37.0 numpy scipy Pillow \
sortedcontainers simplejson pyyaml addict datasets pyarrow \
-i https://mirrors.huaweicloud.com/repository/pypi/simple \
--trusted-host mirrors.huaweicloud.commodelscope download --model damo/speech_dfsmn_aec_psm_16k \
--local_dir ./speech_dfsmn_aec_psm_16k# 输入 Fbank 特征 .npy 文件 [B, T, 240]
python inference.py --feature features.npy --device cpu
python inference.py --feature features.npy --device npu --output mask.npzfrom inference import run_inference
import numpy as np
features = np.random.randn(1, 100, 240).astype(np.float32)
result = run_inference(features, device="npu")
print(f"Mask: {result['mask'].shape}") # [1, 100, 321]
print(f"VAD: {result['vad'].shape}") # [1, 100, 1]
print(f"Time: {result['time_ms']:.2f} ms")使用随机特征 [1, 100, 240]:
测试条件:input [1, 100, 240],50 轮取平均。
| 指标 | CPU | NPU (Ascend 910B3) | 加速比 |
|---|---|---|---|
| 平均耗时 | 759.03 ms | 5.56 ms | 136.54x |
| 中位耗时 | 756.95 ms | 5.58 ms | 135.66x |
对比 CPU (PyTorch) 与 NPU (torch_npu) 在相同 Fbank 特征输入下的 MaskNet 输出:
| 指标 | 数值 |
|---|---|
| 掩码形状 | [1, 100, 321] |
| VAD 形状 | [1, 100, 1] |
| 最大绝对误差 | 0.000317 |
| 平均相对误差 | 0.0181% |
| P99 相对误差 | 0.0668% |
| VAD 准确率 | 100.00% |
本适配聚焦于 MaskNet (DFSMN) 神经网络部分,直接加载 pytorch_model.bin 权重构建 MaskNet 模型。
核心适配步骤:
from modelscope.models.audio.aec.network.se_net import MaskNetMaskNet(indim=240, outdim=321, layers=12, hidden_dim=512, vad=True)model.load_state_dict(torch.load(ckpt_path))model.to("npu:0")完整 AEC 流水线说明:
完整的回声消除流水线包含 3 步:
libmitaec C++ 库):加权 RLS 滤波,消除线性回声分量本适配完成第 3 步的 NPU 迁移。由于第 1 步依赖的 libmitaec C++ 库未随模型提供,完整端到端推理需额外编译该库。
| 依赖 | 用途 |
|---|---|
torch_npu | Ascend NPU 的 PyTorch 后端 |
modelscope | MaskNet 模型定义(无需完整 pipeline) |
numpy | 数值计算与特征处理 |
libmitaec C++ 共享库,当前仅适配神经网络部分