给编码 Agent 装一张嘴:DSH 语音 AI 女友完整搭建教程
开源项目:beiyege-01/dsh-voice-ai-girlfriend 技术栈:React 插件 / AudioWorklet / FastAPI / F 2026-11-2 04:48:0 Author: blog.upx8.com(查看原文) 阅读量:10 收藏

给编码 Agent 装一张嘴:DSH 语音 AI 女友完整搭建教程

开源项目:beiyege-01/dsh-voice-ai-girlfriend

技术栈:React 插件 / AudioWorklet / FastAPI / FunASR / OmniVoice / silero-VAD / DUIX / NapCat

目标平台:Windows 11 + NVIDIA GPU(16GB 显存推荐)+ WSL2

读完这篇你能做到:从一台干净电脑开始,装出一个能听、能说、能被打断、还能对口型说话的 AI 助手


先说清楚:这是什么(这篇文章是给纯小白人看的,ai老鸟绕过)

你在电脑上用 AI 写代码,通常是打字提问、看字回答。这个项目给那个对话框加了两样东西:

一双耳朵——点一下麦克风,你说话,它听。停顿一下自动断句,不用按键发送。

一张嘴——它的回答会被念出来。不是机器合成的塑料音,而是克隆自你提供的 10 秒录音,可以是任何人的声音。

再加三个不那么常见的东西:

  • 你插嘴它会闭嘴。它正说着,你开口,它立刻停,听你说完。想让它把话说完,点一下开关切回"排队"模式。
  • 回答会变成视频。旁边有个小窗口,姑娘闲着会发呆、说话时会开口,口型对得上(这叫数字人,可选)。
  • 出门也能聊。回复自动推到你手机 QQ,文本 + 语音都有(可选)。

能力清单

能力 实测表现
语音识别 5 秒音频 151ms,14 秒音频 155ms
开口延迟 说完停顿 1.8 秒后,约 0.5 秒内开口(不含大模型思考时间)
音色克隆 首轮 1.6 秒出音,之后每句约 1.3 秒
抗噪 -35dB 噪声门,能挡住桌面风扇
打断 说话即打断,服务端同时停止合成(不空烧显卡)
数字人 7.3 秒音频 14 秒出片,长回复切段连续播放
显存占用 全链路峰值约 15GB

先判断:这台机器能装吗

能装的:NVIDIA 独立显卡、显存 16GB 以上、Windows 11、硬盘剩 40GB。

装不了的:AMD/Intel 核显、Mac、没有独立显卡的轻薄本。所有模型推理都依赖 CUDA,这个绕不过去。

会很痛苦的:8GB 显存。能跑,但语音和数字人不能同时开,得来回切。

如果你只是想看看这东西长什么样,不用装——项目 README 里有抖音演示链接。装它是为了自己用,不是为了围观。


第一部分:它怎么跑起来的(5 分钟看懂)

看一张图就够了:

┌────────────────────────────────────────────┐
│  浏览器(就是那个聊天界面)                  │
│                                            │
│   [对话面板]          [女友窗]              │
│   麦克风 ──▶ 文字 ──▶ 回答 ──▶ 声音 ──▶ 播放  │
│                                    ▲        │
└────────────────────────────────────┼────────┘
                                     │
┌────────────────────────────────────┴────────┐
│  语音桥接服务(本地 8765 端口)              │
│  负责:听写、合成语音、生成视频、收发 QQ      │
└──────┬──────────────┬───────────────────────┘
       │              │
┌──────▼──────┐  ┌────▼──────────────────┐
│ TTS 引擎     │  │ 数字人引擎             │
│ 9877 端口    │  │ 9000 端口              │
│ (跑在 WSL) │  │ (跑在 Docker)        │
└─────────────┘  └───────────────────────┘

三层,各管一件事:

第一层,浏览器里的插件。 它只是一堆界面代码——麦克风按钮、开关、那个小窗口。它自己不会说话,所有声音都要找第二层要。

第二层,语音桥接服务。 一个跑在本地的 Python 程序,监听 8765 端口。它像一个转接台:收到浏览器发来的录音,转给识别模型;收到文字,转给合成模型。所有 API 都从这里出入。

