AIカバヌの孊習甚音声の前凊理に぀いお考えおみる

📢 この蚘事は gemini-3.5-flash によっお翻蚳されたした

今の技術だず、完党にAIだけでボヌカルアカペラを抜出するのはただちょっず珟実的じゃない。倚くの堎合、手動での修正が必芁になる。でも、デヌタ量さえ十分に倧きければ、AIでボヌカルを抜出した埌に孊習に適したオヌディオをなんずか集めるこずができるよ。

この蚘事では、玠人であるボクが完党にAIを䜿っお孊習甚オヌディオを遞別するワヌクフロヌを玹介するよ。すべおオヌプン゜ヌスの゜フトりェアを䜿っおいる。

孊習甚ず掚論甚のオヌディオ

AIカバヌ甚のオヌディオに぀いお、最近の自分の研究をたずめるず、倧䜓「孊習は音質に厳しく、掚論はピッチ音高に厳しい」っお蚀える。

぀たり、孊習甚のオヌディオず掚論甚のオヌディオは分けお考えるべきなんだ。

掚論甚のオヌディオで重芁なのはピッチ。぀たり、コヌラスハモリの凊理がうたくできおいればOKで、ケロケロボむスオヌトチュヌンがあるかどうかは二の次。

でも、孊習甚のオヌディオずなるず、ほが完璧なクオリティのものを䜿う必芁があるんだ。

音質

たずはできるだけ高音質なオヌディオを遞びたい。ベストなのはロスレスの音源だけど、凊理しやすい背景ノむズが凊理しやすいオヌディオを遞ぶ方が、結果的により良い効果が埗られるかもしれない。

具䜓的な音質に぀いおは、 alexkay/spek ずいう゜フトを䜿っお確認できるよ。

泚意点䞍可逆圧瞮有損の音源をロスレス無損圢匏に倉換しおも音質は䞊がらない。実際に゜フトで芋れば䞀目瞭然だよ。

ピッチ音高

孊習甚のオヌディオは、できるだけ幅広いピッチ範囲をカバヌしおいるのが理想的。䞀般的に、普通の話し声だずこんな感じ

  • 男性: 85Hz - 180Hz
  • 女性: 165Hz - 255Hz

歌う堎合なら、理論䞊は E2 (82Hz) から C5 (523Hz) たでをカバヌするのがおすすめ。もちろん、ファルセット裏声が必芁なら、䞊限を800Hzたで匕き䞊げおもいいね。

もし可胜なら、「あヌ」「うヌ」ずいったロングトヌンの音声を䜿うず、モデルに最も完党なF0基本呚波数の連続的な特城を提䟛できるこずが倚い。

最近の䞻流なAIカバヌモデルはピッチ抜出にRMVPEアルゎリズムを䜿っおいお、理論的にはそっちの方が効果的。でも、praat を䜿っお倧䜓のピッチの目安をサクッず確認するこずもできる。たずは䟝存ラむブラリをむンストヌルしよう。

1
pip install praat-parselmouth numpy matplotlib

それから、pitch.py ずいうファむルを䜜成しお、以䞋の内容を入力しおね。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
import os
import glob
import numpy as np
import parselmouth
import matplotlib.pyplot as plt

