中級 18 分音声

Whisper + Ollama をローカルで使用:100%オフラインでのトランスクリプション ligne

1時間の会議を文字起こしし、構造化された議事録を作成する:これはOtter、Fireflies、Tactiqが提供しているまさにその機能です。ただし、音声データをサードパーティに送信する必要があります。Whisper(OpenAI製ですが、オープンソースでありオフラインでも実行可能)とLLM Ollamaを組み合わせることで、サブスクリプションなし、情報漏洩なしで、あなたのマシン上で同じことを実現できます。このガイドでは、whisper.cpp → Ollama のパイプラインをエンドツーエンドで構築します:インストール、モデルの選択、bashスクリプト、Pythonスクリプト、そして1時間の会議のローカル文字起こしの具体的なケーススタディ。

著者 Mohamed Meguedmi·更新 2026-08-27·Windows・macOS・Linuxでテスト済み

#ローカルでの文字起こしにWhisper+Ollamaのパイプラインを使う理由は?

会議の録音には、顧客名、数値、戦略上の判断、場合によっては人事データが含まれます。SaaSの文字起こしサービスは、これらの音声を自社のサーバーに保存し、利用規約によっては自社モデルの学習に使用します。機密性を真剣に重視するチームにとって、この点は妥協できません。

OpenAIのWhisperは自由にダウンロードでき、オフラインで動作します。whisper.cpp(Georgi GerganovによるC++移植版)を使えば、PythonやCUDAを必須とせずに、CPUでもGPUでも効率よく実行できます。一方、Ollamaはhttp://localhost:11434でローカルLLMを利用できるようにします。この2つを組み合わせると、音声→テキスト(Whisper)→構造化された要約(Ollama)という流れになります。すべてのデータはお使いのディスク内に留まります。

i
役割分担
Whisper ≠ LLM。Whisperは音声認識(ASR)モデルであり、音声をプレーンテキストに変換します。要約、整形、決定事項の抽出は、その背後にあるLLMの仕事です。これら2つのモデルは全く異なり、互いに置き換えられるものではありません。

#前提条件

ローカルAIキット

お使いのマシンで、プライベートかつ無料のChatGPTを1時間で構築 — LM Studio、Ollama、Open WebUI、ご自身のドキュメント、クラウド不要。

  • 永久に利用できるオンラインスペース
  • PDF + ファイル
  • 生涯アップデート
macOS、LinuxまたはWindows(WSL2)
whisper.cppはどこでもコンパイル可能です。Windows環境ではWSL2を使用してください。ネイティブコンパイルは可能ですが、より多くの手動設定が必要です。
Ollamaがインストールされ、正常に動作しています
ollama run qwen3.5:9b を実行すると、応答が返ってくるはずです。返ってこない場合は、お使いの OS 向けのインストールガイドに戻って確認してください。
C++コンパイラとCMake
Debian/Ubuntu での build-essential cmake、macOS での Xcode Command Line Tools
ffmpeg
.m4a/.mp3/.mp4ファイルを、whisper.cppが入力として受け付ける唯一の形式である16 kHzのWAVに変換するためのものです。
最低 8 GBのRAM
16GBあれば余裕があります。large-v3モデルの読み込みには、RAM/VRAMを約3GB使用します。Qwen 3.5 4Bのような小規模LLMを追加するなら、さらに約3GB必要です。
GPUは任意
RTX 3060 12 GBは、large-v3で1時間の音声を約4分で文字起こしできます。Apple SiliconではMetalが自動的に有効になり、同じくらい高速です。

#1. whisper.cpp をインストールする

公式パッケージは存在しません。リポジトリをクローンしてコンパイルします。2分ほどで、どこにでも移動できるポータブルバイナリが得られます。

クローン+CPU向けビルド
git clone https://github.com/ggerganov/whisper.cpp.git
cd whisper.cpp
cmake -B build
cmake --build build --config Release -j

メインバイナリは build/bin/whisper-cli に存在します(CMakeのリファクタリング以前は main と呼ばれていました)。これを呼び出して、音声をテキストに変換してください。

→
GPUアクセラレーション
CUDA(NVIDIA)の場合は、cmake -B buildコマンドに-DGGML_CUDA=1を追加してください。Apple SiliconではMetalがデフォルトで有効になっているため、設定は不要です。AMD(ROCm)の場合は-DGGML_HIPBLAS=1を指定します。その後、バイナリが起動時にGPUを検出します。
CUDAバリアント
cmake -B build -DGGML_CUDA=1
cmake --build build --config Release -j