第三层,真正的模型。 识别、合成、生成视频这些重活,各自由专门的程序干。它们吃显存,所以单独拆出来,出问题好换、好重启。

为什么非要拆成三层

因为这三层坏一个,不影响其他两个。识别坏了你还能打字提问听语音;合成坏了你还能说话看文字。如果全塞在一个程序里,一个模型加载失败,整个系统就死了。

而且换引擎不用改界面。识别模型从 whisper 换成 FunASR,只改一行配置,浏览器那边完全不知道。

两个反直觉的设计

声音合成不在 Windows 上跑。 中间那个 9877 端口,实际跑在 Windows 里的 Linux 子系统(WSL2)中。听起来很折腾,但收益巨大:

  Windows 原生(Qwen3-TTS) WSL 里跑(OmniVoice)
首轮出音 18.3 秒 1.6 秒
平时出音 2.2 秒 1.3 秒
占显存 7GB 常驻 5.3GB

差了 11 倍的启动速度,值得折腾一次。

插件装了也可能没声音。 插件只有界面,语音能力全在第二、三层。这就是为什么必须先装主仓库的桥接,再装插件——很多人反过来做,装完发现"按钮能点但没反应",就是这个原因。


第二部分:装之前先对照

硬件

项目 要求 怎么查
系统 Win10/11 64 位 winver
显卡 NVIDIA,显存 ≥16GB nvidia-smi
硬盘 剩余 ≥40GB 资源管理器
内存 ≥16GB 任务管理器

nvidia-smi 报"不是内部或外部命令",说明没有 N 卡或驱动没装。

显存怎么被吃掉的:

组件 占用
语音合成 5.3GB 空闲 ~ 11GB 峰值
语音识别 ~1GB
数字人 4~6GB
同时工作 ~15GB

软件(五个,缺一不可)

git --version
python --version        # 3.10 以上
node --version          # LTS 版
npm install -g pnpm
pnpm --version

下载地址:

  • Git:https://git-scm.com/download/win
  • Python:https://www.python.org/downloads/windows/ ← 安装时务必勾 "Add Python to PATH"
  • Node.js:https://nodejs.org/
  • 显卡驱动:https://www.nvidia.cn/drivers/

不需要单独装 CUDA Toolkit,装依赖时会自带。

装完 Python 一定要开个新终端再验证,否则 PATH 没生效,会误判成没装。

要花多久

阶段 内容 时间
一 环境体检 5 分钟
二 代码 + Python 环境 20 分钟
三 识别模型 15 分钟
四 语音合成引擎 30~90 分钟
五 声音素材 + 配置 10 分钟
六 服务验收 10 分钟
七 装插件 + 首次对话 25 分钟
八 数字人(可选) 40 分钟
九 QQ(可选) 20 分钟

最小可用只要一到七,走完就能语音对话。

端口表(排障全靠它)

端口 谁在用
8765 语音桥接服务(核心)
9877 语音合成引擎
3092 聊天界面(DSH 0.2.1)
9000 数字人引擎
3000 QQ 机器人接口
6099 QQ 机器人管理页

六个端口,装完记不住没关系,出问题时回来看这张表。


第三部分:动手装

第一步:环境体检

跑一遍第二部分的检查命令,五个都有版本号、nvidia-smi 能看到显卡,就往下走。


第二步:拿代码和 Python 环境

cd D:\
git clone https://github.com/beiyege-01/dsh-voice-ai-girlfriend.git
cd dsh-voice-ai-girlfriend

后面所有命令都在这个文件夹里执行。

建虚拟环境(相当于给这个项目单独开一个干净的 Python 房间,不影响系统里其他 Python 程序):

python -m venv venv-speech
venv-speech\Scripts\activate

激活成功时,终端行首会出现 (venv-speech)。

文件夹名必须是 venv-speech。 后面的一键启动脚本里写死了这个路径,改成别的名字脚本就找不到 Python 了。

装依赖:

pip install -r bridge\requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

会下载 PyTorch 一整套,5~8GB,几分钟到半小时。国内不走清华镜像基本装不完。

你会看到:最后一行出现 Successfully installed ... 一长串包名。

