物语系列 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
{
"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 / 谐音梗之类的识别不出来, 比较坏