SpeechBrain 语音增强实战:基于 WHAM!/WHAMR! 数据集的 SepFormer 训练与评估指南
【免费下载链接】speechbrainA PyTorch-based Speech Toolkit项目地址: https://gitcode.com/GitHub_Trending/sp/speechbrain
SpeechBrain 在 recipes/WHAMandWHAMR/enhancement 目录下提供了一套完整的**单通道语音增强(speech enhancement)**训练配方,覆盖 WHAM!(带噪)与 WHAMR!(带噪 + 混响)两个经典数据集。本指南以该 recipe 的 README 为骨架,结合仓库内的 train.py、prepare_data.py、dynamic_mixing.py 等源码,完整讲解环境安装、数据准备、模型选择、动态混合训练、测试评估与预训练模型使用。读完本文,你将能够在自己的 WHAM!/WHAMR! 数据上完整复现 SepFormer 语音增强训练流程,并理解其背后的数据管线与训练机制。
数据集与任务概览
WHAM!(WSJ0 Hipster Ambient Mixtures)与 WHAMR!(增加混响的版本)是基于 WSJ0-2/3 Mix 生成的带噪、带混响数据集。二者的区别在于:
- WHAM!:混合语音叠加真实环境噪声(来自咖啡馆、酒吧、餐馆、地铁等场景),
data_folder指向名为wham_original的顶层目录; - WHAMR!:在 WHAM! 基础上额外叠加房间混响(RIR),
data_folder指向名为whamr的顶层目录。
在**语音增强(enhancement)**任务下,num_spks设为 1,目标是从单通道混合信号mix中恢复干净语音s1,同时抑制噪声(及混响);而 separation 配方则将num_spks设为 2,目标是分离出多路说话人。两者的核心训练脚本结构相同,仅数据管线与目标数不同。
该 recipe 的 README 明确说明支持以下模型架构:
- SepFormer(Attention is All You Need in Speech Separation, ICASSP 2021)
- DPRNN(Dual-Path RNN)
- ConvTasnet
- DPTNet
从 hparams 目录 的配置文件看,仓库实际还提供了更多变体:cnntransformer-wham-DM.yaml、cnntransformer-whamr-DM.yaml、convtasnet-whamr-DM.yaml、dprnn-whamr-DM.yaml,以及hparams/models/下的2DFCN+BLSTM.yaml、2DFCN.yaml、BLSTM.yaml、CNNTransformer.yaml等子模型配置。由于实验脚本(train.py)通过 HyperPyYAML 动态加载网络结构,只需更换 YAML 中的Encoder / MaskNet / Decoder定义,即可切换到不同架构。
安装额外依赖
运行本 recipe 前,除 SpeechBrain 基础依赖外,还需安装两个额外包(定义在 extra_requirements.txt):
mir-eval==0.6 pyroomacoustics>=0.7.3mir_eval:用于测试阶段计算 SDR / SDRi(bss_eval_sources);pyroomacoustics:用于 WHAMR! 的 RIR 生成与混响仿真。
安装命令(README 原文):
pip install -r ../extra_requirements.txt注意该相对路径是相对于 enhancement 目录的,即仓库中的 recipes/WHAMandWHAMR/extra_requirements.txt。
快速开始:训练与测试
标准训练
进入 enhancement 目录后,直接运行:
python train.py hparams/sepformer-wham.yaml --data_folder yourpath/wham_original python train.py hparams/sepformer-whamr.yaml --data_folder yourpath/whamr训练过程中,日志打印的 loss 是负 SI-SNR(该 recipe 将负 SI-SNR 直接作为损失函数值),因此 loss 越小越好。
仅测试
若已训练好或已加载预训练模型,只想在测试集上跑评估,追加--test_only标志:
python train.py hparams/sepformer-wham.yaml --data_folder yourpath/wham_original --test_only python train.py hparams/sepformer-whamr.yaml --data_folder yourpath/whamr --test_only--test_only是 SpeechBrainBrain类提供的标准运行选项之一,配合--epoch_counter(或直接加载 checkpoint)即可跳过训练阶段直接评估。
数据集目录约定与自动识别机制
README 强调了一个关键约定:顶层文件夹的命名决定数据集类型。
- WHAM! 数据集顶层目录必须命名为
wham_original(内含wav8k子文件夹); - WHAMR! 数据集顶层目录必须命名为
whamr。
脚本通过--data_folder参数中的路径字符串自动区分两者。这一逻辑在 prepare_data.py 中体现:
if "wham_original" in datapath: create_wham_whamr_csv(datapath, savepath, fs, savename="whamorg_", add_reverb=False, task=task) elif "whamr" in datapath: create_wham_whamr_csv(datapath, savepath, fs, add_reverb=True, task=task) else: raise ValueError("Unsupported Dataset")create_wham_whamr_csv会扫描wav{8k|16k}/{min|max}/{tr,cv,tt}/下的mix_single(enhancement 任务用)或mix_both(separation 任务用)、s1/、s2/、noise/等目录,生成 SpeechBrain 数据加载所需的 CSV 文件(whamorg_tr.csv/whamr_tr.csv等,保存于output_folder/save)。同时它也支持--sample_rate 16000(对应wav16k)与--version max等参数。
关键运行参数(命令行覆盖)
train.py通过sb.parse_arguments解析命令行参数,并允许以--key value方式覆盖 YAML 中的任意配置项。常用覆盖项:
| 参数 | 默认值(sepformer-wham.yaml) | 说明 |
|---|---|---|
--data_folder | /yourpath/wham_original | 数据集根目录(命名需遵循约定) |
--base_folder_dm | /yourpath/wsj0-processed/si_tr_s/ | 动态混合所需的 WSJ0 训练集路径 |
--rir_path | 占位符(WHAMR! 必填) | RIR 目录,不存在时自动生成 |
--dynamic_mixing | True(WHAM!)/False(WHAMR! 基础版) | 是否启用动态混合 |
--test_only | False | 仅运行测试评估 |
--sample_rate | 8000 | 采样率(另有 16k 配置) |
--skip_prep | False | 跳过 CSV 准备 |
混响增强(RIR)与 WHAMR! 支持
WHAMR! 的训练会自动使用数据集自带的房间冲激响应(Room Impulse Responses, RIR)做数据增强。相关逻辑位于 train.py:
if "whamr" in hparams["data_folder"] and hparams["use_speedperturb"]: from create_whamr_rirs import create_rirs from prepare_data import create_whamr_rir_csv if not os.path.exists(hparams["rir_path"]): print("Creating Room Impulse Responses...") run_on_main(create_rirs, kwargs={"output_dir": hparams["rir_path"], "sr": hparams["sample_rate"]}) run_on_main(create_whamr_rir_csv, kwargs={...}) hparams["reverb"] = sb.processing.speech_augmentation.AddReverb(...)要点:
- RIR 目录可自动创建:若
--rir_path指定的目录不存在,create_whamr_rirs.py会自动从 Hugging Face 元数据(speechbrain/sepformer-whamr)拉取 WHAMR! 官方 RIR 生成脚本所需的参数表,基于wham_room.py中的WhamRoom类生成 RIR 波形(参见 create_whamr_rirs.py); - 手动生成:也可以直接运行
../meta/create_whamr_rirs.py(即 recipes/WHAMandWHAMR/meta/create_whamr_rirs.py)预先准备好 RIR 数据; - 去混响目标:WHAMR! 配置中
dereverberate: True表示训练目标为无混响的干净语音(anechoic);在训练前向阶段(train.py),若dereverberate=False,则把混响后的语音作为目标,混合信号则由混响目标求和得到。
动态混合(Dynamic Mixing)
README 特别强调:本 recipe 支持动态混合——在训练过程中实时构造新的混合音频,从而获得无穷多种说话人组合,显著提升数据多样性。
前置条件
需要准备WSJ0数据集(LDC 目录编号 LDC93S6A),并提供一个指向其训练集si_tr_s的路径--base_folder_dm。脚本会自动完成以下工作:
- 采样率转换:若 WSJ0 目录尚未转换为目标采样率(8k 或 16k),会调用
preprocess_dynamic_mixing.py中的resample_folder,利用scipy.signal.resample_poly递归重采样并归一化峰值,生成base_folder_dm + "_processed"(8k)或"_processed_16k"(16k)目录(见 train.py); - 构建说话人哈希表:
build_spk_hashtable遍历 WSJ0 所有 wav 文件,按说话人 ID(文件名前 3 个字符)分组,并统计每个说话人的样本数作为采样权重(见 dynamic_mixing.py); - 实时合成:
audio_pipeline按权重随机选取说话人与话语,以随机偏移截取等长片段,按 WHAM! 的统计规律施加随机增益(第一个源 ~N(-27.43, 2.57) dB,第二个源相对第一个偏移 ~N(-2.51, 2.66) dB,均截断到 [-45, 0] dB),叠加 WHAM! 噪声后整体缩放防止削波(见 dynamic_mixing.py)。
启用动态混合后,训练集使用torch.utils.data.DataLoader(collate_fn=PaddedBatch),每个 worker 独立设置随机种子以保证可复现性。
模型架构与超参数详解
以 sepformer-wham.yaml 为例,网络由 Encoder、MaskNet(Dual-Path 模型)与 Decoder 三部分组成:
| 组件 | 类 | 关键参数 | 说明 |
|---|---|---|---|
| Encoder | speechbrain.lobes.models.dual_path.Encoder | kernel_size: 16,out_channels: 256 | 1D 卷积编码器,将波形映射为特征 |
| MaskNet | speechbrain.lobes.models.dual_path.Dual_Path_Model | num_spks: 1,K: 250,num_layers: 2,norm: ln | 双路径模型,预测掩码 |
| SBtfintra / SBtfinter | SBTransformerBlock | num_layers: 8,nhead: 8,d_ffn: 1024 | 段内 / 段间 Transformer |
| Decoder | speechbrain.lobes.models.dual_path.Decoder | kernel_size: 16,stride: 8,out_channels: 1 | 1D 卷积解码器,重构波形 |
其他核心训练超参数:
- 优化器:Adam,
lr: 0.00015,weight_decay: 0; - 损失:
speechbrain.nnet.losses.get_si_snr_with_pitwrapper(带 PIT 包装的 SI-SNR,增强任务中 PIT 退化为普通 SI-SNR); - 学习率调度:
ReduceLROnPlateau,factor: 0.5,patience: 2;WHAM! 配置从第 65 epoch 起才允许衰减,WHAMR! 为第 85 epoch(dont_halve_until_epoch); - 混合精度:
precision: fp16(WHAM! / WHAMR! 基础版),部分配置如convtasnet-whamr-DM.yaml使用fp32; - 数据增强:
use_speedperturb: True(速度扰动,speed_changes: [95, 100, 105])、use_rand_shift: False、use_wavedrop: False,以及可选的DropFreq/DropChunk参数块; - loss 阈值:
threshold_byloss: True、threshold: -30,用于过滤过难的训练样本; - 梯度裁剪:
clip_grad_norm: 5;epoch 数:N_epochs: 200。
WHAMR! 的 sepformer-whamr.yaml 与 WHAM! 版本的主要差异是:dereverberate: True、dynamic_mixing: False、save_audio: True(并保存前 20 条测试音频,n_audio_to_save: 20)、学习率调度起点为 85。16k 版本 sepformer-whamr-16k.yaml 则启用limit_training_signal_len: True,将训练序列截断到 64000 个采样点。
训练与评估流程源码解析
train.py 定义了继承自sb.Brain的Separation类,核心环节如下:
前向与损失(compute_forward / compute_objectives)
mix_w = self.hparams.Encoder(mix) est_mask = self.modules.masknet(mix_w) mix_w = torch.stack([mix_w] * self.hparams.num_spks) sep_h = mix_w * est_mask est_source = torch.cat([self.hparams.Decoder(sep_h[i]).unsqueeze(-1) for i in range(self.hparams.num_spks)], dim=-1)流程为:Encoder 提取特征 → MaskNet 预测掩码 → 特征与掩码逐元素相乘 → Decoder 重构波形。由于 1D 卷积会改变时间维长度,代码会用 padding 或裁剪将est_source恢复为原始mix长度(train.py)。
compute_objectives中,时域模型直接对targets与predicted_wavs计算 SI-SNR 损失;若配置为频域模型(use_freq_domain: True,如 2DFCN 系列),则先经compute_feats(spectral_magnitude(power=0.5)+log1p)得到幅度谱,再计算谱域损失。
训练批处理
fit_batch中实现了两处实用技巧(train.py):
- loss 硬阈值:当
threshold_byloss=True时,只对 loss 高于threshold(默认 -30)的样本求均值,过滤过简单样本; - 非有限 loss 保护:若 batch 的 loss 为无穷大或为空,则跳过该 batch 并计数(
nonfinite_count),避免训练崩溃。
评估与指标
验证 / 测试阶段(evaluate_batch、on_stage_start)会计算并记录:
- SI-SNR(作为 loss);
- PESQ:通过
pesq库计算,16k 采样率用宽带(wb)模式,8k 用窄带(nb)模式; - checkpoint 按验证集 PESQ 保存最优(
save_and_keep_only(meta={"pesq": ...}, max_keys=["pesq"]))。
测试结束后,save_results会额外调用mir_eval.separation.bss_eval_sources计算SDR / SDRi,并将逐条结果与平均值写入output_folder/test_results.csv(列:snt_id, sdr, sdr_i, si-snr, si-snr_i, pesq)。若save_audio: True,还会把混合音、干净目标与估计源保存为save_folder/audio_results/item{id}_{mix,source,sourcehat}.wav。
复现结果
该 recipe 的 README 给出了 SepFormer 在 WHAM! / WHAMR! 测试集上的官方复现结果(动态混合训练):
| SepFormer, WHAM! | SI-SNR | PESQ |
|---|---|---|
| Dynamic Mixing | 14.4 | 3.05 |
| SepFormer, WHAMR! | SI-SNR | PESQ |
|---|---|---|
| Dynamic Mixing | 10.6 | 2.84 |
训练时间:在 NVIDIA V100(32GB)上,WHAMR!(动态混合)与 WHAM! 均约需2 小时 30 分钟。
预训练模型
README 提供了可直接使用的预训练模型(托管于 Hugging Face,模型卡名称如下,可结合 SpeechBrain 的from_pretrained接口加载):
speechbrain/sepformer-wham-enhancement(WHAM! 增强)speechbrain/sepformer-whamr-enhancement(WHAMR! 增强)speechbrain/sepformer-whamr16k(16 kHz 版 WHAMR!)
此外,训练日志与 checkpoints 的备份亦可从 README 提供的 Dropbox 链接获取。加载预训练模型有两种途径:一是在 YAML 中配置pretrained_separator(train.py 检测到该键时自动下载并加载权重);二是直接使用 SpeechBrain 推理接口(参考 inference 目录下的增强 / 分离接口)。
命令速查表
| 场景 | 命令 |
|---|---|
| WHAMR! 动态混合训练 | python train.py hparams/sepformer-whamr.yaml --data_folder yourpath/whamr --base_folder_dm yourpath/wsj0-processed/si_tr_s --rir_path yourpath/rir_wavs --dynamic_mixing True |
| WHAM! 动态混合训练 | python train.py hparams/sepformer-wham.yaml --data_folder yourpath/wham_original --base_folder_dm yourpath/wsj0-processed/si_tr_s --dynamic_mixing True |
| WHAMR! 静态训练 | python train.py hparams/sepformer-whamr.yaml --data_folder yourpath/whamr --rir_path yourpath/rir_wavs |
| WHAM! 静态训练 | python train.py hparams/sepformer-wham.yaml --data_folder yourpath/wham_original |
| 仅测试 | 上述命令追加--test_only |
引用
若将本 recipe 用于研究或商业用途,请按 README 中的说明引用 SpeechBrain 论文与 SepFormer 论文:
@misc{speechbrainV1, title={Open-Source Conversational AI with SpeechBrain 1.0}, author={Mirco Ravanelli and others}, year={2024}, eprint={2407.00463}, archivePrefix={arXiv}, primaryClass={cs.LG} } @inproceedings{subakan2021attention, title={Attention is All You Need in Speech Separation}, author={Cem Subakan and Mirco Ravanelli and Samuele Cornell and Mirko Bronzi and Jianyuan Zhong}, year={2021}, booktitle={ICASSP 2021} }小结
本 recipe 以统一的SeparationBrain 类为核心,将数据集准备(CSV 生成)、数据增强(速度扰动、DropFreq/DropChunk、RIR 混响)、动态混合、多架构模型切换(SepFormer / DPRNN / ConvTasnet / DPTNet 等)、指标评估(SI-SNR / SDR / PESQ)与 checkpoint 管理整合为一条完整的训练流水线。无论是复现论文结果、在 WHAM!/WHAMR! 上对比不同增强架构,还是基于预训练模型做下游任务,这个目录都是 SpeechBrain 语音增强方向的可靠起点。
【免费下载链接】speechbrainA PyTorch-based Speech Toolkit项目地址: https://gitcode.com/GitHub_Trending/sp/speechbrain
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考