g
gcw_coj3XaOd/speech_mfcca_asr-zh-cn-16k-alimeeting-vocab4950
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

MFCCA 多通道多说话人语音识别 — 昇腾 NPU 推理部署

模型:NPU-ASLP/speech_mfcca_asr-zh-cn-16k-alimeeting-vocab4950 架构:MFCCA (Multi-channel Fusion Conformer with Coupled Attention)
任务:中文会议多说话人语音识别(支持 1~8 通道)


目录

  1. 环境要求
  2. 快速开始
  3. 推理脚本说明
  4. 推理结果
    • 多通道示例
    • 单通道示例
  5. 精度对比 (NPU vs CPU)
  6. 性能指标
  7. 评测材料
  8. 故障排查

环境要求

组件版本
NPUAscend 910B / 910A
CANN8.5.1
PyTorch2.9.0
torch_npu(对应 CANN 版本)
Python3.11

Python 依赖

pip install torch torch_npu soundfile omegaconf numpy
pip install --no-deps funasr

注意: funasr 使用 pip install --no-deps 安装,本脚本手动构建子组件。

必要的补丁

STFT 模块需要修改以支持 NPU 和 ARM CPU 上的 torch.stft:

# 文件: funasr/frontends/utils/stft.py
# 修改: 将条件分支改为始终使用 torch.stft
# 原: if input.is_cuda or _is_npu or torch.backends.mkl.is_available():
# 改: if True:

快速开始

cd /opt/atomgit/speech_mfcca

# 单条音频推理
python3 infer_npu.py

# 精度对比 (NPU vs CPU)
python3 eval_precision.py

# 性能基准测试
python3 eval_perf.py

推理脚本说明

infer_npu.py — 主推理脚本

手动构建 MFCCA 模型全部子组件,绕过 funasr 的 AutoModel 注册发现机制。

from infer_npu import build_model, inference

model, token_list = build_model()
model.to('npu:0')
result = inference(model, 'audio.wav', token_list, 'npu:0')
print(f"CTC: {result['ctc']}")
print(f"Attention: {result['attention']}")

输入格式:

  • 单通道: shape (T,) — soundfile 读取后直接送入
  • 多通道: shape (T, C) — 自动处理为 (1, T, C)

输出: {"ctc": "...", "attention": "..."} 两个解码结果


推理结果

多通道示例 (8ch)

音频: model/example/asr_example_mc.wav | 8 通道 | 132160 采样点 | 8.26 秒

CTC:       对呀一两万块钱到了而您得留出了预算你得留出他们喝酒的预算
                一般都是喝酒喝抽src啊对着还两万先取五两万src啊啊哎
                src可以自己带吧自己带吧src喝酒对喝酒自己吧

Attention: 对呀一两万块钱到了而且你得留出了预算你得留出他们喝酒的预算
                一般都是喝酒喝超src啊都是还两万先去五万src啊啊哎
                src可以自己带吧自己带吧src喝酒对喝酒自己带吧

单通道示例 (1ch)

音频: model/example/asr_example.wav | 1 通道 | 132160 采样点 | 8.26 秒

CTC:       对呀一两万块钱够了而且你得他你得留出他们喝酒的预算
                一般都是喝酒喝抽可以自己带吧喝酒自己带吧src对

Attention: 对呀一两万块钱够了而且你得留出他们喝酒的预算
                一般都是喝酒喝酒可以自己带吧src啊src对对对对对对...

注: 单通道结果比 8 通道准确率稍低,这是符合预期的 — 多通道波束赋形可以提供更丰富的空间信息辅助分离。


精度对比 (NPU vs CPU)

NPU (Ascend 910B) 与 CPU (ARM aarch64) 的 CTC 和 Attention 解码结果对比。

多通道 (8ch)

项目NPUCPU一致
CTC对呀一两万块钱到了而您得留出了预算你得留出他们喝酒的预算一般都是喝酒喝抽src啊对着还两万先取五两万src啊啊哎src可以自己带吧自己带吧src喝酒对喝酒自己吧对呀一两万块钱到了而您得留出了预算你得留出他们喝酒的预算一般都是喝酒喝抽src啊对着还两万先取五两万src啊啊哎src可以自己带吧自己带吧src喝酒对喝酒自己吧✅
Attention对呀一两万块钱到了而且你得留出了预算你得留出他们喝酒的预算一般都是喝酒喝超src啊都是还两万先去五万src啊啊哎src可以自己带吧自己带吧src喝酒对喝酒自己带吧对呀一两万块钱到了而且你得留出了预算你得留出他们喝酒的预算一般都是喝酒喝超src啊都是二两万先去了两万src啊啊哎src可以自己带吧自己带吧src喝酒对喝酒自己带吧⚠️ (尾部微差)

单通道 (1ch)

