昇腾 910B 上跑私有化 ASR:环境准备、算子适配与吞吐实测
记录一套中文语音转写引擎在华为昇腾 NPU 上的私有化落地全过程——版本矩阵、ONNX 到 OM 的模型转换、容器部署命令、现场踩过的六个坑,以及参考性能量级。适合需要在信创环境内部署 ASR 的工程师。

本文记录一套中文语音转写引擎在华为昇腾 NPU 上的私有化落地过程,包含环境版本、模型转换、部署命令、踩过的坑与参考性能量级。
数据口径:文中标注「官网规格」的来自产品公开指标;性能量级表为典型环境下的参考值,实际数值随音频条件、模型规模与并发策略变化,请以实测为准。
为什么非得在国产算力上跑
在政务、金融、军工等场景,系统不仅要"数据不出域",还要"技术自主可控"。这意味着底层算力逐步从进口 GPU 切换到昇腾、寒武纪、海光等国产芯片,操作系统切换到麒麟、统信等国产系统。
落到工程上,是三条硬约束:
- 数据不出域:会议音频包含内部讨论,很多单位明确禁止音频离开内网
- 信创要求:采购目录里可能根本没有进口 GPU 的选项
- 物理隔离:部分场景连内网都不通外网,模型权重必须一次性打包进环境
核心结论:私有化解决"数据在哪",国产化解决"技术在谁手里"。这三条叠加,就把方案收敛到一件事——在国产 NPU 上把 ASR 跑起来,且要跑得动。
适配清单
语像智能语音引擎基于东北大学 NEU NLP 自研算法,原生适配主流算力:
| 算力类型 | 代表型号 | 适用 |
|---|---|---|
| NVIDIA | T4 / L4 / A10 / A100 | 通用、高性能 |
| 昇腾 Ascend | 310P / 910B | 信创、国产服务器 |
| 寒武纪 Cambricon | MLU370 / MLU590 | 信创、国产服务器 |
| 海光 Hygon DCU | DCU 系列 | 国产 x86 路线 |
| 纯 CPU | x86 / ARM | 存量利旧、低并发 |
昇腾是目前国产算力里生态相对完整的一条线(CANN + MindSpore + 模型仓库)。910B 主打训练与高吞吐推理,310P 主打边缘与低功耗。会议转写这种持续并发的活儿,一般用 910B 做中心推理、310P 做边缘节点。
环境准备:版本对齐是最大的坑
昇腾生态的痛点不在算力,在版本矩阵。驱动、固件、CANN、框架、模型格式,五者任一错位都会导致莫名其妙的失败。
我们常用的稳定组合:
| 组件 | 版本 | 备注 |
|---|---|---|
| 驱动 / 固件 | 与 CANN 版本强绑定 | 升级前先查官方兼容表 |
| CANN | 8.x 系列 | 算子库与模型转换工具都在这里 |
| 容器 | Ascend Docker Runtime | 必须用它,普通 Docker 挂载不到 NPU |
| 推理框架 | ONNX Runtime + ACL | 走 OM 模型,不走 MindSpore 也行 |
| OS | openEuler / Kylin V10 / 统信 UOS | 信创环境常见 |
第一步永远是确认 NPU 能被看到:
# 查看 NPU 设备与状态
npu-smi info
# 期望看到 910B 的 Device 列表,健康状态 OK
# 若这里就看不到卡,后面全是白搭——先解决驱动
踩坑记录:在部分 Kylin V10 环境上装完驱动后 npu-smi info 报 dmp 守护进程异常,排查发现是系统自带的 dkms 版本与驱动安装脚本冲突。解决办法是先卸载系统 dkms,用驱动包内置的版本重装。这类发行版适配问题在官方文档里通常查不到,是现场最常见的卡点。
模型转换:ONNX → OM
ASR 模型一般是 PyTorch 训练,导出 ONNX,再转成昇腾的 OM 格式。
导出 ONNX 的三个注意点
torch.onnx.export(
model, dummy_input,
"asr.onnx",
opset_version=14, # 昇腾对低版本 opset 支持更好,别用最新的
do_constant_folding=True,
input_names=["audio", "audio_len"],
output_names=["logits"],
dynamic_axes={ # 关键:音频长度是动态的
"audio": {0: "batch", 1: "time"},
"logits": {0: "batch", 1: "time"},
},
)
三个容易翻车的点:
- opset 版本:不是越高越好。高版本 opset 在转换时更容易遇到算子不支持,14 是兼容性较好的选择。
- 动态轴:音频长度天然可变,必须声明
dynamic_axes,否则只能跑固定长度,实际场景没法用。 - 常量折叠:
do_constant_folding=True能显著减小图规模,转换成功率也更高。
ATC 转换
atc --model=asr.onnx \
--framework=5 \
--output=asr_om \
--input_format=ND \
--input_shape="audio:-1,-1;audio_len:-1" \
--dynamic_dims="1,16000;1,32000;1,48000" \
--soc_version=Ascend910B \
--precision_mode=allow_fp16 \
--log=error
几个参数的实际含义:
--soc_version:必须与实际硬件严格一致。910B 写成 910A 会在加载阶段失败,且错误信息很模糊。--dynamic_dims:动态档位。音频场景建议按秒数分档,档位太多会增加编译时间,太少会频繁触发重编译导致延迟抖动。--precision_mode:allow_fp16在 ASR 上精度损失通常可忽略,吞吐提升明显。
量化要不要做
| 精度 | 吞吐 | 准确率 |
|---|---|---|
| FP16 | 基准 | 基准 |
| INT8 | 提升明显 | 有可感知损失 |
结论:对准确率极其敏感的场景(医疗、法务会议),保持 FP16;内部例会、培训记录这类容错度高的场景,INT8 性价比更高。
部署:容器化是唯一合理选择
裸机装环境在信创现场几乎不可维护。我们用容器交付:
docker run -it --name asr_server \
--device /dev/davinci0 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /data/models:/models \
-p 8000:8000 \
asr-server:910b \
./asr_server --model /models/asr_om --port 8000
- 物理机裸金属、政务云、信创环境均可运行;
- 通过标准 RESTful API / WebSocket 接口对接 OA、会议系统;
- 横向扩容按并发弹性伸缩。
注意那几个 --device:少挂一个就会报 ACL 初始化失败,且报错信息不会告诉你是设备没挂。这是新手最常见的卡点。
另外,不要做私有协议。走标准 RESTful(文件转写)与 WebSocket(实时流),否则对接客户的 OA、会议系统会非常痛苦。
对已有服务器的客户,直接部署纯软件语音引擎,无需采购硬件即可获得国产算力上的私有化转写能力。
参考性能量级
测试条件:昇腾 910B,FP16,中文会议音频,16kHz 单声道。
| 指标 | 参考量级 | 说明 |
|---|---|---|
| 实时率 RTF | 0.1 量级 | 即 1 小时音频约数分钟转完 |
| 单卡并发路数 | 数十路 | 纯转写,会议场景持续并发 |
| 首字延迟 | 亚秒级 | 实时流模式,实测通常低于 1 秒 |
| 中文转写准确率 | ≥98% | 标准普通话会议场景(官网规格) |
| 方言覆盖 | 22 种 | 自动检测(官网规格) |
⚠️ 上表的并发路数是纯转写口径(ASR 单卡,不含说话人分离与纪要结构化)。 叠加说话人分离 + 议题/待办抽取后,单卡路数会显著下降——整机产品标称单机 10 路, 指的就是全链路(转写 + 分离 + 结构化)的并发;集群形态标称 50+ 路。 选型时一定要问清对方报的是哪一层,这三者能差好几倍。
六个真实踩过的坑
这部分是本文最值钱的部分,都是现场掉进去爬出来的。
1. 动态 shape 导致频繁重编译
最初没设 --dynamic_dims,每来一个不同长度的音频就触发一次图编译,延迟飙到几秒。设了分档之后稳定在亚秒级。
2. 长音频内存爆掉 直接把 2 小时会议音频整个送进模型,显存直接 OOM。必须做分片增量推理——按 VAD 切段,逐段送解码器,而不是整段加载。
3. 算子不支持静默失败 某个 LayerNorm 变体在昇腾上没有对应算子,ATC 转换时不报错,运行时输出全零。一定要做转换后的等价性校验:拿同一段音频分别跑 ONNX Runtime(CPU)和 OM(NPU),比对输出差异。
4. 多线程并发下的 context 泄漏 早期版本每个请求创建独立 ACL context,高并发下 context 耗尽。改成 context 池化后解决。
5. 驱动升级后模型要重新转 CANN 大版本升级后,旧 OM 模型可能加载失败或性能倒退。把模型转换纳入 CI,而不是手工转完就完事。
6. 气隙环境的离线打包 物理隔离环境里,CANN 依赖、驱动、模型权重、字体、证书,全都得提前打包。我们踩过一次:现场发现缺一个中文字体,转写结果全是方框。离线包必须在同等环境下预演一遍完整部署流程。
什么时候不该选国产算力
说点实在的。如果你的场景是:
- 没有信创 / 国产化强制要求 → GPU 生态成熟得多,别自找麻烦
- 团队没有懂 CANN 的人 → 运维成本会远超硬件省下的钱
- 只需要低并发(个位数路数)→ 纯 CPU 就够了,别上加速卡
国产算力的正确使用姿势是:有明确合规要求 + 有持续并发压力 + 有工程能力兜底。
选型建议
- 新建信创集群:VV05 / VV10+ 昇腾或寒武纪加速卡;
- 存量 x86 利旧:纯 CPU 或海光 DCU 部署引擎;
- 混合环境:NVIDIA 与国产算力统一纳管,按负载调度。
如果你正在做私有化与云端的路线选择,可对照私有化 ASR 选型对比一文。
常见问题
Q: 语音转写支持哪些国产芯片?
A: 语像智能语音引擎原生适配昇腾 Ascend(310P/910B)、寒武纪 Cambricon(MLU370/MLU590)、海光 Hygon DCU,以及 NVIDIA 全系;纯 CPU 亦可运行,覆盖信创与国产化全栈。
Q: 为什么 ASR 一定要跑在国产算力上?
A: 政务、金融、军工场景通常同时要求数据不出域、信创采购目录合规与物理隔离。这三条叠加后,进口 GPU 往往不在可选范围内,方案只能收敛到国产 NPU 上把 ASR 跑起来且跑得动。
Q: ONNX 模型转昇腾 OM 有哪些常见失败点?
A: 主要集中在三点:opset 版本过高导致算子不支持(建议 14)、未声明 dynamic_axes 导致只能跑固定长度音频、soc_version 与实际硬件不一致导致加载失败且报错模糊。转换后务必做 CPU 与 NPU 的输出等价性校验。
Q: 昇腾上做 INT8 量化值得吗?
A: 取决于场景容错度。INT8 能带来可观的吞吐提升,但会引入可感知的准确率损失。医疗、法务等对准确率极敏感的场景建议保持 FP16;内部例会、培训记录这类容错度高的场景,INT8 性价比更高。
Q: 容器里跑昇腾需要挂载哪些设备?
A: 需要挂载 /dev/davinci0、/dev/davinci_manager、/dev/devmm_svm、/dev/hisi_hdc 四个设备,并挂载驱动目录。少挂任意一个都会报 ACL 初始化失败,且报错信息不会提示是设备缺失。
Q: 纯 CPU 能跑语音转写吗?
A: 能。引擎针对 CPU 做了推理优化,在无独立加速卡的信创或通用服务器上仍可运行,适合低并发或存量设备利旧场景。
Q: Docker / K8s 如何部署?
A: 语像智能以容器镜像交付,支持 Docker 与 Kubernetes 一键部署,可运行于物理机、政务云与信创环境,并对接标准 RESTful / WebSocket 接口。
Q: 国产算力上准确率会下降吗?
A: 不会。算法基于东北大学 NEU NLP 自研模型,算力仅影响推理吞吐与延迟;在昇腾/寒武纪上经量化与算子适配后,中文转写准确率保持同等水平。
