VibeVoice ASR 部署实战:从 Docker + vLLM 推理服务到 Gradio 网络 Demo 的完整搭建
【免费下载链接】VibeVoiceOpen-Source Frontier Voice AI项目地址: https://gitcode.com/GitHub_Trending/vib/VibeVoice
本篇基于仓库内的部署指南 setup_gradio_demo.md,讲清楚 VibeVoice ASR(语音识别)模型在 GPU 环境下的端到端部署流程:如何用一条docker run命令拉起基于 vLLM 的高性能推理服务(支持单卡与多卡数据并行),验证 OpenAI 兼容 API,再叠加 Gradio Web Demo 生成可公开访问的试听/转录页面。读完本文,你可以独立完成 ASR 服务的容器化部署、多 GPU 扩容与故障排查,并深入理解启动脚本 start_server.py 与服务端插件的实现细节。
一、整体架构:两个组件,一条链路
整个 Demo 由两个独立进程组成,均运行在同一个 Docker 容器内:
- ASR 服务:
vllm/vllm-openai:v0.14.1官方镜像中运行 start_server.py,它负责装依赖、拉模型、生成 tokenizer 文件,最终启动vllm serve,对外提供 OpenAI 兼容的/v1/chat/completions接口(模型名注册为vibevoice); - Gradio 前端:gradio_asr_demo_api_video.py 通过 HTTP 调用上面的 API,提供音频/视频上传、流式转写、分段试听与字幕生成界面,可用
--share生成gradio.live公网链接。
从 pyproject.toml 可以看到,vibevoice包通过vllm.general_plugins入口点注册vllm_plugin:register_vibevoice,这意味着 vLLM 无需修改源码即可识别并加载 VibeVoice 模型——安装即插即用。
二、前置条件
- 具备 CUDA 的 GPU(多卡部署需更多显存设备);
- 支持 GPU 的 Docker(
nvidia-docker); - 本地已克隆 VibeVoice 仓库(容器会把当前目录挂载为
/app):
git clone https://github.com/microsoft/VibeVoice.git cd VibeVoice三、Step 1 — 启动 ASR 服务
启动脚本 start_server.py 会自动完成五件事:安装系统依赖(FFmpeg、libsndfile1)、以 vLLM 插件方式安装 VibeVoice、从 Hugging Face 下载模型(默认microsoft/VibeVoice-ASR)、通过 generate_tokenizer_files.py 生成 tokenizer 文件、最后exec启动vllm serve。
3.1 单 GPU(默认)
docker run -d --gpus '"device=0"' --name vibevoice-asr-demo \ --ipc=host \ -p 6001:6001 \ -e VIBEVOICE_FFMPEG_MAX_CONCURRENCY=64 \ -e PYTORCH_ALLOC_CONF=expandable_segments:True \ -v $(pwd):/app \ -w /app \ --entrypoint bash \ vllm/vllm-openai:v0.14.1 \ -c "python3 /app/vllm_plugin/scripts/start_server.py --port 6001"两个环境变量的作用:
VIBEVOICE_FFMPEG_MAX_CONCURRENCY=64:控制音频解码(FFmpeg)的并发上限,DP 模式下启动脚本还会自动为每个 worker 单独注入该值;PYTORCH_ALLOC_CONF=expandable_segments:True:开启 PyTorch 可扩展显存分段分配,缓解显存碎片导致的 OOM。
3.2 多 GPU 数据并行(负载均衡)
docker run -d --gpus '"device=0,1,2,3"' --name vibevoice-asr-demo \ --ipc=host \ -p 6001:6001 \ -e VIBEVOICE_FFMPEG_MAX_CONCURRENCY=64 \ -e PYTORCH_ALLOC_CONF=expandable_segments:True \ -v $(pwd):/app \ -w /app \ --entrypoint bash \ vllm/vllm-openai:v0.14.1 \ -c "python3 /app/vllm_plugin/scripts/start_server.py --port 6001 --dp 4"--dp 4表示在 4 张 GPU 上各跑 1 个独立副本。从源码 start_dp_server 可以看到其实现细节:
- 为每个副本分配独立 GPU(通过
CUDA_VISIBLE_DEVICES)与内部端口(前端端口 + 100、+101……); - 自动安装并启动nginx 反向代理,采用
least_conn(最少连接)调度,worker 数默认为2 × 副本数,对外只暴露一个端口; - 设计注释说明:这样做是为了规避 vLLM 内置 DP 协调器在大音频载荷下的单进程 HTTP 瓶颈;
- 每个后端最多等待 10 分钟就绪,任何一个 worker 退出都会触发整体优雅关闭。
Tip:
--dp N用于 N 路数据并行(吞吐扩容,推荐);--tp N用于张量并行(单卡放不下大模型时切分)。两者默认均为 1,详细原理见 vibevoice-vllm-asr.md。
3.3 检查日志
docker logs -f vibevoice-asr-demo等待出现Application startup complete.即表示服务就绪(含模型下载,首次约 2 分钟以上)。
3.4 启动脚本暴露的全部参数
对照 start_server.py 的 argparse 定义,除--port和--dp/--tp外还可调节:
| 参数 | 说明 | 默认值 |
|---|---|---|
--model, -m | Hugging Face 模型 ID | microsoft/VibeVoice-ASR |
--port, -p | 服务端口 | 8000 |
--max-num-seqs | 单批次最大并发序列数 | 64 |
--max-model-len | 最大模型上下文长度(支撑长音频) | 65536 |
--gpu-memory-utilization | 显存占用比例 | 0.8 |
--skip-deps | 跳过系统依赖安装 | off |
--skip-tokenizer | 跳过 tokenizer 文件生成 | off |
这些值最终会传入由_build_vllm_cmd拼出的vllm serve命令,其中固定携带--dtype bfloat16、--no-enable-prefix-caching、--enable-chunked-prefill、--allowed-local-media-path /app等 ASR 场景针对性配置。
四、Step 2 — 验证服务
# Check the model is loaded curl http://localhost:6001/v1/models预期输出:
{ "data": [{ "id": "vibevoice", ... }] }4.1 用真实音频快速测试
仓库自带的 test_api.py 是最小验证客户端:
docker exec -it vibevoice-asr-demo \ python3 /app/vllm_plugin/tests/test_api.py /app/en-Alice_woman.wav \ --url http://localhost:6001从源码看,该脚本会把音频 base64 编码后以audio_url形式放入/v1/chat/completions请求,prompt 中要求模型按Start time / End time / Speaker ID / Content四个键输出 JSON,并以流式方式接收增量结果;结束后打印总耗时与RTF(实时因子)= 处理时长 / 音频时长,可用于直观评估服务吞吐。它还支持--hotwords参数,把热词以 "with extra info" 形式嵌入 prompt,提升专有名词、人名识别准确率:
python3 /app/vllm_plugin/tests/test_api.py /app/en-Alice_woman.wav --hotwords "Microsoft,Azure,VibeVoice"(测试音频路径可按需替换为挂载目录中的任意 wav/mp3 文件。)
五、Step 3 — 启动 Gradio Demo
Gradio 进程与 ASR 服务分离,便于单独重启前端而不动推理服务。这里用 tmux 让进程在容器内后台常驻。
5.1 安装 tmux
docker exec vibevoice-asr-demo apt-get install -y tmux5.2 在 tmux 中启动 Gradio
docker exec vibevoice-asr-demo bash -c \ "PYTHONUNBUFFERED=1 tmux new-session -d -s gradio \ 'PYTHONUNBUFFERED=1 python3 /app/vllm_plugin/scripts/gradio_asr_demo_api_video.py \ --api_url http://localhost:6001 --share \ 2>&1 | tee /tmp/gradio.log'"PYTHONUNBUFFERED=1保证 Python 输出不缓冲,日志能实时写入/tmp/gradio.log(这也是排查"日志为空"的关键)。
5.3 获取 Share 链接
等待约 20 秒后:
docker exec vibevoice-asr-demo cat /tmp/gradio.log预期看到:
✅ Connected to API: http://localhost:6001 | Model: vibevoice 🚀 Starting VibeVoice ASR Demo * Running on local URL: http://0.0.0.0:7860 * Running on public URL: https://xxxxxx.gradio.livegradio.live链接为公网可访问的临时分享(有效期约 1 周)。
5.4 Gradio 启动参数
| Flag | 说明 | 默认值 |
|---|---|---|
--api_url URL | vLLM 服务地址 | http://localhost:8000 |
--share | 创建 Gradio 公网链接 | off |
--port PORT | 本地 Gradio 端口 | 7860 |
--cloudflared | 用 Cloudflare 隧道代替 Gradio share | off |
--max_video_size MB | 允许上传的视频大小上限 | 50 |
补充源码中同样存在但文档未强调的两个参数(见 gradio_asr_demo_api_video.py):--model_name(不指定时自动从/v1/models探测)与--max_new_tokens(默认 4096)。启动时 demo 会调用demo.queue(default_concurrency_limit=10),即队列模式下最多 10 个请求并发处理,天然支持多人同时使用。
5.5 Demo 前端的实现要点
从 gradio_asr_demo_api_video.py 的源码结构看,它不只是简单的转写页面:
- 多格式兼容:识别
.wav/.mp3/.flac/.ogg/.opus/.m4a等音频与.mp4/.webm/.mov/.mkv等视频扩展名;视频会先用 ffmpeg 抽取 16kHz 单声道 MP3 音轨再提交识别; - 流式输出:
VibeVoiceAPIClient.transcribe_streaming以stream: True请求 API,边收边向页面推送增量文本,并解析usage字段展示 token 统计; - 截断容错:
_parse_segments与_parse_truncated_segments会在响应被截断时尽力抢救出完整的分段(Start/End/Speaker/Content),避免长音频"全军覆没"; - 分段试听与字幕:转写完成后可按说话人分段并行切片(
ThreadPoolExecutor),并生成 SRT / WebVTT 字幕文件; - 热词上下文:界面支持填入 context info,拼入 prompt 后同样走热词增强识别路径。
六、服务管理
6.1 只停 Gradio(保留 ASR 服务)
docker exec vibevoice-asr-demo tmux kill-session -t gradio重启 Gradio:重跑 Step 3 中的 tmux 命令即可。
6.2 全部停止
docker stop vibevoice-asr-demo docker rm vibevoice-asr-demo七、一键完整示例(GPU 0 + 端口 6001)
# 1. Start server docker run -d --gpus '"device=0"' --name vibevoice-asr-demo \ --ipc=host -p 6001:6001 \ -e VIBEVOICE_FFMPEG_MAX_CONCURRENCY=64 \ -e PYTORCH_ALLOC_CONF=expandable_segments:True \ -v $(pwd):/app -w /app \ --entrypoint bash \ vllm/vllm-openai:v0.14.1 \ -c "python3 /app/vllm_plugin/scripts/start_server.py --port 6001" # 2. Wait for startup (~2 min), then verify docker logs -f vibevoice-asr-demo # wait for "Application startup complete." curl http://localhost:6001/v1/models # 3. Install tmux and launch Gradio docker exec vibevoice-asr-demo apt-get install -y tmux docker exec vibevoice-asr-demo bash -c \ "PYTHONUNBUFFERED=1 tmux new-session -d -s gradio \ 'PYTHONUNBUFFERED=1 python3 /app/vllm_plugin/scripts/gradio_asr_demo_api_video.py \ --api_url http://localhost:6001 --share \ 2>&1 | tee /tmp/gradio.log'" # 4. Get the public link sleep 20 && docker exec vibevoice-asr-demo cat /tmp/gradio.log八、故障排查
| 问题 | 处理办法 |
|---|---|
CUDA out of memory | 换用其他 GPU(device=X),或在start_server.py中把--gpu-memory-utilization调低(如0.7) |
| Gradio 日志为空 | 多等一会(约 30s);Gradio 会缓冲输出,务必加PYTHONUNBUFFERED=1 |
Port already in use | 换端口,或停掉占用容器:docker stop <name> && docker rm <name> |
| Share 链接显示 "No interface" | Gradio 仍在加载,等待日志出现Application startup complete |
tmux: command not found | 先执行docker exec <container> apt-get install -y tmux |
补充两条从源码可确认的排查线索:DP 模式下每个后端就绪判定依赖其内部端口的/v1/models(最长等待 10 分钟),若日志停在 "Waiting for all backends to be ready" 应检查--gpus提供的卡数是否 ≥--dp × --tp;--dp N启动前脚本会显式断言 GPU 数量充足,数量不足会直接给出Need X GPUs ... but only Y available的明确报错。
九、延伸阅读
- 部署指南原文:docs/setup_gradio_demo.md
- vLLM ASR 服务完整说明(TP/DP 原理、流式 API、热词):docs/vibevoice-vllm-asr.md
- 一键启动脚本:vllm_plugin/scripts/start_server.py
- Gradio 前端实现:vllm_plugin/scripts/gradio_asr_demo_api_video.py
- API 测试客户端:vllm_plugin/tests/test_api.py
- 流式 Demo 的 FastAPI 服务端(另一条部署路线):vllm_plugin/asr_streaming_server.py
【免费下载链接】VibeVoiceOpen-Source Frontier Voice AI项目地址: https://gitcode.com/GitHub_Trending/vib/VibeVoice
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考