メインコンテンツへスキップ
友田 陽大
音源分離・音声前処理
音源分離
Whisper
文字起こし
音声処理
Python
ASR
MLOps

音源分離でWhisperの文字起こし精度を上げる:音声前処理パイプライン設計

BGMや雑音が乗った音声の文字起こし精度を、音源分離(Demucs / UVR5)の前処理で底上げする方法を解説。ボーカル抽出→16kHz正規化→VAD→Whisperのパイプラインを実コードで示し、いつ効いていつ逆効果か、jiwerでのWER実測、冪等性・コスト・可観測性まで、本番運用の設計を網羅します。

公開日
読了時間
12分
著者
友田 陽大
シェア

この記事のゴール

「BGMが大きくて文字起こしが崩れる」「ライブ音源・街頭インタビューの認識精度が出ない」——Whisper を本番で使うと必ずぶつかる壁です。多くの人はモデルを大きく(large-v3へ)したり、プロンプトを工夫したりしますが、もっと効く打ち手は入力側にあります——音源分離で「声」だけを抜いてからASRに渡すことです。

本稿は、音源分離(Demucs / UVR5・MDX-Net)を前処理に使ってWhisperの精度を上げる設計を、実コードで示します。読み終えたときに、次ができる状態を目指します。

  1. なぜBGM・雑音が文字起こしを壊すのかを理解し、前処理パイプラインを設計できる。
  2. 「分離 → 正規化 → VAD → Whisper」を実装し、効果をWERで実測できる。
  3. いつ効いて・いつ逆効果かを見極め、コストに見合う形で本番適用できる。

筆者について(信頼性の開示):私は、動画をアップロードするだけで「音声分離 → 文字起こし → 翻訳 → 多言語吹き替え → 口元同期」まで全自動化するAI動画ローカライズ基盤を単独で設計・実装し、本番運用しています。第1段の音源分離と第2段の文字起こしは直結しており、前処理の良し悪しが後段すべて(翻訳・要約・字幕)の品質を決めます。本稿は、その繋ぎ目で実際に効いた前処理の記録です。


30秒のまとめ

観点結論
なぜ効くかWhisperはBGM・歓声・雑音が苦手。声だけ抜くと音素が際立ち、音楽/ノイズ下のWERが下がる
パイプライン分離(--two-stems=vocals)→ 16kHzモノ正規化 → VAD(非音声除去)→ Whisper → 後処理
使う分離ツール声/伴奏の2分離で十分。Demucs --two-stems=vocals か UVR5(MDX-Net)のVocal系
いつ効くBGM・音楽・雑踏・低SNRの音声(動画・ライブ・街頭・配信)
いつ逆効果元がクリーンな音声(分離アーティファクトが悪さをする)/歌唱・重唱
採否の決め方自分の素材でWERをA/B実測(jiwer)。感覚で決めない
コスト分離のGPU時間が乗る。音楽検出ゲートで必要な時だけ適用、VADで無音を捨てる
本番設計sha256冪等キャッシュ・構造化ログ(SNR/WER/適用有無)・過剰VAD対策

パイプラインの全体像はこの図です。


なぜBGM・雑音が文字起こしを壊すのか

Whisperを含む音声認識(ASR)は、「人の声(音声)」を主対象に学習されています。そこへBGMや歓声、機械音が混ざると何が起きるか。

  • 音素のマスキング:音楽のエネルギーが、子音・母音の微細な特徴を覆い隠す。特に子音(s/t/k など)は弱く、BGMに埋もれやすい。
  • 誤った言語モデル推論:歌詞・コーラスを「話し言葉」と誤認し、存在しない単語を幻覚する(ハルシネーション)。
  • タイムスタンプのズレ:音楽のリズムを発話境界と取り違え、字幕の同期が崩れる。

結果として、WER(Word Error Rate、単語誤り率。低いほど良い)が悪化します。モデルを大きくしても、入力が濁っていれば限界がある。ならば入力をきれいにする——それが音源分離による前処理です。声と伴奏を分け、声のトラックだけをASRに渡すことで、Whisperは「自分の得意分野」に集中できます。


前処理パイプラインの全体像

  入力音声(動画/配信/録音)
        │
        ▼
 ① 音源分離   ── Demucs --two-stems=vocals  →  vocals.wav(声だけ)
        │                                       no_vocals.wav(BGM・効果音)※吹替で再利用
        ▼
 ② 正規化     ── ffmpeg で 16kHz / モノラル / wav に統一(Whisperの想定形)
        │
        ▼
 ③ VAD        ── 発話区間だけ残す(無音・非音声を捨てる=精度↑・コスト↓)
        │
        ▼
 ④ Whisper    ── 文字起こし(self-host or API)
        │
        ▼
 ⑤ 後処理     ── タイムスタンプ整形・用語辞書補正・句読点

