Duix-Avatar 去 Docker Desktop 本地化完整复盘

Duix-Avatar 去 Docker Desktop 本地化完整复盘

🚀🚀🚀 Duix Avatar------真正开源的AI虚拟形象工具包,支持离线视频生成和数字人类克隆

背景与思路

Duix-Avatar 由三个服务组成,原本通过 Docker Desktop 运行。目标是完全摆脱 Docker Desktop,直接用 WSL2 承载这三个服务。

核心判断:

项目的视频合成核心全部编译成了 .cpython-38-x86_64-linux-gnu.so,只能在 Linux x86_64 + Python 3.8 下运行,Windows native 无法加载,因此 WSL2 是唯一可行的本地化路径。


三个服务说明

【保姆级教程】Windows + Podman 从零部署 Duix-Avatar 数字人项目
【笔记】Podman Desktop 部署 开源数字人 HeyGem.ai
【笔记】在 Podman Machine(Fedora 42)中安装 NVIDIA Container Toolkit 使镜像能使用GPU
Windows 开发环境部署指南:WSL、Docker Desktop、Podman Desktop 部署顺序与存储路径迁移指南
在WSL-podman-machine-default (Fedora Linux 42) 中安装 CUDA 13.0、cuDNN 9.14、Anaconda 2025.06、PyTorch 2.10
用Podman Desktop创建自用的WSL-Fedora Linux子系统
新!在 podman-machine-default 中安装 CUDA、cuDNN、Anaconda、PyTorch 等并验证安装
PyCharm 链接 Podman Desktop 的 podman-machine-default Linux 虚拟环境
Podman Desktop:现代轻量容器管理利器(Podman与Docker)

来自 Podman Desktop 拉取完毕的镜像

服务 镜像 端口 职责
duix-avatar-gen-video guiji2025/duix.avatar 8383 lip-sync 视频合成(核心)
duix-avatar-tts guiji2025/fish-speech-ziming 18180 声音克隆 + TTS
duix-avatar-asr guiji2025/fun-asr 10095 语音识别(ASR)

第一步:确认镜像大小和磁盘空间

复制代码
podman image inspect guiji2025/duix.avatar --format "{{.Size}}"
podman image inspect guiji2025/fish-speech-ziming --format "{{.Size}}"
podman image inspect guiji2025/fun-asr --format "{{.Size}}"
Get-PSDrive J  # 确认目标盘剩余空间

三个镜像合计约 64GB,导出 tar + 导入 vhdx 峰值需要约 130GB 空闲空间。


第二步:建立目录结构

复制代码
New-Item -ItemType Directory -Path J:\duix_export -Force
New-Item -ItemType Directory -Path J:\wsl\duix-avatar -Force
New-Item -ItemType Directory -Path J:\wsl\duix-fish -Force
New-Item -ItemType Directory -Path J:\wsl\duix-asr -Force

第三步:逐个导出容器并导入 WSL2

每次导出一个、验证后删除 tar 再导下一个,节省磁盘峰值占用。

duix-avatar(最小,先练手)

复制代码
podman create --name tmp_avatar guiji2025/duix.avatar sleep 999
podman export tmp_avatar -o J:\duix_export\avatar.tar
podman rm tmp_avatar
wsl --import duix-avatar J:\wsl\duix-avatar J:\duix_export\avatar.tar --version 2
# 验证成功后删除
Remove-Item J:\duix_export\avatar.tar

duix-asr

复制代码
podman create --name tmp_asr guiji2025/fun-asr sleep 999
podman export tmp_asr -o J:\duix_export\asr.tar
podman rm tmp_asr
wsl --import duix-asr J:\wsl\duix-asr J:\duix_export\asr.tar --version 2
Remove-Item J:\duix_export\asr.tar

duix-fish(最大,最后)

