ASR Whisper LLM Fine-tuning Speaker Diarization Machine Learning

自动语音识别大语言模型的训练、评估与部署

Linchuan Du - The University of British Columbia 12 分钟阅读
自动语音识别大语言模型的训练、评估与部署

涵盖 Whisper 微调、说话人分离以及多种 ASR 模型对比评估的综合研究报告。

作者:Linchuan Du 单位:The University of British Columbia 数学系 日期:2023年8月

摘要

自动语音识别(ASR),也称为语音转文字(STT),利用深度学习技术将含有语音的音频转录为文字。大语言模型(LLM)模拟人脑处理词语和短语的方式,具备理解和生成文本数据的能力。LLM 通常包含数百万个权重,并使用各类数据集进行预训练。ASR LLM 通过特征提取和分词(tokenization)将音频输入转换为所需的输入格式。

为了定制具有理想性能的 ASR LLM,我们首先在 Google Colaboratory 上测试了 OpenAI 开发的 Whisper 微调流程。随后将较大模型部署到配备 GPU 的 Windows 环境中,以加速训练并缓解 Colab 和 macOS 上的 GPU 限制问题。我们基于音频质量和转录准确性等信息对音频数据的可靠性进行了评估,并通过数据预处理和超参数调优技术改进和优化了模型。当常规微调无法解决 GPU 内存问题时,采用了基于 LoRA 的参数高效微调(PEFT),冻结大部分参数以节省内存,同时尽量减少性能损失。

我们还探索了利用 Neural Speaker Diarization 为 Whisper 添加多说话人支持的可能性。通过 Pipeline 和 WhisperX 实现了与 Pyannote 的集成。WhisperX 提供了词级时间戳和语音活动检测(VAD)等额外功能。

除 Whisper 外,我们还安装并比较了具有 ASR 功能的其他模型,包括 Meta AI 的 MMS、PaddleSpeech、SpeechBrain 和 ESPNet。使用中文数据集进行了 CER 指标的比较评估。此外,还引入了 Azure AI 的 Custom Speech 进行实时 STT 性能对比(主要针对普通话)。

内容概览

本研究涵盖的主题:

  1. 环境搭建 - Google Colab、Anaconda、VS Code、CUDA GPU
  2. 音频数据源 - Hugging Face、OpenSLR 数据集
  3. Whisper 微调 - 微调、基于 LoRA 的 PEFT、结果
  4. 说话人分离 - Pyannote.audio、WhisperX
  5. 其他模型 - Meta MMS、PaddleSpeech、SpeechBrain、ESPnet
  6. Azure Speech Studio - Custom Speech 训练与部署

1. 环境搭建

a. Google Colaboratory

Google Colaboratory 是一个提供有限免费 GPU/TPU 计算资源的托管 Jupyter Notebook 服务,使用 ipynb 格式编辑和执行 Python 脚本。

通过 Google 账号登录,可以通过页面右上角的"分享"功能与他人共享脚本,也可以选择与 GitHub 账号关联。

在 Colab 上搭建环境:

  1. 选择 Runtime 标签 → Change Runtime 以启用 GPU
  2. 使用 pip 等包安装器安装必要的依赖
1
!pip install packageName

b. Anaconda

除了 Colab,也可以在本地 PC 上搭建环境。Anaconda 是数据科学领域广泛使用的发行平台,支持 Python 数据分析和机器学习模型构建,内含环境和包管理器 Conda。

使用 Anaconda 搭建环境:

  1. Anaconda 下载安装并添加到 PATH 环境变量
  2. 打开命令提示符进入 base 环境(示例:Windows)
1
(base) C:\Users\username>
  1. 创建新的 Conda 环境
1
conda create --name myenv
  1. 根据需要激活/取消激活 Conda 环境
1
2
conda activate myenv
conda deactivate
  1. 通过 PyPI 或 Conda 包管理器安装依赖
1
2
pip install packageName>=0.0.1
conda install packageName

提示: 更多 Conda 命令请参阅 https://conda.io/projects/conda/en/latest/commands

c. Visual Studio Code