各段の**狙い(SRP)**を1行で。

  • ①分離:声を伴奏・雑音から切り離す。WER改善の本体。
  • ②正規化:Whisperは16kHzモノラルを想定。フォーマットを揃えて再現性を上げる。
  • ③VAD:非音声を捨て、幻覚を減らし、Whisperの処理コストも下げる。
  • ④ASR:きれいな声だけを起こす。
  • ⑤後処理:用途(字幕・議事録・翻訳)に整える。

実装:分離 → 正規化 → VAD → Whisper

① 声を抜く(音源分離)

声/伴奏の2分離で十分です。Demucsなら--two-stems=vocalsの1コマンド。

# vocals.wav(声)と no_vocals.wav(BGM・効果音)に分離
demucs --two-stems=vocals -o sep input.wav
# → sep/htdemucs/input/vocals.wav をASRに回す
#   no_vocals.wav は吹き替え時のBGM再利用に取っておく(ローカライズ用途)

ツール選定(Demucs vs UVR5 など)は選定の記事に。声の明瞭さ最優先なら、ボーカル特化のUVR5(MDX-Net) Vocal系も有力です。

② 16kHzモノラルに正規化

Whisperは内部で16kHzを想定します。ここを揃えないと再現性が落ち、稀に音ズレします。

# 分離後のvocalsを 16kHz / モノラル / PCM wav に統一
ffmpeg -y -i sep/htdemucs/input/vocals.wav -ar 16000 -ac 1 -c:a pcm_s16le vocals_16k.wav

③ VADで非音声を捨てる

無音・笑い声・拍手などの非音声区間を落とすと、幻覚が減り、Whisperのコストも下がります。silero-vad が定番です。

import torch

# silero-vad: 発話区間(タイムスタンプ)を返す軽量VAD
model, utils = torch.hub.load("snakers4/silero-vad", "silero_vad", trust_repo=True)
get_speech_timestamps, _, read_audio, *_ = utils

wav = read_audio("vocals_16k.wav", sampling_rate=16000)
speech = get_speech_timestamps(wav, model, sampling_rate=16000)
# speech = [{"start": サンプル, "end": サンプル}, ...]:発話だけ抜き出してASRへ

⚠️ 過剰VADの罠:閾値を上げすぎると語頭・語尾を削り、かえってWERが悪化します。VADは「明らかな無音」を落とす程度に留め、**前後に余白(padding)**を付けるのが安全。後述のWER実測で、VADあり/なしも比較します。

④ Whisperへ

きれいになった声を文字起こしします。self-host vs API の選定・コストはWhisperの記事に。

whisper vocals_16k.wav --language ja --model large-v3 --output_format srt

効果をWERで実測する(感覚で決めない)

ここが本稿で最も重要です。「分離したら良くなった気がする」では本番に載せられません。自分の素材で、分離あり/なしのWERを数値比較します。正解テキスト(リファレンス)を用意し、jiwerで測ります。

from jiwer import wer

# 同じ音声を「分離なし」「分離あり」で起こし、正解と比較
reference = "本日はお集まりいただきありがとうございます"          # 正解
hyp_raw      = transcribe("input_16k.wav")                       # 分離なし
hyp_separated = transcribe("vocals_16k.wav")                      # 分離あり

print("WER (raw):      ", wer(reference, hyp_raw))
print("WER (separated):", wer(reference, hyp_separated))
# 例: raw=0.32 → separated=0.11 のように下がれば、その素材では分離が効いている

評価の作法

  • 代表サンプルを10〜30本用意する(ジャンル・SNR・話者がばらつくように)。
  • WERの中央値で比較する(1本の外れ値に引きずられない)。
  • 分離あり/なし、VADあり/なしを組み合わせて表にする。「いつ効くか」が見える。

この「候補を同じ素材・同じ指標で並べて選ぶ」姿勢は、音源分離ツールの選定(museval記事)と同じ哲学です。


いつ効いて、いつ逆効果か(正直な話)

音源分離の前処理は万能ではありません。誠実に線を引きます。

入力の素性分離前処理の効果
BGM・音楽が大きい(動画・配信・CM)◎ 大きく効く。WERが目に見えて下がる
雑踏・環境音(街頭・店内・車内)○ 効く。声が際立つ
クリーンな会議・電話(BGMなし)△〜× 逆効果も。分離アーティファクトが微妙に悪さをする場合がある
歌唱・重唱(カラオケの歌詞起こし)× 苦手。語と音程・重なりが絡み、ASR自体が不得手

結論「音楽・雑音が混じる素材」には積極的に、「元がクリーンな音声」には不要(むしろ測って判断)。だからこそ、前項のWER実測で素材ごとに採否を決めるのが正解です。


