正解が分かる音声を自分で作って、日本語ASRを測る(そして、その限界)

アプリの作り方

正解が分かる音声を自分で作って、日本語ASRを測る(そして、その限界)

文字起こしモデルの精度を比べようとして、最初に詰まるのが正解テキストの調達になる。

手元の音源を文字起こしして「ここが間違っている」と判定するには、何と言っているかを自分が知っている必要がある。3分半のお笑い音源を耳で全部書き起こそうとして、骨が折れるうえに聞き取れない箇所があいまいなまま残ることに気づいた。

逆から考えた。正解を先に決めて、その通りに読み上げてもらえばいい。

音声合成に台本を渡して読ませれば、投入したテキストがそのまま正解になる。ここではその作り方と、実際にやってみて分かった限界を書く。使ったモデルの比較結果そのものは本編にある。

先に結論を書いておくと、この方法で作った数字は、条件ごとの比較にしか使えなかった。モデル同士の優劣を決める根拠には使えない。理由は後半に書く。

目次
  1. 4パターン作る
    1. 実際に作った4本を聴く
    2. 雑音を足したつもりが、全体が小さくなっていた
  2. 台本どおりに読まれたかを、必ず確かめる
    1. 反復の回数が足りなかったとき、正解を書き換えかけた
  3. 結果は、条件ごとの差だけを読む
  4. この表を、モデル比較に使ってはいけない理由
    1. 声を替えたら、優劣がひっくり返った
  5. それでも、この方法には価値がある

4パターン作る

使ったのは Irodori-TTS。ゲーム制作で使ったものが手元にあった。MITライセンスで、生成した音声の公開にも制限がない。参照テキストはどれも155文字前後にした。

音声 ねらい
clean 素直な読み上げ。基準にする
repetition 同じ言葉を意図的に繰り返す。実際に繰り返している音声を誤判定しないか試す
noisy cleanと同じ音声に音楽とノイズを重ねる
overlap cleanと同じ音声に、別の声を同時に流す

実際に作った4本を聴く

下の4本が、この記事で測った音声そのものになる。noisy と overlap は clean と同一のファイルが土台で、足したものだけが違う。

clean — 素直な読み上げ。基準にする

repetition — 同じ言葉を意図的に繰り返す

noisy — cleanと同じ音声に音楽とノイズを重ねた

overlap — cleanと同じ音声に別の声を同時に流した

noisy と overlap は clean と同一の音声ファイルを土台にしている。違いは足したものだけなので、スコアの差はそのまま雑音や重なりの影響を指す。

台本にはわざと難所を入れた。「京都市と大阪市と名古屋市」のような固有名詞、「1、2、3、…、10」の数字列。固有名詞と数字はASRの弱点だとよく言われるので、そこを踏ませたかった。

雑音を足したつもりが、全体が小さくなっていた

noisy を作るのに ffmpeg で正弦波の和音とピンクノイズを重ねた。できた音声を測ったら、元より平均音量が6dB下がっていた。

amix は既定で入力の数に応じて音量を正規化する。2つ混ぜれば、それぞれが半分になる。雑音を足したはずが、全体が静かになっただけだった。

この状態で1回測ってしまっている。noisy と clean の結果が完全に同じ値で並んで、初めておかしいと気づいた。normalize=0 を付けて作り直した。

[0:a][bg]amix=inputs=2:duration=first:normalize=0

雑音を重ねたら、必ず出来上がりの音量を測る。足したつもりのものが足されていないと、その条件は何も検証していないことになる。

台本どおりに読まれたかを、必ず確かめる

生成した音声を自分では聞いていない。読み上げが台本と一致しているかは、文字起こしにかけて確認した。

この確認は省けない。音声合成は台本どおりに読まないことがある

以前 Windows 内蔵の音声合成で作ったときは、「書き起こせる」を「かきおきこせる」と読んでいた。両モデルとも耳で聞こえたとおり「書き置きこせる」と正しく書き起こしたのに、台本と違うので誤りに計上される。モデルの精度ではなく、正解データの汚れを測っていた。

Irodori-TTS では clean の一致率が完全になったので、そのまま採用した。

反復の回数が足りなかったとき、正解を書き換えかけた

repetition の台本には「ちょん」を8回並べた。できた音声を確認したら、6回しか読まれていない。WhisperもparakeetもN=6と認識していた。