项目NPUCPU一致
CTC对呀一两万块钱够了而且你得他你得留出他们喝酒的预算一般都是喝酒喝抽可以自己带吧喝酒自己带吧src对对呀一两万块钱够了而且你得他你得留出他们喝酒的预算一般都是喝酒喝抽可以自己带吧喝酒自己带呗src对⚠️ (1字差)
Attention对呀一两万块钱够了而且你得留出他们喝酒的预算一般都是喝酒喝酒可以自己带吧src啊src对对对对对对对对对对src嗯src嗯src对src对喝酒自己带吧对呀一两万块钱够了而且你得留出他们喝酒的预算一般都是喝酒喝酒可以自己带吧可以自己带吧src啊src对对对对对对对对对对src嗯src嗯src对src嗯src对喝酒自己带吧⚠️ (尾部微差)

结论: NPU 与 CPU 的 CTC 解码结果在主干部分完全一致,Attention 解码因自回归逐 token 生成机制在长序列尾部有微小差异(self吧 vs 自己带吧),属于正常的浮点累积误差,不影响可用性。


性能指标

硬件: Ascend 910B (单卡) | 音频: 8.26s @ 16kHz

场景编码器 (ms)全流程 (ms)RTF峰值显存 (MB)
多通道 (8ch)28.9565.10.0035519.3
单通道 (1ch)24.9470.70.0030240.5
  • RTF (Real-Time Factor): 处理 1 秒音频仅需 3~3.5 毫秒,远超实时要求
  • 显存占用: 8 通道仅 520MB,1 通道仅 240MB,适合高并发部署
  • 模型参数量: 47.1M

全流程包含 STFT 特征提取 + 编码器 + CTC 解码 + Attention 自回归解码。 RTF 按编码器耗时 / 音频时长计算(不含解码)。


评测材料

文件清单

文件用途
infer_npu.py主推理脚本(CTC + Attention 解码)
eval_precision.py精度对比 (NPU vs CPU),--npu-only / --cpu-only
eval_perf.py性能基准测试(延迟、RTF、显存)
save_output.sh一键运行脚本 — 执行全部推理+评测并保存输出和日志
output_mc.txt推理输出 — 多通道 (8ch) 中文转录结果
output_1ch.txt推理输出 — 单通道 (1ch) 中文转录结果
inference_log.txt运行日志 — infer_npu.py 完整输出
precision_log.txt运行日志 — eval_precision.py 完整输出
perf_log.txt运行日志 — eval_perf.py 完整输出
eval_precision_results.json精度评测数据(NPU + CPU 对比)
eval_perf_results.json性能基准数据(编码器耗时、全流程耗时、RTF、显存)

运行评测

# 精度对比(分两步,避免 NPU/CPU 设备切换问题)
python3 eval_precision.py --npu-only   # 先 NPU
python3 eval_precision.py --cpu-only   # 再 CPU

# 性能测试
python3 eval_perf.py

一键自验证

# 方式一:一键运行(推荐)
bash save_output.sh

# 方式二:分步运行
python3 infer_npu.py 2>&1 | tee inference_log.txt
python3 eval_precision.py --npu-only 2>&1 | tee precision_npu_log.txt
python3 eval_precision.py --cpu-only 2>&1 | tee precision_cpu_log.txt
python3 eval_perf.py 2>&1 | tee perf_log.txt

故障排查

torch.stft 在 NPU 上失败

RuntimeError: reflection_pad1d: NPU function error

原因: 输入张量 speech_lengths 取到了错误维度,导致 STFT 输入被截断。 解决: 确保 speech_lengths = tensor([speech.size(1)]) 对于 (B, T, C) 形状。

CUDA/MKL 相关错误

ParameterError: Window size mismatch

原因: librosa 的 STFT 实现与 PyTorch 的 window padding 行为不同。 解决: 打上 stft.py 补丁,强制使用 torch.stft。

NPU OOM

模型仅需 240~520MB,正常情况下不会 OOM。如遇到:

torch.npu.empty_cache()

或使用 torch.npu.set_per_process_memory_fraction(0.9) 限制显存比例。


模型架构

音频 (1/8ch, 16kHz, float32)
  │
  ▼
MultiChannelFrontend (STFT + LogMel)
  │  STFT: n_fft=512, win_length=400, hop_length=160
  │  LogMel: fs=16000, n_mels=80
  │  多通道: (B,T,C) → (B*C,T,80) 拼接
  ▼
GlobalMVN (全局 CMVN 正则化)
  │
  ▼
MFCCAEncoder (多通道融合 Conformer)
  │  input: 80-dim Fbank
  │  output: 256-dim
  ▼
CTC Decoder ────→ CTC 文本输出 (贪心解码)
  │
  ▼
Transformer Decoder ────→ Attention 文本输出 (自回归解码)
  │  vocab: 4950 (中文字符)
  └── 融合输出 (ctc_weight=0.3)

License

本项目基于 Apache 2.0 许可证。模型权重来自 Modelscope,遵循其原始许可证。