波形域中的语音增强。支持离线和流式评估。实现于https://arxiv.org/abs/2006.12847。训练时,请直接克隆github仓库。
项目描述
实时波形域语音增强(Interspeech 2020)
我们提供了论文《实时波形域语音增强》的PyTorch实现:[实时波形域语音增强](https://arxiv.org/abs/2006.12847)。其中,我们提出了一种因果语音增强模型,该模型在笔记本电脑CPU上实时运行,并处理原始波形。所提出模型基于编码器-解码器架构和跳过连接。它在时间和频率域都进行了优化,使用多个损失函数。经验证据表明,它能够去除各种类型的背景噪声,包括静态和非静态噪声以及房间混响。此外,我们提出了一组直接应用于原始波形的数据增强技术,这些技术进一步提高了模型性能和泛化能力。
音频样本可以在以下链接找到:[样本](https://facebookresearch.github.io/denoiser/)
所提出模型基于Demucs架构,最初是为音乐源分离提出的:[论文](https://hal.archives-ouvertes.fr/hal-02379796/document),[代码](https://github.com/facebookresearch/demucs)
安装
首先,安装Python 3.7(建议使用Anaconda)。
通过pip(如果您只想使用预训练模型)
只需运行
pip install denoiser
开发(如果您想训练或进行修改)
克隆此仓库并安装依赖项。我们建议使用新的虚拟环境或Conda环境。
git clone https://github.com/facebookresearch/denoiser
cd denoiser
pip install -r requirements.txt # If you don't have cuda
pip install -r requirements_cuda.txt # If you have cuda
实时语音增强
如果您想实时使用denoiser
(例如,进行Skype通话),您需要一个特定的回环音频接口。
Mac OS X
在Mac OS X上,这是由Soundflower提供的。首先安装Soundflower,然后您可以运行
python -m denoiser.live
在您喜欢的视频会议应用中,只需选择“Soundflower (2ch)”作为输入,即可享受降噪后的语音。
请观看以下链接中的现场演示: 演示。
Linux(已在Ubuntu 20.04上测试)
您可以使用pacmd
命令和pavucontrol
工具
- 运行以下命令
pacmd load-module module-null-sink sink_name=denoiser
pacmd update-sink-proplist denoiser device.description=denoiser
这将向要使用的麦克风中添加一个Null Output监控器
。在软件中选择它作为输入。
- 启动
pavucontrol
工具。在播放选项卡中,在启动python -m denoiser.live --out INDEX_OR_NAME_OF_LOOPBACK_IFACE
和您要降噪的软件(这里是在线通话)之后,您应该看到两个应用程序。将denoiser界面作为播放目标,该目标将在我们之前创建的接收器上输出处理后的音频流。
其他平台
目前,我们不提供对其他操作系统的官方支持。但是,如果您有一个支持循环回声的声卡(例如Steinberg产品),您可以尝试使其工作。您可以使用python -m sounddevice
列出可用的音频接口。然后一旦您发现了您的循环回声接口,只需运行
python -m denoiser.live --out INDEX_OR_NAME_OF_LOOPBACK_IFACE
默认情况下,denoiser
将使用默认的音频输入。您可以使用--in
标志来更改它。
请注意,在Windows上您需要将python
替换为python.exe
。
解决分离质量不佳的问题
denoiser
可能会引入失真,对于非常高的噪声水平。如果您的计算机处理音频不够快,音频可能会变得“嘎吱嘎吱”的声音。在这种情况下,您将在终端中看到错误消息,警告您denoiser
处理音频不够快。您可以尝试退出所有非必要应用程序。
denoiser
已在Mac Book Pro上进行测试,该电脑配备2GHz四核Intel i5和DDR4内存。您可能会遇到DDR3内存的问题。在这种情况下,您可以通过一次处理多个帧来以速度换取整体延迟。要这样做,运行
python -m denoiser.live -f 2
如果您需要,可以增加到-f 3
或更多,但每次增加都会增加16毫秒的额外延迟。
降噪接收到的语音
您还可以降噪接收到的语音,但您将无法同时降噪自己的语音和接收到的语音(除非您有一台非常强大的计算机和足够的循环回声音频接口)。这可以通过将循环回声接口选为VC软件的音频输出,然后运行来实现
python -m denoiser.live --in "Soundflower (2ch)" --out "NAME OF OUT IFACE"
培训和评估
使用玩具示例快速入门
- 运行
sh make_debug.sh
为玩具数据集生成json文件。 - 运行
python train.py
配置
我们使用Hydra来控制所有训练配置。如果您不熟悉Hydra,我们建议您访问Hydra的网站。一般来说,Hydra是一个开源框架,通过提供动态创建分层配置的能力,简化了研究应用程序的开发。
包含训练我们模型所需的所有相关参数的配置文件可以在conf
文件夹下找到。注意,在conf
文件夹下,dset
文件夹包含不同数据集的配置文件。您应该看到名为debug.yaml
的文件,其中包含调试样本集的相关配置。
您可以通过命令行传递选项,例如./train.py demucs.hidden=32
。请参考conf/config.yaml以获取可能选项的参考。您也可以直接编辑config.yaml
文件,但由于实验的自动命名方式,这不建议这样做,如下文所述。
检查点保存
每个实验都将根据您传递的命令行选项获得一个唯一的名称。重新启动相同的命令将重用现有文件夹,并在可能的情况下从先前的检查点开始自动启动。为了忽略以前的检查点,您必须传递restart=1
选项。请注意,像device
、num_workers
等选项对实验名称没有影响。
设置新数据集
如果您想使用新数据集进行训练,您可以
- 为它创建一个单独的配置文件。
- 将新的配置文件放置在
dset
文件夹下。有关配置数据集的更多详细信息,请参阅conf/dset/debug.yaml。 - 在通用配置文件或通过命令行指向它,例如
./train.py dset=name_of_dset
。
您还需要在egs/
文件夹中生成相关的.json
文件。为此,您可以使用python -m denoiser.audio
命令,该命令将扫描指定的文件夹并将所需的元数据作为json输出。例如,如果您的噪声文件位于$noisy
,而干净文件位于$clean
,您可以这样做
out=egs/mydataset/tr
mkdir -p $out
python -m denoiser.audio $noisy > $out/noisy.json
python -m denoiser.audio $clean > $out/clean.json
用法
1. 数据结构
数据加载器读取名为clean.json
和noisy.json
的干净和噪声json文件。这些文件应包含用于优化和测试模型的wav文件的路径以及它们的大小(以帧为单位)。您可以使用python -m denoiser.audio FOLDER_WITH_WAV1 [FOLDER_WITH_WAV2 ...] > OUTPUT.json
来生成这些文件。您应该为训练集和测试集(以及如果提供则验证集)生成上述文件。一旦完成,您应该创建一个yaml文件(类似于conf/dset/debug.yaml
),其中包含数据集文件夹的更新路径。请参阅conf/dset/debug.yaml以获取更多详细信息。
2. 训练
通过启动train.py
脚本来执行训练
./train.py
此脚本从conf/config.yaml
文件中读取所有配置。
分布式训练
要启动分布式训练,您应该打开分布式训练标志。这可以通过以下方式完成
./train.py ddp=1
日志
日志默认存储在outputs
文件夹中。查找匹配的实验名称。在实验文件夹中,您将找到序列化的模型best.th
,训练检查点checkpoint.th
以及包含度量值的日志trainer.log
。所有度量值也提取到history.json
文件中,以便更容易解析。增强样本存储在samples
文件夹中(如果数据集中设置了noisy_dir
或noisy_json
)。
微调
您可以微调3个预训练模型中的任何一个:dns48
、dns64
和master64
。要这样做
./train.py continue_pretrained=dns48
./train.py continue_pretrained=dns64 demucs.hidden=64
./train.py continue_pretrained=master64 demucs.hidden=64
3. 评估
可以通过以下方式评估模型
python -m denoiser.evaluate --model_path=<path to the model> --data_dir=<path to folder containing noisy.json and clean.json>
请注意,给定的--model_path
路径应从某个best.th
文件中获取,而不是从checkpoint.th
中获取。也可以使用预训练模型,使用--dns48
、--dns64
或--master64
。有关可能的参数的更多详细信息,请参阅
usage: denoiser.evaluate [-h] [-m MODEL_PATH | --dns48 | --dns64 | --master64]
[--device DEVICE] [--dry DRY]
[--num_workers NUM_WORKERS] [--streaming]
[--data_dir DATA_DIR] [--matching MATCHING]
[--no_pesq] [-v]
Speech enhancement using Demucs - Evaluate model performance
optional arguments:
-h, --help show this help message and exit
-m MODEL_PATH, --model_path MODEL_PATH
Path to local trained model.
--dns48 Use pre-trained real time H=48 model trained on DNS.
--dns64 Use pre-trained real time H=64 model trained on DNS.
--master64 Use pre-trained real time H=64 model trained on DNS
and Valentini.
--device DEVICE
--dry DRY dry/wet knob coefficient. 0 is only input signal, 1
only denoised.
--num_workers NUM_WORKERS
--streaming true streaming evaluation for Demucs
--data_dir DATA_DIR directory including noisy.json and clean.json files
--matching MATCHING set this to dns for the dns dataset.
--no_pesq Don't compute PESQ.
-v, --verbose More loggging
4. 噪声消除
可以通过以下方式生成增强文件
python -m denoiser.enhance --model_path=<path to the model> --noisy_dir=<path to the dir with the noisy files> --out_dir=<path to store enhanced files>
注意,您可以为测试数据提供noisy_dir
或noisy_json
。请注意,给定的--model_path
路径应从某个best.th
文件中获取,而不是从checkpoint.th
中获取。也可以使用预训练模型,使用--dns48
、--dns64
或--master64
。有关可能的参数的更多详细信息,请参阅
usage: denoiser.enhance [-h] [-m MODEL_PATH | --dns48 | --dns64 | --master64]
[--device DEVICE] [--dry DRY]
[--num_workers NUM_WORKERS] [--streaming]
[--out_dir OUT_DIR] [--batch_size BATCH_SIZE] [-v]
[--noisy_dir NOISY_DIR | --noisy_json NOISY_JSON]
Speech enhancement using Demucs - Generate enhanced files
optional arguments:
-h, --help show this help message and exit
-m MODEL_PATH, --model_path MODEL_PATH
Path to local trained model.
--dns48 Use pre-trained real time H=48 model trained on DNS.
--dns64 Use pre-trained real time H=64 model trained on DNS.
--master64 Use pre-trained real time H=64 model trained on DNS
and Valentini.
--device DEVICE
--dry DRY dry/wet knob coefficient. 0 is only input signal, 1
only denoised.
--num_workers NUM_WORKERS
--streaming true streaming evaluation for Demucs
--out_dir OUT_DIR directory putting enhanced wav files
--batch_size BATCH_SIZE
batch size
-v, --verbose more loggging
--noisy_dir NOISY_DIR
directory including noisy wav files
--noisy_json NOISY_JSON
json file including noisy wav files
5. 重复结果
在此,我们详细介绍了如何重现论文中的结果。
Valentini数据集
- 下载 Valentini数据集。
- 修改Valentini配置文件并运行处理脚本。
- 按照以下说明生成egs/文件。
- 使用
launch_valentini.sh
(或非因果的launch_valentini_nc.sh
)脚本启动训练。
重要:与我们在论文中所述不同,因果模型使用STFT损失的权重为0.1,而不是0.5。
为了创建egs/文件,修改并运行以下代码
noisy_train=path to valentini
clean_train=path to valentini
noisy_test=path to valentini
clean_test=path to valentini
noisy_dev=path to valentini
clean_dev=path to valentini
mkdir -p egs/val/tr
mkdir -p egs/val/cv
mkdir -p egs/val/tt
python -m denoiser.audio $noisy_train > egs/val/tr/noisy.json
python -m denoiser.audio $clean_train > egs/val/tr/clean.json
python -m denoiser.audio $noisy_test > egs/val/tt/noisy.json
python -m denoiser.audio $clean_test > egs/val/tt/clean.json
python -m denoiser.audio $noisy_dev > egs/val/cv/noisy.json
python -m denoiser.audio $clean_dev > egs/val/cv/clean.json
DNS数据集
- 下载两个DNS数据集,确保使用interspeech2020分支。
- 在DNS配置文件中设置路径以适应您的设置,并运行处理脚本。
- 按照以下说明生成egs/文件。
- 使用
launch_dns.sh
脚本启动训练。
为了创建egs/文件,修改并运行以下代码
dns=path to dns
noisy=path to processed noisy
clean=path to processed clean
testset=$dns/datasets/test_set
mkdir -p egs/dns/tr
python -m denoiser.audio $noisy > egs/dns/tr/noisy.json
python -m denoiser.audio $clean > egs/dns/tr/clean.json
mkdir -p egs/dns/tt
python -m denoiser.audio $testset/synthetic/no_reverb/noisy $testset/synthetic/with_reverb/noisy > egs/dns/tt/noisy.json
python -m denoiser.audio $testset/synthetic/no_reverb/clean $testset/synthetic/with_reverb/clean > egs/dns/tt/clean.json
在线评估
我们的在线实现基于纯Python代码,并对流卷积和转置卷积进行了一些优化。我们在2 GHz的四核Intel i5 CPU上对这个实现进行了基准测试。所提模型的实时因子(RTF)如下:
模型 | 线程 | RTF |
---|---|---|
H=48 | 1 | 0.8 |
H=64 | 1 | 1.2 |
H=48 | 4 | 0.6 |
H=64 | 4 | 1.0 |
为了在您的CPU上计算RTF,请启动以下命令
python -m denoiser.demucs --hidden=48 --num_threads=1
输出应该如下所示
total lag: 41.3ms, stride: 16.0ms, time per frame: 12.2ms, delta: 0.21%, RTF: 0.8
您可以自由探索不同的设置,例如更大的模型和更多的CPU核心。
引用
如果您使用了论文中的代码,请按以下方式引用:
@inproceedings{defossez2020real,
title={Real Time Speech Enhancement in the Waveform Domain},
author={Defossez, Alexandre and Synnaeve, Gabriel and Adi, Yossi},
booktitle={Interspeech},
year={2020}
}
许可
本仓库遵循CC-BY-NC 4.0许可发布,如LICENSE文件中所示。
文件denoiser/stft_loss.py
是从kan-bayashi/ParallelWaveGAN仓库改编的。它是ParallelWaveGAN论文的非官方实现,遵循MIT许可证发布。文件scripts/matlab_eval.py
是从santi-pdp/segan_pytorch仓库改编的。它是SEGAN论文的非官方实现,遵循MIT许可证发布。