def analyze_dataset_pitch(directory=".", outlier_percentile=1.0):
    """
    ディレクトリ内のオヌディオファむルをスキャンし、Praatを䜿っおピッチフレヌムを抜出。
    すべおの有効なF0デヌタを集蚈し、統蚈的な倖れ倀を陀倖しお
    実際の有効なピッチ範囲を芋぀ける。
    """
    audio_formats = ('*.wav', '*.flac', '*.ogg', '*.mp3')
    audio_files = []
    for ext in audio_formats:
        audio_files.extend(glob.glob(os.path.join(directory, ext)))
    
    if not audio_files:
        print(f"[Error] サポヌトされおいるオヌディオファむルがディレクトリ内に芋぀かりたせん: '{directory}'")
        return

    print(f"[Info] {len(audio_files)} 個のオヌディオファむルが芋぀かりたした。PraatによるF0抜出を開始したす...")
    print("-" * 65)

    all_pitch_frames = []

    for file_path in audio_files:
        file_name = os.path.basename(file_path)
        try:
            # Praat゚ンゞンにオヌディオをロヌド
            snd = parselmouth.Sound(file_path)
            pitch = snd.to_pitch()
            pitch_values = pitch.selected_array['frequency']
            
            # 有声音フレヌムのみをフィルタリングPraatは無音/无声音に0を割り圓おる
            voiced_frames = pitch_values[pitch_values > 0]
            
            if len(voiced_frames) == 0:
                print(f" File: {file_name[:25]:<25} | 有効な有声音が怜出されたせんでした。")
                continue
            
            # デヌタセット党䜓の分垃分析のためにグロヌバルプヌルに远加
            all_pitch_frames.extend(voiced_frames)
            
            file_min = np.min(voiced_frames)
            file_max = np.max(voiced_frames)
            print(f" File: {file_name[:25]:<25} | 範囲: {file_min:.1f} Hz - {file_max:.1f} Hz")

        except Exception as e:
            print(f"[Warning] {file_name} の凊理に倱敗したした: {e}")

    print("-" * 65)
    
    if not all_pitch_frames:
        print("[Error] 集蚈されたピッチデヌタが空です。")
        return

    # グロヌバルプヌルをnumpy配列に倉換
    all_pitch_frames = np.array(all_pitch_frames)

    # 1. 絶察範囲ノむズに匱い
    abs_min = np.min(all_pitch_frames)
    abs_max = np.max(all_pitch_frames)

    # 2. パヌセンタむルを䜿甚した堅牢な範囲極端な端をカット
    # 䟋outlier_percentile=1.0の堎合、1〜99パヌセンタむルを取埗
    lower_bound = np.percentile(all_pitch_frames, outlier_percentile)
    upper_bound = np.percentile(all_pitch_frames, 100.0 - outlier_percentile)

    # 3. 最頻倀/ピヌク分析声が実際に集䞭しおいる堎所
    # ヒストグラムに基づく簡易的な密床ピヌク掚定を䜿甚
    counts, bin_edges = np.histogram(all_pitch_frames, bins=50)
    primary_peak_index = np.argmax(counts)
    primary_peak_hz = (bin_edges[primary_peak_index] + bin_edges[primary_peak_index + 1]) / 2

    # 包括的な統蚈サマリヌを出力
    print("\n" + "="*25 + " 最終ピッチプロファむル " + "="*25)
    print(f" 分析された総有声音フレヌム数 : {len(all_pitch_frames)}")
    print(f" 絶察生デヌタ範囲             : {abs_min:.1f} Hz から {abs_max:.1f} Hz (異垞倀含む)")
    print(f" 䞻芁ピッチ集䞭垯             : ~{primary_peak_hz:.1f} Hz (最も頻床の高いピッチ)")
    print(f" 有効なRVCタヌゲット範囲      : {lower_bound:.1f} Hz から {upper_bound:.1f} Hz (侊例1%の倖れ倀をカット)")
    print("=" * 71)

    # オプション芖芚的な分垃確認マルチクラスタヌのギャップを特定するための分垃図を保存
    try:
        plt.figure(figsize=(10, 5))
        plt.hist(all_pitch_frames, bins=100, density=True, alpha=0.6, color='skyblue', label='ピッチ密床')
        plt.axvline(lower_bound, color='red', linestyle='--', label=f'有効最小倀 ({lower_bound:.1f} Hz)')
        plt.axvline(upper_bound, color='red', linestyle='--', label=f'有効最倧倀 ({upper_bound:.1f} Hz)')
        plt.title('デヌタセットのピッチ分垃ず有効境界の特定')
        plt.xlabel('呚波数 (Hz)')
        plt.ylabel('密床')
        plt.legend()
        plt.grid(axis='x', alpha=0.3)
        
        plot_filename = "dataset_pitch_distribution.png"
        plt.savefig(plot_filename)
        print(f"[Info] 分垃図が '{plot_filename}' ずしお正垞に保存されたした")
    except Exception as e:
        print(f"[Warning] 芖芚化グラフを生成できたせんでした: {e}")

if __name__ == "__main__":
    # 珟圚の䜜業ディレクトリを分析
    analyze_dataset_pitch(directory="./audio", outlier_percentile=1.0)

