Torch audio 文档
索引
安装
API 教程
音频数据集
管道教程
训练实用技巧
Conformer RNN-T 语音识别
Emformer RNN-T 语音识别
Conv-TasNet 源分离
HuBERT 预训练与微调(ASR)
实时音视频自动语音识别
Python API 参考文档
Python 原型 API 参考
C++ 原型 API 参考
PyTorch 库
PyTorch
torchaudio
torchtext
torchvision
TorchElastic
TorchServe
在 XLA 设备上使用 PyTorch

Torchaudio-Squim:TorchAudio 中的非侵入式语音评估

作者: Anurag Kumar, Zhaoheng Ni

1. 概述

本教程展示了如何使用 Torchaudio-Squim 来评估语音质量和可懂度的客观和主观指标。

Torchaudio-Squim 在 Torchaudio 中实现了语音评估功能。它提供了接口和预训练模型,用于估计各种语音质量和可懂度指标。目前,Torchaudio-Squim [1] 支持无参考估计的三种广泛使用的客观指标:

  • 宽带语音质量感知评估 (PESQ) [2]

  • 短时客观可懂度 (STOI) [3]

  • 尺度不变信噪比 (SI-SDR) [4]

它还支持使用非匹配参考来估计给定音频波形的主观平均意见分数(MOS)[1, 5]。

参考文献

[1] Kumar, Anurag, 等. “TorchAudio-Squim: TorchAudio 中的无参考语音质量和可懂度测量.” ICASSP 2023-2023 IEEE 国际声学、语音和信号处理会议 (ICASSP). IEEE, 2023.

[2] I. Rec, “P.862.2: 宽带电话网络和语音编解码器评估的 P.862 建议的宽带扩展,” 国际电信联盟, 瑞士–日内瓦, 2005.

[3] Taal, C. H., Hendriks, R. C., Heusdens, R., & Jensen, J. (2010, 3月). 一种用于时频加权噪声语音的短时客观可懂度测量. 在 2010 IEEE 国际声学、语音和信号处理会议中 (pp. 4214-4217). IEEE.

[4] Le Roux, Jonathan, 等. “SDR–半生不熟还是熟透了?.” ICASSP 2019-2019 IEEE 国际声学、语音和信号处理会议 (ICASSP). IEEE, 2019.

[5] Manocha, Pranay, 和 Anurag Kumar. “通过非匹配参考进行 MOS 的语音质量评估.” Interspeech, 2022.

import torch
import torchaudio

print(torch.__version__)
print(torchaudio.__version__)
Plain text
2.6.0
2.6.0
Plain text

2. 准备工作

首先导入模块并定义辅助函数。

我们将需要 torchtorchaudio 来使用 Torchaudio-squim,Matplotlib 来绘制数据,以及 pystoipesq 来计算参考指标。

try:
    from pesq import pesq
    from pystoi import stoi
    from torchaudio.pipelines import SQUIM_OBJECTIVE, SQUIM_SUBJECTIVE
except ImportError:
    try:
        import google.colab  # noqa: F401

        print(
"""
            To enable running this notebook in Google Colab, install nightly
            torch and torchaudio builds by adding the following code block to the top
            of the notebook before running it:
            !pip3 uninstall -y torch torchvision torchaudio
            !pip3 install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cpu
            !pip3 install pesq
            !pip3 install pystoi
            """
        )
    except Exception:
        pass
    raise


import matplotlib.pyplot as plt
Plain text
import torchaudio.functional as F
from IPython.display import Audio
from torchaudio.utils import download_asset


def si_snr(estimate, reference, epsilon=1e-8):
    estimate = estimate - estimate.mean()
    reference = reference - reference.mean()
    reference_pow = reference.pow(2).mean(axis=1, keepdim=True)
    mix_pow = (estimate * reference).mean(axis=1, keepdim=True)
    scale = mix_pow / (reference_pow + epsilon)

    reference = scale * reference
    error = estimate - reference

    reference_pow = reference.pow(2)
    error_pow = error.pow(2)

    reference_pow = reference_pow.mean(axis=1)
    error_pow = error_pow.mean(axis=1)

    si_snr = 10 * torch.log10(reference_pow) - 10 * torch.log10(error_pow)
    return si_snr.item()


def plot(waveform, title, sample_rate=16000):
    wav_numpy = waveform.numpy()

    sample_size = waveform.shape[1]
    time_axis = torch.arange(0, sample_size) / sample_rate

    figure, axes = plt.subplots(2, 1)
    axes[0].plot(time_axis, wav_numpy[0], linewidth=1)
    axes[0].grid(True)
    axes[1].specgram(wav_numpy[0], Fs=sample_rate)
    figure.suptitle(title)
Plain text

3. 加载语音和噪声样本

SAMPLE_SPEECH = download_asset("tutorial-assets/Lab41-SRI-VOiCES-src-sp0307-ch127535-sg0042.wav")
SAMPLE_NOISE = download_asset("tutorial-assets/Lab41-SRI-VOiCES-rm1-babb-mc01-stu-clo.wav")
Plain text
  0%|          | 0.00/156k [00:00<?, ?B/s]
100%|##########| 156k/156k [00:00<00:00, 65.3MB/s]
Plain text
WAVEFORM_SPEECH, SAMPLE_RATE_SPEECH = torchaudio.load(SAMPLE_SPEECH)
WAVEFORM_NOISE, SAMPLE_RATE_NOISE = torchaudio.load(SAMPLE_NOISE)
WAVEFORM_NOISE = WAVEFORM_NOISE[0:1, :]
Plain text

目前,Torchaudio-Squim 模型仅支持 16000 Hz 的采样率。如有必要,请对波形进行重采样。

if SAMPLE_RATE_SPEECH != 16000:
    WAVEFORM_SPEECH = F.resample(WAVEFORM_SPEECH, SAMPLE_RATE_SPEECH, 16000)

if SAMPLE_RATE_NOISE != 16000:
    WAVEFORM_NOISE = F.resample(WAVEFORM_NOISE, SAMPLE_RATE_NOISE, 16000)
Plain text

修剪波形,使它们具有相同的帧数。

if WAVEFORM_SPEECH.shape[1] < WAVEFORM_NOISE.shape[1]:
    WAVEFORM_NOISE = WAVEFORM_NOISE[:, : WAVEFORM_SPEECH.shape[1]]
else:
    WAVEFORM_SPEECH = WAVEFORM_SPEECH[:, : WAVEFORM_NOISE.shape[1]]
Plain text

播放语音样本

Audio(WAVEFORM_SPEECH.numpy()[0], rate=16000)
Plain text

播放噪声样本

Audio(WAVEFORM_NOISE.numpy()[0], rate=16000)
Plain text

4. 创建失真(含噪声)的语音样本

snr_dbs = torch.tensor([20, -5])
WAVEFORM_DISTORTED = F.add_noise(WAVEFORM_SPEECH, WAVEFORM_NOISE, snr_dbs)
Plain text

播放信噪比为20dB的失真语音

Audio(WAVEFORM_DISTORTED.numpy()[0], rate=16000)
Plain text

播放信噪比为-5dB的失真语音

Audio(WAVEFORM_DISTORTED.numpy()[1], rate=16000)
Plain text