ffmpegが既にインストールされていない場合は、別途インストールしてください:

ffmpeg
# Debian / Ubuntu / WSL2
sudo apt install ffmpeg

# macOS
brew install ffmpeg

#2. 適切なWhisperモデルを選択(tiny → large-v3)

Whisperは5つのサイズがあり、それぞれ2つのバリエーション(デフォルトの多言語版と英語専用版(サフィックス .en))があります。フランス語には多言語版を使用してください。以下の表は、実際に異なる点を要約しています。

tiny (75 MB)
高速ですが、フランス語の精度は低いです。手早いテストやRaspberry Piでの使用に限定してください。フランス語の自然発話では、WER(単語誤り率)は約30%です。
base(142 MB)
明瞭な英語音声ならまずまずですが、ノイズのあるフランス語音声には弱いです。使えるリソースが非常に少ない場合には、良い選択肢です。
small (466 MB)
本格的に使える最初の段階です。明瞭なフランス語音声でのWER(単語誤り率)は約10~12%です。控えめな性能のGPUでも、1時間の音声を約3分で文字起こしできます。
medium (1.5 GB)
フランス語の会議音声では、品質と速度のバランスが非常に良好です。WER は約7〜8%。句読点もよく認識します。
large-v3 (3.1 GB)
最先端の性能。明瞭なフランス語音声ではほぼ完璧で、アクセントや背景雑音にも強いです。RAM/VRAMの空き容量が6 GBを超える場合は、優先的に選んでください。

フランス語の会議を文字起こしする場合、実用的にはmediumを標準とし、それを動かせるGPUがあるならlarge-v3を使うことをおすすめします。専用GPUのないノートPCでは、smallが適切な代替になります。

モデルのダウンロード
# Depuis le dossier whisper.cpp
./models/download-ggml-model.sh medium
# ou
./models/download-ggml-model.sh large-v3

モデルは ggml 形式で models/ に保存されます(LLMにおける gguf に相当する形式です)。複数のサイズをダウンロードして、必要に応じて切り替えられます。

i
量子化バージョン
VRAMに余裕がない場合、このスクリプトでは量子化版のlarge-v3-q5_0(約1.1 GB)またはmedium-q5_0(約540 MB)を使えます。フランス語では品質の低下はわずかで、メモリは確実に節約できます。ご自身の音声データで試してみてください。

#3. 音声ファイルを文字起こしする

whisper.cppは16kHzモノラルWAVのみを読み取ります。音声はffmpegで準備し、その後whisper-cliでテキストに変換します。

WAV 16 kHz への変換
ffmpeg -i reunion.m4a -ar 16000 -ac 1 -c:a pcm_s16le reunion.wav
-ar 16000
16 kHzにリサンプリングする(Whisperの学習時のサンプリング周波数)。
-ac 1
モノラルに強制します。いずれにしても、Whisperはステレオを無視します。
-c:a pcm_s16le
16ビットのリトルエンディアンPCM。必要とされる非圧縮WAV形式です。
文字起こし
./build/bin/whisper-cli \
  -m models/ggml-medium.bin \
  -f reunion.wav \
  -l fr \
  -otxt \
  -of reunion

結果は reunion.txt に保存され、タイムスタンプ付きのセグメントで出力されます。以下のフラグが役立ちます:

-l fr
フランス語を強制します。このフラグを設定しないと、Whisperは自動的に言語を検出しますが、短い文では誤検出することがあります。
-otxt / -osrt / -ovtt / -ojson
出力フォーマット:テキストのみ、SRTまたはVTT形式の字幕、またはタイムスタンプ付きのJSON構造化データ。これらを組み合わせることも可能です。
-of <prefixe>
出力ファイルのプレフィックス(拡張子を除く)
-t 8
CPUスレッド数。デフォルトではwhisper.cppは4スレッドを使用していますが、近年のCPUでは8または16に設定すると良いでしょう。
--print-progress
進捗バーを表示します。長いファイルの処理に便利です。
→
パイプライン用JSONフォーマット
LLMと連携する場合、-ojsonを推奨します。開始/終了タイムスタンプ付きのセグメントを取得できるため、最終的な要約に正確な時刻(例:「23:14に決定した」)を引用できます。

