初めに
今回は定番のpyanonoteとwhisperで話者ダイアライゼーションを行ってみます
以下で記事のサンプルリポジトリを公開しています
過去にはほかのライブラリでも試しているので、ほかにどのようなライブラリがあるのか気になる場合はご覧ください
開発環境
- Windows11
- python 3.9
- uv
セットアップ
uv でpython 3.9の環境を作ります. pyanonoteが依存している numbaが3.10以上は対応していませんでした
uv venv -p 3.9 source venv/bin/activate
必要なライブラリを入れていきます
uv pip install pyannote.audio
torchをgpu版を入れます
uv pip install torch==2.5.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu121 --force-reinstall
mp3のファイルを扱えるように 追加のライブラリを入れます
uv pip install pydub
文字お越しようにwhisperを入れます
uv pip install - U openai-whisper
実行
以下のスクリプトを実行することで話者ダイアライゼーションおよび文字起こしを行うことができます
# 必要なライブラリのインポート from pyannote.audio import Pipeline import whisper import numpy as np from pydub import AudioSegment # 話者分離モデルの初期化 pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization-3.1") # Whisperモデルのロード model = whisper.load_model("large-v3") # 音声ファイルを指定 audio_file = "JA_B00000_S00529_W000007.mp3" # MP3ファイルを指定します # 話者分離の実行 diarization = pipeline(audio_file) # MP3ファイルをAudioSegmentで読み込む audio_segment = AudioSegment.from_file(audio_file, format="mp3") # 音声ファイルを16kHz、モノラルに変換 audio_segment = audio_segment.set_frame_rate(16000).set_channels(1) # 話者分離の結果をループ処理 for segment, _, speaker in diarization.itertracks(yield_label=True): # 話者ごとの発話区間の音声を切り出し(ミリ秒単位) start_ms = int(segment.start * 1000) end_ms = int(segment.end * 1000) segment_audio = audio_segment[start_ms:end_ms] # 音声データをnumpy配列に変換 waveform = np.array(segment_audio.get_array_of_samples()).astype(np.float32) # 音声データを[-1.0, 1.0]の範囲に正規化 waveform = waveform / np.iinfo(segment_audio.array_type).max # Whisperによる文字起こし # 音声データをサンプリングレート16kHzに合わせて、テンソルに変換 result = model.transcribe(waveform,fp16=False) # 話者ラベル付きで結果をフォーマットして出力 for data in result["segments"]: start_time = segment.start + data["start"] end_time = segment.start + data["end"] print(f"{start_time:.2f},{end_time:.2f},{speaker},{data['text']}")
結果は以下になります
0.03,4.15,SPEAKER_00,物事に対しても、真っ直ぐに取り組めるような姿勢とか、