怎么验证装对了:

venv-speech\Scripts\python.exe -c "import torch; print(torch.__version__, torch.cuda.is_available())"

输出末尾必须是 True。如果是 False,说明装成了 CPU 版或者显卡驱动太旧,这时候不要往下走——后面所有模型都会跑在 CPU 上,慢到不可用。


第三步:下载识别模型

语音识别用阿里 FunASR 的中文模型,约 850MB。它识别中文比 whisper 准得多:

模型 同音字错误(测三句古诗) 准确率
whisper-turbo 尽→静、目→木、楼→牛、庵→安、钱→前 86%
FunASR 五处全部纠正,只剩 2 处音近错 93%

下载:

pip install modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple

# 先下到缓存
python -c "from modelscope import snapshot_download; snapshot_download('iic/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch')"

# 再拷进项目的 models 目录
mkdir models\funasr
xcopy /E /I "%USERPROFILE%\.cache\modelscope\models\iic--speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch\snapshots\master" "models\funasr\speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch"

还要一个小的:silero VAD(2MB,用来判断"你什么时候在说话",打断功能靠它)。从 silero-vad v4.0 拿 files/silero_vad.jit,放到:

models/silero-vad/silero_vad_v4.jit

一定要 v4 版本。 v5 带了额外组件,在新版 PyTorch 下会随机报错(这个项目实测过:同一个文件下午正常、晚上报错),排查起来很折磨。

你会看到:models/ 下出现两个文件夹。

models/
├── funasr/
│   └── speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch/
└── silero-vad/
    └── silero_vad_v4.jit          ← 约 1.4MB

第四步:语音合成引擎(二选一)

这是全程唯一有难度的环节。 两条路,先看区别再选:

  路线 A:OmniVoice 路线 B:Qwen3-TTS
首轮出音 1.6 秒 18.3 秒
平时出音 1.3 秒 2.2 秒
占显存 5.3GB 7GB
音色 克隆 + 参数设计 只能克隆
难度 高(要配 WSL + CUDA) 低(一条命令)

建议先走 B。 20 分钟跑通,验证整条链路能出声,再升级到 A。这样卡住时你清楚问题在哪一层。直接上 A 卡住的话,你分不清是界面问题、桥接问题还是模型问题。


路线 B:Qwen3-TTS(先跑这个)

pip install modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple
modelscope download --model Qwen/Qwen3-TTS-12Hz-1.7B-Base --local_dir D:\models\Qwen3-TTS-12Hz-1.7B-Base

必须是 -Base 版本。 名字带 VoiceDesign 的那个不支持参考音频克隆,装了也克隆不出你的声音。

记下 D:\models\Qwen3-TTS-12Hz-1.7B-Base 这个路径,第五步要填进配置。


路线 A:OmniVoice(进阶)

先在 Windows 里装 Linux 子系统:

wsl --install -d Ubuntu-22.04

装完重启,设好 Linux 用户名密码。验证 WSL 里能看见显卡:

wsl -d Ubuntu-22.04 -- nvidia-smi

然后进 WSL 里干活:

wsl -d Ubuntu-22.04
mkdir -p ~/omnivoice-wsl && cd ~/omnivoice-wsl

# 装 uv(比 pip 快很多)
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.local/bin/env

uv venv --python 3.12
source .venv/bin/activate

# PyTorch,必须是 CUDA 13 系列
uv pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu130

# FlashInfer 加速(这是 11 倍提速的来源)
uv pip install flashinfer-python flashinfer-jit-cache --extra-index-url https://flashinfer.ai/whl/cu130

# nvcc,版本检测要用
uv pip install nvidia-cuda-nvcc-cu13

# 引擎本体
uv pip install omnivoice

这一段的源地址和包名会随版本变化。 如果某一行报 404 或找不到包,去 flashinfer 官方安装页 抄当前的 cu13 地址,不要硬扛。

这一步失败很正常,也不影响你能用。 退回路线 B 就行,只是首轮慢 10 倍、音色不能参数设计,日常对话完全够用。

把服务脚本拷到 WSL 家里(仓库已经自带了,不用手写):