Visual Studio Code(VS Code)是一款适用于 Windows、macOS 和 Linux 的强大源代码编辑器,支持多种编程语言,具备调试、集成终端执行、扩展功能和 Git 版本控制等能力。

在 VS Code 中搭建环境:

  1. 在 EXPLORER 中打开文件夹并创建文件
  2. 在右下角选择所需环境,使用安装了 IPython 内核的交互式窗口运行,或通过命令执行 Python 脚本
1
python xxx.py
  1. 也可以使用 ipynb 格式(Jupyter Notebook)
  2. 左侧面板的 Git 图标用于源代码管理

提示: 如果环境中的包发生更新,需要重新打开 VS Code。

d. CUDA GPU

CUDA(Compute Unified Device Architecture)是 NVIDIA 开发的并行计算平台和 API,允许开发者利用 NVIDIA GPU 进行各种计算任务。

使用 CUDA GPU:

  1. 安装 CUDA Toolkit
  2. 在命令提示符中查看相关信息
1
nvidia-smi

PyTorch 安装

配置好 CUDA Toolkit 后,从 PyTorch 下载兼容 GPU 的版本。

提示: 如需旧版 PyTorch,请在 Previous PyTorch Versions 查阅正确的安装命令。

可以在 Python 中直接验证版本信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import torch

print(f' CUDA availability on PyTorch is {torch.cuda.is_available()}')
print(f' Current PyTorch version is {torch.__version__}')
print(f' Current CUDA version is {torch.version.cuda}')
print(f' cuDNN version is {torch.backends.cudnn.version()}')
print(f' The number of available GPU devices is {torch.cuda.device_count()}')

# Use CUDA on the device
device = torch.device("cuda")

2. 音频数据源

a. Hugging Face

Hugging Face 是一家专注于自然语言处理(NLP)和人工智能的公司与开源平台。

Hugging Face 令牌设置

创建账号后可以使用已发布的模型或上传自定义模型。READ 和 WRITE 令牌可在 https://huggingface.co/settings/tokens 创建。

常见 ASR LLM 信息:

模型参数量支持语言任务架构
OpenAI Whisperlarge-v2 1550M大多数语言多任务Transformer encoder-decoder Regularized
OpenAI Whisperlarge 1550M大多数语言多任务Transformer encoder-decoder
OpenAI Whispermedium 769M大多数语言多任务Transformer encoder-decoder
OpenAI Whispersmall 244M大多数语言多任务Transformer encoder-decoder
guillaumekln faster-whisperlarge-v2大多数语言多任务CTranslate2
facebook wav2vec2large-960h-lv60-self英语转录Wav2Vec2CTC decoder
facebook wav2vec2base-960h 94.4M英语转录Wav2Vec2CTC decoder
facebook mms1b-all 965M大多数语言多任务Wav2Vec2CTC decoder

常见音频数据集:

数据集时长/规模支持语言
mozilla-foundation common_voice_13_017689 已验证小时108种语言
google fleurs每种语言约12小时102种语言
LIUM tedlium3个版本共118至452小时英语
librispeech_asr约1000小时英语
speechcolab gigaspeech10000小时英语
PolyAI minds148.17k条14种语言

注意: PolyAI/minds14 主要用于意图检测任务,不适合 ASR 用途。

b. Open SLR

Open SLR 是另一个实用的网站,以压缩文件形式托管语音和语言资源。可在 Resources 标签页查看各类音频数据集的概要信息。

中文 ASR 音频数据集:

数据集时长(规模)说话人数转录准确率
Aishell-1 (SLR33)178小时40095%以上
Free ST (SLR38)100小时以上855/
aidatatang_200zh (SLR62)200小时60098%以上
MAGICDATA (SLR68)755小时108098%以上

3. Whisper 模型微调

Whisper 是 OpenAI 于 2022 年 9 月发布的 ASR 系统,使用 680,000 小时的多语言和多任务监督数据进行训练,支持多语言转录和翻译。架构为编码器-解码器 Transformer。

音频被分割为 30 秒的片段,转换为 log-Mel 频谱图后输入编码器。