#4. Ollamaで文字起こしを要約する

未加工の文字起こしが得られたら、OllamaのローカルHTTP APIを通じて送信します。単発の処理には、/api/chatエンドポイントを使うのが最も手軽です。

Ollama の前提条件
ollama pull qwen3.5:9b
# Ou pour un résumé plus fin d'une longue réunion :
ollama pull mistral-small

1時間の会議の文字起こしは、容易に10,000〜15,000トークンに達します。Qwen 3.5 9Bはネイティブで256kのコンテキストに対応しており、十分すぎる容量です。さらに質の高い要約を求めるなら、フランス語に優れたMistral Small 24Bは、16GB未満のVRAMに収まります。

curl を使用した簡単なテスト
curl -s http://localhost:11434/api/chat -d '{
  "model": "qwen3.5:9b",
  "stream": false,
  "options": {"temperature": 0.2, "num_ctx": 16384},
  "messages": [
    {"role": "system", "content": "Tu résumes une réunion de travail en français."},
    {"role": "user", "content": "<COLLE ICI LE CONTENU DE reunion.txt>"}
  ]
}' | jq -r '.message.content'
!
num_ctxはデフォルト値のままにしない
Ollamaはデフォルトで2,048トークンのコンテキスト長でモデルを読み込むため、文字起こしの内容が通知なく切り詰められるおそれがあります。呼び出しのたびにoptionsでnum_ctx(8192、16384、32768…)を明示的に指定するか、Modelfileで固定してください。

#5. パイプライン全体:1時間の会議の議事録作成例

すべてを、音声ファイルを入力として受け取り、Markdown 形式の報告書を出力する Python スクリプトにまとめます。これが、Whisper と Ollama を使った、再利用可能なローカル文字起こしパイプラインの中心となります。

Pythonの依存関係
pip install requests
pipeline_reunion.py
#!/usr/bin/env python3
"""Audio -> transcription Whisper -> compte-rendu via Ollama."""
import subprocess, sys, requests, pathlib, json

WHISPER_BIN = "./build/bin/whisper-cli"
WHISPER_MODEL = "models/ggml-medium.bin"
OLLAMA_URL = "http://localhost:11434/api/chat"
LLM_MODEL = "qwen3.5:9b"

SYSTEM_CR = """Tu es un assistant qui produit des comptes-rendus de
réunion en français à partir d'une transcription brute.

FORMAT DE SORTIE (Markdown) :
# Compte-rendu
## Participants identifiables
## Sujets abordés (1 paragraphe par sujet)
## Décisions prises
## Actions à mener (avec porteur si mentionné)
## Points en suspens

RÈGLES :
- N'invente AUCUN nom, AUCUNE décision, AUCUNE action.
- Si une info manque, écris \"Non précisé\".
- Sois concis : un compte-rendu se lit en 2 minutes.
"""

def to_wav(src: pathlib.Path) -> pathlib.Path:
    dst = src.with_suffix(".wav")
    subprocess.run([
        "ffmpeg", "-y", "-i", str(src),
        "-ar", "16000", "-ac", "1", "-c:a", "pcm_s16le",
        str(dst),
    ], check=True)
    return dst

def transcribe(wav: pathlib.Path) -> str:
    prefix = wav.with_suffix("")
    subprocess.run([
        WHISPER_BIN, "-m", WHISPER_MODEL, "-f", str(wav),
        "-l", "fr", "-otxt", "-of", str(prefix),
        "--print-progress",
    ], check=True)
    return prefix.with_suffix(".txt").read_text(encoding="utf-8")

def summarize(transcription: str) -> str:
    r = requests.post(OLLAMA_URL, json={
        "model": LLM_MODEL,
        "stream": False,
        "options": {"temperature": 0.2, "num_ctx": 16384},
        "messages": [
            {"role": "system", "content": SYSTEM_CR},
            {"role": "user",   "content": transcription},
        ],
    }, timeout=600)
    r.raise_for_status()
    return r.json()["message"]["content"]

if __name__ == "__main__":
    src = pathlib.Path(sys.argv[1])
    wav = to_wav(src)
    print(f"[1/3] Audio converti -> {wav}")
    texte = transcribe(wav)
    print(f"[2/3] Transcription : {len(texte)} caractères")
    cr = summarize(texte)
    out = src.with_name(src.stem + "_compte-rendu.md")
    out.write_text(cr, encoding="utf-8")
    print(f"[3/3] Compte-rendu : {out}")
