跳转至

音色工程 · 01 RVC(在用)

配套:音色工程_00_公用.md(素材 / 清洗 / 混音 / 指标)、音色工程_02_SVC.md(实验线,已暂停)。 RVC = Retrieval-based Voice Conversion,我们现在语音条和翻唱都跑在这套上。


0. 一句话选型

需求 模型 备注
说话(QQ 语音条、TTS 变声) 深澜语音用_v1 46 秒说话素材,够用
唱歌翻唱 深澜翻唱用_v2(48k) 目前听感最顺,长音不飘(配合 crepe)

1. 它是什么

  • 仓库:https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI;CLI 分支用手上的 Applio。
  • 核心:HuBERT / ContentVec 取内容特征 + Faiss 检索,把音色往训练集里"最像的那几条"上拉。
  • 特点:整条音频一次过、不分段 → 响度连贯、没有拼接痕迹,这是我们选它的主要原因。
  • 索引(*.index)= 音色参照库;index-rate 越高越贴训练集(更像,也更容易带噪、过拟合)。

2. 语言

  • 中文占比够就行,不必纯中文。
  • 实测:纯日文素材训出来有怪口音;加入中文素材后口音消失。 原因:ContentVec 把语言信息剥得比较干净 + Faiss 检索把音色压回中文口型。
  • 要日语歌 → 另训一套日语为主的,别硬凑三语。

3. 训练(Applio CLI)

cd <RVC 目录>\Applio                       # cwd 必须是这里,否则 ModuleNotFoundError 'rvc'
python core.py preprocess --model-name X --dataset-path <清洗目录>
python core.py extract  --model-name X --f0-method rmvpe
python core.py train    --model-name X --epochs 200 --batch-size 4 \
  --custom-pretrained --g-pretrained-path pretrained\f0G40k.pth --d-pretrained-path pretrained\f0D40k.pth
python core.py index    --model-name X

坑: - 默认会去 HuggingFace 拉权重(连不上),必须 --custom-pretrained 指本地;HF 走 hf-mirror.com。 - 48k 要用 f0G48k.pth / f0D48k.pth。 - 人声分离(BS-Roformer)是 CPU,极慢:48 分钟音频约 2 小时。 - segment_size(训练窗口)与切片长度要匹配:48k 下 17280 ≈ 0.36s。窗口拉到 34560(0.72s)时,短于 1.5 秒的片段装不下,会报 RuntimeError: The expanded size of the tensor (72) must match the existing size (0)(rvc\lib\algorithm\commons.py:65 slice_segments)→ 训练前先按 ≥1.5s 过滤 filelist。 - logs\<exp>\sliced_audios 里至少要有一个 wav,否则 No wav file found.(rvc\train\train.py:213)。 - 导出模型报 cannot access local variable 'embedder_model' → 缺 model_info.json;报 Unexpected UTF-8 BOM → 该 json 被写成了带 BOM。 - 导出报 'collections.OrderedDict' object has no attribute 'half' → 拿到的是整包训练 checkpoint,要取 ckpt["model"] 再交给 extract_model。 - 中文模型名在 CLI 里会因编码问题读不到索引(could not open ...index)→ 先复制成 ASCII 名再用。

实验记录(2026-11-11):只把训练窗口从 0.36s 拉到 0.72s 重训 20 轮(logs\deepsea_v6,step 8160,25 分钟,lowest 16.775@epoch17)→ 长音抖动没改善(0.134→0.123 半音),高频反而更差(>5kHz 0.024→0.013)。结论:切片长度不是长音发颤的原因。

4. 推理参数(四个旋钮)

参数 作用 取值
pitch 升降调(半音) 翻唱 +10~12;说话 0
index-rate 检索融合强度 0.5(稳)~0.75(像但风险高)
protect 保护清辅音/呼吸声 0.33(默认);调到 0.5 实测更差(高频 0.062→0.050),别乱调
f0-method 音高提取 高音长音用 crepe,其余 rmvpe

升调时伴奏必须同步降调,否则串调:rubberband=pitch=0.8908987(= −2 半音)。 --f0-method harvest 这个选项不存在;可选只有 crepe / rmvpe / fcpe / hybrid,而 fcpe 缺 rvc\models\predictors\fcpe.pt 会直接报 FileNotFoundError,hybrid 跟着崩。

5. 常驻服务(把 116 秒压到 7 秒)

  • 每条语音冷启动要重载 torch + 模型 + 30MB 索引,占 55 秒;10 秒音频整条 116 秒。
  • 解法:常驻 worker 监听 127.0.0.1:8899,一次加载反复用,空闲 600 秒自退。
  • 实测:冷启 57.5s → 热调 0.7s。

6. 高音长音发颤 → 换 crepe(2026-11-11 验证)

现象:转换后 2:51 那种高音长音变成上下起伏的颤音,原唱是平的一条线。

定位:只截长音那 1.6 秒,去掉整体滑音趋势后,统计半音尺度上的摆动。

版本 摆动 std p90 摆动主频
原音 0.04 半音 0.07 —
rmvpe 输出 1.43 半音 2.10 2.7Hz
crepe 输出 0.04 半音 0.10 —

结论:不是模型在抖,是 rmvpe 在 500Hz+ 的持续长音上把音高轨迹画歪了(差两三个半音)。

处理:推理加 --f0-method crepe,其余参数不动。

代价:8 秒段 8.2s → 10.2s,整首多不到一分钟。

验证口径:取长音段 → pyin 抽 f0 → 换半音 → 减线性趋势 → 算 std 与摆动主频。std > 0.5 半音就说明 f0 跟歪了。

成品:voice-samples\成品\08_使一颗心_深澜_crepe音高版.mp3

7. 常见问题(RVC)

Q:破音怎么办? A:先 check_range 看音域,超了降调(降 2–4 半音往往比补素材有效);再用 protect 0.33 + index-rate 0.5;最后才局部重推。

Q:长音发颤 / 像加了 vibrato? A:换 --f0-method crepe(见第 6 节)。

Q:整首发闷、高频少? A:素材本身 5kHz 以上能量低(195 条抽样中位 0.0059,只有前 10% 到 0.11),模型在如实学素材亮度。靠 EQ 硬提会出人机感,优先筛亮素材。

Q:声音发虚 / 气声多? A:素材侧去掉气声重、HNR 低的片段;推理侧降 protect、提 index-rate;后期轻压 + 一点 afftdn。

Q:听着像日语 / 不像中文? A:中文素材占比不够。加中文、砍日语重训。

Q:人机感重? A:多数是过度后期(EQ 提亮、强压缩、噪声门)叠出来的。回原声、少动。

Q:多快能出一版? A:说话模型 200 轮约 1 小时;20 轮探路版 25 分钟(100W 限功耗下)。

8. 待办(RVC 线)

  • [ ] 清洗后的 2677 条重训 48k,对比 深澜翻唱用_v2(是否值得换)
  • [ ] 按 5kHz 能量筛亮素材子集,验证「发闷」能不能从素材侧解决
  • [ ] 模型容量(当前宽 32 / 6 层)加宽是否带来实质提升,一次只改一个变量