# 音源分離でTTS/ASR学習データを作る：クリーン音声データセットの前処理パイプライン

> TTS・ASRモデルの学習データを、音源分離（UVR5/Demucs）でクリーン化して量産する方法を解説。BGM・雑音の除去→リサンプル→VAD分割→品質ゲート→マニフェスト生成のパイプラインを実コードで示し、いつ分離が効き・いつ逆効果か、残留エネルギーでの品質判定、冪等性・コスト、そして音声データの同意とライセンスのガバナンスまで、本番のデータ基盤設計を網羅します。

- 公開日: 2026-06-25
- 著者: 友田 陽大
- タグ: 音源分離, TTS, ASR, データセット, 音声前処理, Python, MLOps, AI音声
- URL: https://tomodahinata.com/blog/source-separation-tts-asr-training-data-preprocessing

## 要点

- 学習データの質がTTS/ASRの質を決める。BGMや雑音が乗った音声で学習すると品質が落ちるため、音源分離で声だけを抽出してクリーンなコーパスを作る
- パイプラインは『分離(声抽出)→リサンプル(ASR=16k/TTS=22-24k)→VADで無音/非音声を捨てる→品質ゲート→重複除去→マニフェスト生成』。各段を冪等・再現可能に組む
- 推論時の文字起こし精度向上（別記事）とは目的が違う。本記事は学習用データセット構築。分離アーティファクトはTTSの自然性を損なうこともあり、クリーン録音には不要
- 品質ゲートは残留音楽エネルギー・無音率・長さ・（正解ありの保留セットでは）SI-SDRで自動選別。明らかな不良を機械で弾く
- 音声データは同意とライセンスが最重要。特にTTS/ボイスクローン用途は話者の明示的同意とPII管理を設計に組み込む

---

## この記事のゴール

TTS（音声合成）や ASR（音声認識）のモデルを学習・ファインチューニングするとき、品質を決める最大の要因は**モデルでもハイパラでもなく、学習データの「質」**です。BGM・笑い声・環境音が混ざった音声で学習すれば、出力もそれを引きずります。

そこで効くのが **音源分離による前処理**——曲や動画から**声だけを抜き出し、クリーンな音声コーパスを量産**する。本稿は、その**データセット構築パイプライン**を、設計と動くコードで示します。読み終えたとき、あなたは次を組めます。

1. **収集音声 → 分離 → リサンプル → VAD分割 → 品質ゲート → マニフェスト**の前処理基盤を設計できる。
2. **いつ分離が効き、いつ逆効果か**を判断し、無駄な処理を避けられる。
3. **音声データの同意・ライセンス**を、データ基盤の設計に最初から織り込める。

> 📐 **この記事の立ち位置**：「いま手元の音声を**より正確に文字起こしする**」前処理は[Whisper精度向上の記事](/blog/source-separation-asr-preprocessing-whisper-accuracy)で扱っています。本稿は目的が異なり、**モデルを学習させるためのクリーンなデータセットを作る**話です。推論前処理とデータ構築は似て非なるもの——本稿はデータ基盤側を扱います。

> **筆者について**：私は音声分離を第1段に持つ **AI音声・動画基盤を単独で設計・実装し、本番運用**しています。学習データの前処理は、モデル性能を底上げする「地味だが最も効く」工程。本稿はその実装知見です。分離モデルの選定は[選定ガイド](/blog/music-source-separation-tool-selection-demucs-uvr-spleeter)に。

---

## 30秒のまとめ（結論を先に）

| 論点 | 結論 |
| --- | --- |
| **なぜ分離するか** | BGM・雑音入り音声で学習すると品質劣化。**声だけ抽出**してクリーン化する |
| **パイプライン** | 分離(声) → リサンプル → VAD分割 → 品質ゲート → 重複除去 → マニフェスト |
| **リサンプル** | **ASR=16kHzモノラル**、**TTS=22.05/24kHz**が一般的（目的のモデルに合わせる） |
| **品質ゲート** | 残留音楽エネルギー・無音率・長さ・（正解ありなら）SI-SDR で自動選別 |
| **分離の使いどき** | BGM/雑音入り素材に有効。**クリーンなスタジオ録音には不要**（アーティファクト混入リスク） |
| **モデル** | クリーン重視なら高品質モデル（[RoFormer](/blog/bs-roformer-mel-band-roformer-vocal-separation-guide)）、量重視なら[MDX-Net](/blog/uvr5-mdx-net-vocal-separation-production-guide) |
| **ガバナンス** | **同意・ライセンス・PII**が最重要。特にTTS/ボイスクローンは話者同意が必須 |

