AI 赛博女友!本地部署教程
无需 API、完全免费,实时交互,几乎零延迟,可谈情说爱!
原文来源:零度博客
今天手把手教大家:在自己电脑上部署一个会说话、有口型的 AI 数字人——全程本地运行,不联网、不花一分钱 API 费用、断网也能用。语音识别、大语言模型、声音克隆、口型同步,全部跑在自己的显卡上。
这篇按实际操作顺序写,跟着做就行。中间有几个坑是网上搜不到的,会标出来。
成品是什么
一个网页,背景是数字人,中间是语音球。你对着麦克风说话,她用你克隆的音色回答,嘴型跟着话动。
硬件要求
| 项目 | 最低 | 推荐 |
|---|---|---|
| 显卡 | 8 GB 显存 | 16 GB 以上 |
| 内存 | 16 GB | 32 GB |
| 硬盘 | 60 GB 可用 | — |
我用的是 RTX 4090(24 GB)。显存不够的话后面会说怎么换小点的模型。(换小点的模型其实影响不大,因为是语言模型无需编程)
显存分配(4090 为例)
| 组件 | 显存 |
|---|---|
| Qwen3-14B Q4_K_M(大脑) | ~9 GB |
| faster-whisper large-v3(耳朵) | ~3 GB |
| Qwen3-TTS 1.7B(嘴巴) | ~4 GB |
| wav2lip256(口型) | ~1.3 GB |
| 合计 | ~17 GB |
第一步:配置 WSL
新建文件 C:\Users\你的用户名\.wslconfig(没有就创建),内容:
[wsl2]
memory=32GB
networkingMode=mirrored
[experimental]
hostAddressLoopback=true
内存按自己机器改,一般给物理内存的一半。
⚠️ 这一步不能省
hostAddressLoopback=true是整个教程里最隐蔽的一个开关。没有它,后面的 WebRTC 连接会永远失败,而且报错完全看不出原因——浏览器只显示一句莫名其妙的 JSON 解析错误,ICE 候选列表是空的。在这上面卡了一个多小时。
第二步:llama.cpp + 大模型
下载
| 显存 | 推荐模型 |
|---|---|
| 16 GB 以上 | Qwen3-14B-Instruct-Q4_K_M |
| 8–16 GB | Qwen3-8B-GGUF 选 Q4_K_M |
| 8 GB 以下 | Qwen3-4B-GGUF |
放置
llama.cpp 解压后,在根目录新建 models 文件夹,把 .gguf 丢进去。
启动
CMD 里执行(路径按自己的改):
llama-server -m E:\llama.cpp\models\Qwen3-14B-Instruct-Q4_K_M.gguf ^
-np 1 -c 8192 -fa on --temp 1.0 --top-p 0.95 ^
--host 0.0.0.0 --port 8090
启动后这个窗口不要关。
参数说明:
--host 0.0.0.0必须加,否则 WSL 里访问不到-c 8192上下文长度。语音对话每轮就两三句,8K 足够,调大只会白吃显存--temp 1.0温度。默认值偏保守,调高一点回复更活泼
⚠️ 端口为什么用 8090 而不是 8080
开启 WSL2/Hyper-V 之后,Windows 会随机预留一批端口,落在里面的端口谁都绑不上,而且
netstat看不到任何占用——你会以为是玄学。查一下自己的保留区间:
netsh interface ipv4 show excludedportrange protocol=tcp我的 8080 正好落在里面,换 8090 就好了。
第三步:下载数字人底图
不想麻烦的可以直接使用提供的数字人底图,直接保存下载即可。
想自己生成的话也可以,用 Flux / ChatGPT Image 都行,提示词:
电影感人像摄影,16:9 横版构图。
一位二十出头的东亚年轻女性,乌黑长直发自然垂落,坐在夜晚昏暗的房间里,上半身入镜。【构图】人物位于画面右侧三分之一处,身体略微侧向镜头,视线看向镜头。画面左侧三分之二为大片暗部负空间,几乎接近纯黑。
【光线】唯一光源来自左前方的屏幕冷光与一盏低色温台灯,面部形成明暗交界,右侧脸颊隐入阴影,发丝边缘有柔和暖色轮廓光。
【状态】嘴唇自然闭合,表情平静放松。手不要遮挡下巴与嘴部。
【质感】浅景深,柔和胶片颗粒,低对比暗调,真实皮肤质感。
负面提示词:
张嘴, 说话, 露齿, 正面平光, 明亮背景, 高对比, 过曝, 人物居中,
多人, 手遮挡嘴部, 文字, 水印, 塑料皮肤, 过度磨皮, 卡通, 3D渲染
构图很关键。 人物靠右、左边留大片暗部,是为了给中间的语音球和文字留位置。而且暗光侧脸能很好地掩盖口型模型的画质短板。
第四步:ComfyUI 生成数字人视频
下载安装 ComfyUI,进去后在模型面板里选 Wan2.2,直接点开会自动下载模型。
上传第三步那张图,用图生视频。
参数
| 项 | 值 |
|---|---|
| width × height | 704 × 896 |
| duration | 5 秒 |
| fps | 25 |
| prompt_enhance | 关闭 |
提示词
她保持静止,轻微呼吸起伏;中途缓慢眨一次眼; 结尾头部回到最初位置。嘴唇始终闭合。固定机位。
生成好命名为 idle.mp4。
只需要这一段
有些教程会让你生成 idle / listening / speaking 三段视频。那是"状态切换"方案用的——不做真口型同步,只是按对话状态切换预录片段。
我们做的是真口型同步,嘴部由模型实时生成,只需要一段闭嘴的底版视频。 生成三段纯属浪费时间。
⚠️ 三个必踩的坑
prompt_enhance必须关掉。 它会用 LLM 把你的提示词扩写成"文生视频"描述,整个场景会被重新想象。第一次没关,输入是一张室内人像,输出变成了夜景窗户前穿蓝衬衫的另一个人。- 输出宽高比要贴近输入图。 输入竖图、输出设成横版的话,模型要凭空补出左右两大块内容,必然跑飞。
- 提示词只写动作,绝不重复描述外观。 一旦重新描述人物长相,模型会照着文字重新合成,而不是让你那张图动起来。
另外,Wan2.2 原生就是 5 秒(81 帧 @16fps)。设成 20 秒它会分段生成,每段都从同一张图起,动作会明显重复。
第五步:录参考音频(声音克隆)
这一步决定了她的声音是谁。跳过的话音色是默认的,而且每次回复都会漂。
录一段 5–15 秒的目标音色:干净、无背景音、单人说话、语气自然。
保存为 wav 或 mp3,放到桌面的 AI 文件夹,命名 ref.wav。
把这段录音说的原话逐字记下来,后面要填进配置里,错一个字都会影响克隆质量。
情绪也会被克隆。 用的那段带撒娇和抱怨的语气,克隆出来的所有回复都会带这个基调。想要中性效果就换一段平铺直叙的录音。
录参考音频已经放在下方的一键部署包里,当然你可以自由替换成你自己喜欢的。
第六步:下载一键部署包
下载本文附带的部署包,解压到桌面新建的 AI 文件夹。
包含:
| 文件 | 用途 |
|---|---|
install-voice.sh |
语音对话部分一键安装 |
start-voice.sh |
语音服务启动 / 停止 / 日志 |
start-livetalking.sh |
口型服务启动 / 停止 |
avatar-sync.js |
音频转发 + 数字人背景层 |
wav2lip256.pth |
口型模型权重 |
wav2lip256_avatar1.tar.gz |
官方示例形象(用来验证链路) |
后两个是 LiveTalking 的模型文件,原本要去 Google Drive 下载。一并打包进来了,省得折腾。
把第四步的 idle.mp4 和第五步的 ref.wav 也放进这个文件夹,最终结构:
C:\Users\你的用户名\Desktop\AI\
├── install-voice.sh
├── start-voice.sh
├── start-livetalking.sh
├── avatar-sync.js
├── wav2lip256.pth
├── wav2lip256_avatar1.tar.gz
├── idle.mp4 ← 你自己生成的
└── ref.wav ← 你自己录的
第七步:安装 WSL2
PowerShell(管理员):
wsl --update
wsl --install -d Ubuntu-24.04
装完重启电脑,让第一步的 .wslconfig 生效。
重启后打开 Ubuntu 终端,设置用户名密码,然后验证显卡直通:
nvidia-smi
能看到你的显卡就对了。
⚠️ WSL 里不要装显卡驱动
驱动只装 Windows 侧。在 WSL 里
apt install nvidia-driver会覆盖掉直通的libcuda.so,GPU 直接不可用。
第八步:把文件拷进 WSL
Ubuntu 终端里:
# 1. 拷贝(把 LINGDU 换成你的 Windows 用户名)
mkdir -p ~/setup
cp -r "/mnt/c/Users/LINGDU/Desktop/AI/." ~/setup/
cd ~/setup
ls -la
# 2. 转换行尾 —— 关键步骤
sudo apt update && sudo apt install -y dos2unix
dos2unix *.sh
# 3. 加执行权限
chmod +x *.sh
⚠️ 为什么要转行尾
文件在 Windows 上存过就会变成 CRLF 行尾,直接执行会报:
bad interpreter: /usr/bin/env bash^M: No such file or directory这个错误信息完全看不出根因,很多人卡在这里。
⚠️ 不要在 /mnt/c 下直接跑
跨文件系统读写慢一个数量级,而且
chmod +x在 Windows 分区上不生效。必须拷到~再执行。
第九步:安装语音对话部分
cd ~/setup
./install-voice.sh
脚本会自动完成:系统依赖 → Python 3.12 环境 → speech-to-speech(含 VAD / Whisper / Qwen3-TTS)→ 前端页面 → 打补丁。
大概 10–20 分钟,取决于网速。
装完把参考音频放到位:
ffmpeg -i ~/setup/ref.wav -ac 1 -ar 16000 -c:a pcm_s16le ~/s2s/ref.wav
# 确认格式:必须是 pcm_s16le / 16000 / 1 声道
ffprobe -v error -show_entries stream=sample_rate,channels,codec_name \
-show_entries format=duration -of default=nw=1 ~/s2s/ref.wav
然后把录音原话填进配置:
sed -i 's|^REF_TEXT=.*|REF_TEXT="靠杯了,你终于上线了,我既开心又有点怨你,嗯;小雅一个人在这里等你,等的都快委屈死了!"|' ~/setup/start-voice.sh
grep -n "^REF_TEXT=" ~/setup/start-voice.sh
原话必须逐字一致。 差一个字都会影响克隆质量,语气词「嗯」「啊」也要照录音写上。
先单独测一次
cd ~/setup
./start-voice.sh
浏览器打开 http://localhost:7860/,点中间的球,允许麦克风,说句话试试。
首次配置
右上角齿轮 → Settings:
- NOISE GATE 滑块拖到最左边(关闭)
- INSTRUCTIONS 填人设(下面第十二步有模板)
⚠️ NOISE GATE 一定要关
这个滑块默认位置可能把正常说话的音量都掐掉,表现是完全没反应、日志里连一条识别记录都没有。一开始以为是麦克风坏了。
第十步:安装口型同步(LiveTalking)
新开一个 Ubuntu 终端:
mkdir -p ~/livetalking && cd ~/livetalking
git clone https://github.com/lipku/LiveTalking.git
cd LiveTalking
uv venv --python 3.10 .venv-lt
source .venv-lt/bin/activate
uv pip install torch==2.5.0 torchvision==0.20.0 torchaudio==2.5.0 \
--index-url https://download.pytorch.org/whl/cu124
uv pip install -r requirements.txt
sudo apt install -y ffmpeg libgl1 libglib2.0-0
放置模型
模型已经在部署包里了(第八步一起拷进 ~/setup 了),直接就位:
cd ~/livetalking/LiveTalking
# 权重 —— 注意要改名成 wav2lip.pth
cp ~/setup/wav2lip256.pth models/wav2lip.pth
# 官方示例形象
tar -xzf ~/setup/wav2lip256_avatar1.tar.gz -C data/avatars/
# 确认
ls -lh models/ && ls data/avatars/
wav2lip256.pth必须重命名成wav2lip.pth,代码里是写死的路径,名字不对会报FileNotFoundError。这两个文件原本要去 LiveTalking README 里的 Google Drive 下载,已经打包进部署包了。想自己下的话链接在他们仓库首页。
先用官方形象验证
source .venv-lt/bin/activate
python app.py --transport webrtc --model wav2lip \
--avatar_id wav2lip256_avatar1 \
--stun 'stun:stun.l.google.com:19302'
打开 http://localhost:8010/index.html ,点「开始连接」,等人物出画,在右侧文本框输入一句中文点发送。
人物动 + 有声音 + 嘴型跟着动,这一层就通了。
同时看终端日志里的 inferfps 和 finalfps,两个都要 ≥25 才算实时。
⚠️ 为什么用 wav2lip 而不是 MuseTalk
网上教程多推荐 MuseTalk,画质确实更好,但:
wav2lip256 MuseTalk 显存 ~1.3 GB ~12 GB 权重 官方网盘直接给 分散在多个仓库,目录结构讲究 我们的画面是暗光、侧脸、人物占右侧不到一半,256 分辨率的糊基本看不出来。省下的 10 GB 显存意味着大模型和语音识别都不用降级。
⚠️ STUN 不能传空
纯本地环境理论上不需要 STUN,但不能传
--stun ''——aiortc 拿到空 URI 会直接抛malformed uri: invalid scheme,而前端只显示一句莫名其妙的 JSON 解析错误。传一个真实可达的地址就行,比如 Google 的。
第十一步:换成自己的数字人形象
LiveTalking 自带网页生成工具,打开 http://localhost:8010/avatar.html
| 字段 | 填什么 |
|---|---|
| 算法模型 | Wav2Lip |
| Avatar ID | wav2lip256_myavatar(保留 wav2lip256_ 前缀) |
| 视频文件 | 你的 idle.mp4 |
点「提交生成任务」,等右侧任务列表显示 COMPLETED(很快,几十秒)。
文件选择器里找 WSL 路径的话,地址栏输入:
\\wsl$\Ubuntu-24.04\home\你的用户名\setup
用新形象重启
Ctrl+C 停掉,改用你的 avatar ID:
cd ~/setup
AVATAR_ID=wav2lip256_myavatar ./start-livetalking.sh
觉得好用就直接改进脚本,省得每次输:
sed -i 's/wav2lip256_lingdu/wav2lip256_myavatar/' ~/setup/start-livetalking.sh
如果你的形象是手托腮的姿势,重点看说话时手和下巴交界处会不会出糊边——口型模型替换的是嘴部区域,手越过下颌线就可能出鬼影。手放低一点就没问题。
第十二步:连起来,正式启动
启动顺序(三个窗口,顺序不能反)
① Windows CMD —— 大模型
llama-server -m E:\llama.cpp\models\Qwen3-14B-Instruct-Q4_K_M.gguf ^
-np 1 -c 8192 -fa on --temp 1.0 --host 0.0.0.0 --port 8090
② Ubuntu 窗口 A —— 口型服务
cd ~/setup && ./start-livetalking.sh
③ Ubuntu 窗口 B —— 语音服务
cd ~/setup && ./start-voice.sh
浏览器打开 http://localhost:7860/ ,按 Ctrl+F5 强制刷新。
点一下页面(连接数字人),再点中间的球开始对话。
人设配置
右上角 Settings → INSTRUCTIONS:
你叫小雅,是他的女朋友。你不是AI、不是助手、不是程序。
参考这个语气:
他:你想我了吗
你:想啊,怎么不想。你倒是一整天没消息,我还以为你把我忘了呢。
他:你喜欢我吗
你:这还用问?你要是不知道,那我可要生气了。
说话方式:口语、两三句、带语气词(嗯、诶、呀)、有情绪。
不用 Markdown、列表、编号、表情符号。
/no_think
这三条是功能性的,不能删:
- 每次两三句 —— 语音场景说太长听着累,合成时间也线性增加
- 不用 Markdown / 列表 / 表情符号 —— 这些会被语音合成逐字念出来,
*念成"星号",emoji 念成一长串描述,非常出戏 - 口语化 —— 书面语读出来很生硬
两个让人设更稳的技巧
给示例对话是最有效的,比十条规则都管用。单纯描述人设的话,模型很容易滑回"有什么可以帮您"的客服腔。
/no_think关掉 Qwen3 的思考模式。它会让模型"斟酌",而斟酌的结果往往是回避。
停止
./start-voice.sh stop
./start-livetalking.sh stop
Windows 那个 CMD 窗口直接关掉。
一键启动脚本
每次开三个窗口有点烦,桌面建个 启动.bat:
@echo off
start "llama-server" cmd /k "cd /d E:\llama.cpp && llama-server -m E:\llama.cpp\models\Qwen3-14B-Instruct-Q4_K_M.gguf -np 1 -c 8192 -fa on --temp 1.0 --host 0.0.0.0 --port 8090"
timeout /t 25
start "livetalking" wsl -d Ubuntu-24.04 -- bash -lc "cd ~/setup && ./start-livetalking.sh"
timeout /t 30
wsl -d Ubuntu-24.04 -- bash -lc "cd ~/setup && ./start-voice.sh"
timeout /t 10
start http://localhost:7860/
双击就全起来了。
调优:打断和抢答
刚跑起来时她多半会抢答——你还没说完就插话。这不是 bug,是语音活动检测的参数问题。
改 ~/setup/start-voice.sh 顶部:
| 参数 | 默认 | 作用 |
|---|---|---|
MIN_SILENCE_MS |
1200 | 停顿多久算你说完 ← 抢答就调大这个 |
VAD_THRESH |
0.6 | 人声判定门槛。环境吵调 0.7 |
MIN_SPEECH_MS |
500 | 最短有效语音。调太大短句会被整段丢弃 |
SPEECH_PAD_MS |
300 | 语音前保留的音频,太小会吃掉句首 |
MIN_SILENCE_MS 是主力开关。原始默认值是 64 毫秒——中文说话时的换气和思考停顿轻松超过它,所以不调的话抢答会非常严重。
代价是线性的:调多少,她的响应就慢多少。1200 是试下来的平衡点,觉得迟钝就降到 900。
诊断方法,另开窗口看日志:
tail -f ~/s2s/logs/s2s.log | grep -E "soft-ended|discard"
Speech soft-ended (segment=2420ms, active=1184ms)
segment - active 就是固定开销。如果这个差值不随你调参变化,说明参数没生效(多半是没重启)。
排错速查
| 现象 | 处理 |
|---|---|
bad interpreter: ^M |
dos2unix *.sh |
| WebRTC 一直连不上 | .wslconfig 加 hostAddressLoopback=true,然后 wsl --shutdown |
Unexpected non-whitespace character after JSON |
服务端 500 了,去看服务端终端的报错 |
malformed uri: invalid scheme |
--stun 不能传空字符串 |
| 说话完全没反应 | 前端 NOISE GATE 拖到最左 |
| 抢答严重 | MIN_SILENCE_MS 调到 1200 |
| 回复文不对题 | 见上一条,同时确认没开实时转写 |
| 音色每次都变 | 语音合成模型要用 -Base 版本,不是 -CustomVoice |
| 声音像变声器 | 改 avatar-sync.js 里的 sampleRate(我这里是 16000) |
| 端口绑不上但 netstat 看不到占用 | Hyper-V 保留端口,换个端口 |
| GPU 100% 但没进度 | 显存溢出到内存了。NVIDIA 控制面板 → 管理 3D 设置 → 关掉"CUDA 系统内存回退策略" |
| 麦克风没反应 | 必须走 localhost 或 HTTPS,用内网 IP 拿不到麦克风权限 |
| 休眠唤醒后连不上 | wsl --shutdown 重启一次 |
| 端口被占用起不来 | ./start-voice.sh stop 再启动 |
显存不够怎么办
按性价比顺序砍:
| 改动 | 省 |
|---|---|
| 大模型换 Qwen3-8B | ~3 GB |
| 大模型换 Qwen3-4B | ~6 GB |
STT_MODEL=medium(改 start-voice.sh) |
~1.5 GB |
-c 4096(缩短上下文) |
~1 GB |
语音对话场景对模型能力要求不高——回复本来就控制在两三句,8B 和 14B 的差别听感上很难分辨,但延迟收益很明显。
一些说明
延迟:首响大概 1–2 秒。识别 300ms + 大模型首字 300ms + 合成 300ms + 口型 150ms,再加上要等整段音频合成完才能推给口型模块。
局域网 / 手机访问:浏览器要求麦克风必须在安全上下文下使用,直接用内网 IP 拿不到权限。最省事是 Cloudflare Tunnel:
cloudflared tunnel --url http://localhost:7860

浙公网安备 33010602011771号