参考资料:

a. 在 Colab 上微调

步骤 1: 使用 Hugging Face 令牌登录以启用数据集下载

1
2
from huggingface_hub import notebook_login
notebook_login()

步骤 2: 通过 load_dataset 加载数据集

提示: 某些数据集可能需要在 Hugging Face 上获取访问权限。

步骤 3: 预处理数据以供 Whisper 使用:

  • 列操作:如 remove_columnscast_column
  • 转录文本归一化:大小写、标点符号、特殊标记
  • 使用 Datasets 库中的 Audio 将采样率更改为 16k
  • 从 transformers 库加载预训练的特征提取器和分词器
1
2
3
4
from transformers import WhisperFeatureExtractor, WhisperTokenizer
WhisperFeatureExtractor.from_pretrained("model_id")
WhisperTokenizer.from_pretrained("model_id")
WhisperProcessor.from_pretrained("model_id")

提示: AutoProcessor 可自动检测处理器类型。

在分词器中通常需要指定目标语言和任务:

1
language="lang", task="transcribe"  # or "translation"

步骤 4: 定义带有标签填充的 Sequence to Sequence Data Collator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import torch
from dataclasses import dataclass
from typing import Any, Dict, List, Union

@dataclass
class DataCollatorSpeechSeq2SeqWithPadding:
    processor: Any

    def __call__(self, features: List[Dict[str, Union[List[int], torch.Tensor]]]) -> Dict[str, torch.Tensor]:
        input_features = [{"input_features": feature["input_features"]} for feature in features]
        batch = self.processor.feature_extractor.pad(input_features, return_tensors="pt")

        label_features = [{"input_ids": feature["labels"]} for feature in features]
        labels_batch = self.processor.tokenizer.pad(label_features, return_tensors="pt")

        labels = labels_batch["input_ids"].masked_fill(labels_batch.attention_mask.ne(1), -100)

        if (labels[:, 0] == self.processor.tokenizer.bos_token_id).all().cpu().item():
            labels = labels[:, 1:]

        batch["labels"] = labels

        return batch

步骤 5: 导入评估指标(WER)

1
2
import evaluate
metric = evaluate.load("wer")

提示: 对于英语和大多数欧洲语言,WER(Word Error Rate)是评估转录准确度的常用指标。

WER 公式: WER = (替换数 + 删除数 + 插入数) / 参考文本总词数

步骤 6: 设计指标计算函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def compute_metrics(pred):
    pred_ids = pred.predictions
    label_ids = pred.label_ids

    label_ids[label_ids == -100] = tokenizer.pad_token_id

    pred_str = tokenizer.batch_decode(pred_ids, skip_special_tokens=True)
    label_str = tokenizer.batch_decode(label_ids, skip_special_tokens=True)

    wer = 100 * metric.compute(predictions=pred_str, references=label_str)

    return {"wer": wer}

步骤 7: 加载条件生成模型并配置

1
2
3
4
5
from transformers import WhisperForConditionalGeneration
model = WhisperForConditionalGeneration.from_pretrained("model_id")

model.config.forced_decoder_ids = None
model.config.suppress_tokens = []

步骤 8: 在 Seq2SeqTrainingArguments 中定义超参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
training_args = Seq2SeqTrainingArguments(
    output_dir="kawadlc/whisperv1",          # 仓库名
    per_device_train_batch_size=16,          # 每 GPU 训练批次大小
    gradient_accumulation_steps=1,           # 批次大小减半时翻倍
    learning_rate=1e-5,                      # 控制过拟合/欠拟合的关键参数
    weight_decay=1e-2,                       # 正则化机制
    warmup_steps=200,                        # 提升早期性能
    max_steps=3000,                          # 总优化步数
    gradient_checkpointing=True,             # 节省内存
    evaluation_strategy="steps",             # 评估策略(其他:"epoch")
    fp16=True,                               # 半精度浮点
    per_device_eval_batch_size=8,            # 每 GPU 评估批次大小
    predict_with_generate=True,              # 执行生成
    generation_max_length=200,               # 自回归生成最大 token 数
    eval_steps=500,                          # 每次评估间隔步数
    report_to=["tensorboard"],               # 保存训练日志到 TensorBoard
    load_best_model_at_end=True,             # 结束时加载最优模型
    metric_for_best_model="wer",             # 最优模型判定指标
    greater_is_better=False,                 # WER 越低越好
    push_to_hub=False,                       # 推送到 Hub(可选)
)

