z
zkx_/speech_dfsmn_aec_psm_16k-ascend
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

speech_dfsmn_aec_psm_16k on Ascend NPU

1. 简介

本文档记录 DFSMN 回声消除模型的残差抑制网络 (MaskNet) 在昇腾 NPU (Ascend 910B3) 上的迁移适配与精度验证结果。

DFSMN AEC 是达摩院语音团队提出的单通道回声消除模型,包含两个阶段:

  • 线性回声消除:基于加权 RLS 滤波器(依赖 C++ 库 libmitaec,暂不在本适配范围)
  • 残差回声抑制:基于 Deep FSMN 结构的 MaskNet 神经网络

本适配聚焦于 MaskNet 部分的 NPU 迁移。MaskNet 输入 240 维 Fbank 特征(3 帧拼接),输出 321 维相位敏感掩码和逐帧 VAD 预测。

相关获取地址:

  • 权重下载地址(ModelScope):https://modelscope.cn/models/damo/speech_dfsmn_aec_psm_16k
  • AEC-Challenge 数据集:https://github.com/microsoft/AEC-Challenge

参考文档:

  • https://modelscope.cn/models/damo/speech_dfsmn_aec_psm_16k
  • https://www.hiascend.com/document/detail/zh/canncommercial/80RC3/overview/index.html

2. 验证环境

组件版本
CANN8.5.1
torch2.8.0
torch_npu2.8.0.post4
modelscope1.37.0
numpy2.2.6
  • NPU:Ascend 910B3,单卡推理
  • MaskNet 大小:约 6.71M 参数,~27MB
  • 输入维度:240(3帧x80维Fbank)
  • 输出维度:321(相位敏感掩码)+ 1(VAD)

3. 环境准备

3.1 创建 Conda 环境

conda create -n speech_dfsmn_aec python=3.10 -y
conda activate speech_dfsmn_aec

3.2 安装依赖

# 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.com

3.3 下载模型权重

modelscope download --model damo/speech_dfsmn_aec_psm_16k \
    --local_dir ./speech_dfsmn_aec_psm_16k

4. 推理验证

4.1 命令行推理

# 输入 Fbank 特征 .npy 文件 [B, T, 240]
python inference.py --feature features.npy --device cpu
python inference.py --feature features.npy --device npu --output mask.npz

4.2 Python API 推理

from 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")

4.3 验证结果

使用随机特征 [1, 100, 240]:

  • CPU:输出 Mask [1,100,321] + VAD [1,100,1],耗时 ~683ms
  • NPU:输出 Mask [1,100,321] + VAD [1,100,1],耗时 ~6ms
  • NPU VAD 预测与 CPU 100% 一致

5. 性能参考

测试条件:input [1, 100, 240],50 轮取平均。

指标CPUNPU (Ascend 910B3)加速比
平均耗时759.03 ms5.56 ms136.54x
中位耗时756.95 ms5.58 ms135.66x

6. 精度评测

6.1 评测方法

对比 CPU (PyTorch) 与 NPU (torch_npu) 在相同 Fbank 特征输入下的 MaskNet 输出:

  • 掩码精度:比较 321 维相位敏感掩码的逐元素相对误差
  • VAD 精度:比较逐帧 VAD 二值化判断的一致性

6.2 评测结果

指标数值
掩码形状[1, 100, 321]
VAD 形状[1, 100, 1]
最大绝对误差0.000317
平均相对误差0.0181%
P99 相对误差0.0668%
VAD 准确率100.00%

6.3 精度结论

  • 掩码平均相对误差为 0.0181%,满足 < 1% 的精度要求
  • VAD 预测准确率为 100.00%,与 CPU 完全一致
  • 精度评测:通过

7. 适配说明

7.1 迁移要点

本适配聚焦于 MaskNet (DFSMN) 神经网络部分,直接加载 pytorch_model.bin 权重构建 MaskNet 模型。

核心适配步骤:

  1. 从 modelscope 导入 MaskNet 定义:from modelscope.models.audio.aec.network.se_net import MaskNet
  2. 构建模型:MaskNet(indim=240, outdim=321, layers=12, hidden_dim=512, vad=True)
  3. 加载权重:model.load_state_dict(torch.load(ckpt_path))
  4. 移至 NPU:model.to("npu:0")
  5. 输入 Fbank 特征:[B, T, 240] → 输出掩码 [B, T, 321] + VAD [B, T, 1]

完整 AEC 流水线说明:

完整的回声消除流水线包含 3 步:

  1. 线性 AEC(CPU,依赖 libmitaec C++ 库):加权 RLS 滤波,消除线性回声分量
  2. 特征提取(CPU):从原始/线性 AEC 音频中提取 80 维 Fbank + 3 帧拼接 = 240 维
  3. MaskNet(NPU):预测相位敏感掩码和 VAD,乘回 STFT 得到干净语音

本适配完成第 3 步的 NPU 迁移。由于第 1 步依赖的 libmitaec C++ 库未随模型提供,完整端到端推理需额外编译该库。

7.2 依赖说明

依赖用途
torch_npuAscend NPU 的 PyTorch 后端
modelscopeMaskNet 模型定义(无需完整 pipeline)
numpy数值计算与特征处理

7.3 注意事项

  1. NPU 内存:MaskNet 约 27MB,单帧推理占用约 1.2GB HBM
  2. 输入维度:必须是 240 维(3 帧 80 维 Fbank 拼接),batch 维度可选
  3. 输出说明:Mask 输出 321 维对应 320 点 FFT 的实部 + 虚部 + 1;VAD 输出 [0,1] 范围的语音概率
  4. 首次推理:首次 NPU 推理有算子编译开销(约 5-10 秒),后续推理稳定在 ~5.6ms
  5. 线性 AEC 依赖:完整的端到端回声消除需要 libmitaec C++ 共享库,当前仅适配神经网络部分