用 SpeechBrain 在 VoiceBank 上训练音素级 CTC 声学模型(CRDNN 实战指南)
用 SpeechBrain 在 VoiceBank 上训练音素级 CTC 声学模型CRDNN 实战指南【免费下载链接】speechbrainA PyTorch-based Speech Toolkit项目地址: https://gitcode.com/GitHub_Trending/sp/speechbrain本篇技术指南围绕 SpeechBrain 仓库中的recipes/Voicebank/ASR/CTC配方展开系统讲解如何基于 VoiceBankNoisy-VCTK 语料训练一个以音素为建模单元、CTC 为训练准则的声学模型并配套完整的超参数配置、数据准备与训练脚本分析。读完本文后你将掌握从数据下载、JSON 标注生成、CRDNN 模型配置到--jit加速训练与 PERPhoneme Error Rate音素错误率评估的完整闭环可以直接在本仓库中复现并改造这一基线配方。一、配方概述音素 CTC 的 ASR 基线recipes/Voicebank/ASR/CTC是 SpeechBrain 中一个轻量而完整的 ASR 基线它使用 VoiceBank 数据集的干净语音训练一个 CTC 声学模型输出单元是音素phoneme而非字符因此最终的评估指标是音素错误率PER而非词错误率WER。该配方由三个核心文件组成文件作用voicebank_prepare.py数据集下载download_vctk、重采样、词表/音素词典构建与 train/valid/test JSON 标注生成prepare_voicebanktrain.py基于sb.Brain定义前向计算、CTC 损失、PER 统计与训练/验证/测试流程hparams/train.yaml全部超参数特征、模型结构VGG2 LiGRU DNN即 CRDNN、数据增强、优化器、调度器与 Checkpoint 策略VoiceBank 数据集本身是「含噪语音」语料Noisy-VCTK来自爱丁堡数据共享平台的 10283/2791 条目包含 28 位说话人的干净/噪声平行语音本配方默认用**干净波形clean_wav**训练音素识别模型但也允许通过一个开关直接切到噪声输入见后文input_type说明。二、数据准备download_vctk 与 prepare_voicebank2.1 一键下载与重采样download_vctkREADME 明确要求使用 voicebank_prepare.py 中的download_vctk()函数完成数据集的下载与重采样。该函数的核心行为如下从https://datashare.ed.ac.uk/bitstream/handle/10283/2791/依次下载 6 个 zip 包clean_testset_wav.zip、noisy_testset_wav.zip、testset_txt.zip、clean_trainset_28spk_wav.zip、noisy_trainset_28spk_wav.zip、trainset_28spk_txt.zip解压后统一重采样通过torchaudio.transforms.Resample(orig_freq48000, new_freq16000)将 48 kHz 原始音频降到 16 kHz输出目录名带_16k后缀最终打包为noisy-vctk-16k.zip并移动到destination。函数签名download_vctk(destination, tmp_dirNone, devicecpu)中的device参数会直接传给 PyTorch 的.to()用于控制重采样计算的运行设备。2.2 标注生成流程prepare_voicebankprepare_voicebank(data_folder, save_folder, valid_speaker_count2, skip_prepFalse)见 voicebank_prepare.py负责把原始音频整理成 SpeechBrain 训练所需的 JSON 标注主要步骤划分说话人训练集 28 位说话人定义在TRAIN_SPEAKERS列表中p226/p287/p227/…/p286前valid_speaker_count默认 2位被划出作为验证集剩余 26 位用于训练测试集使用独立的 testset构建音素词典create_lexicon()voicebank_prepare.py从http://www.openslr.org/resources/11/librispeech-lexicon.txt下载 LibriSpeech 词典并合并脚本内置的MISSING_LEXICON补充条目如 CRUCIALLY、MR、BBC 等 90 余个词条以覆盖 VoiceBank 文本中词典缺失的单词生成 JSONcreate_json()voicebank_prepare.py遍历 wav 列表为每个句子写入noisy_wav、clean_wav、length由read_audio读出的采样点数除以 16 kHz 计算、words、phones五个字段其中文本会先去除标点、转大写再查词典转成音素串并去除相邻重复音素CTC 训练中重复音素会被折叠提前去重有助于对齐稳定。三个输出文件train.json、valid.json、test.json默认写入训练输出目录其相对路径以{data_root}占位符开头运行时由DynamicItemDataset.from_json的replacements{data_root: hparams[data_folder]}替换。skip_prepTrue时整个准备阶段会被跳过已生成 JSON 时skip()函数也会自动识别并跳过这对在已有标注上反复调试训练参数非常有用。三、训练超参数详解hparams/train.yamltrain.yaml 是配方的「灵魂」全部训练行为都由它驱动。下面按模块逐一拆解。3.1 输入与路径配置seed: 1236 __set_seed: !apply:speechbrain.utils.seed_everything [!ref seed] input_type: clean_wav output_folder: !ref results/input_type/phn/seed per_file: !ref output_folder/per.txt save_folder: !ref output_folder/save data_folder: !PLACEHOLDER train_annotation: !ref output_folder/train.json valid_annotation: !ref output_folder/valid.json test_annotation: !ref output_folder/test.json skip_prep: Falseinput_type是关键开关它决定音频管线读取哪个字段。默认clean_wavtrain.py 顶部注释明确指出改成noisy_wav即可训练噪声语音输入。输出目录会随input_type自动区分results/clean_wav/phn/1236或results/noisy_wav/phn/1236data_folder用!PLACEHOLDER占位运行时通过命令行--data_folder...填充JSON 标注默认放在输出目录中由数据准备阶段生成。3.2 训练与特征参数number_of_epochs: 50 batch_size: 8 sorting: ascending lr: 0.5 max_grad_norm: 5.0 sample_rate: 16000 n_fft: 400 n_mels: 4050 个 epoch、batch size 8、学习率 0.5、梯度裁剪阈值 5.0sorting: ascending表示训练集按时长升序排序并配合dataloader_options.shuffle: False使用可显著提升同 batch 内序列长度的整齐度dataio_prep中对应实现见 train.py也可改为descending或random其他取值会直接抛出NotImplementedError特征为 40 维 FBankn_fft400n_mels4016 kHz 采样率下对应约 25 ms 窗长。3.3 模型结构VGG2 LiGRU DNNCRDNNactivation: !name:torch.nn.LeakyReLU dropout: 0.15 cnn_blocks: 2 cnn_channels: (128, 256) cnn_kernelsize: (3, 3) rnn_layers: 4 rnn_neurons: 512 rnn_bidirectional: True dnn_blocks: 2 dnn_neurons: 512 output_neurons: 42 blank_index: !ref output_neurons - 1模型使用 speechbrain/lobes/models/CRDNN.py 中的CRDNN类它是一个sb.nnet.containers.Sequential容器按顺序堆叠2 个 VGG 风格 CNN Block128、256 通道3×3 卷积核随后是一个时间轴最大池化time_pooling: TruePooling1d沿时间轴池化kernel 为 2有效压缩序列长度4 层 512 神经元双向 LiGRUrnn_classsb.nnet.RNN.LiGRU这是 SpeechBrain 自研的轻量门控循环单元2 层 512 神经元 DNN。输出侧是speechbrain.nnet.linear.Linear42 个输出神经元加 log-Softmax。output_neurons: 42对应「40 个音素 blank 未知符号」的编码规模blank_index 42 - 1 41作为 CTC 的 blank 标签索引直接传给 speechbrain/nnet/losses.py 中的ctc_loss。3.4 波形域数据增强与许多先提特征再在特征域增强的做法不同本配方在波形域做增强speechbrain.augment.time_domain由Augmenter统一调度speed_perturb: !new:speechbrain.augment.time_domain.SpeedPerturb orig_freq: !ref sample_rate speeds: [95, 100, 105] drop_freq: !new:speechbrain.augment.time_domain.DropFreq drop_freq_low: 0 drop_freq_high: 1 drop_freq_count_low: 1 drop_freq_count_high: 3 drop_freq_width: 0.05 drop_chunk: !new:speechbrain.augment.time_domain.DropChunk drop_length_low: 1000 drop_length_high: 2000 drop_count_low: 1 drop_count_high: 5 wav_augment: !new:speechbrain.augment.augmenter.Augmenter concat_original: True min_augmentations: 3 max_augmentations: 3 augment_prob: 1.0 augmentations: [speed_perturb, drop_freq, drop_chunk]速度扰动以 95%/100%/105% 三档速度重采样模拟语速变化频率丢弃随机把 0~1 归一化频率区间中的若干频带置零1~3 个频带宽度 0.05时间块丢弃随机抹掉若干段 1000~2000 采样点的时域片段1~5 段concat_original: True意味着每 batch 会拼接原始样本增强样本与原始样本各占一半因为波形被改动音素标签必须同步做标签复制这正是 train.py 中replicate_labels的作用。3.5 优化器、调度器与 Checkpointopt_class: !name:torch.optim.Adadelta lr: !ref lr rho: 0.95 eps: 1.e-8 lr_annealing: !new:speechbrain.nnet.schedulers.NewBobScheduler initial_value: !ref lr improvement_threshold: 0.0025 annealing_factor: 0.8 patient: 0优化器为Adadeltalr0.5rho0.95该优化器自带自适应学习率适合 CTC 这类收敛较慢的任务调度器为NewBob验证集 PER 提升不足 0.0025 时学习率乘以 0.8 退火patient: 0表示立即退火不等待Checkpointer 会把model、output、epoch_counter、scheduler、normalizer都注册为可恢复对象并按验证 PER 最小的原则保存见 train.py 的save_and_keep_only(meta{PER: per}, min_keys[PER])。3.6 损失、统计与日志compute_cost: !name:speechbrain.nnet.losses.ctc_loss blank_index: !ref blank_index ctc_stats: !name:speechbrain.utils.metric_stats.MetricStats metric: !name:speechbrain.nnet.losses.ctc_loss blank_index: !ref blank_index reduction: batch per_stats: !name:speechbrain.utils.metric_stats.ErrorRateStats训练损失compute_cost即ctc_lossblank_index41ctc_stats以 batch 粒度 reduction 记录每个 batch 的 CTC 损失便于最终输出逐条统计per_stats使用ErrorRateStats统计音素错误率其输入来自验证/测试阶段的 CTC 贪心解码结果。四、训练脚本源码剖析train.py4.1 ASR_Brain 的前向与损失train.py 中定义了ASR_Brain(sb.Brain)compute_forward读取波形 →训练阶段可选波形增强 →Fbank提特征 →InputNormalization全局归一化→ CRDNN 模型 → 线性输出层 → log-Softmax返回音素概率pout与长度wav_lenscompute_objectives调用ctc_loss(pout, phns, pout_lens, phn_lens)计算损失并追加到ctc_metrics在验证/测试阶段还会用 speechbrain/decoders/ctc.py 的ctc_greedy_decodeblank_id41做 CTC 贪心解码再交给per_metrics计算 PERon_stage_end验证阶段根据 PER 触发 NewBob 退火并保存最优 checkpoint测试阶段把 CTC 损失与 PER 统计写入per.txt由per_file指定。4.2 数据管线与标签编码dataio_preptrain.py负责构建三个DynamicItemDataset音频管线takes(hparams[input_type])动态决定读取clean_wav还是noisy_wavread_audio后产出sig文本管线把phones字符串按空格拆成音素列表phn_list再用CTCTextEncoderspeechbrain/dataio/encoder.py支持 CTC blank 特殊符号编码为phn_encoded通过label_encoder.load_or_create(path..., from_didatasets[data[train]], output_keyphn_list, special_labels{blank_label: 41}, sequence_inputTrue)在训练集上拟合标签编码器结果缓存为save/label_encoder.txt训练集长度排序逻辑也在此完成。4.3 主流程主流程train.py依次执行sb.parse_arguments解析超参文件与命令行覆盖 →ddp_init_group初始化多卡 DDP →sb.create_experiment_directory创建实验目录 →run_on_main(prepare_voicebank, ...)在单进程上完成数据准备 →dataio_prep建数据集 → 若 hparams 中含pretrained字段则加载预训练权重 → 构造ASR_Brain并fit50 个 epoch训练/验证共用dataloader_options→ 最后evaluate加载验证集上 PER 最低的 checkpoint 在测试集上评测。五、如何运行5.1 标准训练命令按照 README 中的说明在recipes/Voicebank/ASR/CTC目录下执行python train.py hparams/train.yaml --data_folderyour/data/folder --jit其中your/data/folder是download_vctk()产出的数据集根目录包含clean_trainset_28spk_wav_16k、noisy_trainset_28spk_wav_16k等子目录。首次运行时prepare_voicebank会生成 train/valid/test 三个 JSON若已准备过可加--skip_prepTrue直接进入训练。5.2 关于 JIT 编译加速重要README 特别强调了--jit参数启用即时编译JIT可带来50%–60% 的提速官方强烈推荐开启。需要说明的前提是该速度提升是在使用CRDNN 模型时观察到的本配方在 train.yaml 中通过jit_module_keys: [model]显式指定仅对 CRDNN 模型做 JIT 编译而不是盲目编译全部模块。对应机制见 speechbrain/core.py当--jit与jit_module_keys同时存在时只编译列出的模块未列出的模块不会被编译。5.3 常用命令行覆盖与变体切换噪声输入把train.yaml中input_type改为noisy_wav输出目录自动变为results/noisy_wav/phn/seed命令行覆盖超参SpeechBrain 的 hyperpyyaml 机制支持追加--number_of_epochs2 --batch_size16之类的覆盖项无需改动 yaml加载预训练模型继续训练在 yaml 中取消# pretrained: model_clean_ep3.ckpt注释并填入 checkpoint 路径train.py会将其 state_dict 载入模型见 train.py。六、结果与训练开销README 给出的官方基线结果如下VoiceBank 干净语音、音素级 CTC、CRDNN 模型发布版本超参文件输入类型测试集 PER模型下载训练硬件21-02-09train.yamlclean_wav10.12%未提供1×V100 32GB训练开销方面在单张 TESLA V100 上每个 epoch 约 4 分钟50 个 epoch 的完整训练约 3 小时量级。训练日志与 checkpoint 输出在results/clean_wav/phn/1236/下其中save/存放可恢复对象与label_encoder.txtper.txt存放测试阶段逐条 CTC 损失与 PER 统计。七、工程验证配方测试与复现要点该配方被纳入 SpeechBrain 的 recipes 测试矩阵见 tests/recipes/Voicebank.csv 中的 ASR 行测试脚本使用--data_foldertests/samples/separation --train_annotation... --skip_prepTrue --output_neurons18 --number_of_epochs2在迷你样例上做冒烟验证并检查train_log.txt、per.txt、save/label_encoder.txt等产物是否生成同时记录了Test-PER10.12%作为该配方的性能基线。这意味着你可以用同样的覆盖参数快速验证代码路径是否完好python train.py hparams/train.yaml \ --data_folder../../../../tests/samples/separation \ --train_annotation../../../../tests/samples/annotation/enhance_train.json \ --valid_annotation../../../../tests/samples/annotation/enhance_dev.json \ --test_annotation../../../../tests/samples/annotation/enhance_dev.json \ --skip_prepTrue --output_neurons18 --number_of_epochs2注上例中标注文件与output_neurons均为测试专用的简化值完整训练请使用官方 42 音素配置。八、小结与扩展方向recipes/Voicebank/ASR/CTC是一个麻雀虽小、五脏俱全的 CTC-ASR 基线从download_vctk的数据落盘、create_lexicon的词典构建、create_json的音素化标注到ASR_Brain的波形增强 FBank CRDNN CTC 损失闭环再到--jit编译加速与 NewBob 调度、PER 最优 checkpoint 选择覆盖了 SpeechBrain 配方开发的完整套路。如果希望进一步延伸可以在本仓库中对比参照recipes/Voicebank/MTL/ASR_enhance在 VoiceBank 上做「增强 识别」多任务学习使用噪声输入与noisy_sig/clean_sig双通道管线speechbrain/decoders/ctc.pyCTCLanguageModel 与更丰富的 CTC 解码工具speechbrain/lobes/models/CRDNN.pyCRDNN 各组件CNN_Block、时间池化、LiGRU、DNN的详细参数说明。在复现或改造本配方时请注意结果表中的 10.12% PER 是在clean_wav输入、42 音素标签、上述完整增强与调度配置下的官方基线切换到noisy_wav或修改模型规模、增强策略后指标会随之变化应以自己的实验日志为准。引用说明若在研究中引用本配方或 SpeechBrain建议参照 recipes/Voicebank/ASR/CTC/README.md 末尾给出的两篇 BibTeX 条目SpeechBrain 1.0 论文与 SpeechBrain 原始论文按学术规范标注。【免费下载链接】speechbrainA PyTorch-based Speech Toolkit项目地址: https://gitcode.com/GitHub_Trending/sp/speechbrain创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考