Kotoba-Whisper入門 – 日本語音声認識の新しい選択肢

AI

はじめに

Kotoba-Whisperは、Asahi UshioとKotoba Technologiesが共同開発した、日本語の音声認識(ASR)に特化した蒸留Whisperモデルのコレクションです。OpenAIのWhisper large-v3をティーチャーモデルとし、ReazonSpeechの大規模な日本語音声データを用いて学習されました。
元のlarge-v3モデルと比べて6.3倍の高速化を実現しつつ、ほぼ同等の低いエラー率を維持しています。

この記事では、Kotoba-Whisperについての概要を説明し、Transformersライブラリを使った具体的な利用方法をコード付きで紹介します。


こちらの記事もおすすめ

OwlWhisper: 初心者向けのキャラクターエージェント
はじめにOwlWhisperは、高速な音声認識ライブラリ「Faster Whisper」と、高品質な音声合成ライブラリ「Style-Bert-VITS2」を組み合わせたプロジェクトです。初心者でも簡単に音声認識と音声合成を体験できるように設...
Faster WhisperのCTranslate2による高速な音声書き起こし【日本語版リポジトリ】
faster-whisper は、OpenAIのWhisperモデルをCTranslate2 を使って再実装したものです。CTranslate2は、Transformerモデルのための高速な推論エンジンです。この実装は、同じ精度でopena...

Kotoba-Whisperの特徴

  • 高速性: large-v3の6.3倍の速度
  • 高精度: large-v3と同等の低いエラー率
  • 軽量: large-v3の半分以下のパラメータ数
  • 日本語に特化したファインチューニング
  • Transformersライブラリからシームレスに利用可能

環境のセットアップ

Kotoba-Whisperを使うには、Transformers v4.39以降が必要です。
以下のコマンドで最新バージョンをインストールしましょう。

pip install --upgrade pip 
pip install --upgrade transformers accelerate datasets

短い音声の文字起こし

30秒以内の短い音声ファイルは、以下のようにpipelineクラスを使って簡単に文字起こしができます。

import torch
from transformers import pipeline
from datasets import load_dataset, Audio

# モデルの設定
model_id = "kotoba-tech/kotoba-whisper-v1.0"
torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
device = "cuda:0" if torch.cuda.is_available() else "cpu"
model_kwargs = {"attn_implementation": "sdpa"} if torch.cuda.is_available() else {}
generate_kwargs = {"language": "japanese", "task": "transcribe"}

# モデルのロード
pipe = pipeline(
    "automatic-speech-recognition",
    model=model_id,
    torch_dtype=torch_dtype,
    device=device,
    model_kwargs=model_kwargs
)

# サンプル音声を読み込み(16kHzにダウンサンプリング)
dataset = load_dataset("japanese-asr/ja_asr.reazonspeech_test", split="test")
sample = dataset[0]["audio"]

# 推論の実行
result = pipe(sample, generate_kwargs=generate_kwargs)
print(result["text"])

ローカルの音声ファイルを文字起こしする場合は、pipelineを呼び出す際にファイルのパスを渡します。
(音声は16kHzでサンプリングされている必要があります)

result = pipe("audio.mp3", generate_kwargs=generate_kwargs)

セグメントレベルのタイムスタンプが必要な場合は、return_timestamps=Trueを指定して"chunks"の出力を返します。

result = pipe(sample, return_timestamps=True, generate_kwargs=generate_kwargs)
print(result["chunks"])  

長い音声の文字起こし

逐次処理による方法

30秒以上の長い音声ファイルを文字起こしする場合、デフォルトではOpenAIの逐次処理アルゴリズムが使用されます。
これはスライディングウィンドウを使ってバッファ付き推論を行う方法で、チャンク処理より高精度な結果が得られます。
精度が最優先で、レイテンシはそれほど重要でない場合や、長音声を一括処理する場合に適しています。

pipelineクラスを使った逐次処理の例は以下の通りです。

import torch  
from transformers import pipeline
from datasets import load_dataset

# モデルの設定
model_id = "kotoba-tech/kotoba-whisper-v1.0"
torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32  
device = "cuda:0" if torch.cuda.is_available() else "cpu"
model_kwargs = {"attn_implementation": "sdpa"} if torch.cuda.is_available() else {}
generate_kwargs = {"language": "japanese", "task": "transcribe"}

# モデルのロード 
pipe = pipeline(
    "automatic-speech-recognition", 
    model=model_id,
    torch_dtype=torch_dtype,
    device=device, 
    model_kwargs=model_kwargs
)

# サンプル音声の読み込み(長音声のために複数連結)
dataset = load_dataset("japanese-asr/ja_asr.reazonspeech_test", split="test")  
sample = {"array": np.concatenate([i["array"] for i in dataset[:20]["audio"]]), "sampling_rate": dataset[0]['audio']['sampling_rate']}

# 推論の実行
result = pipe(sample, generate_kwargs=generate_kwargs)
print(result["text"])

チャンク処理による方法

一方、単一の長音声ファイルを最速で処理したい場合は、チャンク処理アルゴリズムを使用します。
これは逐次処理の最大9倍の速度で処理できますが、若干精度が落ちるというトレードオフがあります。

チャンク処理を有効にするには、chunk_length_sパラメータをpipelineに渡します。
distil-large-v3では、25秒のチャンク長が最適です。
また、batch_sizeを指定することで、長音声のバッチ処理が可能になります。

import torch
from transformers import pipeline  
from datasets import load_dataset

# モデルの設定
model_id = "kotoba-tech/kotoba-whisper-v1.0"
torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
device = "cuda:0" if torch.cuda.is_available() else "cpu"  
model_kwargs = {"attn_implementation": "sdpa"} if torch.cuda.is_available() else {}
generate_kwargs = {"language": "japanese", "task": "transcribe"}