步骤 9: 使用 trainer.train() 开始训练

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from transformers import Seq2SeqTrainer

trainer = Seq2SeqTrainer(
    args=training_args,
    model=model,
    train_dataset=common_voice["train"],
    eval_dataset=common_voice["test"],
    data_collator=data_collator,
    compute_metrics=compute_metrics,
    tokenizer=processor.feature_extractor,
)

处理 CUDA 内存不足(OOM)错误:

  1. 首选方案: 减小批次大小(配合 gradient accumulation 使用)
  2. Gradient checkpointing: 以少量计算时间换取大幅内存节省
  3. 混合精度训练: 在保持训练稳定性的同时减少内存占用
  4. 清除 GPU 缓存:
1
2
3
4
5
import gc
import torch

gc.collect()
torch.cuda.empty_cache()

提示: 如果以上方法都无效,切换到更小的模型是最后的选择。

b. 数据预处理

Hugging Face 数据集

使用 load_dataset 函数加载数据集:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
common_voice = DatasetDict()

common_voice["train"] = load_dataset("common_voice", "ja", split="train+validated", use_auth_token=True)
common_voice["validation"] = load_dataset("common_voice", "ja", split="validation", use_auth_token=True)
common_voice["test"] = load_dataset("common_voice", "ja", split="test", use_auth_token=True)

# 创建 DatasetDict,选择训练和评估的样本量
common_voice = DatasetDict({
    "train": common_voice['train'].select(range(3500)),
    "validation": common_voice['validation'].select(range(500)),
    "test": common_voice['test'].select(range(100)),
})

# 移除训练中不需要的列
common_voice = common_voice.remove_columns(["age", "client_id", "down_votes", "gender", "path", "up_votes"])

提示: 磁盘空间有限或不需要下载完整数据集时,可使用 streaming=True

将采样率更改为 Whisper 架构要求的 16kHz:

1
common_voice = common_voice.cast_column("audio", Audio(sampling_rate=16000))

转录文本清洗

1
2
3
4
5
# 转为小写并忽略撇号
text = [s.lower() for s in text]
punctuation_without_apostrophe = string.punctuation.replace("'", "")
translator = str.maketrans('', '', punctuation_without_apostrophe)
text = [s.translate(translator) for s in text]
1
2
3
4
# 移除特殊标记
def remove_tags(text):
    clean = re.compile('<.*?>')
    return re.sub(clean, '', text)

c. 微调结果

缩写说明:

  • lr = learning rate, wd = weight decay, ws = warmup steps
  • ms = max steps, #e = number of epochs
  • es = evaluation strategy, ml = max length
  • tbz = train batch size, ebz = eval batch size
  • #ts = train sample size, #es = eval sample size
数据集/规模/划分模型/语言/任务超参数结果
common_voice_11_0 #ts=100, #es=100 train/testWhisper small Hindi Transcribelr=1e-5, wd=0, ws=5, ms=40, es=steps, ml=225, tbz=4, ebz=8WER: 67.442%
common_voice_11_0 #ts=500, #es=500 train+validation/testWhisper small Hindi Transcribelr=1e-5, wd=0, ws=0, ms=60, es=steps, ml=50, tbz=16, ebz=8WER: 62.207%
common_voice #ts=3500, #es=500 train+validated/validationWhisper small Japanese Transcribelr=1e-6, wd=0, ws=50, ms=3500, es=steps, ml=200, tbz=16, ebz=8WER: 2.4%
librispeech_asr #ts=750, #es=250 train.100/validationWhisper medium English Transcribelr=1e-5, wd=0.01, ws=10, ms=750, es=steps, ml=80, tbz=1, ebz=1WER: 13.095%