---

## なぜ学習データの質がすべてを決めるのか

機械学習の鉄則「**garbage in, garbage out**」は、音声でこそ顕著です。

- **TTS**：学習音声に BGM が混ざっていると、合成音にも**背景のにじみ・不自然な質感**が出る。話者の声だけをクリーンに学習させたい。
- **ASR**：雑音・音楽が混ざったデータで学習すると、**ノイズに対する頑健性は上がるが、クリーン音声での精度や転写の安定性**に影響しうる。用途に応じてクリーン/ノイズ入りを設計的に混ぜる。

YouTube・ポッドキャスト・映画など**「声 + BGM」の素材から音声コーパスを作る**とき、音源分離は**声だけを取り出す前処理**として効きます。逆に、**最初からクリーンなスタジオ録音**には分離は不要で、かけると分離アーティファクトがかえって品質を下げることもあります（後述）。

---

## パイプライン全体像

```text
収集音声(声+BGM)
   │
   ├─① 音源分離 → ボーカル(声)だけ抽出          [UVR5 / RoFormer / Demucs]
   │
   ├─② リサンプル/モノラル化                     [ASR=16k / TTS=22.05k or 24k]
   │
   ├─③ VAD で無音・非音声を捨て、発話単位に分割   [Silero VAD 等]
   │
   ├─④ 品質ゲート（不良を機械で弾く）            [残留音楽 / 無音率 / 長さ / SI-SDR]
   │
   ├─⑤ 重複・ニアデュープ除去                    [ハッシュ / 音響指紋]
   │
   └─⑥ マニフェスト生成（音声↔メタの対応表）     [JSONL / CSV]
```

各段は **冪等・再現可能**に組みます（同じ入力に同じ出力）。途中で落ちても、済んだ段はスキップして再開できるように。

---

## 実装：分離 → リサンプル → VAD → 品質ゲート → マニフェスト

### ① 声を抽出する（バッチ）

```python
# extract_vocals.py — 収集音声から声だけを抽出（モデルは1回ロードして使い回す）
from pathlib import Path
from audio_separator.separator import Separator

sep = Separator(output_dir="stage1_vocals", output_format="flac",
                output_single_stem="Vocals")          # 声だけ書き出し
sep.load_model(model_filename="Kim_Vocal_2.onnx")     # 量産はMDX系が軽快

def extract(src: Path) -> str:
    return sep.separate(str(src))[0]                   # 抽出した声のパス
```

クリーンさを最優先するなら、モデルを [BS-RoFormer](/blog/bs-roformer-mel-band-roformer-vocal-separation-guide) に替えます（重いが高品質）。大量処理なら MDX系で速度を取る——**品質と量のトレードオフ**を用途で決めます。

### ② リサンプル & モノラル化

学習対象のモデルに**サンプルレートを合わせます**。一般的には **ASR は 16kHz モノラル**、**TTS は 22.05kHz か 24kHz**。

```python
# normalize.py — 目的に合わせてリサンプル/モノラル化
import subprocess

def to_target(src: str, dst: str, sr: int) -> None:
    # ffmpegで確実に。-ac 1=モノラル, -ar=サンプルレート
    subprocess.run(["ffmpeg", "-y", "-i", src, "-ac", "1", "-ar", str(sr), dst],
                   check=True)

# ASR用: to_target(v, "asr/clip.wav", 16000)
# TTS用: to_target(v, "tts/clip.wav", 24000)
```

### ③ VAD で発話単位に分割

長い音声を**発話（発声区間）単位**に切り、無音・非音声を捨てます。これで「無音だらけのクリップ」を学習に混ぜずに済みます。

```python
# segment.py — VADで発話区間に分割（例: Silero VAD）
import torch

model, utils = torch.hub.load("snakers4/silero-vad", "silero_vad")
(get_speech_timestamps, _, read_audio, *_), = (utils,)

def speech_segments(wav_path: str, sr: int = 16000):
    wav = read_audio(wav_path, sampling_rate=sr)
    ts = get_speech_timestamps(wav, model, sampling_rate=sr)  # 発話区間
    return [(t["start"], t["end"]) for t in ts]              # サンプル位置の配列
```

