0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

サブスク疲れで、使った分だけ払うAI英語学習アプリを個人開発して公開した話(③AI音声の読み間違いを、綴りを伏せたAIに聞かせて見つけた話)

0
Last updated at Posted at 2026-09-27

サブスク疲れで、使った分だけ払うAI英語学習アプリを個人開発して公開した話(③AI音声の読み間違いを、綴りを伏せたAIに聞かせて見つけた話)

①設計思想と技術構成編、②AIに1.9万件を「査読」させた話編 の続きです。今回は、「AIが読み上げた音声が、意図どおりに発音されているか」を、AIで検査した話を書きます。先に書いておくと、私は音声を自分の耳で全数確認できていません。その前提での、検査の仕組みの話です。

TL;DR

  • 英単語アプリの音声(OpenAIのTTS)が、日本語由来の語(sake)や同じ綴りで読みが違う語(lead・bow)などで、発音記号(IPA)と違う読み方をしていることが分かった
  • 最初に考えた「音声とIPAを見せて、一致しているかAIに聞く」方式(gpt-audio)は、較正で誤読を25%見逃し、正しい音声を20%誤判定し、約15%は「聞けない」と拒否された
  • 採用したのは、綴りもIPAも伏せて「聞こえた音」だけを書かせ、あとでテキスト側でIPAと比較する「ブラインド書き起こし」方式(聞き手はgpt-audio-1.5)。3票の多数決で、較正用のセットでは誤読の見逃しが0/50、誤判定が1/44まで下がった(ただしモデルも変えたので、方式だけの効果とは言い切れない)
  • 本番の1,127件に適用して、確定不一致が165件。そこから32件を、書き起こし・IPA・辞書の発音を突き合わせて再点検すると、「実際の読み違い」と言えるのは約2/3だった。判定器は「怪しい候補を絞る道具」で、直す前に自分の耳で聴く必要がある
  • 別の不良として、0.36秒の「シュド」という雑音だけの音声も見つかった。ファイルサイズの閾値では検出しきれず、**全33,128本(男女2声ぶん)を文字起こしで照合(約$6.4・26.5分)して、壊れた音声は約0.1〜0.2%**と分かった

発端: 「sake」が「サケイ」と読まれていた

英単語アプリには、単語ごとに発音記号(IPA)と、TTSで作った音声を付けています。次のような食い違いが見つかりました。

単語: sake(日本酒)
発音記号: /ˈsɑːki/  (サーキ)
実際の音声: 「サーケイ」寄り  (語尾が "kay" になっている)

単語: lead(金属の鉛)
発音記号: /lɛd/  (レッド)
実際の音声: 「リード」  (動詞の lead の読み)

gpt-4o-mini-tts の instructions に「この語は"sah-kee"と読んで」と書いても、読みは変わりませんでした。効いたのは、送るテキスト自体を発音どおりのスペルに置き換える方法(sake → sah-kee)でした(この挙動は、私が使ったモデルでの観察です)。

問題は、「どの語が、どのくらい間違っているのか」を、1.6万語の規模でどう調べるかです。全部を人が聴くのは現実的ではありません。

方式を3回作り直した

①音声とIPAを見せて、一致か聞く → 使えなかった

gpt-audio に音声とIPAを渡して「一致していますか」と聞く方式です。読みが分かっている52本の音声に、正しいIPAと偽のIPA(最小対: led/liːd、sushi/suːˈʃiː など)を組み合わせた110試行で較正したところ、3票の多数決でも:

  • 誤読の見逃し: 25%
  • 正しい音声の誤判定: 20%
  • 約15%の呼び出しで「音声を聞けません」と拒否

でした。IPAを先に見せると、その読みに引きずられて「合っている」と答えてしまうのだろう、と推測しています(ただし、誤判定20%は「正しい音声を不一致と言う」側なので、この仮説だけでは説明できません)。

②軽量モデル(gpt-audio-mini) → 幻聴

聞こえていない別の音を書き起こしました(全然違う語を「幻聴」する)。

③ブラインド書き起こし+テキスト比較 → 採用

綴りもIPAも見せず、聞こえた音だけを書かせます。一括判定では、綴り字風のrespellingと、IPAの両方を書かせました。聞き手は gpt-audio-1.5 です。

出てきた書き起こしを、あとでテキスト側でIPAと比較します。比較には別の軽いモデル(gpt-4.1-mini)を使い、音節数・強勢の位置・強勢母音・子音・文字読みかどうかを構造化して見ています。強勢の位置は、IPAから音節と強勢を数えてコード側でも判定して上書きしました。

