ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Qwen3-ASR 实时/离线语音转写部署

Qwen3-ASR 实时/离线语音转写部署 概述Qwen3-ASR 是阿里云推出的开源语音识别模型,支持离线与实时语音转写。本文介绍在 Ubuntu Linux 系统上使用 Docker 部署 Qwen3-ASR 的完整步骤,包括环境准备、容器启动、模型下载与服务运行。1. 环境准备1.1 安装 Docker若尚未安装 Docker,请先执行以下命令:# 更新软件包列表sudoapt-getupdate# 安装 Docker 依赖sudoapt-getinstall-yca-certificatescurl# 添加 Docker 官方 GPG 密钥sudoinstall-m0755-d/etc/apt/keyringssudocurl-fsSLhttps://download.docker.com/linux/ubuntu/gpg-o/etc/apt/keyrings/docker.ascsudochmoda+r /etc/apt/keyrings/docker.asc# 添加 Docker 软件源echo\"deb [arch=$(dpkg --print-architecture)signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \$(./etc/os-releaseecho"$VERSION_CODENAME")stable"|\sudotee/etc/apt/sources.list.d/docker.list/dev/null# 安装 Docker Enginesudoapt-getupdatesudoapt-getinstall-ydocker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin# 验证安装docker--version1.2 安装 NVIDIA Container Toolkit(GPU 支持)若需使用 GPU 加速,请安装 NVIDIA Container Toolkit:# 检查是否已安装 NVIDIA Container Toolkitnvidia-ctk--version若未安装,按以下步骤安装:查看服务器架构uname-m输出可能是x86_64(AMD64)或aarch64(ARM64)。配置 GPG 密钥与软件源 —— 使用中科大镜像源curl-fsSLhttps://mirrors.ustc.edu.cn/libnvidia-container/gpgkey|sudogpg--dearmor-o/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg写入软件源配置文件 —— 请将下方命令中的 amd64 替换为您第一步查到的实际架构,如果是 ARM 则替换为 arm64echo"deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://mirrors.ustc.edu.cn/libnvidia-container/stable/deb/amd64 /"|sudotee/etc/apt/sources.list.d/nvidia-container-toolkit.list更新软件包列表并安装核心工具包sudoapt-getupdatesudoapt-getinstall-ynvidia-container-toolkit配置 Docker 运行时并重启服务sudonvidia-ctk runtime configure--runtime=docker systemctl restartdocker验证安装nvidia-ctk--version2. 拉取 Qwen3-ASR 镜像dockerpull qwenllm/qwen3-asr:latest3. 创建并运行容器dockerrun--gpusall--nameqwen3-asr\-p9010:80\-p9011:8080\--mounttype=bind,source=/root/qwen3-asr-workspace,target=/data/shared/Qwen3-ASR\--shm-size=4gb\-itdqwenllm/qwen3-asr:latest参数说明:--gpus all:使用所有可用 GPU-p 9010:80:将容器 80 端口映射到主机 9010 端口(WebSocket 服务)-p 9011:8080:将容器 8080 端口映射到主机 9011 端口(HTTP 服务)--mount:将主机目录/root/qwen3-asr-workspace挂载到容器/data/shared/Qwen3-ASR,用于存放模型文件--shm-size=4gb:设置共享内存大小-itd:以交互式、终端分离模式运行4. 下载模型进入容器并下载所需模型:# 进入容器dockerexec-itqwen3-asrbash# 更新 modelscopepipinstall-Umodelscope# 下载 Qwen3-ASR 模型(可选 0.6B 或 1.7B 版本)modelscope download--modelQwen/Qwen3-ASR-0.6B--local_dir./models/Qwen3-ASR-0.6B modelscope download--modelQwen/Qwen3-ASR-1.7B--local_dir./models/Qwen3-ASR-1.7B# 下载对齐模型modelscope download--modelQwen/Qwen3-ForcedAligner-0.6B--local_dir./models/Qwen3-ForcedAligner-0.6B5. 启动服务5.1 离线语音转写服务(2 张卡)gpu-memory-utilization —— 最多占用多少 GPU 内存qwen-asr-serve /data/shared/Qwen3-ASR/models/Qwen3-ASR-1.7B --gpu-memory-utilization0.8--host0.0.0.0--port80--tensor-parallel-size2参数说明:/data/shared/Qwen3-ASR/models/Qwen3-ASR-1.7B:模型文件路径,指向已下载的 1.7B 版本模型。--gpu-memory-utilization 0.8:设置 GPU 内存利用率上限为 80%,避免内存溢出。--host 0.0.0.0:服务监听所有网络接口,允许外部访问。--port 80:服务运行在容器的 80 端口(对应主机映射的 9010 端口)。--tensor-parallel-size 2:使用 2 张 GPU 进行张量并行推理,提升推理速度。后台启动方式(指定 GPU 2,3):CUDA_VISIBLE_DEVICES=2,3nohupqwen-asr-serve /data/shared/Qwen3-ASR/models/Qwen3-ASR-1.7B --gpu-memory-utilization0.8--host0.0.0.0--port8080--tensor-parallel-size2offline_asr.log21后台启动参数说明:CUDA_VISIBLE_DEVICES=2,3:指定使用 GPU 2 和 GPU 3 两张卡。--port 8080:服务运行在容器的 8080 端口(对应主机映射的 9011 端口)。 offline_asr.log 21 :将标准输出和错误输出重定向到offline_asr.log文件,并在后台运行。5.2 生成 SSL 证书(用于 WebSocket 服务)openssl req-x509-newkeyrsa:2048\-keyoutkey.pem-outcert.pem\-days365-nodes\-subj"/CN=localhost"5.3 实时语音转写服务 —— 并行 2 张卡nohupshstart_websocket_server.shonline_asr.log216. WebSocket 服务实现详解本节详细介绍如何实现一个完整的 WebSocket 语音转写服务,包括模型加载、服务器启动和客户端处理。6.1 加载语音识别模型首先需要加载 Qwen3-ASR 模型,配置相关参数:importargparsefromqwen_asrimportQwen3ASRModel# 解析命令行参数parser=argparse.ArgumentParser()parser.add_argument("--asr_model_path",type=str,required=True,help="ASR 模型路径,例如:/data/shared/Qwen3-ASR/models/Qwen3-ASR-1.7B")parser.add_argument("--gpu_memory_utilization",type=float,default=0.8,help="GPU 内存利用率,默认 0.8(80%)")parser.add_argument("--max_model_len",type=int,default=4096,help="模型最大长度")parser.add_argument("--tensor_parallel_size",type=int,default=2,help="张量并行大小,默认使用 2 张 GPU")parser.add_argument("--pipeline_parallel_size",type=int,default=1,help="流水线并行大小")args=parser.parse_args()# 加载 ASR 模型asr=Qwen3ASRModel.LLM(model=args.asr_model_path,gpu_memory_utilization=args.gpu_memory_utilization,max_new_tokens=32,max_model_len=args.max_model_len,tensor_parallel_size=args.tensor_parallel_size,pipeline_parallel_size=args.pipeline_parallel_size,)6.2 启动 WebSocket 服务器创建 WebSocket 服务器,支持 SSL 加密连接:importasyncioimportwebsocketsimportsslimportjsonimportnumpyasnp# 解析 WebSocket 服务器参数parser.add_argument("--host",type=str,default="0.0.0.0",help="服务器监听地址,默认 0.0.0.0(所有接口)")parser.add_argument("--port",type=int,default=9011,help="服务器监听端口,默认 9011")parser.add_argument("--ssl_cert",type=str,default="cert.pem",help="SSL 证书路径")parser.add_argument("--ssl_key",type=str,default="key.pem",help="SSL 私钥路径")args=parser.parse_args()# 配置 SSL 上下文(如果提供了证书和私钥)ssl_context=Noneifargs.ssl_certandargs.ssl_key:ssl_context=ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)ssl_context.load_cert_chain(args.ssl_cert,args.ssl_key)scheme="wss"else:scheme="ws"asyncdefrun_server():"""启动 WebSocket 服务器"""asyncwithwebsockets.serve(handle_client,args.host,args.port,ssl=ssl_context,ping_interval=20,ping_timeout=10,):print(f"WebSocket server started on{scheme}://{args.host}:{args.port}")awaitasyncio.Future()# 永久运行6.3 客户端处理函数处理客户端连接和音频数据流:# 解析流式处理参数parser.add_argument("--unfixed_chunk_num",type=int,default=10,help="非固定块数量")parser.add_argument("--unfixed_token_num",type=int,default=10,help="非固定 token 数量")parser.add_argument("--chunk_size_sec",type=float,default=0.5,help="块大小(秒)")args=parser.parse_args()asyncdefhandle_client(websocket):"""处理单个客户端连接"""# 3.1 初始化识别状态state=asr.init_streaming_state(unfixed_chunk_num=args.unfixed_chunk_num,unfixed_token_num=args.unfixed_token_num,chunk_size_sec=args.chunk_size_sec,)client_address=websocket.remote_addressprint(f"New client connected:{client_address}")try:# 3.2 接收音频并返回结果asyncformessageinwebsocket:ifisinstance(message,bytes):# 客户端发送 float32 PCM 字节数据wav=np.frombuffer(message,dtype=np.float32)iflen(wav)0:asr.streaming_transcribe(wav,state)text=getattr(state,"text","")language=getattr(state,"language","")or""# 返回实时识别结果awaitwebsocket.send(json.dumps({"text":text,"language":language,"is_final":False,}))# 3.3 异常处理exceptwebsockets.exceptions.ConnectionClosedase:print(f"Client disconnected:{client_address}(code={e.code})")exceptExceptionase:print(f"Error handling client{client_address}:{e}")finally:try:# 完成流式识别asr.finish_streaming_transcribe(state)final_text=getattr(state,"text","")print(f"Final transcription for client{client_address}:{final_text}")exceptExceptionase:print(f"Error finishing stream for client{client_address}:{e}")# 启动服务器if__name__=="__main__":asyncio.run(run_server())6.4 服务启动脚本创建启动脚本start_websocket_server.sh:#!/bin/bash# WebSocket 服务启动脚本python websocket_server.py\--asr_model_path/data/shared/Qwen3-ASR/models/Qwen3-ASR-1.7B\--gpu_memory_utilization0.8
返回列表