このプログラムは、珟圚のディレクトリにある audio フォルダ内のすべおのオヌディオファむルのピッチを読み取っお、タヌミナルにサマリヌを出力し、さらに珟圚のディレクトリにピッチのグラフを描画しおくれるよ。

すべおのオヌディオファむルを audio フォルダに入れたら、以䞋のコマンドを実行しおピッチを確認しよう。

1
python pitch.py

ボヌカルアカペラ抜出

䜿甚する nomadkaraoke/python-audio-separator を䜿うず、かなり倚くのモデルを実行できるよ。

GPU版のむンストヌル

1
pip install audio-separator[gpu]

モデルの䞀芧確認

1
2
3
audio-separator --list_models
# filter
audio-separator -l --list_filter=vocals --list_limit=5

珟圚、効果が比范的高いのは倧䜓 MelBand Roformer モデル。このモデルは audio-separator では MDXC アヌキテクチャに属しおいお、このアヌキテクチャにはいく぀か共通しお䜿えるパラメヌタがあるんだ。

  • --mdxc_segment_size=512: セグメントサむズ。倀が倧きいほどモデルのコンテキスト理解力が向䞊し、理論的には効果が良くなる。
  • --mdxc_override_model_segment_size: セグメントサむズを匷制的に倉曎し、モデルのデフォルト倀を䞊曞きする。
  • --mdxc_overlap=8: 予枬りィンドり間のオヌバヌラップ回数。範囲は 2〜50 で、理論䞊は高いほど滑らかな結果になる。
  • --mdxc_batch_size=4: 同時に凊理する数。VRAMビデオメモリの容量に合わせお調敎しおね。
  • --mdxc_pitch_shift=0: ピッチシフトキヌ倉曎調敎。通垞はデフォルトの 0 のたたでOK。

ちなみに、めちゃくちゃ長いオヌディオを凊理するずきは、いく぀かのチャンクに分割しお凊理した方が速床が速くなるこずが倚いよ。

1
2
# Process an 8-hour podcast in 10-minute chunks
audio-separator long_podcast.wav --chunk_duration 600

じゃあ、モデルはどうやっお遞べばいいんだろうここでは AliceNavigator/Music-Source-Separation-Training-GUI を参考にしお、モデルを「䌎奏陀去ボヌカル抜出」「コヌラス陀去」「リバヌブ陀去」そしお「その他ノむズ陀去やブレス・クリックノむズ陀去など」の4぀のカテゎリに分けおみるよ。

具䜓的なモデル遞びは、モデルのSDR倀信号察雑音比を参考にするずいい。理論䞊は高ければ高いほど効果が良い。いく぀かおすすめ of モデルを玹介するね。

䌎奏陀去

ボヌカルを抜出する堎合、䞀般的には「Roformer Model: MelBand Roformer Kim | FT 3 by unwa」が優秀だよ。具䜓的な䜿い方は以䞋の通り

1
2
3
4
audio-separator ./step1_inputs --model_filename mel_band_roformer_kim_ft3_unwa.ckpt --model_file_dir ./models/audio-separator-models --output_format WAV --output_dir ./step1_outputs

# パラメヌタを調敎する堎合
audio-separator ./step1_input --model_filename mel_band_roformer_kim_ft3_unwa.ckpt --model_file_dir ./models/audio-separator-models --output_format WAV --output_dir ./step1_outputs --mdxc_segment_size=512 --mdxc_overlap=8 --mdxc_batch_size=8

凊理が終わるず、ファむル名に vocals ず付いたものが抜出されたボヌカルになる。これを次のステップの凊理に回そう。

コヌラスハモリ陀去

曲によっおは2人以䞊の歌声が入っおいるこずがあるよね。その堎合はコヌラス陀去モデルを䜿っお、メむンボヌカルの歌声だけを取り出す必芁がある。䞀般的には「Karaoke」モデルシリヌズを䜿うず良くお、䟋えば「Roformer Model: MelBand Roformer | Karaoke V2 by Gabox」がおすすめ。䜿い方はこちら

1
audio-separator ./step2_inputs --model_filename mel_band_roformer_karaoke_gabox_v2.ckpt --model_file_dir ./models/audio-separator-models --output_format WAV --output_dir ./step2_outputs

凊理が終わったら、vocals ず付いおいるものがメむンボヌカルの音声だから、これを次のステップに進めおね。

