Whisper+GPT-SoVITS本地部署实战:零基础搭建AI语音克隆系统

一、部署前准备:硬件配置与软件环境
在动手敲代码之前,我们建议你先花十分钟把硬件和软件环境确认一遍。这套流程能帮你省掉反复重装驱动和回滚CUDA的数小时折腾,让整个Whisper加GPT-SoVITS的部署一次到位。
- 确认显卡为NVIDIA RTX 3060 12GB或更高型号
- 安装CUDA 11.8或12.1及对应cuDNN
- 使用Python 3.10创建独立虚拟环境
- 预留至少50GB磁盘空间存放模型与缓存
- 提前下载好Whisper与GPT-SoVITS依赖清单
我们把NVIDIA显卡放在第一位,是因为Whisper的音频编码和GPT-SoVITS的声学模型推理都极度依赖CUDA并行计算。具体来说,显存低于12GB时,GPT-SoVITS在推理长音频或加载大参数模型时会频繁触发OOM。我们建议直接使用RTX 3060 12GB以上的显卡,这是当前性价比最高的起步配置。如果你手上只有8GB显存的卡,我们建议先升级硬件再继续,否则后续调参会非常痛苦。
CUDA和cuDNN的版本必须严格对齐,我们推荐CUDA 11.8或12.1,这两个版本对PyTorch生态的兼容性最好。安装时要注意cuDNN的版本必须与CUDA主版本匹配,错配会导致PyTorch无法调用GPU。Python环境我们锁定3.10,因为Whisper和GPT-SoVITS的依赖库在3.10上测试最充分。我们强烈建议用conda或venv创建独立虚拟环境,避免污染系统Python。
磁盘空间这块经常被低估,模型权重、训练缓存、日志文件以及虚拟环境本身会迅速吃掉大量空间。我们要求至少预留50GB可用空间,最好放在SSD上以加速模型加载。准备工作的逻辑很简单:先把地基打牢,后面拉代码和跑推理才会一帆风顺。我们见过太多人环境没配好就急着跑demo,最后在依赖冲突里浪费整天时间。
conda create -n voice python=3.10 -y
conda activate voice
pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cu118
输出说明:终端依次显示Solving environment、Downloading and Extracting Packages,最后出现Done即表示虚拟环境与PyTorch安装成功。输入nvidia-smi可确认驱动识别正常,输入python -c "import torch; print(torch.cuda.is_available())"应返回True。
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| 本地RTX 3060 12GB | 推理零延迟,数据不出局域网 | 一次性硬件投入较高 | 长期高频使用,注重隐私 |
| 云GPU租用(按小时) | 无需购置硬件,随时升降配 | 持续租赁费用,数据传输有延迟 | 短期验证,偶尔跑批 |
| CPU纯推理 | 零显卡成本,部署门槛低 | 速度慢十倍以上,长音频易卡死 | 仅测试API逻辑,不用于生产 |
| Mac M系列统一内存 | 静音低功耗,内存带宽大 | 部分CUDA算子无法运行,需转译层 | 轻量级实验,非NVIDIA环境 |
我们的明确建议是:如果你已经有一台带RTX 3060 12GB显卡的机器,直接按本文步骤安装CUDA 11.8和Python 3.10环境,然后进入下一节拉取Whisper代码。如果硬件暂时不达标,优先升级显卡,不要试图在CPU上硬扛GPT-SoVITS的训练和推理。
二、Whisper本地部署:高精度语音识别
在正式搭建语音克隆流程之前,我们先把Whisper这块地基打牢。Whisper的安装分两条路线:一条是官方的openai-whisper,另一条是社区优化的faster-whisper。我们直接选faster-whisper,因为它基于CTranslate2重写,在同样的模型权重下推理速度能快上数倍,而且对显存的调度更友好。安装本身不复杂,一条pip命令加上FFmpeg的音频处理库就能跑起来,麻烦的是后面模型权重和CUDA环境的匹配。
模型权重方面,我们主要在large-v3和turbo之间做取舍。large-v3是目前精度最高的版本,对中文、英文以及中英混读的识别都很稳,代价是显存占用大,推理速度相对慢。turbo是官方推出的轻量加速版,速度接近实时,显存需求也低一截,但在极低信噪比的环境下,识别准确率会掉。我们建议先下载large-v3做数据清洗,如果显存吃紧再换turbo做批量粗转。
装好模型后,一定要验证CUDA是否真正生效,别让程序偷偷跑在CPU上。我们通常在初始化WhisperModel时把device设为cuda、compute_type设为float16,然后跑一段固定时长的音频做基准测试,记录每秒处理音频的倍速。音频预处理也不能跳过,我们用FFmpeg把原始视频或录音统一转成16kHz单声道wav,这样能避免采样率不匹配导致的识别率下降。
# 安装 faster-whisper 与 FFmpeg 依赖
pip install faster-whisper ffmpeg-python
# 示例:调用 faster-whisper 进行转写
from faster_whisper import WhisperModel
import ffmpeg
# FFmpeg 预处理:将 input.mp4 统一转为 16kHz 单声道 wav
(
ffmpeg
.input("input.mp4")
.output("temp.wav", ac=1, ar=16000)
.run(overwrite_output=True)
)
# 加载 large-v3 模型,启用 CUDA 加速
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
# 执行转写,beam_size=5 提升解码稳定性
segments, info = model.transcribe("temp.wav", beam_size=5)
# 输出说明:逐段打印识别结果与时间戳
for segment in segments:
print(f"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}")
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| openai-whisper | 官方实现,接口稳定 | 推理速度慢,显存占用高 | 小批量测试与算法验证 |
| faster-whisper | CTranslate2加速,速度提升3-5倍 | 需转换模型格式,部分高级特性受限 | 生产环境批量转写 |
| large-v3 权重 | 识别精度最高,多语言支持强 | 显存需求大,推理耗时较长 | 对准确率要求高的正式数据集 |
| turbo 权重 | 速度接近实时,显存友好 | 精度略低于large-v3 | 实时字幕与快速草稿生成 |
综合来看,我们的明确推荐是:主力环境用faster-whisper搭配large-v3,把device设为cuda、compute_type设为float16,先在一段五分钟的测试音频上确认实时率(RTF)低于0.3,再接入正式流程。如果后续要做GPT-SoVITS的微调,建议现在就把Whisper的转写脚本固化下来,输出带时间戳的文本,方便后面做音频与文本的强制对齐。下一步,我们直接进入GPT-SoVITS的本地部署,把语音识别和语音合成这两块拼图合到一起。
三、GPT-SoVITS环境搭建:语音克隆核心框架
我们先从克隆官方仓库开始。打开终端,进入你打算存放项目的目录,执行git clone命令把GPT-SoVITS的源码拉下来。进入项目根目录后,建议先新建一个独立的Python环境,避免污染系统依赖,这里我们推荐使用Conda创建Python 3.9或3.10的环境。接着安装项目自带的requirements.txt文件,这一步会自动拉取大部分基础依赖。
PyTorch的安装必须和你的CUDA版本严格对应。我们先在终端输入nvidia-smi查看显卡驱动支持的最高CUDA版本,然后去PyTorch官网选择对应的安装命令。音频处理库方面,除了requirements里的基础包,我们还要手动确认librosa和soundfile已经装好,因为后续的音频切分和重采样全靠它们。如果安装过程中出现numpy版本冲突,先把numpy降到1.23.x,再重新安装其他包。
底模下载是语音克隆的核心。我们需要从官方提供的链接下载s1和s2的预训练权重,以及UV R5的对应模型文件,把它们放到项目指定的pretrained_weights目录下。很多人在这一步会遇到文件路径报错,原因通常是下载的压缩包没有解压,或者文件夹命名不对。我们强烈建议按照官方文档的目录结构逐一核对,确保每个pth和ckpt文件都放在正确的位置。
# 1. 克隆仓库
git clone https://github.com/RVC-Boss/GPT-SoVITS.git
cd GPT-SoVITS
# 2. 创建独立环境
conda create -n gpt-sovits python=3.9 -y
conda activate gpt-sovits
# 3. 安装 PyTorch (以 CUDA 12.1 为例)
pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu121
# 4. 安装项目依赖
pip install -r requirements.txt
# 5. 锁定冲突依赖版本
pip install numpy==1.23.5 pydantic==1.10.13
# 输出说明:终端依次显示 Cloning into、Solving environment、Successfully installed 等字样,
# 最后执行 python webui.py 不报 ModuleNotFoundError 即代表环境搭建成功。
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| CUDA 11.8 + PyTorch 2.0 | 兼容性最稳,社区教程多 | 无法调用最新推理加速特性 | NVIDIA 30系及更早显卡 |
| CUDA 12.1 + PyTorch 2.1 | 支持新特性,推理速度更快 | 部分旧音频库需重新编译 | NVIDIA 40系新显卡 |
| CPU-only | 无需独立显卡,安装最简单 | 推理速度极慢,无法训练 | 仅验证代码流程 |
| Docker 镜像 | 环境完全隔离,开箱即用 | 镜像体积大,本地调试困难 | 服务器批量部署 |
对于拥有NVIDIA 30系或40系显卡的用户,我们直接推荐CUDA 12.1 + PyTorch 2.1的组合,按上述步骤装完后,立刻运行webui.py启动Web界面,用一段3到5秒的清晰人声测试推理。如果启动失败,优先检查终端报错是否指向numpy或pydantic版本,把这两个库锁定到requirements指定的版本即可。下一步,我们进入数据预处理与微调训练环节。
四、数据预处理:音频切分与文本标注
我们使用Whisper对原始音频进行批量转写,这是整个预处理流程的第一步。通过命令行调用faster-whisper或openai-whisper,可以快速将长音频转换成带时间戳的文本。转写结果直接决定后续切分的质量,所以我们会优先选择large-v3模型来保证中文识别的准确率。
在转写之前或之后,我们通常会先执行人声分离与降噪处理。使用UVR5或Demucs把背景音乐和人声分开,再用DeepFilterNet做降噪,这样能显著提升Whisper的识别率。处理后的干净人声是后续切分和标注的基础,千万不要跳过这一步。
拿到转写文本后,我们按照3到10秒的规则切分语音片段,同时生成对应的ASR标注文件和TextGrid。切分时我们会避开句子中间的气口,尽量保证语义完整。最后用脚本把音频路径、文本内容、时长信息写成list文件,供GPT-SoVITS训练直接读取。
# 输入:raw_audio/ 目录下的原始音频(wav/mp3)
# 输出:transcripts/ 目录下的 JSON 转写结果 + dataset.list 切分清单
whisper raw_audio/*.wav --model large-v3 --language Chinese \
--output_format json --output_dir transcripts/
# 随后运行切分脚本,按 VAD 静音检测切分 3-10 秒片段
python split_by_vad.py --input_dir raw_audio \
--transcript_dir transcripts --output_dir dataset_sliced \
--min_dur 3 --max_dur 10
# 生成的 dataset.list 格式如下:
# ./dataset_sliced/seg_0001.wav|./dataset_sliced/seg_0001.txt|4.52
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| Whisper large-v3 + VAD切分 | 识别准,切分稳 | 显存占用高,速度较慢 | 高质量中文语音数据集 |
| Whisper medium + 固定时长切分 | 速度快,显存要求低 | 长句易截断,标点对齐差 | 快速验证,粗粒度数据集 |
| UVR5人声分离 + Whisper | 背景音干净,识别率高 | 多一步推理,耗时增加 | 含背景音乐的原始录音 |
| 纯人工标注 + 手动切分 | 文本绝对准确 | 人力成本极高,周期长 | 极小规模精品数据集 |
我们推荐直接采用Whisper large-v3配合VAD切分作为默认方案,先把数据质量和标注对齐做好,再考虑替换更轻量的模型来提速。完成这一步后,我们就可以进入下一节的模型训练配置环节。
五、模型训练:微调GPT与SoVITS
配置config.py与训练超参数是我们动手训练的第一步。打开项目根目录下的config.py,我们会看到batch_size、epoch、learning_rate这些核心字段,它们直接决定训练的稳定性和速度。我们建议在显存小于12GB的机器上把batch_size压到4以内,同时把learning_rate设为1e-4,这样能避免梯度爆炸。如果显存充裕,可以适当提高batch_size来缩短单轮训练时间。
启动GPT语义Token训练之前,我们要确保语音切分、文本正则化和whisper特征提取都已经跑完。我们在终端里执行训练脚本,让它先读取1.wav目录下的音频和对应的.label文件,然后自动生成语义Token并送入GPT模型。训练过程中,控制台会实时打印loss曲线,我们一般看到loss降到0.3以下且曲线平滑时,就可以考虑暂停保存权重。如果loss出现剧烈震荡,就要回退检查学习率是否过高。
训练SoVITS声学模型的流程和GPT略有不同,它需要同时优化synthesizer和discriminator。我们在config.py里把so_vits的epoch设为独立数值,然后启动对应的训练入口,让模型学习音色嵌入和声学细节。这个阶段对显存要求更高,我们习惯把checkpoint保存间隔设成100步,方便随时回滚到最优状态。训练结束后,我们会在weights目录下得到G.pth、D.pth和对应的config.json,这三个文件就是后续推理的核心。
# 进入项目目录并启动训练
cd GPT-SoVITS
python train.py --model gpt --config config.py
# 输入示例:训练日志片段
# [Epoch 12/100] Step 340 | loss: 0.284 | lr: 1.00e-04
# [Epoch 12/100] Step 350 | loss: 0.271 | lr: 1.00e-04
# checkpoint saved to weights/gpt_340.pth
# 输出说明:每10步打印一次loss,每100步自动保存一次权重文件
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| 快速试听版 | 20分钟出结果,方便验证流程 | 音色粗糙,韵律不自然 | 刚跑通环境,需要确认数据格式正确 |
| 标准训练版 | 音色稳定,合成速度与质量平衡 | 需要2-4小时GPU时间 | 日常语音克隆,满足一般视频配音 |
| 高保真精调版 | 呼吸感与情感接近真人 | 显存占用大,训练周期超过10小时 | 商业配音、有声书制作等高要求场景 |
我们推荐先用快速试听版跑通整个训练链路,确认loss正常下降后再切换到标准训练版。下一步我们把保存好的G.pth、D.pth和GPT权重导入推理界面,开始实际语音合成测试。
六、推理部署:本地WebUI与API集成
我们完成模型训练后,第一步是启动inference_webui.py进入本地可视化界面。在WebUI中,我们先上传一段3到10秒的参考音频,并填写需要合成的目标文本。接着调整语速、温度与音色相似度这三个核心参数,点击合成按钮试听效果。这个阶段的目标是把音色质感和语速节奏调到最接近真人的状态。
WebUI适合人工验证,但没法直接接入业务系统,所以我们还要把推理流程封装成本地HTTP服务。我们通常基于FastAPI搭建一个轻量接口,把音频上传、文本处理、模型推理和结果返回整合成一条完整的调用链路。服务启动后,客户端只需要发送JSON或表单请求,就能拿到合成后的音频文件地址或二进制流。
封装过程中,我们要把模型加载放在服务启动阶段,避免每次请求都重新读取权重。同时给参考音频添加强制重采样和响度归一化处理,防止不同来源的音频导致输出质量波动。如果并发量上来,再引入异步任务队列和显存监控,保证服务长时间稳定运行。
# app.py 本地推理服务示例
from fastapi import FastAPI, UploadFile, Form
import uvicorn
app = FastAPI()
@app.post("/synthesize")
async def synthesize(
ref_audio: UploadFile,
ref_text: str = Form(...),
target_text: str = Form(...),
speed: float = Form(1.0),
temperature: float = Form(0.3),
top_k: int = Form(6)
):
# 1. 保存并预处理参考音频
# 2. 调用GPT-SoVITS推理核心
# 3. 返回音频文件路径或base64流
return {
"code": 200,
"audio_url": "http://127.0.0.1:8000/output/result.wav",
"duration": 3.25
}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
# 输入示例:
# curl -X POST http://127.0.0.1:8000/synthesize \
# -F "ref_audio=@ref.wav" \
# -F "ref_text=参考音频对应文本" \
# -F "target_text=今天天气很好" \
# -F "speed=1.0" -F "temperature=0.3"
# 输出说明:
# 返回JSON,包含状态码、音频下载地址和时长,客户端可直接播放或保存。
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| WebUI手动操作 | 零代码,实时调参试听 | 无法自动化,依赖人工点击 | 模型验证与参数调试 |
| FastAPI同步接口 | 开发快,HTTP通用,易对接业务 | 高并发时阻塞,需控制并发量 | 中小规模内部工具 |
| FastAPI+任务队列 | 异步解耦,支持批量合成 | 架构复杂,需维护队列服务 | 生产环境批量音频生成 |
| gRPC内部服务 | 传输效率高,适合微服务 | 调试门槛高,需定义proto | 内部系统间高性能调用 |
我们推荐先用inference_webui.py把音色和参数调到满意,再基于FastAPI封装同步接口供业务调用。如果后续需要处理批量任务,下一步引入Celery或RQ队列,并加上显存监控与自动扩缩容策略。这样既能快速落地,又能为将来的高并发场景留出扩展空间。
七、常见问题:显存优化与故障排查
我们在本地同时部署 Whisper 和 GPT-SoVITS 时,最先撞上的问题就是 CUDA out of memory。这种情况通常发生在两个大模型同时驻留显存,或者推理脚本里 batch size 设置过大的时候。我们的处理思路是先强制把 batch 降到 1,再开启 fp16 半精度推理,最后才考虑模型切分或者换量化方案。
推理结果出现爆音和杂音,八成是音频预处理环节出了问题。我们会先检查输入音频的采样率是否统一到 44.1kHz 或 48kHz,再看推理参数里的 top_k 和 temperature 是否调得过高。另外,底模和微调模型的版本不一致也会引入明显底噪,这时候必须重新对齐版本,而不是继续调参。
模型路径和端口冲突是本地部署最烦人的问题,尤其是同时跑 Whisper API 和 GPT-SoVITS WebUI 的时候。我们习惯先用 netstat 或 lsof 确认端口占用,再把模型绝对路径写进配置文件,避免相对路径在不同终端下解析出错。如果端口被占,直接改配置文件比杀进程更稳妥。
底模更新后旧版微调模型经常加载失败,这是版本兼容的硬伤。我们的原则是底模大版本升级时,同步拉取对应的 SoVITS 分支,并用 conda 建独立环境隔离依赖。不要指望新版 PyTorch 能无脑兼容旧 ckpt,重新导出权重比调试报错更高效。
# 输入示例:在终端按顺序执行以下命令
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
lsof -i :9880
python -c "import torch; print(torch.cuda.is_available())"
# 输出说明:第一行显示当前显存占用与总量,第二行若为空表示端口可用,
# 若显示 PID 则需修改配置文件中的端口号;第三行返回 True 代表 CUDA 驱动正常。
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| fp16 半精度推理 | 显存占用减半,速度更快 | 精度极轻微下降 | 显存 8-12GB 的主流显卡 |
| int8 量化 | 显存占用极低 | 音质有可感知损失 | 显存 4-6GB 的入门显卡 |
| 降低 batch + 音频分帧 | 无需改动模型结构 | 吞吐量下降,延迟升高 | 长音频转写与流式推理 |
| CPU 推理兜底 | 零显存占用 | 速度极慢,仅适合调试 | 无独显的临时验证环境 |
如果大家现在正被显存卡住,我们直接建议先开 fp16 并把 batch 压到 1,这是性价比最高的方案;端口冲突就改配置文件,不要硬刚;底模一旦更新,立刻重建 conda 环境并重新导出微调权重。下一步,我们会整理一份从零到一的完整部署 Checklist,把环境、路径、依赖一次性固化下来,让大家照着敲就能跑通。