ローカルAIとの6ヶ月:WhisperとOllamaで議事録作成を自動化した方法

AI tutorial - IT technology blog
AI tutorial - IT technology blog

手動メモ作成という「税金」

6ヶ月前、私たちの社内ドキュメントは「ブラックホール」のような状態でした。アーキテクチャレビューやクライアントとの会議で発生するメモは、内容が不十分だったり、共有が2日遅れたりと、毎週およそ12時間が「同期の負債」として失われていました。

多くのエンジニアリングリードと同様に、私もクラウドベースのAI議事録ツールを試しました。それらは洗練されてはいましたが、ユーザーあたり月額30ドルというサブスクリプション費用、そして何より、クライアントの生データを外部サーバーに送信することを一切禁じるセキュリティポリシーという大きな壁に直面しました。

そこで私は、プライバシーの外注をやめ、ローカルファーストのパイプラインを構築することに決めました。半年間本番環境で運用した結果、成果は明らかです。手動の苦労は、OpenAIのWhisperで文字起こしを行い、Ollamaで要約するPythonベースのワークフローに置き換わりました。これは単なる技術的な好奇心ではなく、すべてのデータを手元のハードウェアに保持したまま、自分の時間を取り戻すための実用的な方法です。

アーキテクチャ:Whisper + Ollama

ワークフローは非常にシンプルです。音声ファイル(MP4、MP3、またはWAV)を取り込み、構造化されたMarkdownドキュメントに変換します。クラウドを使わずにこれを実現するには、マシン上で実行される2つの専門エンジンが必要です。

1. 音声文字起こし:OpenAI Whisper

Whisperは、ローカルでの文字起こしにおける業界標準です。古いライブラリは強い訛りやカフェの背景ノイズに弱い傾向がありましたが、WhisperのTransformerアーキテクチャはそれらを驚くほど容易に処理します。いくつかのモデルサイズが用意されていますが、私のテストでは、「small」モデルがクリアな英語音声で95%の精度を誇り、中堅クラスのGPUで実時間の約5倍の速度で動作します。

2. 知能:OllamaによるローカルLLM

生の文字起こしデータは煩雑です。言い淀みや発言の重なり、「えーと」「あのー」といったフィラー(埋め草)が含まれます。この混沌としたデータを論理的な構成に変換するには、大規模言語モデル(LLM)が必要です。私はモデルの管理にOllamaを使用しています。Llama 3.1やMistralをシンプルなAPIを備えたバックグラウンドサービスとしてラップしてくれるため、より優れたモデルがリリースされた際の入れ替えも容易です。

実践:パイプラインの構築

こちらが実際に運用しているスタックです。Pythonを接着剤(グルー)として使用します。ハードウェアについては、少なくとも8GBのVRAMを搭載したNVIDIA製GPUがスイートスポットですが、最新のApple Mシリーズチップを搭載したMacでも優れた結果が得られます。

ステップ1:環境構築

まず、コアライブラリを準備します。openai-whisperエンジンとollamaクライアントが必要です。

# Whisperとその依存関係のインストール
pip install openai-whisper setuptools-rust

# Ollama Pythonクライアントのインストール
pip install ollama

# ffmpegは音声処理を支えるバックエンドエンジンです
# Linux: sudo apt install ffmpeg | Mac: brew install ffmpeg

ステップ2:Whisperによる音声の文字起こし

このスクリプトはWhisperモデルを初期化し、録音データを処理します。素早いデバッグには「base」、日々の実用的なノート作成には「small」の使用をお勧めします。

import whisper

def transcribe_audio(file_path):
    # 'small'はVRAM使用量と精度のバランスが最適です
    model = whisper.load_model("small")
    
    print("文字起こし中... (通常、音声の長さの約1/5の時間がかかります)")
    result = model.transcribe(file_path)
    
    return result["text"]

# 使用例
# transcript = transcribe_audio("sprint_planning.mp4")

ステップ3:Ollamaで価値を抽出する

テキストデータが得られたら、それをクリーンアップする必要があります。コツはプロンプトにあります。AIにはクリエイティブなライターではなく、集中力の高い技術秘書として振る舞ってもらう必要があります。

import ollama

def generate_minutes(transcript):
    prompt = f"""
    タスク:この技術会議の文字起こしをMarkdown形式で要約してください。
    ルール:簡潔にまとめること。雑談よりも決定事項を優先してください。
    
    含める内容:
    - 主要な目的
    - 重要な技術的決定事項
    - 未解決のブロッカー
    - アクションアイテム(担当者 + 期限)
    
    文字起こし内容:
    {transcript}
    """
    
    response = ollama.generate(model='llama3.1', prompt=prompt)
    return response['response']

ステップ4:バッチプロセッサ

私は通常、これをCLIツールとして実行しています。特定のフォルダを監視し、夜間に録音データを処理させます。こうすることで、午前9時にログインしたときには、前日の会議のMarkdown要約がすでに受信トレイに揃っている状態になります。

6ヶ月間の運用から得た教訓

ツールの構築は簡単ですが、チームで信頼して使えるようにするのはより困難です。私たちが解決した主な3つの課題を紹介します。

1. VRAMの壁

WhisperとLLMはメモリを大量に消費します。8GBのビデオカードで両方を同時に実行しようとすると、システムがハングする可能性が高いです。Whisperモデルをロードして文字起こしを完了させた後、Ollamaを呼び出す前にモデルオブジェクトを明示的に削除することで、クラッシュの99%を防げることがわかりました。

2. 「誰が何を言ったか」問題

標準のWhisperは、話者名のない「テキストの塊」を生成します。2〜3人の同期会議であれば、Llama 3.1は文脈から話者を特定することに驚くほど長けています(例:「Dockerイメージをプッシュしておきます」という発言は明らかにDevOpsリードのものです)。より大人数の場合は、faster-whisperpyannote-audioを統合して、適切な話者分離(ダイアリゼーション)機能を追加することをお勧めします。

3. 容赦ないプロンプティング

初期の要約は中身のないものでした。「チームは挨拶を交わした」といった内容が含まれていましたが、そんなものを読む必要はありません。そこでシステムプロンプトを「社交的な内容はすべて無視せよ。決定事項やアクションアイテムに繋がらない文章は破棄せよ」と更新しました。これにより、議事録の有用性は一晩で3倍になりました。

結論

クラウドを捨てて、ローカルのWhisperとOllamaスタックに切り替えたことは、昨年私が行ったワークフロー改善の中で最高のものでした。プライバシーへの不安が解消され、金曜日の会議で何が起きたかを月曜の朝に必死に思い出す必要もなくなりました。高性能なGPUへの初期投資と数時間のPythonスクリプティングが必要ですが、その見返りは、月額料金のかからない、永続的でプライベートな秘書です。機密性の高いコードやクライアントデータを扱う場合、これは単なる選択肢ではなく、もはや必須と言えるでしょう。

Share: