本文档从环境检查到镜像构建、容器运行、接口调用写全流程,按顺序执行即可在华为云昇腾910B NPU 上完成部署并跑通转录。
本项目在华为云昇腾910B NPU上部署 Qwen3-ASR-1.7B 语音识别服务,提供 HTTP API,接口风格与同仓库 Whisper 部署一致,便于统一网关或替换。
模型信息:
| 项目 | 要求 |
|---|---|
| NPU | 华为昇腾910B,至少 1 卡 |
| 内存 | 32GB+(推荐 64GB) |
| 存储 | 10GB+ SSD(模型与缓存) |
| 系统 | openEuler 22.03 LTS SP1 或 Ubuntu 20.04+ |
| CANN | 7.0.0+(推荐 7.0.4) |
在构建镜像和运行容器之前,请先在宿主机上确认以下环境正常。
在终端执行:
npu-smi info若能看到 NPU 型号、显存等信息,说明驱动正常。若报错或找不到命令,请先安装昇腾驱动与 CANN,参考:
https://www.hiascend.com/software/cann
若在宿主机上需要用到 CANN:
source /usr/local/Ascend/ascend-toolkit/set_env.shdocker --version若无 Docker,可安装(以 Ubuntu 为例):
sudo apt-get update
sudo apt-get install -y docker.io
sudo usermod -aG docker $USER # 当前用户加入 docker 组,需重新登录生效ls -l /dev/davinci*应能看到至少 /dev/davinci0。后续运行容器时会通过 --device=/dev/davinci0 把该设备挂进容器。
不需要。 本方案使用 Docker 部署,所有 Python 依赖(qwen-asr、torch、FastAPI 等)都在镜像构建时装进容器,宿主机上只要具备:
宿主机不需要安装 qwen-asr、torch、transformers 等,也不用建虚拟环境。
唯一可能用到 pip 的情况:若你使用 ./scripts/download_model.sh 下载模型,需要在宿主机上安装 HuggingFace 命令行工具:
pip install "huggingface_hub[cli]"若你改用手动下载或不提前下载(让容器首次启动时从 HuggingFace 拉取),则宿主机上连这个都不需要装。
部署时主要用到的是项目根目录和 scripts 下的脚本,其余为代码与配置。
Qwen3-ASR-1.7B/
├── api/ # 服务代码(无需手动改)
│ ├── main.py # FastAPI 主服务
│ ├── model_loader.py # 模型加载(支持 NPU)
│ └── inference.py # 推理封装
├── config/
│ └── config.yaml # 服务与模型配置
├── scripts/ # 部署与测试脚本(小白重点用这里)
│ ├── download_model.sh # 第一步:下载模型
│ ├── build.sh # 第二步:构建镜像
│ ├── deploy.sh # 第三步:启动容器
│ ├── test_transcribe.sh # 用本地音频文件测试转录
│ ├── test_metrics.sh # 调用 /health、/metrics 监控接口
│ └── test_with_official_audio.sh # 用官方示例音频 URL 测试本地接口
├── test_audio/ # 本地测试音频(提交时由 .gitattributes 用 Git LFS 跟踪)
├── .gitattributes # Git LFS:test_audio/*.wav 等走 LFS
├── Dockerfile # 昇腾 NPU 镜像定义
├── requirements.txt
└── README.md # 本文档重要概念:
/data0/workspace,下面再放子目录 Qwen3-ASR-1.7B。/app/models,这样容器就能读到模型。下面四步按顺序执行即可完成「从镜像到脚本调用」的全流程。
模型需放在宿主机上,再通过挂载给容器使用。首次部署建议先下载模型,避免容器内拉取失败或过慢。
在项目根目录执行(把 /data0/workspace 换成你实际要放模型的目录):
cd Qwen3-ASR-1.7B
chmod +x scripts/*.sh
./scripts/download_model.sh /data0/workspace脚本会提示选择下载方式:
pip install "huggingface_hub[cli]"下载完成后,模型会在 /data0/workspace/Qwen3-ASR-1.7B(或你指定的目录下的 Qwen3-ASR-1.7B)。
若不下载,也可以直接跑容器,首次启动时会尝试从 HuggingFace 拉取(可能较慢或受网络影响)。
手动下载示例 (GitCode):
# 使用 GitCode 镜像仓库下载
git clone https://atomgit.com/hf_mirrors/Qwen/Qwen3-ASR-1.7B.git /data0/workspace/Qwen3-ASR-1.7B手动下载示例 (HuggingFace):
# HuggingFace
pip install -U "huggingface_hub[cli]"
huggingface-cli download Qwen/Qwen3-ASR-1.7B --local-dir /data0/workspace/Qwen3-ASR-1.7B确认目录存在且内有 config.json 等文件即可:
ls /data0/workspace/Qwen3-ASR-1.7B在项目根目录执行:
cd Qwen3-ASR-1.7B
./scripts/build.sh或直接使用 Docker 命令:
cd Qwen3-ASR-1.7B
docker build -t qwen3-asr-ascend:latest .-t qwen3-asr-ascend:latest 表示镜像名为 qwen3-asr-ascend,标签为 latest。docker images | grep qwen3-asr 应能看到该镜像。启动容器时需把宿主机上的模型目录挂载进容器,并指定使用哪张 NPU 卡。
使用脚本(推荐):
cd Qwen3-ASR-1.7B
./scripts/deploy.sh /data0/workspace 0 8002参数含义:
/data0/workspace,其下有 Qwen3-ASR-1.7B)/dev/davinci0)http://localhost:8002 访问服务)不传参时默认等价于:./scripts/deploy.sh /data0/workspace 0 8002。
手动执行等价命令(宿主机若有 CANN 驱动,请挂载 driver 与可选 add-ons,不要挂载整个 Ascend,否则会覆盖镜像内 nnal/atb/set_env.sh 导致报错):
docker run -d \
--name qwen3-asr-api \
--device=/dev/davinci0 \
--restart=unless-stopped \
-p 8002:8000 \
-v /data0/workspace:/app/models \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-e LOCAL_MODEL_PATH=/app/models/Qwen3-ASR-1.7B \
-e DEVICE=npu \
-e NPU_VISIBLE_DEVICES=0 \
-e ASCEND_RT_VISIBLE_DEVICES=0 \
-e ASCEND_DEVICE_ID=0 \
qwen3-asr-ascend:latest参数简要说明:
| 参数 | 含义 |
|---|---|
--name qwen3-asr-api | 容器名称,便于 docker logs、docker stop 等操作 |
--device=/dev/davinci0 | 把 NPU 0 透传给容器 |
-p 8002:8000 | 宿主机 8002 端口映射到容器内 8000 |
-v /data0/workspace:/app/models | 宿主机模型目录挂载到容器内 /app/models |
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver | 重要:只挂载 driver,提供 libascend_hal.so 等 NPU 库;勿挂载整个 /usr/local/Ascend,以免覆盖镜像内 nnal/atb/set_env.sh 报错 |
-e LOCAL_MODEL_PATH=... | 容器内模型路径,必须为挂载目录下的 Qwen3-ASR-1.7B |
-e DEVICE=npu | 使用 NPU |
-e NPU_VISIBLE_DEVICES=0 | 使用第 0 号 NPU |
-e ASCEND_RT_VISIBLE_DEVICES=0 | 昇腾运行时可见设备,需与 --device 对应 |
-e ASCEND_DEVICE_ID=0 | 昇腾单卡时设备 ID,部分环境必需 |
若模型目录或端口不同,只需把 /data0/workspace、8002、davinci0 换成你的实际路径、端口和设备号即可。deploy.sh 会检测宿主机 /usr/local/Ascend/driver 和 add-ons 并仅挂载这两项。
查看是否启动成功:
docker ps | grep qwen3-asr应能看到名为 qwen3-asr-api 的容器在运行。
首次启动会加载模型,可能需要 1~2 分钟,可看日志:
docker logs -f qwen3-asr-api看到类似「模型加载成功」或服务已监听 8000 端口即可进行下一步。
在宿主机或能访问该机的机器上执行(端口与上一步一致,这里以 8002 为例):
curl http://localhost:8002/health正常会返回 JSON,例如:
{
"status": "healthy",
"model_loaded": true,
"npu_available": true,
"cuda_available": false,
"version": "1.0.0"
}model_loaded 为 true 表示模型已加载,npu_available 为 true 表示 NPU 可用。
使用 Qwen3-ASR 官方示例音频(自动下载后请求本地接口),无需准备本地文件:
cd Qwen3-ASR-1.7B
chmod +x scripts/*.sh
./scripts/test_with_official_audio.sh 8002192.168.1.100 或 http://192.168.1.100:8002脚本会:健康检查 → 下载官方中文/英文示例(asr_zh.wav / asr_en.wav)→ 请求本地转录接口并打印结果。官方示例地址:https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-ASR-Repo/。
可将测试音频放在项目下的 test_audio/ 目录,再执行:
./scripts/test_transcribe.sh test_audio/your.wav 8002或任意路径:./scripts/test_transcribe.sh /path/to/your/audio.wav 8002
脚本会先调 /health 检查服务,再上传音频并打印转录结果(JSON 和纯文本)。
./scripts/test_metrics.sh [端口] [health|metrics|all]/health 再输出 /metrics(Prometheus 格式)。health 仅健康检查,metrics 仅拉取指标,all 两者都要(默认)。示例:./scripts/test_metrics.sh 8002 metrics 只拉取 Prometheus 指标。
若要把 test_audio/ 里的音频提交到 Git:已配置 .gitattributes,该目录下的 .wav、.mp3 等会通过 Git LFS 跟踪,避免大文件撑大仓库。首次使用需安装并初始化 LFS:git lfs install,再正常 git add、git commit 即可。
转录(返回 JSON):
curl -X POST "http://localhost:8002/v1/audio/transcriptions" \
-F "file=@/path/to/audio.wav" \
-F "model=Qwen3-ASR-1.7B" \
-F "language=zh" \
-F "response_format=json"只返回文本:
curl -X POST "http://localhost:8002/v1/audio/transcriptions" \
-F "file=@/path/to/audio.wav" \
-F "model=Qwen3-ASR-1.7B" \
-F "response_format=text"把 /path/to/audio.wav 换成实际音频路径即可。
若本机或内网能访问该服务器,可在浏览器打开:
http://<服务器IP>:8002/docshttp://<服务器IP>:8002/health服务与 Whisper 部署保持同一套风格,便于替换或统一网关。
| 用途 | 方法 | 路径 | 说明 |
|---|---|---|---|
| 健康检查 | GET | /health | 返回 status、model_loaded、npu_available 等 |
| 语音转录 | POST | /v1/audio/transcriptions | 上传音频,返回识别文本(JSON/text) |
| 语音转写 | POST | /v1/audio/translations | 与转录一致,按「转写为文本」处理 |
| 批量转录 | POST | /v1/audio/batch | Body 中 files 为 base64 音频数组 |
| 监控指标 | GET | /metrics | Prometheus 格式 |
转录请求参数(form-data):
file: 音频文件(必填)model: 可选,默认 Qwen3-ASR-1.7Blanguage: 可选,如 zh、en,不传则自动检测response_format: 可选,json(默认)、text、verbose_json转录响应示例(response_format=json):
{
"text": "识别出的文本内容",
"language": "zh"
}运行容器时可通过环境变量微调行为,常用如下:
| 变量 | 说明 | 默认 |
|---|---|---|
LOCAL_MODEL_PATH | 容器内模型路径 | 无则从 HuggingFace 下载 |
MODEL_CACHE_DIR | 缓存目录 | /app/models |
DEVICE | 设备 | 自动检测(NPU 下为 npu) |
NPU_VISIBLE_DEVICES | 使用的 NPU 编号 | 可选 |
ASCEND_RT_VISIBLE_DEVICES | 昇腾运行时可见设备,需与 --device 一致 | 可选,deploy.sh 已按 NPU 卡号传入 |
ASCEND_DEVICE_ID | 昇腾单卡设备 ID,部分环境必需 | 可选,deploy.sh 已按 NPU 卡号传入 |
PORT | 容器内服务端口 | 8000 |
WORKERS | Uvicorn 进程数 | 1 |
LOG_LEVEL | 日志级别 | INFO |
libascend_hal.so: cannot open shared object file)。libascend_hal.so 或 CANN 相关:说明容器内缺少 NPU 驱动库。宿主机需已安装 CANN,并只挂载 driver(及可选 add-ons),勿挂载整个 /usr/local/Ascend(否则会覆盖镜像内 nnal/atb/set_env.sh 导致 “set_env.sh: No such file or directory”):
# 宿主机上确认存在
ls /usr/local/Ascend/driver
# 使用 deploy.sh 时会自动挂载 driver 与 add-ons;若手动 docker run,请加:
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver./scripts/deploy.sh /data1/develop/models/Qwen 0 8002。cd Qwen3-ASR-1.7B
docker build --no-cache -t qwen3-asr-ascend:latest .
docker stop qwen3-asr-api 2>/dev/null; docker rm qwen3-asr-api 2>/dev/null
./scripts/deploy.sh /data1/develop/models/Qwen 0 8002docker logs qwen3-asr-api 看报错。--device=/dev/davinci0)、宿主机没有 /dev/davinci0、端口被占用(换一个 -p 端口)。docker logs -f qwen3-asr-api。/data0/workspace/Qwen3-ASR-1.7B 且内有 config.json 等;LOCAL_MODEL_PATH 为 /app/models/Qwen3-ASR-1.7B。device_map=npu:0,日志中会看到尝试 auto 或 cpu,服务仍可能能启动(可能较慢)。/usr/local/Ascend,覆盖了镜像内的 nnal/atb 等目录,而宿主机上可能没有该脚本。deploy.sh 时会自动只挂载 driver 与 add-ons;若手动运行,请用 -v /usr/local/Ascend/driver:/usr/local/Ascend/driver,不要用 -v /usr/local/Ascend:/usr/local/Ascend。halGetDeviceInfo failed: drvRet=4、Can't get ascend_hal device count、Runtime boot failed,并出现「DEVICE=npu 但 NPU 不可用,将回退到 CPU」和「Qwen3-ASR 模型加载成功 (device_map=cpu)」。DEVICE=cpu 再启动容器,减少每次健康检查触发的 RUNTIME 报错刷屏,例如:
docker run -d ... -e DEVICE=cpu ...npu-smi info 确认 NPU 与驱动正常;确认宿主机 CANN/驱动版本与基础镜像 quay.io/ascend/vllm-ascend:v0.11.0rc0 兼容;参考华为云/昇腾文档中「容器内使用 NPU」的官方说明(设备透传、驱动挂载、版本匹配等)。./scripts/deploy.sh /data0/workspace 0 8003,后续访问用 http://localhost:8003。docker stop qwen3-asr-api
docker rm qwen3-asr-api
./scripts/deploy.sh /data0/workspace 0 8002若需限制 CPU/内存并持久化日志,可参考:
docker run -d \
--name qwen3-asr-api \
--device=/dev/davinci0 \
--restart=unless-stopped \
-p 8002:8000 \
--cpus="8" \
--memory="16g" \
-v /data0/workspace:/app/models \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /data/logs/qwen3-asr:/app/logs \
-e LOCAL_MODEL_PATH=/app/models/Qwen3-ASR-1.7B \
-e DEVICE=npu \
-e NPU_VISIBLE_DEVICES=0 \
-e ASCEND_RT_VISIBLE_DEVICES=0 \
-e ASCEND_DEVICE_ID=0 \
-e WORKERS=1 \
qwen3-asr-ascend:latest其中 /data/logs/qwen3-asr 为宿主机日志目录,可按需修改。
whisper-large-v3-turbo 部署结构