cp -f /mnt/d/dsh-voice-ai-girlfriend/bridge/omnivoice/demo_flashinfer.py \
      /mnt/d/dsh-voice-ai-girlfriend/bridge/omnivoice/start_server.sh \
      ~/omnivoice-wsl/
chmod +x ~/omnivoice-wsl/start_server.sh

路径按你项目实际位置改。或者直接从 Windows 跑 bridge\start-omnivoice-wsl.ps1,它会自动部署。

启动(Windows 侧一键,会检测、部署、启动、等就绪、同步配置):

powershell -ExecutionPolicy Bypass -File bridge\start-omnivoice-wsl.ps1

你会看到:

curl.exe -s -o NUL -w "%{http_code}" http://127.0.0.1:9877/

返回 200 就活了。日志在 WSL 的 ~/omnivoice-wsl/server.log。

有个隐蔽的坑:WSL 系统里如果自带 nvcc 12.8,会干扰 FlashInfer 的版本检测,服务直接起不来。start_server.sh 里已经帮你设了 CUDA_HOME 指向 CUDA 13 的 nvcc,别去动它。


第五步:准备声音 + 填配置

5.1 录一段 10 秒的声音

AI 的声音是克隆来的,你给什么它像什么。

要求 说明
时长 10 秒左右(5~20 秒都行)
内容 干净人声,不能有背景音乐、不能有杂音
说什么 用你自己的话自然读一句,不要跨句截取
文件 命名 ref_audio.wav,放项目根目录(和 bridge/ 文件夹同级)

跨句截取会让合成结果混进参考内容——不是理论风险,实测踩过。

5.2 建音色库

voices/
└── 小雅/                    ← 文件夹名就是音色名
    ├── ref_audio.wav        ← 你刚录的那段
    └── ref_text.txt         ← 这段录音逐字对应的文字(UTF-8 编码)

ref_text.txt 必须和录音逐字一致,标点也要对。文本对不上,音色就飘。

想换声音就多建几个文件夹,界面上有个 🎙️ 按钮可以随时切。

5.3 复制配置文件

copy bridge\bridge-config.example.json bridge\bridge-config.json

用记事本打开 bridge\bridge-config.json,改四处。

① 跨域白名单 —— 最容易漏,漏了必失败

"cors_origins": [
  "http://127.0.0.1:3092",
  "http://localhost:3092",
  "http://127.0.0.1:3080",
  "http://localhost:3080"
]

模板里只有 3080,但新版聊天界面跑的是 3092。不改这里,浏览器会拦住请求,表现是:语音按钮能点、没声音、控制台一堆红字。这个坑排查起来极其浪费时间,因为报错不会指向真正原因。

② 合成引擎地址

路线 A:

"omnivoice": { "base": "http://172.x.x.x:9877" }

填 WSL 的内网 IP(wsl hostname -I 查),或者让启动脚本自动同步。

路线 B:

"tts": {
  "model_name": "D:/models/Qwen3-TTS-12Hz-1.7B-Base",
  "ref_text": "你录的那句话"
}

③ 默认音色

"persona": { "default_voice": "小雅" }

填 voices/ 下的文件夹名。

④ 数字人端口(第八步才用)

"digital_human": { "duix_base": "http://127.0.0.1:9000" }

是 9000,不是 8383。 网上不少教程照抄镜像里写的 8383,会启动失败——Windows 保留端口段 8347-8446 正好包含 8383,映射不上去。项目里已经改成 9000。

其他配置不用动,都是相对路径自动解析。


第六步:先验证服务(别跳)

先把"声音服务"单独跑通,再去装插件。 这一步省掉,后面出问题你分不清是插件坏了还是服务坏了。

bridge\start-bridge.cmd

会弹一个小终端窗口,不要关它。

浏览器打开:

http://127.0.0.1:8765/api/health

你会看到:

{"status":"ok","stt":false,"tts":false,"stt_error":null,"tts_error":null}

false 是正常的,不是失败。 模型是"用的时候才加载",第一次调用才会载入。很多人看到两个 false 以为装坏了,其实一切正常——这两个值变成 true,只说明你之前调用过。

测听写

另开一个终端,在项目根目录、虚拟环境激活状态下:

venv-speech\Scripts\python.exe bridge\smoke_stt.py

对着麦克风说一句话。第一次要等 10~30 秒加载模型,之后每次 150 毫秒级。

测出声

venv-speech\Scripts\python.exe bridge\smoke_tts.py --text "你好,我是小雅。"

跑完项目根目录会生成 tts_out.wav,播放它。

听到克隆自你录音的声音,就成功了。 声音不像 → 回去检查 ref_text.txt 是否和录音逐字一致。

卡在这里怎么办

现象 原因 怎么办
8765 连不上 服务没起 看那个小终端窗口的报错
tts_error 有内容 模型路径错 / 驱动旧 检查路径的盘符和斜杠(正斜杠或双反斜杠都行);nvidia-smi 看驱动
合成引擎连不上 WSL 服务没起 / IP 变了 curl http://127.0.0.1:9877/
第一次合成等很久 正常 模型加载 + 预热,之后每句 0.5 秒
识别偶尔是空的 FunASR 对超短语音或纯噪声返回空 正常防护,不是 bug
显存不足 / OOM 同时开了太多东西 关掉数字人,先只跑语音

验收标准:health 里 stt 和 tts 都变成 true,而且你确实听到了声音。


第七步:装聊天界面和插件

7.1 准备聊天界面

这个项目是 DSH(DeepSeek Harness,一个开源 AI 编码工具)的扩展,所以要先有一份 DSH:

git clone https://github.com/deepseek-ai/deepseek-harness.git D:\DSH\deepseek-harness-v021
cd D:\DSH\deepseek-harness-v021
pnpm install

记住这个路径,等一下和以后每天启动都要用。

7.2 装插件

dsh plugin --profile web-v021 add github:beiyege-01/dsh-voice-ai-girlfriend-plugin

三个容易踩的地方:

坑 说明
--profile 的位置 新版必须写在 add 前面,写后面会报参数错
profile 名字 0.2.x 用 web-v021;0.1.3 用 web-v013;更旧的用 web
pnpm 版本太新 会限制构建脚本,按它打印的提示在 pnpm-workspace.yaml 里允许 esbuild,然后重跑

7.3 启动

cd D:\DSH\deepseek-harness-v021
pnpm dsh --profile web-v021 --port 3092

浏览器打开它打印出来的带 token 的链接。

7.4 首次对话验收

按顺序做四件事,哪一步不过就停在那查:

① 看控制台

按 F12 打开控制台,应该只有一行:

[ui-voice] loaded, bridge = http://127.0.0.1:8765

出现 CORS 相关的红字 → 回第五步改跨域白名单。

② 看工具行

输入框附近应该有这些控件:麦克风、⚡(插话)、👧(女友窗)、🎭(数字人)、🔊(朗读)、🎙️(音色)、🖼️(待机)、👤(形象)、QQ。

③ 打字试朗读

随便发一句"你好",等她回答完,应该听到语音。

听不到的话,先看 /api/health:

  • tts:true 但没声音 → 浏览器这边的问题(开多了标签页 / 音量 / 没点过页面——浏览器规定用户没交互过不许自动播音频)
  • tts:false → 客户端根本没发请求,看控制台报错

④ 点麦克风说话

点一下(变红脉冲)→ 说一句话 → 停顿 1.8 秒 → 自动识别上屏 → 她语音回答。

走到这里,最小可用版本就完成了。


第四部分:日常怎么用

界面上的按钮看着多,常用的就四个。

按钮 作用 什么场景用
麦克风 点一下开始连续听,再点停止 主要交互方式
⚡ 亮=插话,灭=排队 见下面解释
🔊 开/关朗读 在办公室不想被听见
🎭 开/关数字人 想要口型视频 / 只想快点听

插话和排队的区别

这是最容易搞混的一个设计,但它很关键。

插话(⚡ 亮):她正在回答,你开口说第二句,她会立刻停下当前回答来听你说。适合"我改主意了"、"不对,换个方向"。

排队(⚡ 灭):她正在回答,你说话,这句话会排队等她说完再处理。适合"我想到个补充"。

