
「Whisperで文字起こしすると、なんか変な日本語が出てくる…」
「ていうか、そもそも処理に時間かかりすぎじゃない?」
そんな風に感じたこと、ありませんか?
私も最初は「APIが重いのかな?」なんて思ってたんですが、原因はまさかの“無音”でした。
こんにちは、ノーコード+AIでちょっと便利なツールを作ってる、シランコーダーです。
今回は、英語コーチングセッションの生徒音声をWhisperで文字起こししたときに、不自然な発言が大量に出現&処理がやたら遅いという事件が発生。
「なにこれ…“アイノーダット”を10回くらい連呼してるんだけど!?」
「生徒さんそんなこと言ってないのに、なんで?」
そんな混乱から始まり、原因をひとつずつ検証し、最終的にたどり着いたのは
「音声の前処理が超大事だった」というシンプルだけど強烈な気づきでした。
この記事では、実際にどんな音声だったのか?
なにをどう処理したら、22秒で文字起こしが終わるレベルに改善されたのか?
非エンジニア視点でリアルに紹介していきます。
🔍 なにが起きた?謎の“アイノーダット”大量発生
ある日、いつもどおりWhisper APIでセッション音声の文字起こしを実行。
今回の対象は、生徒さん側の録音データ(Zoom録音の片チャンネル)です。
「処理にちょっと時間かかってるな〜」と思いつつ、しばらく待って出力されたログを確認すると…
[289.36s - 292.36s] アイノーダット
[292.36s - 294.36s] アイノーダット
[294.36s - 296.36s] アイノーダット
[296.36s - 298.36s] アイノーダット
[298.36s - 300.36s] アイノーダット
[300.36s - 302.36s] アイノーダット
[302.36s - 304.36s] アイノーダット
……おや?
生徒さん、こんなこと一言も言ってなかったはずなんですが……?
しかも、その前後にも「えー」「うん」「あー」みたいな
曖昧な発話っぽい文字が連続して出てきて、全体の内容もなにかおかしい。
これは明らかに異常。
ですが同時に、“よくある”ことでもあります。
実はこれ、Whisperが無音やノイズに「何かをしゃべってる」と勘違いしてしまったときに起きる、ありがちな現象なんです。
でも、そもそもなぜこうなってしまったのか?
その原因は次のセクションでくわしく見ていきます。
🎧 原因は“無音”? Whisperが悩んでしまう理由
今回の音声は、Zoomで録音した生徒さんのチャンネル音声。
つまり、生徒が話していない時間は、ほぼ完全に“無音”でした。
ここに問題があります。
Whisperは、音声ファイル全体を通して「人間の発話っぽいもの」を探し、文字起こしを行うAIです。
ところが、無音が続くと👇
- 📉「あれ、これなんか聞き逃してる?」と勘違い
- 🎲 とりあえず「聞こえたっぽい何か」を出そうとする
- 🌀 結果「アイノーダット」「うーん」「4時半」など謎ワードを連発…
まるで、無音のなかで幻聴を見てしまったAIのような出力になってしまうのです。
しかもこの無音部分に反応しようとするせいで、
- 文字起こしにやたら時間がかかる
- 出力が無意味な文字で埋まる
- 使いたいログが見つけにくくなる
という、地味にダメージの大きい問題が連鎖的に発生します。
では、どうすればこの“無音の罠”を回避できるのか?
🛠 事前処理で解決!ベストな音声加工手順
Whisperにとって“無音”は天敵。
でも、その無音を削除するとタイムスタンプがズレてしまう…
かといって、そのままにすると処理は遅いし、精度も落ちる。
この矛盾を解決するベストな方法がこちら👇
✅ Normalize + Compressor(音量補正)
- Normalize(ノーマライズ):
音声全体の音量を均一に調整し、小さな声も聞き取りやすくします。 - Compressor(コンプレッサー):
突発的な大きな音を抑えて、聞きやすさをアップ。
結果として、Whisperが発話部分を“発話”として認識しやすくなります。
🔎 この2つを組み合わせることで、無音に悩まず、発話だけをちゃんと拾うようになります。
✅ モノラル化+サンプリングレート統一(16kHz)
Whisperはステレオよりモノラルが得意。
また、16kHzなどの標準的なサンプリングレートでそろえることで、無駄な混乱を避けられます。
💡 実際にこの手順で処理した音声では、Whisperがスムーズに音を追えるようになり、処理時間も劇的に短縮されました。
なお、無音を完全にミュートする方法も試しましたが、Whisperが逆に困って「幻聴」を見始めてしまったので不採用に。
📌 結論:無音は削らずに“静かにする”のが正解!
次は、実際にどういう文字起こし結果が得られたかを見ていきましょう。
ただし…完璧とは言えません。その理由も合わせてご紹介します。
📄 精度は?出力結果と課題まとめ
音声をしっかり整えて、満を持してWhisperで文字起こし!
その結果、処理速度と精度にはこんな変化がありました👇
⏱ 処理スピードの改善がすごい!
- Before(生声そのまま):
1ファイルあたり最大で 5分以上 待たされることも… - After(Normalize+Compressor処理済):
同じ音声が わずか22秒 で完了!
🧠 Whisperが無音で迷わなくなり、「聞くべきところ」に集中できるようになった結果です。
✅ 精度の向上も体感レベル
- 小声・ぼそぼそ声がしっかり拾われるように
- 単語の切れ目や発話の始まりも認識しやすくなった
- 発話ごとのタイムスタンプが安定して付くように
🎉 Whisperのポテンシャルを、ようやくちゃんと引き出せた感じ!
❗ でも完全ではない。課題も…
たとえば…
[302.36s - 307.36s] Thank you for listening
[338.36s - 341.36s] Thank you for listening
[368.36s - 372.36s] Thank you for listening
[379.36s - 382.36s] Thank you for listening
[389.36s - 392.36s] Thank you for listening
💥 同じフレーズを何度も幻聴のように出力する現象は、まだ解消しきれていません。
これは無音処理とは別の問題で、Whisperが音声の“雰囲気”だけを手がかりに勝手に再生してしまうことが原因。
この対策については、後述のセクション「🔍 連打対策:幻聴ループはどう防ぐ?」で詳しく紹介します。
🧩 ファイル統合&話者付けでセッション化
音声の前処理と文字起こしが終わったら、次はセッション全体の会話ログを1つに統合する作業です。ここでは以下の3つをセットで処理します。
① divisionファイルの結合
Whisper APIにはファイルサイズ制限があるため、20MBを超える音声は分割していました。
そこで必要になるのが、divisionごとの文字起こし結果を合体させる処理。
input_audio/
├─ 〇〇__division_1.wav
├─ 〇〇__division_2.wav
└─ 〇〇__division_3.wav
↓
input_json/
└─ session_xxx_raw.json(タイムスタンプ順に結合されたログ)
② タイムスタンプ補正(division 2以降)
分割された音声は前後10秒の重複を含んでいるため、division 2以降のセグメントにはオフセットを加えて整合性をとります。
例:
division2_start_offset = 12 * 60 # 12分=720秒
segment["start"] += division2_start_offset
segment["end"] += division2_start_offset
division2_start_offset = 12 * 60 # 12分=720秒
segment["start"] += division2_start_offset
segment["end"] += division2_start_offset
これで、全体を通して正しいタイムラインが復元されます。
③ 発話者タグの自動付与
コーチと生徒の音声は別ファイルで処理しているため、話者の区別は簡単です。
{
"speaker": "coach",
"text": "じゃあ、次いってみましょうか。",
"start": 33.2,
"end": 35.1
}
これにより、セッション全体を通した「誰が何を言ったか」のログが完成!
🎯 この「話者付き・時間整列済み」のログが、レポートや分析の基礎データになります。
⚠️ Whisperの罠!?「連打ループ」と「空白ノイズ地獄」
Whisperの精度がすごいのは間違いないんですが、今回は想定外の落とし穴にハマりました。
特に「生徒の音声」によくある2大トラブルをご紹介します。
[289.36s - 304.36s] アイノーダット
[304.36s - 307.36s] アイノーダット
[308.36s - 341.36s] Thank you for listening(計4回)
生徒は一度しか言っていないのに、Whisperくんは鬼のように連打してくることがあります。
🤔 原因は?
- 無音のあとにちょっとした音が入り、その前の発言を誤って繰り返している
- 発音が不明瞭だと、Whisperが「さっきのやつかな?」と誤認
✅ 対処法(現状)
現時点では、あとで人の目でチェックして削除するしかありません。
ただし、こういった「連打っぽいフレーズ」だけを自動検知して省くルールづくりも可能です。
今後は、GPTや音響的特徴を使って対処する予定です。
🔇 ② 無音すぎてWhisperが迷子に!?
意外だったのが、無音が多すぎるとWhisperが迷うということ。
- 話してないのに「うん」「あー」と勝手に書かれる
- 空白時間に意味のない単語が補われる
🧪 実験の結果…
Normalize + Compressor をかけるだけで→ 変な発言が激減&処理速度も爆速になりました。
❌ 処理前:7分の音声に10分以上かかる+謎の連打だらけ
✅ 処理後:22秒で完了+誤認識激減
🎯 本記事の最大の学び
Whisperは優秀だけど、
「人間の話し方」に最適化されてるから、無音が多いと逆に精度が落ちる!
だからこそ👇
- Normalize + Compressor は神処理
- 完全ミュート処理はむしろ逆効果
- 今後は「発話の少ない人ほど音声前処理が重要」になる
🧩 最後のピース:「JSON構造化」&「レポート整形」へ
文字起こしが終わったら、いよいよ実用レベルの整形処理に入ります。
この段階では、「使えるデータかどうか」がすべて。
🗂 まずは構造化:session_{id}_raw.json
の完成
Whisperで得られた発話ログをベースに、以下の形式で構造化します:
{
"start": 289.36,
"end": 291.36,
"speaker": "student",
"text": "アイノーダット"
}
- 🔑
start
/end
:タイムスタンプ(divisionが複数ある場合はoffset加算済) - 🧑🏫
speaker
:処理していた音声が生徒なので、全て"student"
に固定 - 💬
text
:Whisperの認識結果(必要に応じて誤字補正も)
💡 division分割がある場合でも、すべてのログをタイムスタンプ順にソートして1つのJSONに統合しています。
この一貫性が、あとからの可視化やレポート整形の基盤になります。
📝 今回は整形ルールに未着手
今回は、「Normalize + Compressor の有効性」を検証することが主目的だったため、
整形(連打削除・誤認補正・前後文脈判断など)は未実施です。
ですが、今後のステップでは以下を計画しています:
- ✅ 変な連打(同じ単語が連続してる)をGPTで検出・削除
- ✅ 「発言の意図」や「思考のゆらぎ」なども拾えるログ整形
- ✅ コーチ音声とのマージ(話者ごとのデータを時系列で統合)
🌱 最後に:声のゆらぎを“見える化”するために
今回の検証を通して改めて思ったのは、
いい文字起こしは、感情を伝える“声のメモ”になる
ということ。
だからこそ、ただの変換ではなく👇
- 🧼 ノイズを整え
- 🕰 時系列を守り
- 💬 人の言葉らしさを保つ
この一連の流れが「AIでセッションを記録する」未来の基盤になると思っています。