40 段音频查出 16 处毛病,落在 12 段(30%)上:采样率不统一 4、时长过短 4、 削波/整段静音/直流偏置/双声道各 2。六项检查、二十行代码、两秒钟——比训废一轮便宜太多。
上一节把模型信息填对了。这一节上传素材、开训。但上传前那一步质检,是这一整章最划算的动作。
一、上传前必跑的六项
音频的问题和图片不一样:图片看一眼就知道坏没坏,音频必须算。六项检查覆盖了绝大多数事故:
| 问题 | 怎么判 | 不改会怎样 |
|---|---|---|
| 采样率不统一 | 文件头里的采样率 | 被当成「慢半拍」 |
| 双声道 | 声道数不等于 1 | 有的脚本只取一路 |
| 时长过短 | 时长小于 3 秒 | 学不到完整音素 |
| 整段静音 | RMS 低于 1e-3 | 拉低均值,白耗算力 |
| 削波 | 超 0.99 的点超过 1% | 波形削平,信息丢了 |
| 直流偏置 | 均值绝对值超 0.05 | 开头一声闷响 |
| 前两项读文件头就知道,后四项要真读波形算。好在都是几行 numpy 的事。 | ||
| 这六项里只有「削波」是不可修的—— | ||
| 削掉的波峰补不回来,只能重录或把音量调低重录。其余五项都能用脚本批量修。 |
二、处与段:又是两个口径
Demo 里 40 段查出 16 处,但只落在 12 段上。因为一段可能同时踩两个毛病。 报数的时候要说清是哪一个: 「16 处」说的是数据集有多脏,「12 段」说的是我要处理多少个文件。这两个数在排工时的时候差得远。 注意「时长过短」那 4 段没有被算进「要返工」里—— 它不是不能修,是修不了:1.2 秒的片段补不出后面的话。只能删掉或者重录。 所以质检输出最好分三档: 能自动修的(采样率、声道、直流、静音)、必须人工的(削波、过短)、直接删的(空文件、 纯噪声)。分好档,返工才不会乱。
三、训练的四个参数
素材传上去之后,通常只有四个参数可调:轮数、batch、学习率、以及「留多少做验证」。 轮数:音色模型一般 10 到 30 轮。 少了音色不像,多了会把素材背下来(表现为「只会念素材里的句子,换一句就崩」)。 batch:显存够就大一点,训练更稳。 但它和轮数是联动的——batch 翻倍,同样轮数下步数减半,等效训练量变小。 学习率:默认值通常就能用。 要改的话先改轮数,别先动学习率——学习率出问题的表现是「训崩」,轮数出问题的表现是「不够像」, 后者更好判断。 验证集:留 10% 不参与训练,用它听效果。 这一步很多人省掉,结果就是「训练集听着完美,换个句子全崩」——那就是过拟合, 而你没有验证集就发现不了。
四、训完之后怎么判断好坏
平台会给一个 loss 曲线。 但声音这件事,loss 低不等于好听。loss 只保证「重建得像素材」,不保证「换句话也自然」。 所以验收要靠听,而且要用训练集里没有的句子去听。四句话就能听出大部分问题: ① 一句常用语(听音色像不像);② 一句长句(听尾音散不散); ③ 一句带数字和英文的(听会不会卡住);④ 一句带情绪的(听语调有没有起伏)。 四句里有一句明显不对, 就回去看数据——八成是某几段素材的采样率或音量不一致,模型在「两个音色」之间摇摆。
五、动手 Demo:音频质检:40 段查出 16 处,12 段要返工
用 numpy 造 40 段「嗓音」写成 wav,故意混进六类问题:采样率 22050 混在 44100 里、时长 1.2 秒、 整段静音、峰值削波、直流偏置、双声道。 逐段读文件头和波形,算 RMS、峰值、削波比例、直流分量, 统计每类问题的段数并分离出「必须返工」的那一批。
with wave.open(p, "rb") as w:
ch, sr, nf = w.getnchannels(), w.getframerate(), w.getnframes()
raw = w.readframes(nf)
x = np.frombuffer(raw, dtype="<i2").astype(np.float32) / 32768.0
rms = float(np.sqrt(np.mean(x ** 2)))
clip = float(np.mean(np.abs(x) > 0.99))
dc = float(np.mean(x))
sec = nf / float(sr)
if sr != 44100: tags.append(u"采样率不统一")
if ch != 1: tags.append(u"双声道")
if sec < 3.0: tags.append(u"时长过短")
if rms < 1e-3: tags.append(u"整段静音")
if clip > 0.01: tags.append(u"削波")
if abs(dc) > 0.05: tags.append(u"直流偏置")
实跑输出:
--------------------------------------------------------------------
音频质检:40 段查出 16 处,12 段要返工
--------------------------------------------------------------------
音频段数 40 段
总时长 2.5 分钟
问题类型 段数
------------------
采样率不统一 4
时长过短 4
削波 2
整段静音 2
直流偏置 2
双声道 2
要返工的段 12 段(30%)
一共 **16 处**毛病,落在 **12 段**上——**又是「处」和「张」两个口径。**
「采样率不统一」是**最容易被忽略**的一类:文件都能播。
但训练脚本按 44.1 kHz 读,22050 的那四段会被当成「慢半拍」。
「削波」看的是超过 0.99 的采样点比例。**波形削平了就是信息丢了,补不回来**——只能重录或调低音量。
「直流偏置」听不出来,但会让波形整体偏离零点,
**特征是开头有一声闷响。** 减掉均值就能修。
「整段静音」两段是故意的:真实素材里常有人把「没说话的时间」也导进来了。
所以上传前该跑的检查就六项:
**采样率、声道、时长、RMS、削波比例、直流偏置。**
二十行代码,跑一遍不到两秒。
done -> _out_39l.txt
表里六行很整齐:采样率不统一 4、时长过短 4,其余四项各 2。这是造数据时埋的,
不是真实分布——真素材里「采样率不统一」通常最多。
第二行是「要返工的段」:12 段(30%)。注意它把「时长过短」排除了,
因为 1.2 秒的片段修不出来,只能删。
「削波」判据是 |x| > 0.99 的采样点占比超过 1%。
这个阈值不能定成「等于 1.0」——浮点转 int16 时 0.999 也会被截到 32767,用等号会漏一半。
「直流偏置」这一项最容易被忽略:它听起来「没什么不对」,但每次起音会有一声闷响,
而且会让训练时的归一化偏掉。
说明:这 40 段是我用正弦加噪声造的,不是真人声。但判据全是真判——采样率、声道、时长读文件头;
RMS、削波、直流算波形。换成真素材,代码一行不用改。
30 秒实验
- 把时长阈值从 3 秒改成 5 秒,看「时长过短」涨到几段。 阈值越严,要重录的越多——所以这个数要和录音成本一起定。
- 把削波阈值从 0.99 改成 0.9,看那行涨到几段。 0.9 会开始误伤正常的高音量素材——阈值只能贴着 1.0 定。
- 给「整段静音」那两段加上 -60 dBFS 的底噪,再看检查结果。 它们会从「静音」变成「通过」——但依然没有训练价值。
常见误区
- 「文件能播就行」。采样率不统一、直流偏置这些问题,播放器会自动纠正,训练脚本不会。
- 「削波调一下增益就好」。削掉的波峰补不回来,只能重录或降音量重录。
- 「不留验证集,看 loss 就行」。loss 低只说明「重建得像素材」,不说明换句话也自然。
自测三问(点开对答案)
1. 上传前要跑哪六项检查? —— 采样率、声道、时长、RMS、削波比例、直流偏置。前两项读文件头,后四项算波形。 2. 六项里哪一项不能自动修? —— 削波。波峰被削平就是信息丢了,只能重录或降低录音音量重录。 3. 为什么一定要留验证集? —— 因为过拟合的表现是「训练集听着完美,换句子就崩」。不留验证集,你发现不了这件事。模型训完,接下来是玩它:让克隆出来的声音去唱歌。 而这一步的第一个问题不是技术,是音高能不能对上。
- ☐ (本节完,下一节 8.2.1 克隆声音唱歌)