### ④ 品質ゲート（不良を機械で弾く）

ここが**データセットの質を守る要**です。明らかな不良クリップを自動で除外します。

```python
# quality_gate.py — クリップを機械的に選別する
import numpy as np
import soundfile as sf

def passes_quality(path: str, *, min_sec=1.0, max_sec=15.0,
                   max_silence_ratio=0.5) -> bool:
    audio, sr = sf.read(path)
    dur = len(audio) / sr
    if not (min_sec <= dur <= max_sec):
        return False                                   # 短すぎ/長すぎを除外
    # 無音率：振幅が極小なサンプルの割合
    silence = float(np.mean(np.abs(audio) < 1e-3))
    if silence > max_silence_ratio:
        return False                                   # 無音だらけを除外
    return True
```

正解（原ステム）がある**保留セット**では、`SI-SDR` で分離品質そのものを採点し、閾値以下を弾けます（測り方は[品質評価ガイド](/blog/music-source-separation-quality-evaluation-sdr-museval)）。正解が無い本番素材では、**伴奏側に残った音楽のエネルギー比**を「分離の漏れ」の代理指標に使います。

### ⑤⑥ 重複除去 & マニフェスト生成

```python
# manifest.py — 重複を除き、学習フレームワークが読む対応表を作る
import hashlib, json
from pathlib import Path

def content_hash(path: Path) -> str:
    h = hashlib.sha256()
    with path.open("rb") as f:
        for b in iter(lambda: f.read(1 << 20), b""):
            h.update(b)
    return h.hexdigest()

def build_manifest(clips_dir: str, out_jsonl: str) -> int:
    seen: set[str] = set()
    n = 0
    with open(out_jsonl, "w", encoding="utf-8") as w:
        for clip in sorted(Path(clips_dir).glob("*.wav")):
            key = content_hash(clip)
            if key in seen:
                continue                               # 完全重複を除外
            seen.add(key)
            w.write(json.dumps({"audio": str(clip)}, ensure_ascii=False) + "\n")
            n += 1
    return n                                            # 採用クリップ数
```

ASR ならここに**書き起こしテキスト**（人手 or [Whisper](/blog/openai-whisper-production-guide-selfhost-vs-api) で生成→検収）を、TTS なら**話者ID・テキスト**を対応づけます。

---

## いつ分離が効いて、いつ逆効果か（正直な話）

音源分離は万能ではありません。**かけない方が良い場面**もあります。

| 素材 | 分離すべき？ |
| --- | --- |
| YouTube/ポッドキャスト（声+BGM） | ✅ 効く。声を抽出してクリーン化 |
| 映画/ドラマ（声+効果音+音楽） | ✅ 効く（難度は上がる） |
| **スタジオ録音のクリーン音声** | ❌ 不要。分離アーティファクトで**かえって劣化**しうる |
| すでに声だけのナレーション | ❌ 不要 |

> 💡 **TTS では特に注意**：分離は微細なアーティファクト（高域のにじみ等）を残すことがあり、それが**合成音の自然性**に響きます。クリーンに録れる素材は分離せず、**分離は「汚れた素材を救う」手段**と位置づけるのが正解です。

---

## コスト・冪等性・可観測性

大量の音声を処理するデータ基盤は、本番システムと同じ規律で組みます。

- **冪等性**：各段の出力を**入力の内容ハッシュ**で決定論的に命名し、済みはスキップ。再実行で二重処理しない。
- **コスト**：分離は GPU を食う最重工程。**必要な素材だけ分離**（クリーン素材は素通し）し、モデルは用途で軽重を選ぶ。
- **可観測性**：各段の**通過数・除外数・除外理由**を記録。「なぜこのクリップが落ちたか」を後から追える状態に。
- **スケール**：数千件超は[GPUワーカー基盤](/blog/music-source-separation-production-api-gpu-worker-queue)や[AWSバッチ](/blog/audio-source-separation-aws-gpu-batch-pipeline)に載せる。GPUが効かない等の沼は[トラブルシューティング](/blog/uvr5-audio-separator-troubleshooting-gpu-cuda-oom)へ。

---

## ⚠️ データガバナンス：同意とライセンスが最重要