# モデルのロード
pipe = pipeline(
    "automatic-speech-recognition",
    model=model_id, 
    torch_dtype=torch_dtype,
    device=device,
    model_kwargs=model_kwargs,
    chunk_length_s=15,  
    batch_size=16
)

# サンプル音声の読み込み(長音声のために複数連結) 
dataset = load_dataset("japanese-asr/ja_asr.reazonspeech_test", split="test")
sample = {"array": np.concatenate([i["array"] for i in dataset[:20]["audio"]]), "sampling_rate": dataset[0]['audio']['sampling_rate']}

# 推論の実行
result = pipe(sample, generate_kwargs=generate_kwargs)  
print(result["text"])

プロンプトを用いた文字起こし

Kotoba-Whisperでは、以下のようにプロンプトを与えることで、文字起こしの内容をある程度コントロールできます。

import re
import torch
from transformers import pipeline
from datasets import load_dataset, Audio

# モデルの設定  
model_id = "kotoba-tech/kotoba-whisper-v1.0"
torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
device = "cuda:0" if torch.cuda.is_available() else "cpu"
model_kwargs = {"attn_implementation": "sdpa"} if torch.cuda.is_available() else {}  
generate_kwargs = {"language": "japanese", "task": "transcribe"}

# モデルのロード
pipe = pipeline(
    "automatic-speech-recognition",
    model=model_id,
    torch_dtype=torch_dtype,  
    device=device,
    model_kwargs=model_kwargs
)

# サンプル音声の読み込み
dataset = load_dataset("japanese-asr/ja_asr.reazonspeech_test", split="test")  

# プロンプト無しの場合
text = pipe(dataset[10]["audio"], generate_kwargs=generate_kwargs)['text']
print(text)
# 81歳、力強い走りに変わってきます。

# プロンプト有りの場合: 「81」を「91」に変更
prompt = "91歳" 
generate_kwargs['prompt_ids'] = pipe.tokenizer.get_prompt_ids(prompt, return_tensors="pt").to(device)
text = pipe(dataset[10]["audio"], generate_kwargs=generate_kwargs)['text'] 
# 現在のASRパイプラインはプロンプトを文字起こしの先頭に追加するので、それを削除
text = re.sub(rf"\A\s*{prompt}\s*", "", text)
print(text)  
# あっぶったでもスルガさん、91歳、力強い走りに変わってきます。

推論のさらなる高速化と省メモリ化

GPUが対応していれば、Flash Attentionを使うことで、推論速度とVRAM使用量をさらに改善できます。

pip install flash-attn --no-build-isolation  
model_kwargs = {"attn_implementation": "flash_attention_2"} if torch.cuda.is_available() else {}  

モデルの評価

Kotoba-Whisperの性能評価は、以下のように行えます。
ここでは例としてCommonVoice 8.0の日本語サブセットを使用します。

評価には、データセットの読み込みに🤗 Datasetsを、WERの計算に🤗 Evaluateを使用するので、
事前にインストールしておきます。

pip install --upgrade pip
pip install --upgrade transformers datasets evaluate jiwer  
from tqdm import tqdm

import torch
from transformers import pipeline
from datasets import load_dataset, Audio
from evaluate import load  

# モデルの設定
model_id = "kotoba-tech/kotoba-whisper-v1.0"
torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
device = "cuda:0" if torch.cuda.is_available() else "cpu"
model_kwargs = {"attn_implementation": "sdpa"} if torch.cuda.is_available() else {}  
generate_kwargs = {"language": "japanese", "task": "transcribe"}

# データの設定  
generate_kwargs = {"language": "japanese", "task": "transcribe"}
dataset_name = "japanese-asr/ja_asr.reazonspeech_test"  
audio_column = 'audio'
text_column = 'transcription'

# モデルのロード
pipe = pipeline(
    "automatic-speech-recognition",
    model=model_id,
    torch_dtype=torch_dtype,  
    device=device,
    model_kwargs=model_kwargs,
    batch_size=16
)

# データセットの読み込みと16kHzへのリサンプリング
dataset = load_dataset(dataset_name, split="test")  
transcriptions = pipe(dataset['audio']) 
transcriptions = [i['text'].replace(" ", "") for i in transcriptions]
references = [i.replace(" ", "") for i in dataset['transcription']]

# CERの計算
cer_metric = load("cer")  
cer = 100 * cer_metric.compute(predictions=transcriptions, references=references)
print(cer)

JSUT Basic5000などの他のデータセットで評価する場合は、dataset_nameを変更します。

dataset_name = "japanese-asr/ja_asr.jsut_basic5000"  

さいごに

以上、Kotoba-Whisperについて詳しく解説しました。
音声認識のタスクで日本語を扱う際には、ぜひ選択肢の一つとして検討してみてください。

高速かつ高精度な音声認識を手軽に実現できるKotoba-Whisperが、
皆さんの機械学習プロジェクトの助けになれば幸いです。

ノートブック

Google Colaboratory

謝辞

  • WhisperモデルのOpenAI
  • モデル統合の🤗 Transformers
  • Distil-Whisperのコードベースを提供してくれたHugging Face 🤗
  • ReazonSpeechデータセットのReazon Human Interaction Lab

参考サイト

https://huggingface.co/kotoba-tech/kotoba-whisper-v1.0
Robust Speech Recognition via Large-Scale Weak Supervision
We study the capabilities of speech processing systems trained simply to predict large amounts of transcripts of audio on the internet. When scaled to 680,000 h...

コメント

タイトルとURLをコピーしました