注意: 日语是基于字符的语言,因此字符错误率(CER)是更合适的评估指标。

d. 基于 LoRA 的 PEFT

参数高效微调(PEFT)仅微调少量模型参数,同时冻结预训练 LLM 的大部分参数,大幅降低计算和存储成本。

**LoRA(Low Rank Adaptation)**将预训练模型的权重分解为低秩矩阵,显著减少需要微调的参数数量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
model = WhisperForConditionalGeneration.from_pretrained(
    'openai/whisper-large-v2',
    load_in_8bit=True,
    device_map="auto"
)

from peft import LoraConfig, PeftModel, LoraModel, LoraConfig, get_peft_model, prepare_model_for_int8_training

model = prepare_model_for_int8_training(model)

def make_inputs_require_grad(module, input, output):
    output.requires_grad_(True)

model.model.encoder.conv1.register_forward_hook(make_inputs_require_grad)

config = LoraConfig(
    r=32,
    lora_alpha=64,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05,
    bias="none"
)

model = get_peft_model(model, config)
model.print_trainable_parameters()

PEFT 训练参数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
training_args = Seq2SeqTrainingArguments(
    output_dir="jackdu/whisper-peft",
    per_device_train_batch_size=8,
    gradient_accumulation_steps=1,
    learning_rate=1e-4,
    weight_decay=0.01,
    warmup_steps=0,
    num_train_epochs=3,
    evaluation_strategy="steps",
    fp16=True,
    per_device_eval_batch_size=8,
    generation_max_length=150,
    logging_steps=100,
    remove_unused_columns=False,  # PEFT 必需
    label_names=["labels"],       # PEFT 必需
)

PEFT 结果:

数据集/规模/划分模型/语言/任务超参数结果
common_voice_13_0 #ts=1000, #es=100 train+validation/testWhisper medium Japanese Transcribelr=1e-3, wd=0, ws=50, #e=3, es=steps, ml=128, tbz=8, ebz=8WER: 73%, NormWER: 70.186%
common_voice_13_0 #ts=100, #es=30 train+validation/testWhisper large-v2 Vietnamese Transcribelr=1e-4, wd=0.01, ws=0, #e=3, es=steps, ml=150, tbz=8, ebz=8WER: 26.577%, NormWER: 22.523%

提示: PEFT 参考资料:

e. 损失曲线可视化

1
2
3
4
5
6
7
8
9
plt.figure(figsize=(10, 6))
plt.plot(training_epoch, training_loss, label="Training Loss")
plt.plot(evaluation_epoch, evaluation_loss, label="Evaluation Loss")
plt.xlabel("Training Epochs")
plt.ylabel("Loss")
plt.title("Loss Curves for Whisper Fine-Tuning")
plt.legend()
plt.grid(True)
plt.show()

需要关注的模式:

  • 过拟合: 训练损失低但验证损失高
  • 欠拟合: 训练损失和验证损失都很高
  • 平滑性: 平滑的曲线表示训练过程稳定
  • 损失停滞: 模型难以从现有数据中继续学习

f. 基线结果

数据集/划分/规模模型/任务结果
distil-whisper/tedlium-long-form testWhisper medium baseline en→enWER: 28.418%
distil-whisper/tedlium-long-form validationWhisper large-v2 baseline en→enWER: 26.671%
librispeech_asr clean testWhisper large-v2 baseline en→enWER: 4.746%
Aishell S0770 test #353Whisper large-v2 baseline zh-CN→zh-CNCER: 8.595%
Aishell S0768 test #367Whisper large-v2 baseline zh-CN→zh-CNCER: 12.379%
MagicData 38_5837 test #585Whisper large-v2 baseline zh-CN→zh-CNCER: 21.750%

4. 说话人分离

说话人分离(Speaker Diarization)是将语音音频按不同说话人进行分段的技术,目标是识别和区分音频流中的各个说话人。

a. Pyannote.audio

Pyannote.audio 是用于说话人分离、语音活动检测和话语轮次分割的开源工具包。