ここで「じゃあ正解を6回に直そう」とやりかけて、手を止めた。

反復の数え落としはASRの弱点そのものになる。両方のモデルが同じ方向に間違っている可能性がある。反復を正しく扱えるかを測るテストの正解を、その能力を疑われている道具で決めたら、何も測っていないのと同じになる。

台本側を4回に減らして作り直した。回数を減らせば音声合成が読み飛ばさない。今度は台本と一致した。

結果は、条件ごとの差だけを読む

対抗馬の nvidia/parakeet-tdt_ctc-0.6b-ja は、ReazonSpeech の35,000時間以上で学習した日本語モデルになる。約625MBと軽く、Windowsのローカルで動く。

期待したのは構造の違いだった。Whisperは入力と出力の長さが縛られていないattention seq2seqで、これが反復ループの温床になる。parakeetのTDT/CTCはフレーム同期で、出力するたびに時間インデックスが必ず前に進む。出力の回数がエンコーダのフレーム数で頭打ちになるので、同じ語を無限に吐き続ける形にはなりにくい。

補足しておくと、TDT自体はRNN-Tの変種で、次に何を出すかは過去に出したトークンを見て決める。自己回帰しないのはCTCブランチのほうになる。「自己回帰しないからループしない」ではなく「時間が必ず前進するからループが止まる」が正確なところ。

3回ずつ実行した結果。参照は155文字前後なので、CER 0.013 は約2文字、0.071 は約11文字にあたる。

音声 parakeet Whisper Whisper+VAD
clean 0.071 0.013 0.103
repetition 0.095 0.017 0.017
noisy 0.071 0.013 0.000
overlap 0.348 0.348 0.368

repetitionの行から読める。同じ言葉を繰り返している音声を、両モデルとも書き起こせている。繰り返しそのものは問題を起こさない。同じ語が続いているという理由だけで異常と判断してはいけない。

cleanでparakeetが0.071と沈んでいるのには、はっきりした理由があった。出力を読むと「数字も読みます」の直後が「この文章は」になっている。「1、2、3、…、10」が丸ごと消えていた。11文字の差は精度の差ではなく、数字列1本の欠落そのものになる。

この表を、モデル比較に使ってはいけない理由

さきほど「読み上げが台本と一致しているか確認した」と書いた。その確認に使ったのがWhisperだった。

評価される側が、テストデータの検定役を兼ねている。

Whisperが完璧に書き起こせた音声だけを「正解付き音声」として採用したのだから、Whisperがそこで良いスコアを出すのは当たり前になる。cleanのWhisperが0.013という数字は、この選び方が効いている可能性を排除できない。

反復の節では循環論法を自分で見つけて回避したのに、その30行前で同じ種類の誤りを犯していた。片方だけ気づいて片方を見落としていた。指摘されるまで分からなかった。

避けるなら、検定役には評価対象でない第三のモデルを使うか、生成音声を自分の耳で確認する。

声を替えたら、優劣がひっくり返った

同じ4パターンを、別の音声合成で作って測ったこともある。Windows内蔵の音声合成を使った版になる。

音声 内蔵TTSの声 Irodoriの声
clean parakeet 0.039 / Whisper 0.077 parakeet 0.071 / Whisper 0.013
overlap parakeet 0.845 / Whisper 0.477 parakeet 0.348 / Whisper 0.348

同じモデル、同じ台本、同じ測り方。読み手の声を替えただけで、cleanの優劣が入れ替わり、overlapでは片方が崩壊していたものが互角になった。

合成音声のベンチマークは、その声に対する成績を測っている。読み手が1人なら、話者1人ぶんのサンプルでしかない。

それでも、この方法には価値がある

ここまで限界ばかり書いたので、使いどころも書いておく。

条件を1つだけ変えた音声を作れるのが、この方法の強みになる。noisy と overlap は clean と同一のファイルが土台なので、スコアの差は足したものの影響だけを指す。人間に同じ文章を3回読んでもらっても、発話そのものが毎回変わるので、この統制はできない。

雑音を足すと何が起きるか、声が重なると何が起きるか。同一モデル内での条件比較なら、合成音声は人間の録音より鋭い

モデル同士を比べたいなら、人間の声で測る。私はそうした。結果は本編に書いた。