复制代码
podman create --name tmp_fish guiji2025/fish-speech-ziming sleep 999
podman export tmp_fish -o J:\duix_export\fish.tar
podman rm tmp_fish
wsl --import duix-fish J:\wsl\duix-fish J:\duix_export\fish.tar --version 2
Remove-Item J:\duix_export\fish.tar

第四步:修复 GPU 直通(三个发行版都要做)

容器镜像内 /lib/x86_64-linux-gnu/ 里有大量空占位 .so 文件,会干扰 WSL2 的 GPU 桥接库,需要清除并重建软链。

复制代码
# 对 duix-avatar、duix-asr、duix-fish 各执行一次,替换发行版名称
wsl -d duix-avatar -- bash -c "
find /lib/x86_64-linux-gnu/ -name 'libnvidia-*.so*' -empty -delete &&
find /lib/x86_64-linux-gnu/ -name 'libcuda*.so*' -empty -delete &&
find /lib/x86_64-linux-gnu/ -name 'libcudadebugger*.so*' -empty -delete &&
echo '/usr/lib/wsl/lib' > /etc/ld.so.conf.d/wsl.conf &&
ldconfig 2>/dev/null &&
rm /usr/bin/nvidia-smi 2>/dev/null &&
ln -s /usr/lib/wsl/lib/nvidia-smi /usr/bin/nvidia-smi &&
nvidia-smi | head -5
"

验证标准:能看到 NVIDIA-SMI 输出和 GPU 型号即成功。


第五步:建立数据目录软链

客户端实际使用的数据目录是 D:\heygem_data\(注意:不是 README 里写的 duix_avatar_data,要以客户端 asar 解包后的实际路径为准)。

复制代码
# avatar:face2face 数据目录
wsl -d duix-avatar -- bash -c "
rm -rf /code/data &&
ln -s /mnt/d/heygem_data/face2face /code/data &&
ls /code/data/
"

# fish:voice/data 目录
wsl -d duix-fish -- bash -c "
rm -rf /code/data &&
ln -s /mnt/d/heygem_data/voice/data /code/data &&
ls /code/data/origin_audio/ | tail -3
"

第六步:修复 fish 服务的 ASR 主机名配置

fish 服务内部通过 WebSocket 连接 ASR,配置文件里主机名是 Docker 容器名 duix-avatar-asr,在 WSL2 环境中无法解析,需要改为 127.0.0.1

复制代码
"
f = open('/code/config/config.py', 'r')
content = f.read()
f.close()
content = content.replace('duix-avatar-asr', '127.0.0.1')
f = open('/code/config/config.py', 'w')
f.write(content)
f.close()
print('done')
" | wsl -d duix-fish -- bash -c "cat > /tmp/fix_config.py && python3 /tmp/fix_config.py"

# 验证
wsl -d duix-fish -- bash -c "grep fun_asr_host /code/config/config.py"

期望输出:fun_asr_host = '127.0.0.1'


第七步:设置环境变量

复制代码
wsl -d duix-avatar -- bash -c "echo 'export PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512' >> /root/.bashrc"

第八步:写一键启动脚本

fish 服务需要直接监听 18180(WSL2 没有 Docker 的端口映射层),不能用 8080。

复制代码
@'
# Duix Avatar 一键启动脚本(WSL2 版,无需 Docker Desktop)
Write-Host "启动 duix-asr (ASR服务 port:10095)..." -ForegroundColor Cyan
Start-Process wsl -ArgumentList "-d duix-asr -- bash -c `"cd /workspace/FunASR/runtime && sh /run.sh`"" -WindowStyle Normal

Start-Sleep 2

Write-Host "启动 duix-fish (TTS服务 port:18180)..." -ForegroundColor Cyan
Start-Process wsl -ArgumentList "-d duix-fish -- bash -c `"cd /code && /opt/conda/envs/python310/bin/python3 tools/api_server.py --listen 0.0.0.0:18180`"" -WindowStyle Normal

Start-Sleep 2