学習データは、**技術以前にガバナンスの問題**です。ここを外すと、作ったモデル自体が使えなくなります。

- **音源のライセンス**：収集元（市販曲・配信音声等）の**学習利用が許諾されているか**を確認。著作物の無断学習は法的リスク。
- **話者の同意（特にTTS/ボイスクローン）**：実在話者の声で TTS を学習するなら、**本人の明示的同意**が必須です。声は本人性に直結する情報——同意・用途・撤回手段を設計に組み込みます（同意ガバナンスの考え方は[ボイスクローンの同意設計記事](/blog/qwen-tts-voice-cloning-self-hosting-consent-governance-guide)に）。
- **PII**：書き起こしや音声に含まれる個人情報の取り扱い・保管・マスキングを規定する。
- **来歴（provenance）**：各クリップの**出所・ライセンス・同意状態**をマニフェストに残し、監査可能にする。

---

## よくある質問（FAQ）

**Q. 推論時の文字起こし前処理と何が違う？**
A. 目的が違います。[Whisper精度向上の記事](/blog/source-separation-asr-preprocessing-whisper-accuracy)は「**いまの音声を正確に転写する**」話。本記事は「**モデルを学習させるためのクリーンなデータセットを作る**」話です。パイプラインは似ていても、出口（マニフェスト・品質ゲート・ガバナンス）が異なります。

**Q. どのモデルで分離すべき？**
A. **クリーンさ最優先なら[RoFormer](/blog/bs-roformer-mel-band-roformer-vocal-separation-guide)**、**量・速度優先なら[MDX-Net](/blog/uvr5-mdx-net-vocal-separation-production-guide)**。データセット規模とGPU予算で決めます。

**Q. サンプルレートは何にすべき？**
A. **学習対象モデルに合わせます**。ASR（Whisper系）は **16kHz モノラル**、TTS は **22.05/24kHz** が一般的。途中の分離は44.1kHzで行い、最後に目的SRへリサンプルする流れが安全です。

**Q. クリーンな録音にも分離をかけるべき？**
A. **いいえ**。分離はアーティファクトを残しうるため、クリーン素材には不要——かえって品質を下げることがあります。分離は「汚れた素材を救う」用途に限定するのが定石です。

**Q. 品質ゲートは何で判定する？**
A. 長さ・無音率・残留音楽エネルギーなどの**機械指標**で明らかな不良を弾き、正解がある保留セットでは **SI-SDR** で分離品質を採点します（[品質評価ガイド](/blog/music-source-separation-quality-evaluation-sdr-museval)）。

---

## まとめ：モデルの前に、データを整える

TTS/ASR の品質は、**学習させる前のデータ整備でほぼ決まります**。

1. **声を抽出してクリーン化**（汚れた素材のみ。クリーン録音は素通し）。
2. **目的SRへリサンプル → VAD分割 → 品質ゲート → 重複除去 → マニフェスト**。
3. **冪等・コスト最適・可観測**に組み、スケールは GPU バッチ基盤へ。
4. **同意・ライセンス・PII・来歴**をデータ基盤に最初から織り込む。

> 「モデルを学習させる」前の**データ基盤こそ、品質と法的安全性の分かれ目**です。TTS/ASR のためのクリーンな音声データ基盤を本番品質で構築したい方は、[実績](/case-studies/ai-video-localization-lipsync)とともにご相談ください。**一人 × 生成AI**で、データ収集から学習・運用まで一気通貫で支援します。

---

## 出典・関連リソース

- **分離ライブラリ**：[nomadkaraoke/python-audio-separator（MIT）](https://github.com/nomadkaraoke/python-audio-separator)
- **VAD**：[snakers4/silero-vad](https://github.com/snakers4/silero-vad)
- **音声I/O**：ffmpeg（リサンプル/フォーマット変換）
- **品質評価**：本ブログ [音源分離の品質を数値で測る](/blog/music-source-separation-quality-evaluation-sdr-museval)
- **モデル選定**：本ブログ [音源分離ツールの選び方](/blog/music-source-separation-tool-selection-demucs-uvr-spleeter)

※ ライブラリのAPI・推奨サンプルレートは更新されます。実装前に一次情報を確認してください。学習データの利用可否・話者同意・PII の扱いは法域やサービス規約に依存します。データ収集・利用は必ず一次情報と法務確認のうえ進めてください。