起動
python pipeline_reunion.py reunion.m4a

1時間の会議をRTX 3060 12 GBとmediumモデルで処理する場合、文字起こしに約3分、Qwen 3.5 9Bによる要約に約30秒かかります。合計は4分未満で、ネットワークリクエストはゼロです。MacBook M2 16 GBでCPU + Metalを使用する場合は、合計約6分です。

→
非常に長い会議
文字起こしが90分を超える、または30,000トークンを超える場合は、テキストを10,000トークンずつのブロックに分割し、各ブロックを要約してから、LLMに要約を統合するよう依頼してください。これは典型的なmap-reduceパターンです。そうしないと、num_ctxの設定上は全文を受け付けられても、要約の品質が大きく低下します。

#ヒントとトラブルシューティング

無音区間で文字起こしにハルシネーションが発生する
Whisperは、長い無音区間で実際には話されていない文を生成することがあります(「字幕制作:...」「ご視聴ありがとうございました」など)。VADを有効にしてください:--vad --vad-model models/ggml-silero-v5.1.2.bin(同じスクリプトでダウンロードしてください)。
固有名詞が正しく文字起こしされない
Whisper は同僚の名前を知りません。--prompt "Marie, Julien, Samir, ACME Corp, ProjetX" を使って、初期プロンプトに名前を渡してください。名前が正しい綴りで書き起こされます。
圧縮された音声(Zoom、Teams)
ZoomのMP4録画ファイルにはしばしば品質の低いモノラル音声が含まれます。音質が重要であれば、Zoomの「音声のみ」エクスポート(M4A)を推奨します。もしくはOBSと併用して同時録画を行うことをお勧めします。
Macでのggml_metal_initエラー
Metalを有効にせずにコンパイルしたか、whisper.cppがリソースを見つけられない状態です。最初からコンパイルし直してください:rm -rf build && cmake -B build && cmake --build build --config Release -j。
コンテキストが大きい場合のOllamaのタイムアウト
HTTPクライアントが処理の終了前に接続を切ってしまいます。requests側でタイムアウトをtimeout=600(10分)に延ばしてください。サーバー側では、OLLAMA_KEEP_ALIVE=30mによってモデルを読み込み済みの状態に保てます。
文字起こしが途中で切れる
要約が音声の途中で途切れるように感じられる場合は、num_ctx が低すぎる可能性があります。トークン数(.txt に対して wc -w を実行し、結果に 1.3 を掛けた値 ≈ トークン数)を確認し、num_ctx をその 2 倍に設定してください。
話者分離(誰が話しているか)
whisper.cppは話者ダイアライゼーションに対応していません。話者を区別するには、文字起こしの前にpyannote.audioをパイプラインに追加し、その後、各セグメントに注釈を付けてください。これは別の処理層であり、ここでは扱いません。
i
実際のハードウェアコスト
日常的な使用(1日2〜3回の会議の文字起こし)であれば、16 GBのMac mini M4(約700ユーロ)または12 GBの RTX 3060 搭載ミニPC(中古で約600ユーロ)で十分です。文字起こしSaaSの月額約15ユーロ/ユーザーと比較して、これは初期投資のみで、5人のチームであれば1年未満で元が取れます。

#さらに詳しく

このパイプラインはローカルで文字起こしと要約を行います。次に進む方向として、ニーズに応じた3つの選択肢があります。

faster-whisperによる医療記録の生成
診療の文字起こしガイドでは、faster-whisper(最適化されたPython移植版)を使用し、医療情報の守秘義務、pyannoteによる話者分離、医療分野でのGDPR遵守に重点を置いています。同じ構成を応用した興味深い例です。
サマリー用の適切なLLMの選定
要約は、処理の各段階の中で品質のばらつきが最も大きい部分です。量子化の選び方ガイドではQ4_K_M、Q5_K_M、Q8_0を比較しています。細かなニュアンスを含む長文では、その違いを耳で聞き取れます。
n8n でパイプラインを自動化
音声ファイルが届いたらすぐに処理パイプラインを起動するには(監視フォルダ、メール、Slack)、n8n + Ollamaの自動化ガイドをご覧ください。コードを書かずにワークフローを構築する方法を紹介しています。
このガイドは役に立ちましたか?

ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。