Write-Host "启动 duix-avatar (视频合成服务 port:8383)..." -ForegroundColor Cyan
Start-Process wsl -ArgumentList "-d duix-avatar -- bash -c `"export PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512 && cd /code && python3 app_local.py`"" -WindowStyle Normal

Write-Host ""
Write-Host "服务启动中,等待约 30 秒后可打开客户端..." -ForegroundColor Green
Write-Host "  ASR:   ws://127.0.0.1:10095" -ForegroundColor Gray
Write-Host "  TTS:   http://127.0.0.1:18180" -ForegroundColor Gray
Write-Host "  Video: http://127.0.0.1:8383" -ForegroundColor Gray
'@ | Out-File -FilePath D:\Program\start-duix.ps1 -Encoding UTF8

一键停止脚本

复制代码
@'
Write-Host "停止所有 Duix 服务..." -ForegroundColor Yellow
wsl -d duix-avatar -- bash -c "pkill -f app_local.py 2>/dev/null; echo done"
wsl -d duix-fish   -- bash -c "pkill -f api_server.py 2>/dev/null; echo done"
wsl -d duix-asr    -- bash -c "pkill -f run_server.sh 2>/dev/null; pkill -f funasr 2>/dev/null; echo done"
wsl --terminate duix-avatar
wsl --terminate duix-fish
wsl --terminate duix-asr
Write-Host "所有服务已停止" -ForegroundColor Green
'@ | Out-File -FilePath D:\Program\stop-duix.ps1 -Encoding UTF8

踩坑记录

原因 解法
nvidia-smi 无输出 镜像内有空占位 .so 覆盖了 WSL 桥接库 删除空文件 + 软链到 /usr/lib/wsl/lib/nvidia-smi
TTS 返回 500 NoneType has no attribute send config.py 里 ASR 主机名是 Docker 容器名 duix-avatar-asr 改为 127.0.0.1
TTS 端口 18180 不通 WSL2 没有 Docker 的端口映射,服务监听 8080 但客户端访问 18180 直接让服务监听 18180
file not exists 软链指向了错误的数据目录 duix_avatar_data,客户端实际写入的是 heygem_data 重建软链指向 heygem_data
SQLite 绑定错误 train() 失败返回 false,被当作 voiceId 写入数据库 根因是以上几个问题,逐一修复后自然解决

最终验证

复制代码
Test-NetConnection -ComputerName 127.0.0.1 -Port 8383   # 视频合成 ✅
Test-NetConnection -ComputerName 127.0.0.1 -Port 18180  # TTS ✅
Test-NetConnection -ComputerName 127.0.0.1 -Port 10095  # ASR ✅

GPU 合成期间 sm 83%,完全 GPU 推理,速度与原 Docker 版本一致。

相关推荐
企业培训大师2 小时前
学校组织线上考试用什么系统合适?3款高适配系统推荐
大数据·人工智能
character08252 小时前
Django全栈开发入门:构建一个博客系统
jvm·数据库·python
豆豆2 小时前
支持信创国产化的CMS:PageAdmin平台版,集成AI与站群全能平台
大数据·人工智能·cms·网站建设·网站制作·建站系统·网站管理系统
春日见2 小时前
Matlab快速入门 基础语法教学
java·开发语言·驱动开发·matlab·docker·计算机外设
skywalk81632 小时前
iwr -useb https://openclaw.ai/install.ps1 | iex 这里的iwr怎么安装?
windows
m0_564876842 小时前
Transformer架构
人工智能
大傻^2 小时前
LangChain4j AI Services 深度解析:声明式 API 与接口驱动开发
人工智能·langchain·openai·langchain4j
Dfreedom.2 小时前
工具箱思维:在计算机视觉中如何选对工具、用好工具(计算机视觉篇)
人工智能·计算机视觉·目标跟踪
腾科IT教育2 小时前
人工智能三级好考吗?考试难度解析
人工智能·ai训练师·人工智能算法工程师