エンコーダが音声の特徴列hを作り、デコーダが過去の出力ラベルとhを参照して次を生成する。
基本的な再帰型デコーダの式。sは前ステップの状態、αは参照の重み、cは文脈ベクトル。
RNNでは同じ層の状態を時刻順に更新する。Self-Attentionは位置間の関係を直接計算できる。
Conformerも大域的Self-Attentionを使う。
二乗の計算量を解消する方式ではなく、畳み込みで局所情報も扱う構造。
Conformerはエンコーダの構造。CTCやTransducerなどの出力方式と組み合わせる。
| 順序 | モジュール | 役割 |
|---|---|---|
| 1 | Feed-Forward | 位置ごとの変換。出力を1/2倍して残差へ加える |
| 2 | Multi-Head Self-Attention | 大域的な関係 |
| 3 | Convolution | 近隣フレームのパターン |
| 4 | Feed-Forward | もう一度、出力を1/2倍して残差へ加える |
| 5 | LayerNorm | ブロックの最後に正規化 |
Macaron形式の1/2は残差へ加える出力の係数。FFNの隠れ次元を半分にする意味ではない。
Gulati et al. (2020), Table 2。Conformer Transducer、LibriSpeechのWER(%)。
| モデル | パラメータ | LMなし clean / other | LMあり clean / other |
|---|---|---|---|
| S | 10.3M | 2.7 / 6.3 | 2.1 / 5.0 |
| M | 30.7M | 2.3 / 5.0 | 2.0 / 4.3 |
| L | 118.8M | 2.1 / 4.3 | 1.9 / 3.9 |
clean / otherはtest-clean / test-other。LMは外部言語モデル。
Radford et al. (2022, OpenAI)。ここでは原論文と、実習の多言語版smallを中心に扱う。
| 2022年の原論文:合計680,000時間 | 内訳(概算) |
|---|---|
| 英語の文字起こし | 438,000時間 |
| 英語以外の文字起こし | 117,000時間 |
| 他言語の音声から英語への翻訳 | 125,000時間 |
後発のモデルは学習データが異なる場合がある。版を区別する。
TransformerのEncoder-Decoder。実習のsmallを例にする。
| 処理 | 内容 |
|---|---|
| 音声の前処理 | 16 kHz、最大30秒の窓 → 80チャネルのログメル特徴量 |
| 2層Conv + GELU | 時間方向を1/2に縮小 |
| Transformerエンコーダ | 音声表現を計算 |
| Transformerデコーダ | 過去の出力と音声表現から自己回帰生成 |
<|startoftranscript|> # 開始
<|ja|> # 言語
<|transcribe|> # 文字起こし
<|translate|> # 英語へ翻訳
<|notimestamps|> # 時刻を出さない場合large-v3は128メルチャネル。80チャネルという説明を全モデルへ一般化しない。
| モデル | パラメータ数 | GPUメモリの概数 |
|---|---|---|
| tiny | 39M | 約1 GB |
| base | 74M | 約1 GB |
| small | 244M | 約2 GB |
| medium | 769M | 約5 GB |
| large系 | 1550M | 約10 GB |
| turbo | 809M | 約6 GB |
公式READMEの概数。実際の速度とメモリ量は機器・設定・音声によって変わる。
実習はsmall。メモリ・待ち時間に応じてbaseやtinyへ変更できる。日本語では.enなしを使う。
turboは翻訳用には訓練されていないので、翻訳実習にはsmallを使う。
| 機能・特性 | 意味と確認点 |
|---|---|
| ゼロショット評価 | 対象データセットで追加学習せずに評価。未見の条件での精度保証ではない |
| 多言語・多タスク | 文字起こし、英語への翻訳、言語識別 |
| タイムスタンプ | 通常はセグメント単位。単語時刻はattentionとDTWによる追加推定 |
| 長い音声 | 30秒窓を順次処理。既定では前の認識テキストも条件に使う |
| 認識誤り | 雑音・沈黙での架空のテキスト、固有名詞などの誤りを確認 |
word_timestamps=Trueはlarge-v2以降だけの機能ではない。language="ja"は認識条件の指定で、正答を保証しない。
公式transcribe実装。自動言語検出は最初の最大30秒を使う。
| 名前 | 用途 |
|---|---|
| ESPnet | End-to-End音声処理のモデルと学習レシピ |
| SpeechBrain | ASR・TTS・話者処理などのPyTorchツール |
| Kaldi | GMM-HMMやDNN-HMMなどの音声認識 |
| fairseq | wav2vec 2.0・HuBERTなどの系列モデル |
| Hugging Face Transformers | 対応モデルを共通APIで利用するライブラリ |
from transformers import pipeline
asr = pipeline("automatic-speech-recognition",
model="openai/whisper-small", device="cpu")
result = asr("audio.wav", generate_kwargs={
"language": "japanese", "task": "transcribe"})
print(result["text"])短い日本語音声の例。transformers・PyTorch・FFmpegの導入が必要。次の実習はopenai-whisperを直接使う。
1:Colabでインストール
%pip install -q openai-whisper jiwer
!apt-get -qq update
!apt-get -qq install -y ffmpeg2:デバイスを確認
import whisper
import torch
device = "cuda" if torch.cuda.is_available() else "cpu"
print("使用デバイス:", device)3:モデルをロード
model = whisper.load_model("small", device=device)
decode_options = {"fp16": device == "cuda"}GPUの割り当ては環境による。CPUでも動くが時間がかかる場合がある。
from google.colab import files
# 短い音声ファイルを1つ選ぶ
uploaded = files.upload()
if not uploaded:
raise ValueError("音声ファイルを1つ選んでください")
file_path = next(iter(uploaded))
result_file = model.transcribe(
file_path, language="ja", task="transcribe", **decode_options)
print("認識結果:", result_file["text"])
# これはセグメント単位のタイムスタンプ
for segment in result_file["segments"]:
start, end = segment["start"], segment["end"]
print(f"[{start:.1f}s → {end:.1f}s] {segment['text']}")language="ja"は日本語として認識する条件を指定する。ここで表示する時刻はセグメント単位。
本文のStep 5にあるRECORD_JSとrecord_audio()の定義を先に実行する。
| 段階 | 処理 |
|---|---|
| 録音 | eval_jsで録音完了のPromiseを待つ |
| 形式の扱い | MediaRecorderの実際のMIME形式で保存し、FFmpegでPCM WAVへ変換 |
| 終了 | 成功・失敗のどちらでもマイクのtrackを停止 |
recorded_path = record_audio(sec=5)
result_mic = model.transcribe(
recorded_path, language="ja", task="transcribe",
**decode_options)
print("認識結果:", result_mic["text"])録音データを最初からWAVと仮定しない。変換後は16 kHz・モノラル。
ブラウザ録音を利用できない場合は、端末で録音したファイルをStep 4でアップロードできる。
audio_path = file_path # マイク音声なら recorded_path
result_ja = model.transcribe(
audio_path, language="ja", task="transcribe", **decode_options)
result_auto = model.transcribe(
audio_path, task="transcribe", **decode_options)
result_en = model.transcribe(
audio_path, language="ja", task="translate", **decode_options)from jiwer import cer
reference = "今日の天気はとても良くて気持ちがいい"
# 上の文を audio_path の実際の発話へ書き換える
hypothesis = result_ja["text"].strip()
cer_value = cer(reference.strip(), hypothesis)
print(f"CER: {cer_value:.1%}")両端の空白だけを除き、句読点などは残す設定。全条件で同じ規則を使う。英語翻訳を日本語の正解文とのCERで評価しない。
条件例から用意できる2〜3条件を試す。速度・雑音の比較は、同じ文・話者・モデル・認識設定で行う。
| 条件 | 正解文 | 認識結果 | CER | 誤りの例 |
|---|---|---|---|---|
| 読み上げ | … | … | …% | … |
| 速い発話 | … | … | …% | … |
| 雑音を加える | … | … | …% | … |
| 自然な方言・アクセント | … | … | …% | … |
| 専門用語 | … | … | …% | … |
CERは挿入が多いと100%を超えることもある。
提出方法:Google Drive(または メール添付)
締め切り:翌週末 23:59
提出内容:
任意追加:最も興味深い誤りパターンを1つ選んで、なぜその誤りが起きたかを推測して書く。
音声認識システムの評価指標(WER・CER・SLUE ベンチマーク)
第9回は動画回です。
Google Forms テストがあります。事前に今日の実習でやった CER の計算に慣れておきましょう。
本日は同期回。Zoomで参加していない学生は録画視聴で補完してもらう。実習コード(Colab)は後日メールでも共有する。
目標を冒頭で明示して、本日の流れを頭に入れてもらう。第7回(GMM-HMM, wav2vec 2.0)の続きとして位置づける。
第7回の構成に発音辞書も含めて対比する。「文字の時間位置を事前に与えない」と説明する。HMMも学習中に対応を推定できる。
それぞれの概念を次のスライドで詳しく説明する。まず大枠のイメージを掴んでもらう。
CTCの変換は隣接重複の統合が先、blank除去が後。a_b__bはabbになる。blankを無音と同一視しない。
数式は「すべての有効な変換経路の確率を足し合わせて最大化する」という直感を伝える。厳密な導出は省略してよい。
自己回帰デコーダは過去の出力ラベルを条件にする。推論の逐次生成と、teacher forcingを使うTransformer学習時の並列化を区別する。
全位置間のSelf-AttentionはO(T^2)。標準Conformerもこの計算を含み、二乗の計算量を解消する方式ではない。
Macaron形式の1/2はFFN出力を残差へ加える際の係数。隠れ次元を半分にする意味ではない。
Table 2のConformer Transducerの結果をLMあり/なしで分けて比較。MのLMありtest-otherは4.3%。Lの1.9/3.9も外部LMありの値。
2022年のWhisperはWeb上の音声・テキスト対応による弱教師あり学習。英語以外の文字起こし117,000時間、英語翻訳125,000時間。後発モデルと区別する。
smallでは80メルチャネル、large-v3では128。transcribeは30秒窓を順に処理し、既定では過去の認識テキストも条件として使う。
実習は多言語版smallを使用。GPUの有無と空きメモリ・待ち時間に応じてbaseやtinyを選べる。turboは翻訳実習には使わない。
実習での誤りパターン観察の観点として弱みを記憶しておいてもらう。
Transformersのpipelineは対応モデルを使う選択肢の一つ。主実習はopenai-whisper。別のツールで公開されたモデルがすべて同じAPIで動くわけではない。
ColabのGPU割当は保証されない。deviceを確認し、CPUではfp16=Falseとする。
表示しているのはセグメント時刻。単語時刻はword_timestamps=TrueによるattentionとDTWの追加推定で、large-v2以降だけの機能ではない。
本文の完全な録音コードを先に実行する。eval_jsが返すPromiseの完了を待ち、MediaRecorderのMIME形式を保持する。FFmpegで内容を判別してWAVに変換し、finallyでマイクを停止する。
同じ音声・正解文で比較する。jiwer.cerは文字編集距離を正解長で割る。句読点・空白などの前処理規則を全条件でそろえ、英語翻訳を日本語CERで評価しない。
全条件をやりきれなくてもOK。2〜3条件の分析でも十分な考察ができる。完成した分析表はGoogle Driveに提出(翌週末23:59)。