两种模式下,"你说话她立刻闭嘴"这个行为都保留——开关只管你说的话怎么投递,不管打断。

为什么要点麦克风才能打断

自动打断只在麦克风处于聆听状态时生效。如果你没开麦克风,手动点一下麦克风也能打断。

这个设计是为了省资源:不聆听的时候不占麦克风,也不做语音检测。

只开一个标签页

这是必须遵守的。

浏览器每个标签页都会独立加载一份插件、各自有一个播放器。开三个标签页,她一句话会被念三遍。

日志里能看到十几个 WebSocket 连接,那就是铁证。关掉多余的标签页就好了。


第五部分:装不上怎么办

排障三问(90% 的问题三分钟定位)

出问题别急着翻文档,按这个顺序问自己:

1. 桥接收到请求了吗? 看那个 8765 的小终端窗口。没收到 → 问题在浏览器这边(插件、跨域、配置)。收到了 → 问题在服务端。

2. 模型加载了吗? 看 /api/health 的 stt / tts。一直是 false → 模型从没被调用过,说明请求根本没到。

3. 端口通吗?

Test-NetConnection 127.0.0.1 -Port 8765

TcpTestSucceeded : True 才算通。

故障对照表

装的时候

症状 原因 解决
torch.cuda.is_available() 是 False 装成 CPU 版 / 驱动旧 重装 cu 版 torch,更新显卡驱动
pip 装依赖超时 网络 加 -i https://pypi.tuna.tsinghua.edu.cn/simple
模型下载失败 HuggingFace 被墙 set HF_ENDPOINT=https://hf-mirror.com 后重试
一键脚本找不到 Python 虚拟环境改名了 目录必须叫 venv-speech
dsh plugin add 报参数错 --profile 位置错 写在 add 之前
pnpm 拒绝执行构建脚本 pnpm ≥10 的安全限制 在 pnpm-workspace.yaml 的 allowBuilds 里允许 esbuild

用的时候

症状 原因 解决
按钮能点但完全没声音 跨域白名单少了 3092 改 cors_origins
一句话被念好几遍 开了多个标签页 只留一个
她念完不回话 / 念到一半乱码 长了代码块/URL 被直接念 项目已内置文本清洗,若仍出现请提 issue
环境音被识别成"幽灵消息" 噪声门不够紧 项目默认 -35dB;风扇太近仍是物理限制
说着说着自己被打断 喇叭声音被麦克风录回去 项目已用 VAD 过滤,确认没有外放音箱贴太近
声音不像参考录音 文本和录音对不上 检查 ref_text.txt 逐字一致性
关掉朗读后显卡还在满载 — 已在服务端修掉,若仍出现说明版本旧
数字人一直"生成中" 形象视频不在 temp 目录 检查 D:\duix_avatar_data\face2face\temp\
数字人服务起不来 端口映射错 必须 9000:8383
QQ 收不到语音 给自己发语音 / 格式不对 QQ 不支持自发语音;必须 silk 格式,桥接已内置转换
QQ 消息进不来 WebSocket 配成了服务器 必须配"WebSocket 客户端",地址 ws://127.0.0.1:8765/api/qq/onebot

三个最坑的细节

如果只记三件事,记这三条:

1. /api/health 里 false 不代表失败。 模型懒加载,第一次用才载入。看到 false 就去修东西,是纯浪费时间。

2. 跨域白名单必须含 3092。 模板里只有 3080,新版界面跑 3092。症状是"按钮能点、没声音",报错不会告诉你原因。

3. 数字人端口是 9000。 镜像文档写 8383,但 Windows 保留段占了它,映射会上不去。项目已改成 9000。


第六部分:可选增强

数字人(口型视频)

让回答变成一段对口型的视频。不开也完全能用,开了会更好看但更慢。

开之前准备好数据目录(必须在 D 盘,配置写死了):

mkdir -p D:\duix_avatar_data\face2face\temp

放一个正脸说话的 mp4 进去,命名 my_avatar.mp4。

提速 30% 的关键一步(画面不糊,只是帧数降低):

ffmpeg -i my_avatar.mp4 -vf fps=15 -c:v libx264 -crf 20 -preset fast -an my_avatar_15fps.mp4

