基于Kaldi x-vector的说话人分割:自定义数据训练与应用问询
刚好我之前折腾过用自有数据训Kaldi x-vector做说话人分割,给你捋一遍完整流程,毕竟SRE16的默认脚本绑死了LDC语料,咱们得做些适配调整:
Kaldi对数据目录的结构有固定要求,你得在egs/sre16/v2/data下新建一个自己的数据集目录(比如my_train),里面必须包含三个核心文件:
wav.scp:每行是[utterance-id] [音频文件绝对路径],比如utt_001 /home/data/audio/001.wavutt2spk:每行是[utterance-id] [speaker-id],用来关联语音段和说话人,比如utt_001 spk_001spk2utt:是utt2spk的反向映射,每行是[speaker-id] [该说话人的所有utterance-id],可以用命令自动生成:utils/utt2spk_to_spk2utt.pl data/my_train/utt2spk > data/my_train/spk2utt
另外注意:音频最好转成16kHz单声道,如果不是的话用sox批量转换:
sox input.wav -r 16000 -c 1 output.wav
找到egs/sre16/v2/run.sh主脚本,你需要做这些关键修改:
- 替换数据路径:把脚本里所有指向LDC语料的路径(比如
data/sre16_train)改成你自己的data/my_train - 跳过LDC专属步骤:注释掉脚本里下载、解压LDC数据的代码块
- 保留特征配置:x-vector默认用MFCC+CMVN+delta特征,这部分的
steps/make_mfcc.sh和steps/compute_cmvn_stats.sh逻辑可以直接复用
改完脚本就可以启动训练了,核心步骤如下:
- 先检查数据目录合法性,避免后续报错:
utils/validate_data_dir.sh data/my_train
如果提示错误,按照要求修正(比如重复的utterance-id、缺失的音频文件等)
2. 提取音频特征:
steps/make_mfcc.sh --nj 4 data/my_train exp/make_mfcc/my_train mfcc steps/compute_cmvn_stats.sh data/my_train exp/make_mfcc/my_train mfcc
--nj是并行任务数,根据你的CPU核心数调整
3. 训练TDNN结构的x-vector模型:
直接运行run.sh里的nnet3训练模块,或者单独执行local/nnet3/xvector/tuning/run_xvector_1a.sh。训练完成后,模型会保存在exp/xvector_nnet_1a/目录下,final.raw就是最终的模型文件。
小提示:如果你的自有数据规模较小(比如不足100个说话人),可以修改
local/nnet3/xvector/xvector.conf里的模型结构,比如减少TDNN层数或隐藏单元数,避免过拟合
SRE16示例里自带说话人分割脚本local/diarization/run_diarization.sh,你需要做这些调整:
- 替换模型路径:确保脚本里的模型路径指向你自己训练的
exp/xvector_nnet_1a/ - 准备待分割音频:在
data目录下新建my_test目录,只需要生成wav.scp(不需要utt2spk和spk2utt) - 启动分割流程:
local/diarization/run_diarization.sh --nj 4 data/my_test exp/xvector_nnet_1a exp/diarization_my_test
分割结果会存在exp/diarization_my_test/rttm/目录下,RTTM格式文件可以用工具查看每个说话人的时间区间
- 数据规模是关键:x-vector是数据驱动模型,至少要有几百个说话人,每个说话人10条以上语音段,否则模型泛化性极差
- 数据多样性很重要:尽量包含不同场景(安静/嘈杂)、不同口音的音频,提升模型鲁棒性
- 调参优化:如果分割效果不好,可以调整VAD阈值(在
sid/compute_vad_decision.sh中)、聚类相似度阈值,或者给训练数据加噪声、语速变换等增强操作
内容的提问来源于stack exchange,提问作者humble_wolf