将 Pyannote.audio 与 Whisper 配合使用:

1
pip install -qq https://github.com/pyannote/pyannote-audio/archive/refs/heads/develop.zip
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
login(read_token)
device = "cuda:0" if torch.cuda.is_available() else "cpu"

from pyannote.audio import Pipeline, Audio
sd_pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization", use_auth_token=True)
wav_files = glob.glob(os.path.join(audio_dirpath, '*.wav'))

pipe = pipeline(
    "automatic-speech-recognition",
    model="openai/whisper-large-v2",
    chunk_length_s=30,
    device=device,
)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
results = []

for audio_file in wav_files:
    diarization = sd_pipeline(audio_file, min_speakers=min_speakers, max_speakers=max_speakers)
    audio = Audio(sample_rate=16000, mono='random')
    for segment, _, speaker in diarization.itertracks(yield_label=True):
        waveform, sample_rate = audio.crop(audio_file, segment)
        text = pipe(
            {"raw": waveform.squeeze().numpy(), "sampling_rate": sample_rate},
            batch_size=8,
            generate_kwargs={"language": "<|zh|>", "task": "transcribe"}
        )["text"]
        results.append({
            'start': segment.start,
            'stop': segment.end,
            'speaker': speaker,
            'text': text
        })

b. WhisperX

WhisperX 集成了 Whisper、音素模型(Wav2Vec2)和 Pyannote.audio。它声称在实时语音识别上比 Whisper large-v2 快 70 倍,并提供词级时间戳和 VAD 功能的说话人分离。

1
2
conda install pytorch==2.0.0 torchaudio==2.0.0 pytorch-cuda=11.8 -c pytorch -c nvidia
pip install git+https://github.com/m-bain/whisperx.git
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
diarize_model = whisperx.DiarizationPipeline(
    model_name="pyannote/speaker-diarization",
    use_auth_token='hf_token',
    device=device
)

model = whisperx.load_model(
    whisper_arch=model,
    device=device,
    compute_type=compute_type,
    language=language_abbr
)

audio = whisperx.load_audio(matching_file_path)
diarize_segments = diarize_model(matching_file_path, min_speakers=6, max_speakers=6)
result = model.transcribe(audio, batch_size=batch_size)
result = whisperx.assign_word_speakers(diarize_segments, result)

提示: 各自的优势:

  • WhisperX: 多说话人场景、VAD、额外音素模型、更便于处理本地音频
  • Whisper Pipeline: 支持更多语言、灵活的分块长度(30秒以下)、更便于处理 HF 数据集

WhisperX 结果:

数据集模型/任务/计算类型结果
TED LIUM 1st release SLR7 testWhisperX medium en→en int8WER: 37.041%
TED LIUM 1st release SLR7 testWhisperX large-v2 en→en int8WER: 36.917%
distil-whisper/tedlium-long-form validationWhisperX large-v2 en→en int8 batch_size=1WER: 24.651%
distil-whisper/tedlium-long-form validationWhisperX medium en→en int8 batch_size=1WER: 24.353%
AISHELL-4 selected audio fileWhisperX manual checkCER: 15.6%~24.658%

5. 其他模型

a. Meta MMS

Meta AI 的 Massively Multilingual Speech(MMS)项目将语音技术的支持语言从约 100 种扩展到 1,100 多种。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from transformers import Wav2Vec2ForCTC, AutoProcessor

model_id = "facebook/mms-1b-all"
target_lang = "cmn-script_simplified"
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
processor = AutoProcessor.from_pretrained(model_id)
model = Wav2Vec2ForCTC.from_pretrained(model_id)

processor.tokenizer.set_target_lang(target_lang)
model.load_adapter(target_lang)
model = model.to(device)

b. PaddleSpeech

PaddleSpeech 是 PaddlePaddle 平台上的中文开源工具包,支持 DeepSpeech2、Conformer 和 U2(Unified Streaming and Non-streaming)等架构。详情请参阅功能列表

1
2
pip install pytest-runner
pip install paddlespeech
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from paddlespeech.cli.asr.infer import ASRExecutor
asr = ASRExecutor()