改名覆盖 my_avatar.mp4(原版先备份)。实测 7.3 秒音频从 20.1 秒降到 14.1 秒。

再关超分(又能快 10%)。在 D:\duix_avatar_data\face2face\config.ini 里:

[digital]
chaofen = 0
batch_size = 2

起容器:

docker compose -f bridge\docker-compose-5060ti.yml up -d

冷启动要 1~3 分钟,别急着以为失败了。检查:

curl.exe "http://127.0.0.1:9000/easy/query?code=probe"

有 JSON 返回(哪怕是"任务不存在")就说明服务在线。

然后点界面上的 🎭 按钮,发一条长一点的消息。女友窗底部会显示"数字人生成中 1/3…",一段生成完立刻播,声音和口型是同步的(音频已经混进视频里了)。

一键启动(强烈建议)

每次开机要手动起三个东西,容易漏。用脚本固化。

先改脚本里的路径。 打开 bridge\start-full-stack.ps1,找到第 54 行附近这一块:

$LatestHarness = 'E:\DSH\deepseek-harness-v021'    # ← 改成你的实际路径
$LatestProfile = 'web-v021'
$LatestPort    = 3092

这几行是作者自己电脑的路径,不改在你机器上一定失败。

然后每天启动就两步:

  1. 手动打开 Docker Desktop(只有用数字人才需要)
  2. 双击 bridge\start-full-stack.cmd

脚本会按正确顺序把六个东西拉起来,最后打印一张自检表:

步骤 做什么
1/6 检查 Docker 和数字人容器
2/6 起合成引擎 + 同步配置 + 起桥接
3/6 桥接保险(起不来就修)
4/6 起聊天界面 + 打开带 token 的链接
5/6 数字人状态
6/6 汇总自检表

常用参数:

bridge\start-full-stack.cmd -NoDsh         # 只起语音,不开界面
bridge\start-full-stack.cmd -NoBrowser     # 不开浏览器
bridge\start-full-stack.cmd -WithQQ        # 顺便拉起 QQ 机器人

已经跑着的不会重复启动(按端口探活判断),随时可以重跑。

QQ 双向对话

出门用手机 QQ 接着聊。

  1. 下载 NapCat.Shell.Windows.Node.zip,解压到 D:\QQ\NapCat
  2. 用 napcat\launcher-win10-user.bat 启动(会关掉所有正在运行的 QQ,用小号登录)
  3. 打开 http://127.0.0.1:6099,token 在 napcat\config\webui.json
  4. 网络配置里加两样:
    • HTTP 服务器:127.0.0.1:3000,记下 token
    • WebSocket 客户端:ws://127.0.0.1:8765/api/qq/onebot
  5. 配置里填 qq 段,重启桥接
"qq": {
  "enabled": true,
  "napcat_base": "http://127.0.0.1:3000",
  "napcat_token": "你设的 token",
  "target_qq": 你的主号QQ号
}

验证:

curl.exe -X POST http://127.0.0.1:8765/api/qq/send -H "Content-Type: application/json" -d "{\"text\":\"你好\",\"voice\":true}"

主号收到文本 + 语音就通了。

四个必踩的坑:

坑 原因
语音收不到 QQ 不支持给自己发语音;格式必须是 silk(桥接已内置转换)
消息进不来 WebSocket 配成了"服务器",会抢 8765 端口
重启后接口丢了 必须在管理页里启用保存,不要 kill 进程
每次都要填 token 改 webui.json 里的 token 为固定值

第七部分:给想改代码的人

前面都是"怎么用"。这一节给想改的人——四条设计思路和几个值得看的文件。

四条能复用的经验

1. 流式系统的关键不是"多快",是"什么时候开始"。

大模型输出、语音合成、播放、视频生成,四个环节速度差几十倍。把它们各自做成独立队列,语音合成完一句就播一句,不用等全文——用户感知到的就是快的那个。

2. 打断必须做三层,少一层都不彻底。

播放器停 → 客户端请求中止 → 服务端停止合成。只做前两层,会出现"听着停了,显卡还在满载"。第三层要用协作式取消:客户端断开连接后,服务端循环里定期检查标志位,发现没人听了就 break。