「音声を判定する」のではなく、「音声を書き起こす」と「書き起こしを比較する」に分けたのが、効いたと考えています。ただし、①から③では聞き手のモデルも gpt-audio から gpt-audio-1.5 に替えているので、方式だけの効果とは切り分けられていません。拒否がなくなったのは、モデル差の可能性が大きいです。

特定の語を再確認するときの落とし穴

一括判定のあとで、sakeの音声を作り直して、「本当に直ったか」を確かめる場面がありました。そのときに使った簡略版(respellingだけを書かせる)と、踏んだ落とし穴です。

PROMPT = (
    "Listen to this short audio clip of a single word or phrase. "
    "Do NOT guess the spelling. Write only how it sounds, as a hyphen-separated "
    "English-style respelling with the stressed syllable in CAPITAL letters, "
    "on one line. Output nothing else."
)
  • 拒否票・ゴミ出力を除外する: 「Sorry, I can't help」「JSONを返す」「audio clipをください」などが gpt-audio-1.5 でも混ざりました。票に数えると結果が崩れるので、キーワードで除外して、有効票が3票そろうまで最大8〜14回呼びます。文脈を説明する前置きを足すと、逆に全拒否になったので、プロンプトは最小のままにしました
  • 分類は「ハイフン連結」と「空白分割」の両方に対応する: yer-SAH-kee のように語頭に別の語が連結したり、SAW KEE のように空白で分割されたりします。完全一致で数えると、実際は合っているのに不合格扱いになります
import re

# BAD: 拒否・ゴミ出力の語句パターン(例: r"sorry|can't|cannot|json|clip|please|assist")
KEE = re.compile(r"s(ah|aa|a|aw|ar)[-\s]?k(ee|ey|i)\b", re.I)   # sake の "kee"。ハイフン・空白の両方に効く
valid = [v for v in results if v and not BAD.search(v)]          # results: 聞き手の出力(複数回)
hits = sum(1 for v in valid if KEE.search(v))
  • 前後に無音を足す: 音声の前後に0.5〜0.7秒の無音をつけると、語頭の子音(g→d、b→d など)の聞き違いが減りました(全体の精度は同等でした)
  • どうしても拒否される長文は、文末だけを切り出す: ffmpegで末尾1.8秒だけにすると通ることがありました

較正用セットでの最終的な数字は、3票の多数決で「誤読の見逃し 0/50・正しい音声の誤判定 1/44」(TTS自体が意図どおり読んでいない語を除いた集合)です。TTSの実際の不良を含めた全110試行では、見逃し2%・誤判定14%でした。

本番の1,127件に当てた結果と、その「精度」

1.6万語のうち、怪しいものに絞って1,127件を判定しました(同綴り異音語・日本語由来語・外来語・フランス語・略語・特殊なIPAなど、区分ごとに抽出。1件あたり概算で約$0.003〜0.007)。

区分(抜粋) 判定数 確定不一致
同綴り異音語(lead・bowなど) 190 21
日本語由来語 309 40
外来語 248 26
略語(語読み型) 79 16
短すぎる音声 ※後述の雑音 37 35
対照群(普通の語) 60 2
全体(他の区分を含む) 1,127 165

(フランス語44件・特殊なIPA24件など、他の区分は省略しています。)

対照群(60語)でも2件、約3%が「不一致」と出ます。これくらいは方式自体の誤検出とみて差し引く必要があります(60語なので、あくまで目安です)。標識をつけた区分は、それより高く出ています。

ここで大事なのは、確定不一致165件から無作為に32件を選んで、書き起こし・IPA・辞書の発音を突き合わせて再点検したところ、「実際の読み違い」と言えるのは約2/3(21件)だったことです。この段階では耳では聴いていません(書き起こしテキストの再点検です)。残りは、判断が分かれる差、アクセント差(アメリカ英語の t が d のように聞こえる等)、IPA表記の側の問題、判定器の誤検出でした。判定器は、粗い差(別の語として読む・強勢位置・子音・音節数・文字読み)には強い一方、母音の微妙な違いや語尾の弱母音は信用できません。

「AIが不一致と言った」だけでは直さず、直す候補は、最終的に自分の耳で聴いてから差し替える、という運用にしました。

別の不良: 「シュド」という雑音

