# MuseTalk GPU Worker 部署指南 本目录包含两个组件: 1. **gpu_worker.py**:反向轮询客户端,部署在 RTX2060 本地,轮询 SaaS API 拉取口型任务,调用本地 MuseTalk 服务推理,上传结果回 SaaS。 2. **musetalk_server.py**:MuseTalk Flask HTTP 服务端,接收 gpu_worker.py 的推理请求,调用 MuseTalk 模型生成口型同步视频。 --- ## 一、环境准备 ### 1.1 硬件要求 - GPU: NVIDIA RTX 2060 或更高(显存 ≥ 6GB) - CUDA: 11.8+ - Python: 3.10+ - ffmpeg: 需安装并加入 PATH ### 1.2 安装依赖 ```bash cd deploy/gpu_worker python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` --- ## 二、MuseTalk 服务端部署(musetalk_server.py) ### 2.1 配置环境变量 复制 `.env.example` 为 `.env`,修改配置: ```bash cp .env.example .env vim .env ``` 关键配置: | 变量 | 说明 | 默认值 | |------|------|--------| | `MUSE_PORT` | 监听端口 | `7861` | | `MUSE_INFERENCE_TIMEOUT` | 推理超时秒数 | `600` | | `MUSE_VIDEO_MAX_MB` | 视频上传大小限制 MB | `100` | | `MUSE_AUDIO_MAX_MB` | 音频上传大小限制 MB | `20` | | `MUSE_DEFAULT_FPS` | 视频 fps 兜底值 | `25.0` | | `MUSE_TEMP_DIR` | 临时文件目录 | `/tmp/musetalk_$$` | ### 2.2 启动服务 ```bash # 前台运行(调试用) python musetalk_server.py # 后台运行(生产用 systemd) sudo systemctl start musetalk-server sudo systemctl enable musetalk-server ``` ### 2.3 验证健康检查 ```bash curl http://127.0.0.1:7861/health ``` 应返回: ```json { "status": "healthy", "gpu": { "gpu_name": "NVIDIA GeForce RTX 2060", "memory_total_mb": 6144, "memory_used_mb": 1024, "memory_free_mb": 5120 }, "current_task": { "task_id": null, "running": false, "elapsed_seconds": 0.0 }, "timestamp": 1700000000.0 } ``` --- ## 三、GPU Worker 客户端部署(gpu_worker.py) ### 3.1 配置环境变量 复制 `.env.example` 为 `.env`,修改配置: ```bash cp .env.example .env vim .env ``` 关键配置: | 变量 | 说明 | 默认值 | |------|------|--------| | `API_BASE_URL` | SaaS API 基础 URL | `https://staging-api.xiaoxiajianji.com` | | `GPU_WORKER_TOKEN` | 长期 API Token(与服务端一致) | - | | `MUSE_TALK_URL` | 本地 MuseTalk 服务地址 | `http://127.0.0.1:7861` | | `POLL_INTERVAL` | 轮询间隔秒 | `5` | | `HEARTBEAT_INTERVAL` | 空闲心跳间隔秒 | `15` | | `REQUEST_TIMEOUT` | HTTP 请求超时秒 | `900` | | `TASK_MAX_RETRY` | 本地最大重试次数 | `1` | | `TASK_HEARTBEAT_INTERVAL` | 推理期间任务心跳间隔秒 | `30` | | `MIN_VIDEO_DURATION_SECONDS` | 最短输入视频时长秒 | `3` | ### 3.2 启动 Worker ```bash # 前台运行(调试用) python gpu_worker.py # 后台运行(生产用 systemd) sudo systemctl start xiaoxia-gpu-worker sudo systemctl enable xiaoxia-gpu-worker ``` ### 3.3 验证启动日志 应看到: ``` ============================================================ MuseTalk GPU Worker 启动 worker_id = rtx2060-xxxx api_base = https://staging-api.xiaoxiajianji.com muse_talk = http://127.0.0.1:7861 poll = 5.0s / heartbeat = 15.0s ============================================================ MuseTalk 健康检查通过: {...} 注册/心跳成功 ``` --- ## 四、常见问题排查 | 现象 | 可能原因 / 排查 | |---|---| | 日志 401 `Invalid GPU worker token` | `.env` 的 `GPU_WORKER_TOKEN` 与服务端不一致 | | 日志 `MuseTalk 健康检查未通过` | 本地 MuseTalk 没启动,或端口不是 7861;`curl http://127.0.0.1:7861/health` 验证 | | 任务长时间不被拉取 | Worker 和服务端连不上;检查 API_BASE_URL 是否可达、Token 是否正确 | | 推理后上传 OSS 失败 | 本地出口网络被防火墙拦截 OSS 域名(oss-cn-hangzhou.aliyuncs.com) | | 服务端看到任务回退到 pending 重试 | 任务心跳真正超时(默认 900s):Worker 进程崩溃/断网,或推理彻底卡死;正常长推理期间心跳线程每 30s 续期,不会回退 | | 日志 `MuseTalk 推理超时或连接失败` | 视频太长或显存不足;可临时调大 REQUEST_TIMEOUT(服务端 GPU_TASK_TIMEOUT_SECONDS 需同步调大),或限制输入视频时长 | | 日志 `视频过短(x.xxs < 3s)` | 输入视频不足 3s,MuseTalk 对短视频会 division by zero,已在本地直接上报失败;可用 MIN_VIDEO_DURATION_SECONDS 调整阈值 | | MuseTalk 服务端 503 `GPU 正在处理其他任务` | 并发请求被锁拒绝,等当前推理完成即可 | | MuseTalk 服务端 504 `推理超时` | 推理超过 MUSE_INFERENCE_TIMEOUT,客户端会调 /cancel 终止服务端任务 | --- ## 五、安全注意事项 - `.env` 包含长期 Token,文件权限设为 600(`chmod 600 .env`) - Token 泄露要立即在服务端更换 `GPU_WORKER_TOKEN` 并重启 Worker - Worker 只需要出站访问 SaaS API 和 OSS,不需要开放任何入站端口 - MuseTalk 服务端只监听本地 127.0.0.1(或 0.0.0.0 但通过防火墙限制),不暴露到公网 - 临时文件自动清理(推理完成/失败后),无需手动维护 --- ## 六、工程改进记录(musetalk_server.py) 相比原 `worker.py`,修复了以下 8 个 bug: 1. **Flask 单线程阻塞**:`app.run(threaded=True)`,推理时 `/health` 仍可响应 2. **fps=0 除零崩溃**:`_get_video_fps()` 兜底 `MUSE_DEFAULT_FPS` 3. **ffmpeg 不检查返回码**:`subprocess.run(check=True)` + 超时检查,失败立即报错 4. **无并发锁**:`threading.Lock` 控制并发,第二请求立即 503 5. **无推理超时**:线程 join timeout,超时返回 504 并调 `/cancel` 6. **结果文件不清理**:推理完成/失败后自动删除临时目录 7. **无人脸检测兜底**:MuseTalk 推理内部处理(TODO: 可在 `_run_inference` 前置检查) 8. **上传无大小限制**:`_check_file_size()` 校验,超限返回 413 新增: - `/cancel` 端点:终止当前推理任务,清理临时文件 - `/health` 端点:返回 GPU 显存信息和当前任务状态