3. 状态判断用"精确 ID",不要用"区间"。

打断后要"吞掉本条回复的剩余部分"。写成"跳过所有序号小于等于当前的",在异步时序里一定会误伤——你以为是吞旧的,实际上新数据已经进来了。改成记具体那一条的 ID。

4. 阈值必须实测,不能拍脑袋。

-35dB 噪声门、1800ms 断句、48 字分段、384ms 打断确认——每个数字背后都是一次对比实验。特别是 dBFS 是负数,守卫条件写反了不会报错,只会静默失效。

值得看的文件

想了解什么 看哪个文件
录音、断句、打断检测 dsh-plugin/src/client/voice/recorder.ts
播放队列 dsh-plugin/src/client/voice/speaker.ts
切句逻辑 dsh-plugin/src/client/voice/sentences.ts
流式朗读编排(最核心) dsh-plugin/src/client/voice/reply-listener.tsx
女友窗 + 视频续播 dsh-plugin/src/client/voice/companion.tsx
音频采集(48k→16k 降采样) dsh-plugin/src/client/worklets/mic-capture.ts
所有服务端接口 bridge/voice_bridge.py

两个聪明的实现

降采样用三点平均,不用插值。

大多数 Windows 声卡是 48kHz,降到 16kHz 恰好是 3:1。直接三点取平均既快又能当抗混叠滤波器,省掉每个音频块 640 次浮点乘法。只有 44.1kHz 才走插值分支。

请求链和播放链分开。

请求(串行):第1句 ──▶ 第2句 ──▶ 第3句
                              │
播放(排队):第1句播完 ──▶ 第2句播完 ──▶ 第3句
                ↑ 第2句合成完先排队等

两条链速度不同,硬绑在一起就会互相拖累。分开之后,第 1 句在播的时候,第 3 句可能已经合成好了。

项目规模

约 7100 行有效代码:

部分 行数
TypeScript(界面) ~3100
Python(服务) ~2100
文档 ~1000
启动脚本 ~400

附录

A. 完整验收清单

打印出来逐项打勾:

环境
[ ] nvidia-smi 能看到显卡
[ ] git / python / node / pnpm 四个都有版本号
[ ] torch.cuda.is_available() == True

模型
[ ] models/funasr/ 下有模型文件
[ ] models/silero-vad/silero_vad_v4.jit 约 1.4MB
[ ] 合成引擎在线(9877 能访问,或 Qwen3 路径正确)

配置
[ ] ref_audio.wav 在项目根目录
[ ] voices/<音色名>/ 下有两个文件
[ ] cors_origins 里包含 3092
[ ] 虚拟环境目录叫 venv-speech

服务
[ ] /api/health 返回 status:ok
[ ] smoke_stt 能识别出文字
[ ] smoke_tts 能出声且音色正确
[ ] health 里 stt / tts 变成 true

界面
[ ] 控制台只有一行 [ui-voice] loaded
[ ] 工具行控件齐全
[ ] 打字能触发朗读
[ ] 点麦克风说话能上屏

固化
[ ] start-full-stack.ps1 里的 harness 路径已改成自己的
[ ] 自检表每一项都是 OK

B. 每天开机流程

1. 打开 Docker Desktop(只有用数字人才需要)
2. 双击 bridge\start-full-stack.cmd
3. 等自检表打印完
4. 浏览器打开(只开一个标签页)

C. 项目结构

dsh-voice-ai-girlfriend/
├── bridge/                    # 语音服务(Python,可独立跑)
│   ├── voice_bridge.py        # 所有接口都在这
│   ├── qq_bridge.py           # QQ 相关
│   └── omnivoice/             # WSL 里的合成服务
├── dsh-plugin/                # 浏览器插件源码
│   ├── src/client/voice/      # 录音、播放、切句、女友窗
│   └── build.mjs              # 打包脚本
├── assets/bg-images/          # 5 套内置待机动画
├── voices/                    # 音色库(自己建)
├── models/                    # 模型(自己下,不入库)
└── docs/                      # 开发日志

文章来源: https://blog.upx8.com/Agent-DSH-AI
如有侵权请联系:admin#unsafe.sh