Skip to content

物语系列 GPT-SoVITS 模型训练记录 ​

记录在做物语AI配音时候的工作流以及踩坑点

—— 来自未来的记录, 你好, 直接 Agent 自动化实现

那么下面大概记录一下自己怎么做的(最后炼化成了一个Skill)

数据集准备 ​

之前是自己听然后 AU 来切,之后切换成 Agent 代理, 最后自己审核一遍

首先捋清楚我们需要什么 —— 把一个长的音频片段切成比较短的片段,同时最好每一句都比较清晰,背景音小,最好一句话就是一句话. 这些是质量比较高的数据的自然语言描述.

我们人脑会帮我们做好非常复杂的计算 —— “听”一遍之后,就会觉得这个片段质量挺高,值得加入数据集. 那么如果我们要做自动化,最重要的是怎么量化“觉得这个片段质量挺高”这样的一个抽象概念呢?

那么我的方法 ——

切分音频 ​

我们拿到的数据是一段段的长音频, 要切成一个个小句子 —— 那么如何判断一句话的开始与结束? 如何判断句子与句子之间我们要切在什么时间戳的位置?

第一想到的字幕 —— 因为它对齐时间轴, 所以优先按照字幕来进行切割即可(不过依旧需要做相邻、同 Speaker 的 subtitle cues 合并之类的小操作).

不过我们依旧不能假定一定有字幕, 或是字幕的 timing 一定是正确的. 所以在没有可靠字幕时采取 ASR + VAD —— VAD 用于定位语音活动区间,ASR 提供文本以及 word-level timing,再结合 silence / word boundary 得到候选 Start / End。它们并不能直接证明“一句话已经完整结束”,所以后续还需要单独检查 boundary completeness.

多角色处理 ​

因为物语系列的副音轨一般是两个人的对话, 所以一个 Clip 可能会混杂着两个人的声音, 这明确是不妙的脏数据.

采取的检测方式是切分小的时间切片过一遍 Embedding 做是否是同一个 Speaker 的分析, 然后做余弦相似度计算 —— 如果两个切片差别非常大则判定为不是同一个人

背景音判断 ​

在背景音比较大的时候应该是脏数据, 此处这里设计的 pipeline 是对切片全局做一次背景音和人声分离,然后比较 dB 的大小, 此处要求人声要高过背景音 20dB (仅供参考)

同时也要求对当前的 Frame 做比较 —— 不单纯看全局 RMS 的是为了防止局部非常”过激“的爆鸣声.

当然,实际上 Skill 中记录的更复杂 ——

  • global vocal/background
  • active-frame p10
  • active-frame median
  • background/mix
  • close-background fraction

分类 ​

此处会结合上述提到的各种问题(以及其他没列出来的)分析,把模型没有检测出来问题的切片放进accepted_candidate文件夹,然后其他按照检测到的问题分进对应的文件夹中,等待人工检测

验证 ​

然后调用 Python 脚本来进行每个切片的 SHA-256 验证, 证明当前文件夹中的数据和自动化 Pipeline 中给出的 Report 中记录的数据是一致的.

同时验证文件名称“BakeMonigatari-06-863536-865636.wav”(类似这样的东西),上面的时间戳和 Agent 给出的 Report 报告是一致的(哦对了, Agent 在切好音频之后会写一份 JSON 报告,记录切的音频时间戳,存在什么问题等字段)

最后输出一个 review-list.json

json
{
  "item_id": "...",
  "automatic_status": "review",
  "reasons": [
    "background_too_loud"
  ],
  "speaker_folder": "...",
  "source_path": "...",
  "start_ms": 863536,
  "end_ms": 865636,
  "output_sha256": "...",
  "metrics": {}
}

里面记录的数组中的每一个元素类似这种

这样方便拓展 —— 比如做个什么前端展示 Tool 之类的

完整处理数据集和微调 ​

完全按照手册跑了, 不过像是物语这样的如果直接使用 stt 做成数据集中的文本文件,可能会遇到什么 neta / 谐音梗之类的识别不出来, 比较坏

Released under the MIT License.