Pythonで話者識別ライブラリPyannote.audioを使ってみる

スポンサーリンク
Whisper
スポンサーリンク

会議などの議事録を作成するのに便利な話者識別ライブラリPyannote.audio(ピアノート・オーディオ)を使ってみました。GitHubでオープンソースとして公開されています。Whisperなどのspeak-to-textと組み合わせることにより、議事録を簡単に作成することができます。MITライセンスで公開されており、適切なライセンスと著作権表示をすることで、商用利用も可能です。

前準備

Pyannote.audioは、必須ではありませんが、GPU環境での実施が推奨されています。GPU環境の構築については、参考記事へのリンクを示しますので、詳しくはそちらをご参照ください。

WindowsへのNVIDIA CUDAのGPU環境構築

Windowsのネイティブ環境にvenvで仮想環境を構築し、Pyannote.audioをインストールしていきます。まず、好きなフォルダを作成し、そこで、仮想環境を作ります。Pyannote.audioはPython3.8推奨なので、Python3.8の環境を作成します。もし、別のバージョンのPythonの人や、Python自体をインストールしていない人は、Python3.8をインストールしておきます。(参考記事:Windowsで複数のバージョンのPythonをインストールする

Python3.8系であれば、Python3.8.15がおススメです。下記のPythonの公式ページからご自分の環境にあったPythonをインストールしましょう。

Python 3.8.10

仮想環境はターミナルからvenvで構築します。

> py -3.8 -m venv venv
> .\venv\Scripts\Activate.ps1
(venv)> python -m pip install -U pip setuptools

CUDA11.7を入れる場合は、以下のようにPyTorchでGPUが使えるように設定します。

(venv)> pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117

Pyannote.audioのインストール

必要なライブラリをインストールします。

GithubからPyannote.audioのクローンを作成します。もし、Gitをインストールしていない場合は、公式ページから入手してください。

git cloneコマンドで、githubからクローンを作成します。

(venv)> git clone https://github.com/pyannote/pyannote-audio

続いて、requirements.txtのリストアップから、必要なライブラリをインストールします。

(venv)> pip install -r ./pyannote-audio/requirements.txt

本体をインストールします。

(venv)> pip install pyannote.audio

Pyannote.audioの認証

pyannote.audioのモデルをダウンロードするためには、Hugging faceのトークンが必要になります。費用は発生しませんが、pyannote.audioを使って論文発表する際は引用したり、企業であったら、開発に寄付することを検討しましょう。

1.Hugging faceのアカウント作成
Hugging faceのページからアカウントを作成します。
2.https://huggingface.co/pyannote/speaker-diarizationのページから、所属とwebサイト、使用目的を入力して、同意ボタンを押します。

3.同様に、https://huggingface.co/pyannote/segmentationのページにも同じ情報を入力して、同意する。
4.https://huggingface.co/settings/tokensにアクセスして、New tokenから、pyannote.audioのトークンを作成し、入手する。

続いて、「.cashe」にトークンを保存します。まずターミナルなどで、hugging faceのCLIにアクセスします。トークンを聞いてきたら、先ほど作成したトークンを入力します。これで、CLIやPythonファイルでpyannote.audioが使えるようになります。

(venv)> huggingface-cli login

Token:
Add token as git credential? (Y/n) Y
Token is valid.
Your token has been saved in your configured git credential helpers (manager-core).
Your token has been saved to C:\Users\username\.huggingface\token
Login successful

もし、上記の実行時に権限エラーで実行できない場合、ターミナルのアイコンを右クリックで選択し、管理者として実行するとエラーは出ないと思います。

また、続いて、JupyterLabでインタラクティブ環境で使うためのライブラリをインストールし、JupyterLabを起動します。

(venv)> pip install jupyterlab
(venv)> pip install huggingface_hub
(venv)> jupyter lab

実行後、以下のコマンドで、hunggingfaceのログイン画面が出てきますので、ここで、先ほどのトークンを入れてやると、Jupyter Labでpyannote.audioが使えるようになります。

from huggingface_hub import notebook_login
notebook_login()

Pyannote.audioを使う

それでは使ってみます。今回はJupyterLabで使っていきます。サンプルの音声として、VoiceVoxで生成した会議の音声を使用します。過去の記事でPythonを使ってVoiceVoxエンジンを使った記事も書いているので、もし、音声生成について興味があれば、そちらもご覧ください。

VOICEVOXエンジンを使ったPythonでの「高」品質音声合成API

VOICEVOXで生成した会議の音声 ※VOOCEVOX:ずんだもん、VOICEVOX:四国めたん、VOICEVOX:波音リツ、VOICEVOX:冥鳴ひまり

音声は、4人のVOICEVOXのキャラクターたちがAIに関するフリーディスカッションを行っています。ちなみに、音声のシナリオ原案はchatGPTで生成しています。音声は自由にダウンロードしてお使いください。

Pyannote.audioはPipelineでモデルを呼び出し、音声をあてがうだけで話者識別をしてくれます。モデルの呼び出しでは、トークンを通していれば、モデルをダウンロードしてきます。今回は、上の「meeting.wav」の話者識別をしてみます。

from pyannote.audio import Pipeline
pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization@2.1")

diarization = pipeline("meeting.wav")

for turn, _, speaker in diarization.itertracks(yield_label=True):
    print(f"start={turn.start:.1f}s stop={turn.end:.1f}s speaker_{speaker}")
start=0.5s stop=5.5s speaker_SPEAKER_01
start=6.6s stop=8.1s speaker_SPEAKER_03
start=9.0s stop=15.1s speaker_SPEAKER_00
start=16.0s stop=19.5s speaker_SPEAKER_03
start=20.3s stop=27.9s speaker_SPEAKER_02
start=28.7s stop=36.4s speaker_SPEAKER_03
start=37.3s stop=46.5s speaker_SPEAKER_00
start=47.4s stop=54.8s speaker_SPEAKER_02
start=55.6s stop=63.7s speaker_SPEAKER_03
start=64.5s stop=69.2s speaker_SPEAKER_00
start=70.1s stop=75.5s speaker_SPEAKER_02
start=75.5s stop=75.6s speaker_SPEAKER_01
start=76.2s stop=85.5s speaker_SPEAKER_01

上記のように話者を特定できました。上の結果でSPEAKERの00は波音リツ、01は冥鳴ひまり、02は四国めたん、03はずんだもんですので、後付けで、SPEAKERとして当てはめてやると、誰がどのタイミングで話したかわかりやすくなります。

speaker_dict = {"SPEAKER_00":"波音リツ","SPEAKER_01":"冥鳴ひまり","SPEAKER_02":"四国めたん","SPEAKER_03":"ずんだもん"}
for turn, _, speaker in diarization.itertracks(yield_label=True):
    speaker_name = speaker_dict[speaker]
    print(f"開始={turn.start:.1f}s 終了={turn.end:.1f}s 発言者: {speaker_name}")
開始=0.5s 終了=5.5s 発言者: 冥鳴ひまり
開始=6.6s 終了=8.1s 発言者: ずんだもん
開始=9.0s 終了=15.1s 発言者: 波音リツ
開始=16.0s 終了=19.5s 発言者: ずんだもん
開始=20.3s 終了=27.9s 発言者: 四国めたん
開始=28.7s 終了=36.4s 発言者: ずんだもん
開始=37.3s 終了=46.5s 発言者: 波音リツ
開始=47.4s 終了=54.8s 発言者: 四国めたん
開始=55.6s 終了=63.7s 発言者: ずんだもん
開始=64.5s 終了=69.2s 発言者: 波音リツ
開始=70.1s 終了=75.5s 発言者: 四国めたん
開始=75.5s 終了=75.6s 発言者: 冥鳴ひまり
開始=76.2s 終了=85.5s 発言者: 冥鳴ひまり

その他の機能

pyannote.audioでは話者の人数を自動で判断してくれますが、明示することで精度を上げることができます。

# 人数を設定して、話者識別をする
diarization = pipeline("meeting.wav", num_speakers=4)

# 人数の上下限を設定して、話者識別する
diarization = pipeline("meeting.wav", min_speakers=2, max_speakers=10)

また、jupyter labなどのインタラクティブ環境で、計算したダイアライゼーションを直接指定することで、タイムラインを表示することができます。

diarization = pipeline("meeting.wav")
diarization

ダイアライゼーションの中身を見ると、下記のようになっていて、それぞれ会話の切れ目でセグメントを分割し、内部的にスコアを比較して、近い音声を同じスピーカーとして割り当てているようです。

list(diarization.itertracks(yield_label=True))
[(<Segment(0.497812, 5.49281)>, 'D', 'SPEAKER_01'),
 (<Segment(6.60656, 8.12531)>, 'J', 'SPEAKER_03'),
 (<Segment(8.98594, 15.1284)>, 'A', 'SPEAKER_00'),
 (<Segment(15.9722, 19.4653)>, 'K', 'SPEAKER_03'),
 (<Segment(20.2753, 27.9028)>, 'G', 'SPEAKER_02'),
 (<Segment(28.7128, 36.3909)>, 'L', 'SPEAKER_03'),
 (<Segment(37.2516, 46.5159)>, 'B', 'SPEAKER_00'),
 (<Segment(47.3766, 54.8353)>, 'H', 'SPEAKER_02'),
 (<Segment(55.6284, 63.6609)>, 'M', 'SPEAKER_03'),
 (<Segment(64.4709, 69.1959)>, 'C', 'SPEAKER_00'),
 (<Segment(70.0734, 75.5072)>, 'I', 'SPEAKER_02'),
 (<Segment(75.5072, 75.5578)>, 'E', 'SPEAKER_01'),
 (<Segment(76.1822, 85.4634)>, 'F', 'SPEAKER_01')]

さらに、pyannote.audioでは二人以上の音声がオーバーラップした場合でもある程度見極めてくれるようです。(詳細は開発した方の論文をご参照ください。)

ref. “pyannote.audio: neural building blocks for speaker diarization”, Hervé Bredin et al., 2019.

最後に

話者識別のライブラリpyannote.audioを紹介しました。これをwhisperなどのライブラリを組み合わせることで、発言した人を認識した議事録なんかも作れそうです。それについてもまた、記事にしてこうと思います。

Whisper
スポンサーリンク
鷹の目週末プログラマー

コメント