コスト最適化:必要な時だけ分離する

分離はGPU時間がそのままコストです。全件に常時かけるのは無駄。ゲートを設けます。

  • 音楽/SNR検出ゲート:簡易な音楽検出(または平均SNR推定)で、BGMが有意な区間だけ分離に回す。クリーンなら素通し。
  • VADで無音カット:発話区間だけWhisperに渡せば、ASR側のコストも下がる(無音を起こさない)。
  • 冪等キャッシュsha256(音源 + パラメータ)で結果をキャッシュ。同じ素材の再分離をゼロに。
def needs_separation(audio_path: str, *, snr_threshold_db: float = 15.0) -> bool:
    """BGM/雑音が有意なクリップだけTrue。クリーンな音声は分離をスキップしてコストを節約。"""
    snr = estimate_snr_db(audio_path)        # 簡易SNR推定(声と背景のエネルギー比)
    return snr < snr_threshold_db            # SNRが低い=背景が大きい=分離が効く

私の基盤では、この「音楽がある所だけ分離 + VADで無音スキップ」で、前処理のGPUコストを必要最小限に抑えています。**本番設計(冪等性・回復性・可観測性)の詳細は音源分離を本番APIにする記事**に。


本番で詰まる落とし穴

  • サンプルレート不一致:分離出力は44.1kHz、Whisperは16kHz想定。正規化を必ず挟む(②)。これを忘れると稀に音ズレ・精度低下。
  • 過剰VADで語頭欠け:VADを攻めすぎると単語の頭を削る。控えめ+paddingで。WERで検証。
  • アーティファクトの混入:分離が強すぎると、声に金属的なノイズが乗りASRが誤る。クリーン素材には分離しない判断を。
  • 二重処理:同じ音源を分離→起こしを何度も回すと、GPU×API代が二重に乗る。冪等キャッシュで防ぐ。
  • 可観測性の欠如:どのクリップで分離を適用し、SNR/WERがどうだったかを構造化ログに残す。後から「なぜこの回だけ精度が悪い」を追える状態に。音声内容(PII)はログに出さない

よくある質問(FAQ)

Q. Whisperをlarge-v3にすれば分離は要らない? A. モデル拡大と前処理は別の効き方です。BGMが大きい素材では、largeにしても分離前処理の上積みが出ることが多い。両方を実測して費用対効果を見てください。

Q. 分離ツールはDemucsとUVR5どちら? A. 声の明瞭さ最優先ならUVR5(MDX-Net)のVocal系、手軽さ・総合力ならDemucs --two-stems=vocals。WER実測で並べて選ぶのが確実(選定記事)。

Q. リアルタイム字幕にも使える? A. 分離は基本オフライン処理でレイテンシが乗ります。準リアルタイムまでが現実的。厳密なライブは、軽量分離+ストリーミングASRの別設計を検討。

Q. 歌の歌詞を起こしたい。 A. 苦手領域です。歌唱はASR自体が不得手で、分離しても限界がある。専用の歌詞認識手法を検討してください。

Q. WERのリファレンス(正解)が無い。 A. 少数でいいので人手で正解を作るのが結局最速です。10本でも、分離あり/なしの傾向は十分見えます。


まとめ:精度は「モデル」より「入力」で決まることがある

文字起こしの精度を上げる、と聞くと多くの人はモデルやプロンプトに向かいます。しかし入力が濁っていれば、どんな高性能モデルも本領を出せません。音源分離で声をきれいにする前処理は、BGM・雑音が混じる素材で最も費用対効果の高い一手です。

実装の道筋はシンプルです。

  1. 分離(声を抜く)→ 16kHz正規化 → VAD → Whisper のパイプラインを組む。
  2. 自分の素材でWERをA/B実測し、「いつ効くか」を見極める。
  3. 音楽検出ゲート+冪等キャッシュで、必要な時だけ・一度だけ分離する。

そして——この「繋ぎ目の設計」こそ、外注で差がつくところです。WhisperやDemucsを単体で動かすのは誰でもできますが、前処理と後段を一本のパイプラインとして繋ぎ、WERで検証し、コストを刻むのは、実運用の経験がそのまま品質になります。

私は、本稿の前処理を実際に本番運用しているAI動画ローカライズ基盤の「分離→文字起こし」の繋ぎ目で実装しました。文字起こし・翻訳・字幕・吹き替えを含む音声/動画AIパイプラインの構築をお考えなら、実績をご覧のうえご相談ください。一人 × 生成AIで、速く・安く・安全に作ります。


出典・関連リソース

※ 効果は素材に強く依存します。本番適用前に必ず自分のデータでWERを実測してください。

友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事で解説した技術の適用事例

AI動画ローカライズ・リップシンク基盤

ケーススタディを見る