ASR Whisper LLM Fine-tuning Speaker Diarization Machine Learning

音声認識における大規模言語モデルの学習・評価・デプロイ

Linchuan Du - The University of British Columbia 10 分で読めます
音声認識における大規模言語モデルの学習・評価・デプロイ

Whisperのファインチューニング、話者ダイアライゼーション、複数ASRモデルの比較評価に関する包括的な研究レポートです。

著者: Linchuan Du 所属: The University of British Columbia 数学科 日付: 2023年8月

概要

自動音声認識(ASR)は、音声テキスト変換(STT)とも呼ばれ、ディープラーニング技術を用いて音声を含む音声データをテキストに変換する技術です。大規模言語モデル(LLM)は人間の脳のように単語やフレーズを処理し、テキストデータの理解と生成が可能です。LLMは通常、数百万のパラメータを持ち、多様なデータセットで事前学習されています。ASR用のLLMは、特徴抽出とトークン化によって音声入力を所望の形式に変換します。

理想的な性能を持つASR LLMをカスタマイズするため、OpenAIが開発したWhisperのファインチューニング手順をまずGoogle Colaboratoryでテストしました。その後、学習を高速化しGPU可用性の制限を回避するため、Windows OS上のGPU搭載環境に移行しました。音声品質やトランスクリプトの正確性などに基づいてデータの信頼性を調査し、データ前処理やハイパーパラメータチューニングによるモデルの改善・最適化を行いました。通常のファインチューニングでGPUメモリ問題を解決できない場合には、LoRAを用いたパラメータ効率的ファインチューニング(PEFT)を使用し、大部分のパラメータを凍結してメモリ使用量を削減しつつ、性能の低下を最小限に抑えました。

また、Neural Speaker Diarizationを用いたWhisperの複数話者対応の可能性を調査しました。Pyannoteとの統合をパイプラインおよびWhisperXを用いて実装しました。WhisperXはワードレベルのタイムスタンプや音声活動検出(VAD)などの機能を備えています。

Whisper以外にも、Meta AIのMMS、PaddleSpeech、SpeechBrain、ESPNetなどのASR機能を持つモデルを導入し、Whisperのベースラインと比較しました。中国語データセットを用いて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

ローカル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環境をactivate/deactivate
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は、圧縮ファイル形式の音声・言語リソースをホストする便利なWebサイトです。Resourcesタブで各種音声データセットの概要を確認できます。

中国語ASR用音声データセット:

データセット時間(サイズ)話者数トランスクリプト精度
Aishell-1 (SLR33)178時間40095%以上
Free ST (SLR38)100時間以上855/
aidatatang_200zh (SLR62)200時間60098%以上
MAGICDATA (SLR68)755時間108098%以上

3. Whisperモデルのファインチューニング

Whisperは、2022年9月にOpenAIがリリースした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ライブラリを使用してサンプリングレートを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: Data Collatorの定義(Sequence to Sequenceのラベルパディング付き)

 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,           # バッチサイズ半減時に2倍に
    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,               # 自己回帰生成の最大トークン数
    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 Out of Memory(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%

注: 日本語は文字ベースの言語であるため、Character Error Rate(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. 話者ダイアライゼーション

話者ダイアライゼーションは、音声データを異なる話者に対応するセグメントに分割する技術です。音声ストリーム中の個々の話者を識別・区別することが目的です。

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. データセットのアップロード

学習・テストデータセットのアップロードには3つの方法があります:

  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翻訳で言語の壁を超えましょう。今すぐ無料でお試しください。

無料ではじめる