sovits模型保存全流程:从checkpoint到config.json的完整配置指南
发布时间:2026/9/26 11:03:02来源:尧图网络
1. 训练完不保存等于白炼sovits 模型保存到底在存什么很多人第一次跑完 sovits 训练看到终端刷出一堆 loss 数字就以为大功告成结果换了个数据集想再炼一炉回头发现上一个模型找不到了或者找到了却加载不起来。问题不在训练本身而在于保存环节没做对。sovits 的模型保存不是简单地把一个文件丢进文件夹它涉及 checkpoint 权重、config.json 配置、logs 目录结构三者的配合缺一个都可能导致模型无法复现。这篇文章聚焦训练后的保存环节面向已经跑通 sovits 训练、准备做模型归档和迁移的语音克隆开发者。我会给出可复制的保存目录结构、config.json 关键字段的配置说明、checkpoint 命名规范以及加载验证的具体命令和预期输出。目标只有一个让你炼完的模型能稳定保存、随时加载、换机器也能跑起来。如果你同时管理多个模型或多次实验调用凭证和 API 通道的混乱也会拖慢节奏。我习惯用 TaoToken 统一管理多模型调用的 Key官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 后面会讲怎么把它接进你的工作流。先把保存这件事做扎实。2. 保存前的准备TaoToken 统一 Key 与目录规划在动手保存之前有两件事值得先理清楚一是你的模型调用凭证怎么管二是保存目录怎么规划。很多人炼了五六个模型之后Key 散落在各种配置文件里换个环境就要重新翻一遍非常痛苦。TaoToken 的作用是把多个模型的调用凭证收敛到一个通道里。你可以在控制台创建 API Key然后在需要调用模型的地方统一走这个 Key。对于 sovits 这种本地训练为主、但偶尔需要调用外部模型做辅助推理的场景统一 Key 能省掉不少切换成本。具体操作上先到控制台创建 Key# 访问控制台创建 API Key浏览器打开 # https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite创建完成后把 Key 写进环境变量避免硬编码到脚本里# Linux / macOS export TAOTOKEN_API_KEYsk-你的key # Windows PowerShell $env:TAOTOKEN_API_KEYsk-你的keyAPI 端点统一用 https://taotoken.net/api 注意这个地址不带 UTM 参数直接作为 base_url 使用即可。如果你用的是 OpenAI 兼容的客户端配置大概长这样# config_api.py import os API_KEY os.environ.get(TAOTOKEN_API_KEY) BASE_URL https://taotoken.net/api # 后续调用时传入 # client OpenAI(api_keyAPI_KEY, base_urlBASE_URL)目录规划方面建议在项目根目录下建一个saved_models文件夹每个模型一个子目录用模型名加日期命名。这样做的原因是 sovits 训练过程中会在logs目录下生成大量中间文件如果不做隔离换数据集时很容易把上一个模型的权重覆盖掉。# 推荐的保存目录结构 saved_models/ ├── myvoice_20240115/ │ ├── G_44000.pth # 生成器权重 │ ├── D_44000.pth # 判别器权重 │ ├── config.json # 模型配置 │ └── train_data_backup/ # 训练数据备份 └── another_20240120/ ├── G_44000.pth ├── D_44000.pth ├── config.json └── train_data_backup/这个结构的好处是每个模型自包含迁移时整个文件夹拷走就行不会丢配置也不会串数据。3. 可复制的保存配置checkpoint 命名与 config.json 字段sovits 训练结束后logs目录下通常会有多个 checkpoint 文件命名格式类似G_44000.pth和D_44000.pth。这里的数字代表训练步数G 是生成器D 是判别器。保存时不要只留最后一个建议保留几个关键步数的版本因为不同步数的模型在音色稳定性和自然度上会有差异。命名规范上我建议在原始文件名基础上加模型标识避免多个模型的 checkpoint 混在一起时分不清# 原始文件 logs/44k/G_44000.pth logs/44k/D_44000.pth logs/44k/config.json # 归档后重命名 saved_models/myvoice_20240115/G_myvoice_44000.pth saved_models/myvoice_20240115/D_myvoice_44000.pth saved_models/myvoice_20240115/config_myvoice.jsonconfig.json 是保存环节最容易出问题的地方。这个文件记录了模型的采样率、音高提取方式、说话人数量等关键参数如果配置和权重不匹配加载时会直接报错。下面是一个典型的 config.json 关键字段说明{ train: { log_interval: 200, seed: 1234, epochs: 100, batch_size: 6, learning_rate: 0.0001, betas: [0.8, 0.99], lr_decay: 0.999875, save_every_epoch: 10, if_cache_data_in_gpu: false }, data: { training_files: filelists/train.txt, validation_files: filelists/val.txt, sampling_rate: 44100, filter_length: 2048, hop_length: 512, win_length: 2048, n_speakers: 1 }, model: { inter_channels: 192, hidden_channels: 192, filter_channels: 768, n_heads: 2, n_layers: 6, kernel_size: 3, p_dropout: 0.1, resblock: 1, resblock_kernel_sizes: [3, 7, 11], resblock_dilation_sizes: [[1, 3, 5], [1, 3, 5], [1, 3, 5]], upsample_rates: [8, 8, 2, 2, 2], upsample_initial_channel: 512, upsample_kernel_sizes: [16, 16, 4, 4, 4], n_layers_q: 3, use_spectral_norm: false, gin_channels: 256, ssl_dim: 256, n_speakers: 1 }, spk: { myvoice: 0 } }几个必须核对的字段sampling_rate要和训练数据一致44100 和 48000 不能混n_speakers要和实际说话人数量匹配单说话人就是 1spk里的映射关系决定了推理时怎么指定音色。这些字段如果保存时写错加载模型时会出现维度不匹配或者音色错乱。保存操作本身很简单把logs/44k下的 G、D 权重和 config.json 复制到归档目录然后按上面的命名规范重命名# 创建归档目录 mkdir -p saved_models/myvoice_20240115 # 复制并重命名 cp logs/44k/G_44000.pth saved_models/myvoice_20240115/G_myvoice_44000.pth cp logs/44k/D_44000.pth saved_models/myvoice_20240115/D_myvoice_44000.pth cp logs/44k/config.json saved_models/myvoice_20240115/config_myvoice.json # 备份训练数据如果 dataset_raw 还有用 cp -r dataset_raw/myvoice saved_models/myvoice_20240115/train_data_backup/注意dataset_raw在预处理后会被加载到dataset文件夹训练时实际用的是dataset。如果你之后还要用这份数据务必在换数据集之前备份因为dataset_raw里同时放两份数据会导致预处理时把它们混在一起炼出来的模型音色会出问题。4. 加载验证用命令确认模型能跑起来保存完不代表结束必须验证模型能正常加载。最直接的方式是用推理脚本加载 checkpoint 和 config看是否能输出音频。先确认你的推理入口脚本通常是inference_main.py或 webui。用命令行方式验证# 加载模型进行推理测试 python inference_main.py \ -m saved_models/myvoice_20240115/G_myvoice_44000.pth \ -c saved_models/myvoice_20240115/config_myvoice.json \ -n test_input.wav \ -t 0 \ -s myvoice \ -f 0 \ -o output_test.wav参数说明-m指定生成器权重-c指定配置文件-n是输入音频-t是变调参数-s是说话人名称要和 config.json 里spk的 key 一致-f是特征提取相关参数-o是输出文件。预期输出应该类似这样INFO:root:Loading model from saved_models/myvoice_20240115/G_myvoice_44000.pth INFO:root:Config loaded: sampling_rate44100, n_speakers1 INFO:root:Speaker myvoice mapped to id 0 INFO:root:Processing test_input.wav INFO:root:Inference done, saved to output_test.wav如果看到Config loaded和Speaker mapped这两行说明配置和权重匹配成功。如果报错KeyError: myvoice说明 config.json 里的spk字段没有这个说话人如果报size mismatch说明权重和配置的维度对不上通常是n_speakers或gin_channels写错了。另一种验证方式是在 Python 里直接加载import torch import json # 加载配置 with open(saved_models/myvoice_20240115/config_myvoice.json, r) as f: config json.load(f) print(sampling_rate:, config[data][sampling_rate]) print(n_speakers:, config[data][n_speakers]) print(speakers:, list(config[spk].keys())) # 加载权重 checkpoint torch.load(saved_models/myvoice_20240115/G_myvoice_44000.pth, map_locationcpu) print(checkpoint keys:, list(checkpoint.keys())[:5]) print(model state dict loaded:, model in checkpoint or state_dict in checkpoint)预期输出会打印出采样率、说话人数量和权重里的关键 key。如果checkpoint keys里能看到model或state_dict说明权重文件完整。如果你在验证过程中需要调用外部模型做对比或者辅助处理可以用 TaoToken 的 API 通道模型对话入口在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 统一 Key 直接调用不用再单独配一套凭证。5. 本篇常见错排查保存后加载失败的几种情况保存环节的坑主要集中在配置不匹配和文件缺失上。下面是我实际遇到过的几种典型报错和排查方法。报错一FileNotFoundError: config.json原因通常是复制时路径写错或者 config.json 没有跟着权重一起归档。排查方法是确认归档目录下三个文件都在ls -la saved_models/myvoice_20240115/ # 应该看到 G_*.pth、D_*.pth、config_*.json 三个文件报错二RuntimeError: Error(s) in loading state_dict for SynthesizerTrn这是权重和配置维度不匹配。最常见的是n_speakers不一致比如训练时是 2 个说话人保存的 config 里写成了 1。排查方法是打开 config.json 核对data.n_speakers和model.n_speakers是否一致以及spk里的说话人数量是否匹配。报错三推理出来的音频是噪声或者音色不对这种情况通常是采样率不匹配。训练数据是 44100但推理时用了 48000 的配置或者反过来。检查 config.json 里的data.sampling_rate确保和训练时一致。另外hop_length和win_length也要核对这两个参数影响音频帧的切分方式。报错四换数据集后上一个模型加载不了这是因为logs/44k目录被新训练的模型覆盖了。sovits 训练时默认往logs/44k写 checkpoint如果你没有在训练前把旧模型归档新训练会直接覆盖。解决办法就是本文强调的训练完立刻归档到saved_models下的独立目录不要依赖logs目录长期保存。报错五KeyError: speaker_nameconfig.json 里的spk字段没有包含你指定的说话人名称。检查spk的 key 是否和推理命令里-s参数一致。比如 config 里是myvoice: 0推理时就要用-s myvoice不能写成-s MyVoice大小写敏感。排查时建议按这个顺序先确认文件齐全再核对 config 关键字段最后检查推理参数。大部分问题在前两步就能定位。6. 多模型管理与长期编码把保存流程固化下来单次保存做好之后下一步是把流程固化让每次训练完都能自动归档。我自己的做法是写一个保存脚本训练结束后手动跑一次把 checkpoint、config 和训练数据备份一次性搞定。#!/bin/bash # save_model.sh MODEL_NAME$1 DATE$(date %Y%m%d) SAVE_DIRsaved_models/${MODEL_NAME}_${DATE} mkdir -p $SAVE_DIR # 复制权重和配置 cp logs/44k/G_*.pth $SAVE_DIR/G_${MODEL_NAME}.pth cp logs/44k/D_*.pth $SAVE_DIR/D_${MODEL_NAME}.pth cp logs/44k/config.json $SAVE_DIR/config_${MODEL_NAME}.json # 备份训练数据 if [ -d dataset_raw/${MODEL_NAME} ]; then cp -r dataset_raw/${MODEL_NAME} $SAVE_DIR/train_data_backup/ fi echo Model saved to $SAVE_DIR ls -la $SAVE_DIR用法就是bash save_model.sh myvoice脚本会自动按日期建目录并完成归档。这样每次训练完跑一次不会漏文件也不会覆盖旧模型。如果你长期做语音克隆开发模型数量会越来越多调用凭证的管理也会变复杂。TaoToken 的 Coding Plan 适合这种长期编码场景把多个模型的调用统一到一个通道里入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有具体的配置示例。API Key 管理页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 可以随时创建和吊销 Key。如果你用 Claude Code 做开发辅助Anthropic 兼容入口在 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 配置方式和前面讲的 base_url 替换类似。回到保存本身最后再强调一个细节每次训练前先确认logs/44k目录是干净的或者至少把旧模型归档后再开始新训练。我踩过的坑就是直接开炼第二个模型结果第一个模型的 checkpoint 被覆盖只能重新训练。现在我的习惯是训练脚本跑完立刻执行保存脚本归档完成后再动数据集。这样即使后面要回头炼第一个模型把归档目录里的权重复制回logs/44k删掉除 diffusion 文件夹外的旧文件再运行 webui 就能恢复。整个流程跑顺之后模型保存就不再是负担而是标准动作。
网站建设高端定制企业官网