これは何?
kotoba-whisper-v2.2はローカルで文字起こしできる音声認識(ASR)モデルである。
会議情報などの機微情報を他企業の運営する生成AIにアップロードすることがためらわれる場面でもローカルで動作するならば活用できるのではと思い、検証してみた。
セットアップする際にいろいろハマったので手順をまとめる。
GitHubのほうにもまとめている。
ENVIRONMENT
- python 3.10: python3.12だと自分の環境ではうまく動かなかったのでバージョンを下げた。
- Ubuntu 22.04
環境構築
install uv
オリジナルの手順はpip
を使っていたが、Python 3.12だとうまく動かなかったので仮想環境を作るついでにuv を使うことにした。
curl -LsSf https://astral.sh/uv/install.sh | sh
install python 3.10
uv python install 3.10
uv python find
/home/sigma/.local/share/uv/python/cpython-3.10.18-linux-x86_64-gnu/bin/python3.10
uv python pin 3.10.18
cat .python-version
3.10.18
uv run python
Python 3.10.18 (main, Jul 23 2025, 00:36:45) [Clang 20.1.4 ] on linux
プロジェクトのセットアップ
uv init workspace
cd workspace
uv run main.py # test
install dependencies
ほぼ元の手順通りですが、uv
でインストールしている。
cd workspace
uv pip install --upgrade pip
uv pip install --upgrade transformers accelerate torchaudio
uv pip install "punctuators==0.0.5"
uv pip install "pyannote.audio"
uv pip install git+https://github.com/huggingface/diarizers.git
Hugging Faceのセットアップ
Hugging Faceのアカウントを作る。
アカウントができたら、2つのモデルに対してフォームを埋めて利用規約に同意する。
自分がHuggingFaceを初めて使ったので、わかりにくく感じたので書いておく。
accept the terms-of-use for the following two models:
pyannote/segmentation-3.0
pyannote/speaker-diarization-3.1
トークンを以下ページから作成しておく
Hugging FaceのCLIツールを入れてログインします。
ログイン時にトークンを求められるのでコピペします。
uv pip install -U "huggingface_hub[cli]"
git config --global credential.helper store
./.venv/bin/huggingface-cli login
その他のライブラリ
ffmpegが入っていないとエラーが出たので一応記載しておく。
sudo apt install ffmpeg
テストしてみる
sample codeを動かしてみる。
cd workspace
wget https://huggingface.co/kotoba-tech/kotoba-whisper-v2.2/resolve/main/sample_audio/sample_diarization_japanese.mp3
uv run main.py
{'chunks': [{'timestamp': [22.1, 24.97], 'text': '水をマレーシアから買わなくてはならないのです', 'speaker_id': 'SPEAKER_00'}, {'timestamp': [0.03, 13.85], 'text': 'これも先ほどがずっと言っている自分の感覚的には大丈夫ですけれども', 'speaker_id': 'SPEAKER_01'}, {'timestamp': [5.03, 18.85], 'text': '今は屋外の気温', 'speaker_id': 'SPEAKER_01'}, {'timestamp': [7.63, 21.45], 'text': '昼も夜も上がってますので', 'speaker_id': 'SPEAKER_01'}, {'timestamp': [9.91, 23.73], 'text': '空気の入れ替えだけではかえって人が上がってきます', 'speaker_id': 'SPEAKER_01'}, {'timestamp': [13.48, 22.1], 'text': '愚直にその街の良さをアピールしていくという', 'speaker_id': 'SPEAKER_02'}, {'timestamp': [17.26, 25.88], 'text': 'そういう姿勢が基本にあった上での', 'speaker_id': 'SPEAKER_02'}, {'timestamp': [19.86, 28.48], 'text': 'こういうPR作戦だと思うんですよね', 'speaker_id': 'SPEAKER_02'}], 'speaker_ids': ['SPEAKER_00', 'SPEAKER_01', 'SPEAKER_02'], 'chunks/SPEAKER_00': [{'timestamp': [22.1, 24.97], 'text': '水をマレーシアから買わなくてはならないのです', 'speaker_id': 'SPEAKER_00'}], 'text/SPEAKER_00': '水をマレーシアから買わなくてはならないのです', 'chunks/SPEAKER_01': [{'timestamp': [0.03, 13.85], 'text': 'これも先ほどがずっと言っている自分の感覚的には大丈夫ですけれども', 'speaker_id': 'SPEAKER_01'}, {'timestamp': [5.03, 18.85], 'text': '今は屋外の気温', 'speaker_id': 'SPEAKER_01'}, {'timestamp': [7.63, 21.45], 'text': '昼も夜も上がってますので', 'speaker_id': 'SPEAKER_01'}, {'timestamp': [9.91, 23.73], 'text': '空気の入れ替えだけではかえって人が上がってきます', 'speaker_id': 'SPEAKER_01'}], 'text/SPEAKER_01': 'これも先ほどがずっと言っている自分の感覚的には大丈夫ですけれども今は屋外の気温昼も夜も上がってますので空気の入れ替えだけではかえって人が上がってきます', 'chunks/SPEAKER_02': [{'timestamp': [13.48, 22.1], 'text': '愚直にその街の良さをアピールしていくという', 'speaker_id': 'SPEAKER_02'}, {'timestamp': [17.26, 25.88], 'text': 'そういう姿勢が基本にあった上での', 'speaker_id': 'SPEAKER_02'}, {'timestamp': [19.86, 28.48], 'text': 'こういうPR作戦だと思うんですよね', 'speaker_id': 'SPEAKER_02'}], 'text/SPEAKER_02': '愚直にその街の良さをアピールしていくというそういう姿勢が基本にあった上でのこういうPR作戦だと思うんですよね'}
とりあえず、サンプルのmp3は動いた。
そこそこ長そうなmp3を試す
自分のPodcast(15分程度)を試してみた。
精度とかどうか
- 10年後にこれを見返したら、どんなことを話したかは意訳してわかるレベルには文字起こしができている。
- 話者分離はおまけかなくらいの精度
- 2人しかいないはずが3人目が登場している
- 自分じゃない人のセリフが混じっていたりする。
スペックが足りない気がする
手元のノートパソコンだと1時間以上はかかった。
GPUがないと使い物にはならなそう。
Gooble Colaboratoryを使ってもいいが、機微情報のアップロードとして咎められずに文字起こししたいのが今回の趣旨だったので。