for audio_file in wav_files:
    result = asr(
        model='conformer_wenetspeech',
        lang='zh',
        sample_rate=16000,
        audio_file=audio_file,
        device=paddle.get_device()
    )
    transcript.append(result)

提示: Linux 上的 ASR 训练教程:asr1

c. SpeechBrain

SpeechBrain 是蒙特利尔大学开发的开源对话式 AI 工具包。

1
pip install speechbrain
1
2
3
4
5
6
7
8
from speechbrain.pretrained import EncoderDecoderASR

asr_model = EncoderDecoderASR.from_hparams(
    source="speechbrain/asr-transformer-aishell",
    savedir="pretrained_models/asr-transformer-aishell",
    run_opts={"device": "cuda"}
)
result = asr_model.transcribe_file(audio_file)

d. ESPnet

ESPnet 是一个涵盖语音识别、文本转语音、语音翻译和说话人分离的端到端语音处理工具包。

1
pip install espnet_model_zoo
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from espnet2.bin.asr_inference import Speech2Text

speech2text = Speech2Text.from_pretrained(
    model_id,
    maxlenratio=0.0,
    minlenratio=0.0,
    beam_size=20,
    ctc_weight=0.3,
    lm_weight=0.5,
    penalty=0.0,
    nbest=1
)

e. 基线结果对比

英语:

数据集模型/方法WER
librispeech_asr cleanMeta MMS mms-1b-all4.331%
common_voice_13_0 #1000Meta MMS mms-1b-all23.963%

中文:

数据集模型/方法CER
Aishell S0770 #353PaddleSpeech Default (conformer_u2pp_online_wenetspeech)4.062%
Aishell S0768 #367SpeechBrain wav2vec2-transformer-aishell8.436%
Aishell S0768 #367Meta MMS mms-1b-all34.241%
MagicData 4 speakers #2372PaddleSpeech conformer-wenetspeech9.79%
MagicData 4 speakers #2372SpeechBrain wav2vec2-ctc-aishell15.911%
MagicData 4 speakers #2372Whisper large-v2 baseline24.747%

核心发现: 在中文推理方面,PaddleSpeech 的性能优于 Whisper,而 Meta MMS 的中文转录结果则不如 Whisper。

6. Azure Speech Studio

Azure AI Speech Services 是 Microsoft Azure 提供的一组基于云的语音相关服务。可以在 Speech Studio 中创建不同语言的 Custom Speech 项目。

a. 上传数据集

上传训练和测试数据集有三种方式:

  1. Speech Studio(直接上传)
  2. REST API
  3. CLI 使用

Azure Blob Storage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
pip install azure-storage-blob

from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient

def upload_zip_to_azure_blob(account_name, account_key, container_name, local_zip_path, zip_blob_name):
    connection_string = f"DefaultEndpointsProtocol=https;AccountName={account_name};AccountKey={account_key};EndpointSuffix=core.windows.net"
    blob_service_client = BlobServiceClient.from_connection_string(connection_string)

    container_client = blob_service_client.get_container_client(container_name)
    if not container_client.exists():
        container_client.create_container()

    zip_blob_client = container_client.get_blob_client(zip_blob_name)
    with open(local_zip_path, "rb") as zip_file:
        zip_blob_client.upload_blob(zip_file)

音频格式要求:

  • 格式:WAV
  • 采样率:8kHz 或 16kHz
  • 声道:单声道
  • 压缩:ZIP 格式,2GB 以内,10,000 个文件以内

b. 模型训练与部署

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
pip install azure-cognitiveservices-speech

from azure.cognitiveservices.speech import SpeechConfig, SpeechRecognizer, AudioConfig

predictions = []

for root, _, files in os.walk(wav_base_path):
    for file_name in files:
        if file_name.endswith(".wav"):
            audio_file_path = os.path.join(root, file_name)
            audio_config = AudioConfig(filename=audio_file_path)
            speech_recognizer = SpeechRecognizer(speech_config=speech_config, audio_config=audio_config)
            result = speech_recognizer.recognize_once()
            predictions.append(result.text)