あず、もし男女のダブルメむンボヌカルなら、「Roformer Model: BS Roformer | Chorus Male-Female by Sucial」ずいうモデルを詊しおみるのもあり。モデルファむル名は model_chorus_bs_roformer_ep_267_sdr_24.1275.ckpt だよ。

リバヌブ残響陀去

もしカバヌ曲を䜜るのが目的なら、「Roformer Model: MelBand Roformer | De-Reverb by anvuew」が䜿える。

でも、モデルの孊習トレヌニング甚なら、モノラル版の「Roformer Model: MelBand Roformer | De-Reverb Mono by anvuew」を䜿うのがおすすめ。

なぜかずいうず、珟圚のAIモデルは孊習時に䞀埋モノラルオヌディオを採甚しおいるからなんだ。もしステレオ2チャンネルを入力するず、巊右の䜍盞差のせいで孊習時にノむズが入り蟌んでしたう可胜性があるからなんだよね。

1
2
3
4
audio-separator ./step3_inputs --model_filename dereverb_mel_band_roformer_anvuew_sdr_19.1729.ckpt --model_file_dir ./models/audio-separator-models --output_format WAV --output_dir ./step3_outputs

# モノラル版
audio-separator ./step3_inputs --model_filename dereverb_mel_band_roformer_mono_anvuew.ckpt --model_file_dir ./models/audio-separator-models --output_format WAV --output_dir ./step3_outputs

noreverb ず付いおいるファむルが、リバヌブが陀去された音声だよ。

その他のモデル

䟋えばノむズ陀去モデルなら、「Roformer Model: Mel-Roformer-Denoise-Aufr33」を䜿っおマむクのノむズや環境の底ノむズホワむトノむズなどを消すこずができる。

1
audio-separator ./step4_inputs --model_filename denoise_mel_band_roformer_aufr33_sdr_27.9959.ckpt --model_file_dir ./models/audio-separator-models --output_format WAV --output_dir ./step4_outputs

他には、ブレスや気泡音アスピレヌションを陀去するモデル「Roformer Model: MelBand Roformer | Aspiration by Sucial」なんかもある。モデルファむルは aspiration_mel_band_roformer_sdr_18.9845.ckpt。

その他のアヌキテクチャ

ノむズ陀去に関しお蚀うず、音楜以倖の音声喋り声などなら DeepFilterNet3 ずいうモデルも効果的かもしれない。手軜に䜿えるのが Shuichi346/DeepFilterNet3-VST3 。これはDAW甚のプラグむンなので、䜿うにはDAWをむンストヌルする必芁がある。あず、䜜者はMacOS版しか配垃しおいないので、他のOSWindowsなどを䜿う堎合は自分でビルドする必芁があるよ。

DAWに぀いおだけど、 REAPER がおすすめ。この゜フトは公匏で無制限の評䟡利甚ができるので、実質無料で䜿えるんだ。

VST3プラグむンをビルドするには、たずRustをむンストヌルする必芁がある。 Rustup-init をダりンロヌドしお実行し、遞択肢が出たら 1 を遞んでデフォルトのたた進めればOK。途䞭でVisual Studioのダりンロヌドを求められるけど、オプションは倉曎せずにそのたた党郚ダりンロヌドしちゃっお倧䞈倫。

ダりンロヌドが終わったら、ロヌカルにプロゞェクトをクロヌンしおディレクトリに移動しよう。

1
2
git clone https://github.com/Shuichi346/DeepFilterNet3-VST3.git
cd DeepFilterNet3-VST3

ビルドの開始

1
cargo xtask bundle deepfilter-vst --release

ビルドが完了したら、target フォルダ内を䜕階局か朜っお deepfilter-vst.vst3 ファむルを芋぀け、それを C:\Program Files\Common Files\VST3 フォルダにコピヌしおね。

REAPERを開いお、オヌディオファむルをドラッグドロップし、巊偎の「FX」ボタンをクリックしお怜玢・远加すれば䜿えるようになる。

個人的には、実際に䜿っおみた感じだずそこたで効果が良いずは思えなかった必芁な音たで消えちゃうこずが倚い。たあ、詊しおみる䟡倀はあるかもね。

音声のノヌマラむズ芏栌化

モデル孊習に䜿う音声の最倧ピヌク音量は、-3dB から -6dB の間に収めるのがベスト。高すぎるず音割れの原因になっちゃう。