調べている途中で、別の種類の不良が見つかりました。ファイルサイズがちょうど5,760バイト(0.36秒)の音声が、「シュド」という無内容の雑音になっていました。音声ディレクトリ全体で193ファイルです。

  • 35語(5,760Bの33語と、極端に短い数語)を原綴りで再合成して判定したところ、24語は合格、11語は不合格。そのうち chin・troops・speaker・feedback は、3回とも同じ「シュド」でした(同じ綴りで繰り返し壊れる語がある)
  • 末尾に「.」を足す、単語を2回言わせる(chin, chin)と直る例があった
  • 実際にアプリが使う139本は、文字起こしで内容を確かめながら再生成して差し替えました(133本は1回目で成功、6本は2回目)。無料の範囲の基本語(cow・face・rice など)も29語壊れていたので、最初の印象を損なっていたはずです

そこで「返ってきたmp3が短すぎるときは、キャッシュせず再試行する」ガードを入れました。ところが、後で全数を調べると、サイズの閾値だけでは足りないことが分かりました。

全数検査: 33,128本を文字起こしで照合

「壊れた音声は、文字起こしすれば別の語になるはず」と考えて、gpt-4o-transcribe(英語プロンプト付き)で、本番の単語音声のうち本文が現在の語と一致する**33,128本(男女2声ぶん)**を文字起こしし、綴りと照合しました(軽量な文字起こしモデルは、英語の音声を日本語や韓国語の文字で返すことがあり、不向きでした)。

  • エラー0、費用は約$6.4(約¥970)、所要は約26.5分
  • 一致度が低い272本を、別の設定(mini+プロンプト・プロンプトなし・whisper)で二次確認
  • 括弧つき・略語・数字・同音語・STT側の拒否(不適切語など)を除いた結果、壊れている疑いが強いものが約20本、「別の語に聞こえる」ものが約60本

サイズで見分けられない例もありました。8KB未満の音声(十数本を抽出)を文字起こしすると、ほぼ全てが不良でした(3,456Bの音声が「체크해봐」、6,528Bが「Gitarren」など。壊れた音声には、gpt-4o-transcribe でも韓国語などが返ります)。さらに8,832Bの音声(thumb→「Hair」)や、9,600Bの音声にも不良が混じっていました。バイト数だけでは判別できません。

対応としては、疑いの強いものを再生成して、綴りと0.9以上一致した42本だけを差し替えました(同音語や、綴りと発音が食い違う語 knee・eye・owe・mosque・pho などは「元が正しい可能性」で除外)。この差し替えも、文字起こしとの一致度だけで決めていて、耳では確認していません。壊れた音声の実際の発生率は、**33,128本中の約0.1〜0.2%**でした。

いまは、合成のたびにも照合している

全数検査は一度きりなので、音声を新しく作るたびに、短いテキスト(40字以内)は文字起こしで照合するようにしました。別の語に聞こえたら再試行(最大3回)、最後まで晴れなければ最も綴りに近い音声を採用します(同音語で「再生できない語」を作らないため)。費用は1回あたり約$0.0001、遅延は約1〜2秒です。

限界

  • 耳での確認は、まだ一部だけです。判定は「別の音声LLMが書き起こした音」と「IPA」の照合で、真値は聞き手のモデルに依存します
  • 判定器は、同じ系統(OpenAI)のTTSの音声を、同じ系統のモデルで聞いているので、系統的な聞き違いは3票でも残りえます
  • 詳しく調べたのは、怪しいものに絞った1,127語(全1.6万語の約7%)です。残りの約1.5万語の潜在的な不良は未確認です(全件を照合するのは、費用の面で見送りました)
  • 一括判定の総費用は、較正込みで約$8でした(単価は概算です)
  • 音素認識器(wav2vec2系など)は試していません。IPAの表記ゆれ(米英・辞書差)と相性が悪そうで、LLMの書き起こしのほうが構造を比較しやすいと考えたためです

学んだこと

  • **「AIに一致を聞く」より「AIに聞こえた音を書かせて、人間側のコードで比べる」**方向のほうが、私の環境ではうまくいった(モデルの更新も混ざっているので、断定はできません)
  • AIの判定は「候補を絞る道具」。確定不一致の精度は、書き起こしの再点検で約2/3。直す前に、自分の耳で聴く
  • サイズや長さのような簡単な指標は、不良の一部しか捕まえない。全数を安く検査できるなら、全数を見るほうが早い(約$6.4で済んだ)
  • TTS自体が意図どおり読まない語が混ざると、判定器の較正が崩れる(真値が怪しい語は除いて評価した)

試してみたい方へ

ログイン不要ですぐ単語・フレーズを閲覧できます。発音記号は登録なしでも見られます。

→ https://study.nyangailab.com/?utm_source=qiita&utm_medium=social&utm_campaign=q03_tts_verify

質問・感想・「その検証、穴があるのでは」等のツッコミ、歓迎です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?