【2026-07-21 追記】ここで作った4本は、large-v3-turbo と Kotoba-Whisper を足した続編でもそのまま使っている。turbo は clean と noisy で CER 0.000 を出したが、上に書いた検定バイアスがあるので、この数字をモデル同士の優劣には使っていない。

音声の作り方も、CERの計算も、集計も github.com/BugattiAlpha/asr-ja-bench に置いてある。台本を差し替えれば、自分の条件で同じことができる。

▶ 検証に使ったコードは GitHub に置いてある。台本と音声を差し替えれば、自分の音源でそのまま測れる。

音声合成: Irodori-TTS(Aratako, MIT)

日本語の文字起こし、Whisperより良いモデルはあるのか。測り方を3回間違えながら比べた記録日本語の文字起こし、Whisperより良いモデルはあるのか。測り方を3回間違えながら比べた記録前のページ

large-v3-turbo は large-v3 の代わりになるか。日本語で測って、速度の測り方を2回間違えた記録次のページlarge-v3-turbo は large-v3 の代わりになるか。日本語で測って、速度の測り方を2回間違えた記録

ピックアップ記事

  1. Claude Mission Control の作り方 — Tauri+Pyth…

  2. 競艇予想AIの作り方 — LightGBMで「当たる順位」を学習させる実装ガイド…

  3. New Eden Intelligence Hub の作り方 — EVE Onl…

  4. 高精度OCRデスクトップアプリの作り方 — PaddleOCR-VLとPyIns…

関連記事

  1. ブラウザで動く都市開発シミュを作る①|React+TypeScript+Canvasの土台と3レイヤ設計【Aurum City制作】
  2. アプリの作り方

    MiniMax H3をVRAM 8GBで動かす — ComfyUI導入手順と、800×448が実用上…

    映像とステレオ音声を1パスで生成する MiniMax H3 を、公式が…

  3. Transcription Studio の作り方 — Whisper をローカルで走らせ、エンジンを切り替えて文字起こしする

    アプリの作り方

    Transcription Studio の作り方 — Whisper をローカルで走らせ、エンジン…

    音声/動画をドロップするとローカルの Whisper で文字起こしする…

  4. JavaScriptでRPGを作る②|データ駆動設計 — 敵・職業・スキルを“データ追記だけ”で増やす【Archipelago Saga制作】

    アプリの作り方

    JavaScriptでRPGを作る②|データ駆動設計 — 敵・職業・スキルを“データ追記だけ”で増や…

    ゲームのボリュームは「コード」でなく「データ」で増やす。職業・スキル・…

  5. 背景除去アプリを作る②|AIなしでここまで抜ける — FloodFill・クロマキー・Color-to-Alphaの古典CVエンジン【背景除去Studio制作】

    アプリの作り方

    背景除去アプリを作る②|AIなしでここまで抜ける — FloodFill・クロマキー・Color-t…

    白背景の商品写真はAIより古典CVの方が速くて正確。四隅FloodFi…

注目

AIで、ここまで作れる

AIで作った2D RPGを、ブラウザでそのまま遊べます。その「作り方=最後まで完成させる進め方」も実例つきで公開中。

▶ ゲームを遊ぶやり方を読む

PR

お名前.com 独自ドメイン取得(PR)

独自ドメイン:お名前.com(本サイトで使用・PR)

  1. 正解が分かる音声を自分で作って、日本語ASRを測る(そして、その限界)

    アプリの作り方

    正解が分かる音声を自分で作って、日本語ASRを測る(そして、その限界)
  2. Claude Fable 5 のプラン変更を一次ソースで確認した — 50%枠は他モデルと共通

    AI・テック動向

    Claude Fable 5 のプラン変更を一次ソースで確認した — 50%枠は…
  3. Claude API が会話途中の system メッセージに対応 — キャッシュを壊さず方針を差し替える

    AI・テック動向

    Claude API が会話途中の system メッセージに対応 — キャッシ…
  4. Claude Code のスクリーンリーダーモード — 機械処理に流用しようとして間違えた

    AI・テック動向

    Claude Code のスクリーンリーダーモード — 機械処理に流用しようとし…
  5. WordPress 7.1 Beta 1 公開 — 8月19日の iframe 化前に、自サイトのブロックを1行で棚卸しする

    AI・テック動向

    WordPress 7.1 Beta 1 公開 — 8月19日の iframe …
PAGE TOP

TAG CLOUD

ドラッグで回転・クリックでそのタグの記事一覧へ