c. Azure 结果

测试数据集训练数据集错误率(自定义 / 基线)
MagicData 9452 11:27:39sAishell 12小时以上4.69% / 4.24%
MagicData 9452 11:27:39sAishell+Minds14 32小时以上: 1小时以上4.67% / 4.23%
MagicData+Aishell+CV13 8721 11:45:52sAishell+CV13 8小时以上: 7小时以上2.51% / 3.70%
MagicData+Aishell+CV13 8721 11:45:52sAishell+CV13+Fleurs 8小时以上: 7小时以上: 9小时以上2.48% / 3.70%

注意: 最优 Azure 模型使用 AISHELL-1、mozilla-foundation/common_voice_13_0 和 google/fleurs 训练,达到了 2.48% 的错误率。

7. 展望

核心发现与未来方向:

  1. 数据源: 具有高质量转录的中文语音数据远少于英语
  2. 硬件限制: 多 GPU 训练或更高端 GPU(NVIDIA 40 系列)有助于在更大模型上取得更好结果
  3. LoRA 配置: 不同 LoRA 参数对 PEFT 模型性能的影响值得进一步探索
  4. 说话人分离: Pyannote.audio 与 Whisper 的集成显示出潜力,但在多说话人会议场景中的分离能力仍有待提升
  5. Azure Speech Services: 保持高音频质量和词级转录准确性至关重要。过滤低质量的训练音频文件可提升模型性能

8. 参考文献

  1. Anaconda, Inc. (2017). Command reference - conda documentation. conda.io/projects/conda/en/latest/commands
  2. OpenAI (2022, September 21). Introducing Whisper. openai.com/research/whisper
  3. Radford, A., Kim, J.W., Xu, T., Brockman, G., McLeavey, C., & Sutskever, I. (2022). Robust Speech Recognition via Large-Scale Weak Supervision.
  4. Gandhi, S. (2022, November 3). Fine-Tune Whisper for Multilingual ASR with Transformers. huggingface.co/blog/fine-tune-whisper
  5. The Linux Foundation (2023). Previous PyTorch Versions. pytorch.org/get-started/previous-versions
  6. Hugging Face, Inc. (2023). Hugging Face Documentations. huggingface.co/docs
  7. Srivastav, V. (2023). fast-whisper-finetuning. github.com/Vaibhavs10/fast-whisper-finetuning
  8. Mangrulkar, S., & Paul, S. (2023). Parameter-Efficient Fine-Tuning Using PEFT. huggingface.co/blog/peft
  9. Bredin, H., et al. (2020). pyannote.audio: neural building blocks for speaker diarization. ICASSP 2020.
  10. Bain, M., Huh, J., Han, T., & Zisserman, A. (2023). WhisperX: Time-Accurate Speech Transcription of Long-Form Audio. INTERSPEECH 2023.
  11. Meta AI (2023, May 22). Introducing speech-to-text, text-to-speech, and more for 1,100+ languages. ai.meta.com/blog/multilingual-model-speech-recognition
  12. Pratap, V., et al. (2023). Scaling Speech Technology to 1,000+ Languages. arXiv.
  13. Zhang, H. L. (2022). PaddleSpeech: An Easy-to-Use All-in-One Speech Toolkit. NAACL 2022.
  14. Ravanelli, M., et al. (2021). SpeechBrain: A General-Purpose Speech Toolkit.
  15. Gao, D., et al. (2022). EURO: ESPnet Unsupervised ASR Open-source Toolkit. arXiv:2211.17196.
  16. ESPnet (2021). espnet_model_zoo. github.com/espnet/espnet_model_zoo
  17. Microsoft (2023). Custom Speech overview - Azure AI Services. learn.microsoft.com/en-us/azure/ai-services/speech-service/custom-speech-overview
  18. Microsoft (2023). Speech service documentation. learn.microsoft.com/en-us/azure/ai-services/speech-service/
分享这篇文章

免费试用 VoicePing

借助 AI 翻译跨越语言障碍。立即开始使用免费计划。

免费开始