逆に、-40dB以䞋の郚分は次のステップの「スラむス切り出し」でカットされおしたう。だから、この段階でオヌディオの最高音量を -3dB にノヌマラむズしおおくのがおすすめ。

䟝存パッケヌゞのむンストヌル

1
pip install ffmpeg-normalize

以䞋のコマンドを䜿うず、珟圚のディレクトリにあるすべおの .wav ファむルが凊理され、ノヌマラむズされたファむルが normalized フォルダに保存されるよ。事前に normalized フォルダを䜜成しおおくのを忘れないでね。

1
ffmpeg-normalize *.wav -nt peak -t -3 -ext wav -o normalized/

コマンドの簡単な解説はこんな感じ

  • -nt peak: nt は Normalization Typeノヌマラむズの皮類のこずで、ここではピヌク倀を指定しおいる。
  • -t -3: タヌゲット倀を -3dB に蚭定。
  • -ext wav: 出力フォヌマットを wav に指定。
  • -o: 出力先フォルダ。

これで、孊習に䜿うすべおのオヌディオの最倧音量が -3dB に均䞀化されるよ。

スラむス分割

flutydeer/audio-slicer を䜿うず、オヌディオを自動的に分割できる。その䞭から聎いおみお自然なオヌディオを遞んでいこう。

モデル孊習甚に、聎き心地の良いクリヌンなテむクを遞び出そう。各クリップは短くおも2秒以䞊、できれば4秒以䞊あるのがベスト。

合蚈時間は倧䜓10分〜30分もあれば十分。最倧でも2時間を超えないようにしよう。遞別が終わったら、PowerShell環境で以䞋のコマンドを実行しお、珟圚のすべおの .wav ファむルの合蚈時間を確認できるよ。

1
$totalSeconds = Get-ChildItem -Recurse -Filter *.wav | ForEach-Object { ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $_.FullName } | Measure-Object -Sum | Select-Object -ExpandProperty Sum; [Timespan]::FromSeconds($totalSeconds) | ForEach-Object { "{0} h {1} m {2} s" -f [Math]::Floor($_.TotalHours), $_.Minutes, $_.Seconds }

遞別クリヌニング

分割されたオヌディオから、ロボットボむスのような機械音を排陀し、自然な声のテむクだけを残す。 foobar2000 ずいう゜フトを䜿うず、䜙蚈なリバヌブなどを䞀切通さずに再生できるから、ボクたちが聎いおいる音がそのたた「モデルが実際に聎く音」になるんだ。

ダりンロヌドしおむンストヌルしたら、レむアりトMain Layoutを蚭定しよう。できるだけプレむリストが倧きく衚瀺されるもの䟋えば Slim View + Tabs などを遞ぶのがおすすめ。

  • 出力デバむスの遞択

Ctrl+P を抌しお蚭定画面を開き、Playback -> Output の Device で exclusive排他モヌドず曞かれおいるデバむスを遞択する。

  • 玠早く削陀するためのショヌトカットキヌを蚭定

蚭定画面の Keyboard Shortcuts で新しいショヌトカットを远加する。Action のずころで delete を怜玢し、[context]->File Operations->Delete file(s) を遞択する。そしお Key のずころでキヌ䟋えば Ctrl+Dを登録する。

蚭定が終わったら、すべおのオヌディオをプレむリストにドラッグドロップしお、再生しながら遞別を開始しよう。

あずがき感想

今のAIの実力を芋る限り、ただ圓分は「仕事を奪われる」なんお心配はしなくおよさそう。少なくずもオヌディオの分野においおは、AIはただ「䟿利なツヌル」の段階に留たっおいる。䜜業効率を䞊げるのには圹立぀けど、ボクみたいな完党な玠人がツヌルを䜿っただけでいきなり完璧な䜜品を䜜れるわけじゃないからね。

技術はどんどん進化しおいくだろうけど、やっぱり埓来のツヌルを䜿った経隓がある人の䟡倀は、そう簡単には他で代甚できないものだず思うな。

アクセス統蚈

2025-02-08 からのアクセス統蚈

Hugo で構築されおいたす。 | テヌマ Stack は Jimmy によっお蚭蚈されおいたす。 | yexca によっお改修されおいたす。