# Gpt Sovits Local Voice Training

> Deploy and operate GPT-SoVITS for local voice cloning on Windows: ask for the install location before any download, inspect GPU/CPU/CUDA/7-Zip/FFmpeg, choose a compatible version, prepare accurately transcribed recordings, fine-tune GPT and SoVITS, troubleshoot WebUI/API/checkpoint failures, load custom weights, and verify a real local WAV. Trigger for GPT-SoVITS installation, voice-clone training, speaker fine-tuning, local TTS API setup, or failures during dataset preparation and model training.

- Skill: `sevenjustin21/gpt-sovits-local-voice-training` (Agent Skill, multi-file: 10 files)
- Install (CLI): `npx skillmds@latest add sevenjustin21/gpt-sovits-local-voice-training`
- Raw SKILL.md: https://api.skillmd.com/api/skills/sevenjustin21/gpt-sovits-local-voice-training/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: MIT
- Author: Sevenjustin21 (https://skillmd.com/u/sevenjustin21)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/sevenjustin21/gpt-sovits-local-voice-training

---


# GPT-SoVITS 本地声音工作流

把这份 Skill 当作一条可审计的 Windows 本地工作流。目标是让一个没有当前对话记忆的 agent，也能从零完成部署、准备本人声音素材、微调、试听和本地 API 交付；每一步都用本机代码、日志、文件和端口验证，不用经验替代证据。

## 0. 先确认边界

开始前确认：

1. 请求者拥有录音和声音的使用权，或已取得明确同意。只处理授权的声音，不把克隆用于冒充、欺诈、绕过身份验证或隐瞒合成身份。
2. 这是本地部署；API 默认只绑定 `127.0.0.1`。除非用户明确授权并完成认证、访问控制和风险评估，不公开端口、不建立隧道、不安装系统服务。
3. 原始录音永远先保留只读副本。训练实验使用独立的 `training/<experiment>` 目录，模型输出使用独立的版本目录，不覆盖官方预训练模型。
4. “训练命令返回”不等于“声音训练完成”。完成必须同时满足：数据标注匹配、训练进程成功退出、目标权重存在且大小合理、API 能加载自定义权重、实际生成 WAV 且通过格式和非静音检查。

## 1. 安装前必须询问和探测

### 1.1 在下载前询问安装位置

如果用户没有给出安装目录，先询问，不下载、不克隆、不解压。至少询问：

- GPT-SoVITS 项目放在哪个绝对路径、是否允许创建该目录；
- 模型和缓存是否也放在该盘，目标盘剩余空间是否足够；
- 是否已有项目或旧版本，是否需要保留；
- 用户要使用集成 Windows 包，还是源码/运行时目录。

把用户确认的路径保存为任务变量，例如 `$gptRoot`、`$voiceToolsRoot`、`$experimentRoot`；不要把 `$HOME`、`$PID` 或其他系统变量当作自定义变量。

### 1.2 下载前收集硬件和完整依赖证据

在网络操作前运行只读探测，并记录输出：

```powershell
Get-CimInstance Win32_OperatingSystem | Select-Object Caption,Version,OSArchitecture
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader
Get-Command 7z.exe,7zz.exe -ErrorAction SilentlyContinue | Select-Object Name,Source
Get-Command ffmpeg.exe,ffprobe.exe -ErrorAction SilentlyContinue | Select-Object Name,Source
```

若命令不在 `PATH`，再检查用户明确安装的路径、注册表卸载信息或项目配置；不能据此断言工具不存在。若用户说已有 7-Zip 或 FFmpeg，验证它的真实可执行文件和版本，并优先复用。不要额外安装 Docker、WSL、系统 CUDA 或第二套 Python，除非用户另行授权且兼容性证据要求这样做。

同时探测现有 Python/运行时、PyTorch、CUDA 和 GPU：

```powershell
& "$gptRoot\runtime\python.exe" --version
& "$gptRoot\runtime\python.exe" -c "import torch,sys; print(sys.version.split()[0]); print(torch.__version__); print(torch.cuda.is_available()); print(torch.version.cuda); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'no-cuda')"
```

将“官方 README 的测试环境”和“本机实际环境”分开记录。版本不一致时优先检查项目自带 runtime、`install.ps1`、`requirements.txt`、模型文件和实际启动日志，不要盲目升级。

在下载、安装或修改 PATH 前，先做完整依赖盘点。依赖不是一张对所有机器都相同的固定清单；先根据用户选择的“集成包/源码”“GPU/CPU”“是否自动 ASR”“是否做人声分离”确定分支，再逐项标记为“已满足、缺失、版本不兼容、无需或待确认”。至少检查：

| 类别 | 何时必需 | 核验对象 |
|---|---|---|
| Windows/架构/PowerShell | 所有 Windows 部署 | Windows 版本、64 位、PowerShell、权限、目标盘空间 |
| Python 运行时与 pip | 所有运行方式 | 集成包自带 `runtime\python.exe`，或项目要求的 Conda/venv、`pip` 版本 |
| Conda | 源码方式执行官方 `install.ps1` 时 | 当前 shell 可调用的 `conda`、目标环境和 `conda info`；集成包不因源码脚本而额外安装 Conda |
| Git | 仅源码克隆、更新或固定 commit | `git.exe` 版本；已有压缩包时不因为没有 Git 就安装 |
| 解压能力 | 安装包/模型为压缩包时 | 7-Zip/`7z.exe`/`7zz.exe`、Windows `tar` 或 `Expand-Archive` 至少一种 |
| FFmpeg 与 ffprobe | 音频转换、切分、格式和试听验证 | 两个真实可执行文件及版本；不能只检查 PATH 名称 |
| HTTP/诊断工具 | API 试听或下载诊断时 | `curl.exe`、PowerShell Web 请求能力；先复用 Windows 自带版本 |
| NVIDIA 驱动与 GPU | GPU 推理/训练时 | `nvidia-smi`、设备管理器证据、显存；不能把系统 CUDA Toolkit 当成 PyTorch CUDA runtime |
| PyTorch 系列 | 当前 GPT-SoVITS 分支运行时 | 项目 Python 中的 `torch`、`torchaudio`、`torchcodec`（若当前代码/依赖要求），CUDA 可用性 |
| Windows 原生运行库 | 某些 Python 原生包导入或启动报 DLL 错误时 | VC++ Redistributable 和实际 DLL/导入错误；没有证据时不预装 |
| 项目 Python 包 | 运行 WebUI、训练或 API 的分支 | 读取实际 `requirements.txt`、`extra-req.txt`，在项目 Python 中逐包导入并运行 `pip check` |
| 预训练模型与文本/内容模型 | 推理、特征提取、SoVITS/GPT 微调时 | 从当前代码配置和 README 得到的权重、BERT/CNHuBERT、G2PW 等实际文件 |
| ASR 模型与数据 | 选择自动转写时 | FunASR/Whisper 分支的包、模型缓存和语言模型；手工文字稿可不安装 ASR |
| NLTK/Open JTalk/UVR5 资源 | 仅对应文本前端、日语或人声分离分支 | 代码实际导入、模型目录和首次运行日志；未走该分支标记为可选 |
| 网络、证书、下载源 | 需要下载源码、包或模型时 | GitHub/Hugging Face 可达性、代理/证书、缓存和模型落盘路径 |

用项目自己的运行时检查包，而不是用系统 Python 代替：

```powershell
$pythonExe = Join-Path $gptRoot 'runtime\python.exe' # 源码/Conda 时改为已确认的解释器
& $pythonExe --version
& $pythonExe -m pip --version
& $pythonExe -m pip check
& $pythonExe -c "import importlib.util as u, torch; print('torch=', torch.__version__); print('cuda=', torch.cuda.is_available(), 'torch_cuda=', torch.version.cuda); print('torchaudio=', u.find_spec('torchaudio') is not None); print('torchcodec=', u.find_spec('torchcodec') is not None)"
```

然后读取实际项目的 `requirements.txt`、`extra-req.txt`、`install.ps1`、`pyproject.toml`/`setup.py`（存在才读），把每个声明包与导入结果对照；不要用“能打开 WebUI”替代依赖检查。对外部程序分别验证真实路径和版本：

```powershell
Get-Command git.exe,tar.exe,curl.exe,ffmpeg.exe,ffprobe.exe,7z.exe,7zz.exe -ErrorAction SilentlyContinue |
  Select-Object Name,Source,Version
```

`Get-Command` 找不到 7-Zip 或 FFmpeg 时，只能说“当前 PATH 未发现”。继续检查用户提供的路径、常见安装目录、卸载注册表和项目配置；找到后用绝对路径执行 `--version`。同理，`nvidia-smi` 失败只能说明该命令没有给出证据，不能直接断言没有 NVIDIA GPU 或驱动。

### 1.3 缺失依赖必须先询问，不得擅自安装

把缺失项按“运行必需、训练必需、ASR/文本前端条件必需、可选工具”分组，向用户逐项报告。每一项在安装前都询问：

1. 是否允许安装或下载；
2. 安装到哪个绝对路径（项目/runtime、Git、7-Zip、FFmpeg、缓存/模型、训练输出分别询问，不能用一个模糊的“默认位置”代替）；
3. 是否允许加入 PATH；
4. 选择哪个下载源/代理，是否允许联网；
5. 已有旧版本是否保留，是否只复用现有版本；
6. 是否允许创建目录、下载模型和占用目标盘空间。

可直接使用下面的询问格式：

```text
依赖门禁发现以下项目尚未得到满足：
- [类别/名称]：已观察证据……；影响……；当前可替代方案……

请确认：
1. 是否允许安装/下载这些缺失项？（不允许则停在诊断或改走可用替代方案）
2. 每项安装或保存到哪个绝对路径？项目运行时、外部工具、模型/缓存、训练输出分开填写。
3. 是否允许修改 PATH？如果不允许，我会在启动脚本中使用绝对路径。
4. 使用哪个下载源，是否允许联网？
5. 是否保留已有版本，不覆盖现有安装？
```

用户确认前只做只读探测和报告，不下载、不安装、不改 PATH、不替换已有版本。用户确认后也要一类一类安装，记录安装器、版本、绝对路径、退出码和验证命令；失败时保留日志并回到门禁，不自动升级整个环境。VC++ Redistributable 通常由系统安装器写入系统组件位置，未必支持自定义运行库目录；遇到这一项时要明确询问“是否允许系统级安装”，另问“安装器下载/保留在哪个绝对路径”，不能虚构一个可选的运行库目录。

若用户已经有某个依赖但不在 PATH，优先让用户提供或确认它的绝对路径；若项目可用绝对路径运行，就不要为了 PATH 再安装一份。若选择源码方式而没有 Git，可在用户同意后选择官方压缩包作为替代，不把 Git 强行列为所有安装的必需项。

### 1.4 选择安装来源和版本

先读取 [官方 README 与教程综合参考](references/official-readme-and-guide-synthesis.md)，再读取官方 README、安装脚本和本机包结构，确认当前版本支持的 Windows 方式、预训练模型、Python/PyTorch/CUDA 组合及 FFmpeg 要求。官方说明、当前本机代码和运行结果冲突时：

- 官方文档说明“应该怎样”；
- 本机代码和 `--help` 说明“这份安装实际接受什么”；
- 运行日志说明“这台机器实际做到什么”。

未解决的版本冲突标记为未知，先做最小探测，不要用最新版本覆盖可用环境。

## 2. 部署与启动语义

### 2.1 最小部署顺序

1. 创建用户确认的项目目录和独立工具目录。
2. 下载或解压到明确的临时目录；核对顶层是否包含 `GPT_SoVITS`、`runtime`、`webui.py`、`api_v2.py` 等实际文件。
3. 对官方 `.7z` 集成包优先复用已验证的 7-Zip；解压后检查是否多了一层嵌套目录和文件数量。官方教程特别提醒某些通用解压器可能漏文件，不要用它们替代已验证的 7-Zip。
4. 验证预训练模型、BERT/CNHuBERT、G2PW（中文需要时）、ASR 模型（需要自动标注时）和 FFmpeg/ffprobe 的实际路径；训练/数据路径优先使用无空格、无中文的 ASCII 路径，若当前脚本支持中文路径也以实际代码为准。
5. 用项目自带 Python 启动一次 WebUI，保存 stdout/stderr、版本、端口和退出码。

不要因为某个集成包的 `go-webui.bat` 与当前目录不同，就凭经验改名或补文件。先读启动脚本；若脚本失败，保留窗口输出或从 PowerShell 运行以获取真实错误。

### 2.2 WebUI 与 API 是两个进程

按照本机启动脚本验证端口，不先假设端口号。常见本地包装中：

- WebUI 在 `127.0.0.1:9874`，用于切分、ASR、特征提取、训练和手工推理；
- `api_v2.py` 在 `127.0.0.1:9880`，用于 HTTP TTS。
- 集成包常见推理 WebUI 为 `9872`、UVR5 WebUI 为 `9873`；这些只是包装脚本的常见值，必须从本机脚本和 listener 重新确认。

WebUI 不需要 API 才能打开；API 也不是训练的前置条件。API 只在需要程序化生成或验证 HTTP 集成时启动。检查端口和接口：

```powershell
Get-NetTCPConnection -LocalAddress 127.0.0.1 -State Listen
Invoke-WebRequest http://127.0.0.1:9874/ -UseBasicParsing -TimeoutSec 5
Invoke-WebRequest http://127.0.0.1:9880/openapi.json -UseBasicParsing -TimeoutSec 5
```

关闭时关闭对应的前台窗口或使用项目自己的退出接口；不要误杀整台机器的所有 Python 进程。

### 2.3 部署完成后主动交付素材说明

安装成功后，不要等用户问“接下来给什么”。主动告诉用户：

- 需要本人、单人、清晰、无背景音乐和强混响的录音；
- 需要与录音逐字对应的文字稿，ASR 只能作为草稿，用户校对后的文字才是标注真值；
- 录音格式优先 WAV、单声道、16-bit PCM，项目会统一到 32 kHz；M4A/AAC 可以先保留原件再用 FFmpeg 转换；
- 先做流程验证可用约 1–3 分钟；想要更稳定的第一版，建议准备约 10–20 分钟干净语音、覆盖不同音素和正常语速；更高覆盖度可以准备 20–60 分钟。以上是操作建议，不是官方硬性最低值；质量取决于录音、文字准确度、切片和训练设置；
- 单段通常以约 2–12 秒为目标，过长或含多句的段落应切分；
- 说话人、语言、录音环境和文本必须记录；不要混入其他人、音乐、回声、剪辑爆音或错误文字。

## 3. 数据准备：先保留原件，再生成训练副本

推荐实验布局：

```text
<voice-tools-root>\training\<experiment>\
  original\              # 原始 M4A/WAV，只读保留
  raw\                   # 统一采样率后的 WAV
  slices\                # 自动切分片段
  labels\                # 原文、ASR 草稿、人工修正版
  reports\               # 数量、时长、字符匹配、错误报告
  requests\              # 可选的 API JSON 请求，不放密钥
```

使用绝对路径和显式 UTF-8。先检查音频，再转换；不要直接覆盖原始 M4A：

```powershell
& "$ffmpegExe" -i "$inputAudio" -ar 32000 -ac 1 -sample_fmt s16 "$rawWav"
& "$ffprobeExe" -v error -show_entries format=duration:stream=sample_rate,channels -of default=noprint_wrappers=1 "$rawWav"
```

### 3.1 切分、ASR 和校对

优先使用当前 WebUI 的“切分音频→ASR→校对”流程；CLI 入口以本机代码为准。官方当前 README 的常见入口是 `audio_slicer.py`、`tools/asr/funasr_asr.py -i <input> -o <output> -l <language>` 和 `tools/asr/fasterwhisper_asr.py -i <input> -o <output> -l <language> -p <precision>`；旧版本参数可能不同，先读 `-h`/WebUI 实际命令。每一步都保存输入、输出和退出码。

ASR 校对规则：

1. 逐段试听，不只看 ASR 文本；
2. 用用户提供的实际发音改写文字稿；例如原文写“窠巢”，但录音实际读成“巢穴”，训练标注应写“巢穴”；
3. 保留语义必要的中文标点，但不要添加录音中没有的词；
4. 对每一行执行“音频文件存在、文本非空、说话人和语言合法、音频顺序可追踪”的检查；
5. 去除标点后比较标注与用户确认全文，报告字符数和第一个不匹配位置；不匹配时先修正，不进入训练。

### 3.2 `.list` 与特征文件的契约

官方 TTS 标注格式是：

```text
audio_path|speaker_name|language|text
```

语言值按本机版本支持情况使用 `zh`、`ja`、`en`、`ko`、`yue` 等。中文训练使用对应的文本前端和 BERT/CNHuBERT。完成数据预处理后，按语言和当前分支检查本机实验目录是否出现并且数量一致：

```text
2-name2text.txt
3-bert/
4-cnhubert/
5-wav32k/
6-name2semantic.tsv
7-sv_cn/
```

`6-name2semantic.tsv` 的表头必须是一个真实的 Tab 分隔：`item_name<TAB>semantic_audio`；不要把两个字符 `\t` 当作表头。中文分支才强制核对 BERT 目录；英语、日语、粤语或韩语分支出现空的 `3-bert` 可能是官方教程所述的正常情况。其余当前分支实际要求的 phoneme、CNHuBERT、semantic、SV 特征必须按同一个文件名集合匹配，任何缺失、重复或错位都停止训练。

## 4. 微调顺序与训练验证

### 4.1 先 SoVITS，再 GPT

V2/V2Pro 等版本通常先训练 SoVITS，再训练 GPT；具体脚本和参数以当前 `webui.py` 的实际分支为准。常见本机入口是：

```text
GPT_SoVITS/s2_train.py
GPT_SoVITS/s1_train.py --config_file <yaml>
```

WebUI 的训练函数会动态写临时 JSON/YAML、设置实验名、预训练 G/D 或 S1 权重、输出目录和 GPU。优先使用 WebUI 让它创建目录和配置；手动运行前必须复制同样的配置并预创建输出目录。

### 4.2 关键资源和参数

- 根据实测显存选择 batch size、半精度、gradient checkpoint 和 epoch；不能把某台 RTX 2060 的设置当成通用默认。
- V2Pro 需要匹配的 `s2Gv2Pro.pth` 与 `s2Dv2Pro.pth`，GPT 使用版本匹配的 S1 预训练权重；先验证文件存在和加载日志中的 `All keys matched successfully` 或同等证据。
- 为每次实验使用新名字和独立 `logs/<experiment>`；保留每 epoch 的可推理权重，除非用户明确要求清理。
- 小数据集上的 `top_3_acc=1.0` 只说明训练集拟合得很好，不能证明自然度、泛化或声音像本人；必须让用户听不同文本，并把小数据集结果标为“流程验证/可能过拟合”。

### 4.3 每个训练阶段的完成条件

SoVITS 完成必须看到：数据集数量、`skipped_phone`/`skipped_dur`、预训练权重加载、每个目标 epoch 的保存成功、训练进程退出码 0 或项目明确的 `training done`；同时检查 `logs_s2_<version>` 和版本化 SoVITS 权重。

GPT 完成必须看到：`semantic_data_len` 与 `phoneme_data_len` 一致、数据集进入训练、每个目标 epoch 的 GPT 权重、checkpoint 和 `Trainer.fit` 的正常结束；同时检查版本化 GPT 权重。

不要把只有日志、只有 checkpoint 或只有 WebUI“完成”提示当作完成。缺一个可加载的目标权重就回到故障定位。

## 5. API 加载、试听和交付

API 初次启动的配置通常仍指向官方预训练权重。训练出的自定义权重必须显式加载，并且必须通过一次真实 `/tts` 生成验证。官方 `api_v2.py` 常见接口为：

```text
GET /set_gpt_weights?weights_path=<absolute-or-project-relative-path>
GET /set_sovits_weights?weights_path=<absolute-or-project-relative-path>
POST /tts
GET /control?command=exit
```

加载接口返回 `success` 只证明加载函数接受请求；随后还要生成 WAV、用 `ffprobe` 检查采样率/声道/时长，并用 FFmpeg 音量分析或人工试听确认不是静音。

`/tts` 至少提供：`text`、`text_lang`、`ref_audio_path`、`prompt_lang`、`prompt_text`。参考音频的实际内容必须与 `prompt_text` 一致；优先选择清晰、约几秒到十几秒的单段，而不是把整段长录音直接当参考。

当前版本还可能要求或接受 `batch_threshold`、`split_bucket`、`fragment_interval`、`seed`、`parallel_infer`、`overlap_length`、`min_chunk_length`、`sample_steps`、`super_sampling` 等字段；这些字段和 `media_type`/`streaming_mode` 的可选值必须读取目标 `api_v2.py`/`openapi.json`。注意 `/set_refer_audio` 使用 `refer_audio_path`，不是 `/tts` 的 `ref_audio_path`；完整字段表见 [故障与 API 参考](references/api-and-troubleshooting.md)。

在 Windows 上不要假定 PowerShell `Invoke-WebRequest -OutFile` 能可靠保存二进制响应；若出现空引用或无法解析 WAV，用显式 UTF-8 JSON 文件配合 `curl.exe --data-binary @request.json --output result.wav`，再检查 HTTP 状态和文件头。不要把错误 JSON 当成 WAV 交付。

交付时报告：

- 实际使用的 GPT/SoVITS 权重完整路径和实验名；
- API 地址、启动方式和“重启后是否需要重新加载自定义权重”；
- 试听文件路径、时长、格式和已执行的验证；
- 数据量、训练设置、过拟合风险和未验证事项；
- 如果用户要求清理，精确列出删除的模型文件，确认原始录音是否保留。

## 6. 故障恢复顺序

遇到失败时使用：`复现 → 保存日志 → 定位边界 → 一次只改一个变量 → 最小修复 → 重跑原场景 → 独立验证`。

优先查阅 [故障与 API 参考](references/api-and-troubleshooting.md)，不要凭错误猜测安装或重装。

常见关键点：

- `.bat` 窗口闪退：从 PowerShell 运行对应 `.ps1`，记录真实 stdout/stderr 和退出码；不能把“窗口消失”当成 API 失败。
- WebUI 可访问但 API 没开：这是正常的两个进程状态，分别按端口和 `/openapi.json` 验证。
- 首次保存 checkpoint 报错：检查日志写入的目标，例如 `logs_s2_v2Pro\G_*.pth`；手工配置可能没有创建 `logs_s2_v2Pro`，而 WebUI 会创建。补齐精确目录后重跑，不改模型文件。
- PyTorch Windows 分布式出现 `kubernetes.docker.internal` 地址警告：只有在随后完成 barrier、进入训练并正常保存时才能判为非致命；若进程退出，继续读取 traceback 和退出码。
- PowerShell 将原生 Python stderr 标成 `NativeCommandError`：这是管道呈现方式，不等于 Python 失败；以日志内容和 `$LASTEXITCODE` 为准。
- 训练结束但没有权重：检查版本分支、保存目录、权限、磁盘空间、是否使用了正确的 `s1_train.py`/`s2_train.py`，并对目标目录做独立 `Get-ChildItem` 验证。
- API 返回 200 但试听文件坏：检查请求 JSON 编码、HTTP 响应头、文件大小和 WAV 头；用 `curl.exe` 保存并用 `ffprobe` 验证。
- 目录或中文文件名乱码：先判断终端显示编码、文件 BOM 和实际解码方式，使用显式 UTF-8；不要把乱码写回标注。

## 7. 不要提前做的事

不要在用户尚未确认安装路径和硬件前下载；不要因为已有 7-Zip/FFmpeg 就断言它不存在；不要自动把新权重覆盖预训练目录；不要为了“方便”公开 `9880`；不要把 ASR 草稿直接当真值；不要删除原始录音；不要在小数据集达到高训练准确率后宣称声音质量已验证；不要创建或交付 Skill 之后继续偷偷训练、上传或推送数据。

## 参考资料路由

- 安装、版本、模型和数据格式：读取 [Windows 部署与数据参考](references/windows-deployment-and-data.md)。
- 官方 README、版本分支、教程经验值和官方指南故障线索：读取 [官方 README 与教程综合参考](references/official-readme-and-guide-synthesis.md)。
- 训练配置、真实文件契约、试听和排错：读取 [故障与 API 参考](references/api-and-troubleshooting.md)。
- 官方来源、本机代码证据和时效边界：读取 [来源账本](references/source-ledger.md)。

完成任一任务后，在最终回复中区分“已观察事实”“采取的动作”“仍未知/未验证”，并给出用户可以直接打开或执行的完整路径和命令。

