首页 / 资讯中心 / 文章详情

VITS-fast-fine-tuning训练准备:预训练模型、配置文件与语音素材样例数据指南

VITS-fast-fine-tuning训练准备:预训练模型、配置文件与语音素材样例数据指南 ★ FEATURED ARTICLE
简介这份资源是面向语音合成初学者与开发者的VITS-fast-fine-tuning训练样例数据包帮助用户跳过从零搭建的环节快速理解并实践模型微调流程。包内共983个文件以979个wav语音素材为主体另含2个pth预训练模型权重、1个json配置文件与1个txt说明文件压缩包约587.21MB。语音素材覆盖不同发音人、语速与情感的音频片段可用于验证模型性能或作为自建数据集的参考pth文件承载模型结构与权重加载后即可迁移到自有任务json配置则集中定义参数、优化器与训练细节便于按硬件条件调整。已有912人学习下载适合想快速体验VITS微调、生成个性化语音合成效果的读者参考使用。1. VITS-fast-fine-tuning 训练准备样例数据里到底该放什么很多人第一次接触 VITS-fast-fine-tuning卡住的地方不是训练脚本怎么跑而是训练之前那一堆东西到底该怎么摆。预训练模型放哪、配置文件改哪几行、语音素材切成什么样才算合格这三件事没理顺后面 loss 曲线再好看也是白搭。我见过太多人把语音素材一股脑丢进去结果训练到一半报采样率不匹配或者配置文件里路径写的是绝对路径换台机器直接崩。这篇笔记就围绕「训练准备的样例数据」这个点把预训练模型、配置文件、语音素材这三块拆开讲清楚让你拿到一份能直接复现的最小数据集结构。适合已经跑通过推理、准备做角色定制或音色微调的从业者也适合想搞清楚 VITS 微调数据组织逻辑的新手。2. 预训练模型与配置文件先搞懂它们各自管什么2.1 预训练模型不是越大越好先看底座匹配VITS-fast-fine-tuning 的预训练模型通常分两部分生成器Generator和判别器Discriminator有些仓库还会额外带一个说话人编码器或音色提取模块。样例数据里如果只放一个.pth文件训练脚本大概率会报缺 key。常见做法是准备三个文件G_xxxx.pth、D_xxxx.pth以及可选的speaker_encoder.pth或content_encoder.pth。这里有个血泪经验不要拿不同版本的预训练权重混搭比如生成器是 1.0 版、判别器是 1.1 版加载时 key 名对不上报错信息还特别隐晦只告诉你unexpected key不告诉你哪个模块对不上。选预训练模型时先确认你的目标语言和音色风格。如果做中文角色优先选在中文语料上预训练过的底座如果只有英文底座微调时语音素材最好也以英文为主否则音素映射会对不齐。样例数据里建议放一个pretrained/目录结构如下pretrained/ ├── G_0.pth ├── D_0.pth └── speaker_encoder.pth # 可选看仓库要求加载逻辑一般写在配置文件里路径用相对路径不要写/home/xxx/...这种绝对路径。相对路径的基准是训练脚本的工作目录通常是仓库根目录。如果你不确定就在训练脚本里打印os.getcwd()看一眼再填。2.2 配置文件分三层模型结构、训练超参、数据路径配置文件是训练准备里最容易翻车的地方。VITS-fast-fine-tuning 的配置文件通常是一个 JSON 或 YAML里面至少包含三块模型结构参数、训练超参数、数据路径。样例数据里应该放一份改好的配置文件而不是让使用者自己去猜。常见做法是复制仓库里的configs/base.json然后改这几个字段{ train: { log_interval: 200, eval_interval: 1000, seed: 1234, learning_rate: 2e-4, betas: [0.8, 0.99], eps: 1e-9, batch_size: 4, fp16_run: true, epochs: 100 }, data: { training_files: filelists/train.txt, validation_files: filelists/val.txt, max_wav_value: 32768.0, sampling_rate: 44100, filter_length: 2048, hop_length: 512, win_length: 2048, n_mel_channels: 80, mel_fmin: 0.0, mel_fmax: null }, 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], upsample_initial_channel: 512, upsample_kernel_sizes: [16, 16, 4, 4], n_layers_q: 3, use_spectral_norm: false, gin_channels: 256, n_speakers: 1 } }这里有几个参数必须和你的语音素材对齐。sampling_rate要和音频文件的采样率一致不一致的话训练脚本不会自动重采样而是直接报错或者出怪声。n_speakers如果是单角色微调就填 1多角色才改大。batch_size在显存不够时先降到 2 或 1不要硬撑否则 OOM 之后你还要重新调。fp16_run在 30 系显卡上可以开20 系及以下建议关掉不然容易出 NaN。提示配置文件里的training_files和validation_files指向的是 filelist 文件不是音频目录。filelist 里每一行是「音频路径|说话人ID|文本」的格式路径同样建议用相对路径。2.3 语音素材的格式与切分别让静音段毁掉训练语音素材是样例数据里最占体积的部分也是最容易出问题的部分。VITS-fast-fine-tuning 对语音素材的要求可以总结成三条采样率统一、单条时长适中、文本对齐干净。采样率常见的是 22050、44100具体看预训练模型用的什么。如果你拿到的素材是 48000要么用 ffmpeg 重采样要么改配置文件里的sampling_rate但改配置意味着 mel 频谱参数也要跟着调不如直接重采样省事。# 批量重采样到 44100单声道16bit mkdir -p wavs_resampled for f in wavs/*.wav; do ffmpeg -i $f -ar 44100 -ac 1 -sample_fmt s16 wavs_resampled/$(basename $f) done切分方面单条音频建议在 3 到 10 秒之间。太短了模型学不到连贯的韵律太长了训练时显存占用高而且文本对齐容易出错。切分时不要用固定时长硬切最好用静音检测。常见做法是用pydub的split_on_silence或者用silero-vad做端点检测。切完之后要人工抽听几条确认没有把字切碎。我一般会保留一个raw/目录放原始素材一个wavs/放切好的样例数据里只放切好的和对应的文本文件。文本文件通常是一个.list或.txt每行对应一条音频。格式是音频路径|说话人ID|文本文本里不要有换行和竖线。中文文本建议先做一遍正则清洗去掉括号里的备注、特殊符号数字转成汉字。这一步偷懒后面训练出来的模型就会在数字和英文上翻车。3. 从零搭一份可复现的样例数据目录3.1 目录结构定下来后面少改十次路径样例数据的目录结构不需要多复杂但一定要固定。我一般会按下面的方式组织训练脚本、配置文件、filelist 都在根目录下能找到相对路径vits_fast_finetune_sample/ ├── pretrained/ │ ├── G_0.pth │ ├── D_0.pth │ └── speaker_encoder.pth ├── configs/ │ └── finetune.json ├── filelists/ │ ├── train.txt │ └── val.txt ├── wavs/ │ ├── 001.wav │ ├── 002.wav │ └── ... ├── raw/ │ └── original.wav └── text/ └── transcript.txt这个结构的好处是配置文件里写../pretrained/G_0.pth或者pretrained/G_0.pth都能找到取决于你的工作目录。filelist 里写wavs/001.wav|0|你好训练脚本从根目录跑就能直接读到。如果你把音频放在data/wavs/下面filelist 里就要跟着改改漏一处就是FileNotFoundError。3.2 生成 filelist 的脚本与文本清洗filelist 不要手写手写必错。用脚本生成顺便做文本清洗。下面这个 Python 脚本会遍历wavs/目录按文件名排序生成 train 和 val 两个 filelist默认按 9:1 划分import os import random wav_dir wavs transcript_file text/transcript.txt output_train filelists/train.txt output_val filelists/val.txt val_ratio 0.1 speaker_id 0 # 读取文本假设 transcript.txt 每行是 文件名|文本 text_map {} with open(transcript_file, r, encodingutf-8) as f: for line in f: line line.strip() if not line: continue parts line.split(|, 1) if len(parts) ! 2: continue text_map[parts[0]] parts[1] # 收集所有 wav 文件 wav_files sorted([f for f in os.listdir(wav_dir) if f.endswith(.wav)]) items [] for wav in wav_files: key os.path.splitext(wav)[0] if key not in text_map: print(f跳过无文本的音频: {wav}) continue text text_map[key].strip() # 简单清洗去掉多余空格和特殊符号 text text.replace( , ).replace(|, ) items.append(f{wav_dir}/{wav}|{speaker_id}|{text}) random.seed(1234) random.shuffle(items) val_size max(1, int(len(items) * val_ratio)) val_items items[:val_size] train_items items[val_size:] os.makedirs(filelists, exist_okTrue) with open(output_train, w, encodingutf-8) as f: f.write(\n.join(train_items)) with open(output_val, w, encodingutf-8) as f: f.write(\n.join(val_items)) print(ftrain: {len(train_items)} 条, val: {len(val_items)} 条)这个脚本里speaker_id固定为 0单角色微调够用。多角色的话把说话人信息也放进 transcript 里格式改成文件名|说话人ID|文本脚本里对应解析。random.seed(1234)保证每次划分一致方便复现。文本清洗只做了最基础的去空格和去竖线实际用的时候建议再加一步正则把[()]里的内容去掉数字转汉字可以用cn2an这类库但不要过度清洗否则文本和音频对不上。3.3 配置文件里的路径与参数联动检查配置文件改完之后不要急着跑训练先做一遍路径检查。写一个小脚本把配置文件里所有路径字段读出来逐个判断文件是否存在import json import os with open(configs/finetune.json, r, encodingutf-8) as f: config json.load(f) paths_to_check [ config[data][training_files], config[data][validation_files], ] for p in paths_to_check: if os.path.exists(p): print(fOK: {p}) else: print(f缺失: {p}) # 检查 filelist 里的音频路径 for list_file in paths_to_check: if not os.path.exists(list_file): continue with open(list_file, r, encodingutf-8) as f: for line in f: line line.strip() if not line: continue wav_path line.split(|)[0] if not os.path.exists(wav_path): print(f音频缺失: {wav_path}) break这个检查脚本能帮你提前发现 90% 的路径问题。特别是 filelist 里的音频路径如果写的是绝对路径换台机器就崩如果写的是相对路径但工作目录不对也会崩。跑一遍这个脚本比训练到一半报错再回头找要省时间得多。4. 避坑与排查训练准备阶段最常见的 5 个翻车点4.1 采样率不匹配训练出电音现象训练 loss 正常下降但推理出来的音频有电流声或者音调不对。原因语音素材的采样率和配置文件里的sampling_rate不一致mel 频谱提取时频率轴错位。解决用ffprobe检查每条音频的采样率统一重采样到配置文件里的值。不要只检查第一条批量检查for f in wavs/*.wav; do sr$(ffprobe -v error -select_streams a:0 -show_entries streamsample_rate -of defaultnoprint_wrappers1:nokey1 $f) if [ $sr ! 44100 ]; then echo $f 采样率是 $sr fi done4.2 filelist 里文本含竖线解析错位现象训练时文本编码报错或者模型学出来的发音和文本完全对不上。原因filelist 用竖线分隔字段文本里如果本身有竖线解析时字段数就多了。解决生成 filelist 之前把文本里的竖线替换掉或者用其他分隔符比如|改成\t但配置文件里的data部分也要对应改。最省事的办法还是清洗文本去掉竖线。4.3 预训练模型 key 不匹配加载失败现象启动训练时报Missing key(s) in state_dict或Unexpected key(s)。原因预训练模型和当前代码版本的模型结构不一致或者生成器和判别器版本混搭。解决先打印预训练模型的 key 列表和模型定义的state_dict对比。常见做法是只加载匹配的 key不匹配的跳过但这样可能影响效果。最好是找同一版本的预训练权重。import torch ckpt torch.load(pretrained/G_0.pth, map_locationcpu) if model in ckpt: ckpt ckpt[model] for k in list(ckpt.keys())[:10]: print(k)4.4 显存不够硬撑 batch_sizeOOM 后白跑现象训练几个 step 后报 CUDA out of memory。原因batch_size设大了或者音频切得太长。解决先把batch_size降到 2如果还不行就降到 1同时开梯度累积。音频单条时长控制在 10 秒以内超过 10 秒的要么切短要么在配置文件里调大hop_length但调hop_length会影响音质优先切音频。4.5 验证集划分不合理eval loss 没有参考价值现象训练 loss 一直降但推理效果很差eval loss 却看不出问题。原因验证集太小或者和训练集分布差异太大比如验证集里全是短音频训练集里全是长音频。解决划分时保证验证集至少有 10 条并且随机打乱。如果素材本身很少比如只有几十条那就不要单独划验证集用训练集的一部分做 eval或者干脆不做 eval靠推理听效果。5. 用一份最小样例数据跑通训练前的自检5.1 自检清单跑训练前先过这五步在按下训练启动命令之前我习惯过一遍自检清单。这份清单不依赖任何训练框架纯靠文件检查和试听就能完成。第一步确认pretrained/下三个文件都在大小不是 0。第二步确认configs/finetune.json里sampling_rate和音频实际采样率一致。第三步确认filelists/train.txt和val.txt里每一行的音频路径都能找到文件。第四步随机抽三条音频试听确认没有静音段、没有截断。第五步确认文本和音频对得上抽一条音频看文本是不是它读的内容。这五步里最容易偷懒的是第四步和第五步。很多人觉得音频是别人给的应该没问题结果训练完发现模型把背景噪音也学进去了。试听不需要全部听抽三条就行但一定要听。5.2 用一条命令验证数据加载如果训练框架支持 dry run优先用 dry run 跑一遍数据加载。如果不支持就自己写一个最小数据加载脚本只加载一个 batch打印音频张量和文本编码的形状import torch from torch.utils.data import DataLoader # 假设你用的是仓库里的 TextAudioLoader # 这里只演示形状检查逻辑 dataset TextAudioLoader(filelists/train.txt, config) loader DataLoader(dataset, batch_size2, shuffleFalse) for batch in loader: audio, text, spec batch[0], batch[1], batch[2] print(faudio shape: {audio.shape}) print(ftext shape: {text.shape}) print(fspec shape: {spec.shape}) break形状对了说明数据加载没问题。如果 audio 的维度是[batch, 1, T]text 是[batch, T_text]spec 是[batch, n_mel, T_spec]基本就对了。如果某个维度是 0回去检查 filelist 和音频文件。5.3 训练启动命令与日志观察数据自检通过后启动训练。命令一般长这样python train.py -c configs/finetune.json -m finetune_run-c指定配置文件-m指定模型保存目录。启动后不要马上走开盯着日志看前 50 个 step。重点看三件事loss 是不是在降显存占用是不是稳定有没有 warning 说某个文件读不到。如果前 50 个 step 正常后面大概率没问题。如果 loss 是 NaN检查fp16_run是不是该关或者学习率是不是太大。日志里如果出现MelSpectrogram相关的 warning通常是音频太短或者静音段太多回去检查音频切分。如果出现KeyError或者IndexError多半是 filelist 格式问题用前面那个检查脚本再跑一遍。5.4 样例数据值不值得做我的判断习惯最后说一个我自己的习惯。每次准备样例数据之前我会先问自己这份数据能不能在 30 分钟内跑通一个 epoch。如果跑不通说明数据准备有问题先别急着调模型。VITS-fast-fine-tuning 的微调效果七分靠数据三分靠调参。预训练模型选对底座配置文件路径和采样率对齐语音素材切干净这三件事做到位训练基本不会翻车。反过来数据准备偷懒后面调参调到怀疑人生也救不回来。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站