RTX3060 + CUDA × Whisper ─ 4時間会議をチャンク分割で10分文字起こし

RTX3060 + CUDAで爆速文字起こし ─ チャンク分割で4時間会議を10分処理できた HowTo

会議やインタビューの文字起こし──いまやクラウドサービスやスマホアプリを使えば誰でも簡単にできる時代になりました。Notta、Otter、Gladia……選択肢はいくらでもあります。

しかし、その便利さに飛びついたときに考えたいのが「情報はどこへ流れているのか?」という点です。クラウドに音声をアップロードする以上、データが学習に利用されたり、第三者に扱われる可能性を完全に排除することはできません

社内会議、インタビュー、顧客対応──いずれもNDA(秘密保持契約)やコンプライアンスに抵触しかねない情報を含んでいるのではないでしょうか。

そこで今回試したのが、ローカルGPU(RTX3060 + CUDA)を使った自前の文字起こし環境です。オープンソースのWhisperをCUDAで高速化し、MP4からMP3抽出・チャンク分割を経て文字起こしを行いました。

結果は──「4時間の会議録を、たった10分で処理完了」。
クラウドに頼らず、手元のGPUだけでこのレベルの処理ができることに驚かされました。

なぜローカルで文字起こしを試みたのか

クラウド型の文字起こしサービスは、確かに便利です。音声をアップロードすれば、数分後には文字データとして返ってくる。精度も向上し、エディタ機能や話者識別まで備わっているものも珍しくありません。

しかし──そこで忘れてはいけないのが 「情報管理」 の問題です。
公開しても問題ない講演やセミナーであれば気軽に使えますが、会議録やインタビューの多くは 外に出してはいけない情報 を含みます。NDAに縛られた契約情報や、社内だけの意思決定プロセスなど、外部クラウドに送信すること自体がリスクになり得ます。

この現実を前に、「それなら自分の手元のGPUで処理してしまえばいいのでは?」という発想に至りました。
幸い、オープンソースの Whisper はローカル実行が可能であり、CUDAを有効化すればGPUによる高速化も狙えます。

今回の取り組みは、その実験です。
題材には春日部市議会の公式アーカイブ映像を選びました。公共素材であり、著作権面の懸念も少なく、かつ数時間に及ぶ長尺データ──まさに実験にはうってつけの条件でした。

環境構築

今回の実験は、普段使っている Windows マシンに環境を整え、ローカルGPUで文字起こしを実行しました。必要なのは意外とシンプルです。

  • GPU: NVIDIA GeForce RTX 3060(12GB VRAM)
  • CPU: Intel core i7 8700
  • MEM: 32GB
  • ドライバ/CUDA: Driver Version 581.29 / CUDA Version 13.0
  • 開発環境:
    • Python(3.11.5)
    • CUDA Toolkit
    • Visual Studio(C++デスクトップ開発)
    • cmake version 4.1.1

Whisper本体は faster-whisper を使用し、CUDA対応でコンパイルしました。
CMakeコマンドは以下の通りです:

cmake -S . -B ./build -A x64 -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=ON

CPUのみでも動作は可能ですが、処理速度は文字通り桁違いです。体感では 数十倍の差 があり、長時間の音声を扱うなら GPU は必須だと実感しました。

環境構築を終えると、ローカルサーバーを立ち上げて音声ファイルをPOSTすれば、Whisperが文字起こしを返してくれる仕組みが整います。

whisper-server の起動例

D:\whisper.cpp\build-cuda\bin\Release\whisper-server.exe `
  -m D:\whisper.cpp\models\ggml-small.bin `
  --host 0.0.0.0 --port 8000 --threads 8
  • -m : 使用するモデル(今回は small を指定)
  • --host 0.0.0.0 : 外部からのアクセスも許可(LAN内で利用可能)
  • --port 8000 : HTTPサーバの待受ポート
  • --threads 8 : スレッド数指定(CPU併用の並列処理を最適化)

これを立ち上げると、http://localhost:8000/inference に音声ファイルをPOSTするだけで文字起こし結果がJSONで返ってきます。あなたのPowerShellスクリプト(gen_text.ps1)はこのエンドポイントを利用しています。

素材と処理フロー

公開素材の選定

実験素材には、春日部市議会 令和7年9月定例会 議案質疑(1日目) の公式アーカイブ動画を用いました。

議会中継は公開情報であり、著作権面の懸念が少なく、さらに 長時間・複数話者・専門用語あり という「文字起こし検証にうってつけ」の条件を備えていました。

前処理

MP4 → MP3 抽出

議会中継動画(MP4)から音声のみを抽出。
ffmpeg を用いればワンライナーで可能です。

ffmpeg -i input.mp4 -vn -acodec libmp3lame -ar 16000 -ac 1 meeting_16k_mono.mp3
  • -vn : 映像を無視
  • -acodec libmp3lame : MP3エンコード指定
  • -ar 16000 : サンプリングレートを16kHzに変換(ASR向け)
  • -ac 1 : モノラル変換

無音検出によるチャンク分割

約5分前後ごとに49ファイルに分割。処理単位を短くすることでモデルの安定性を確保。

以下は、Powershellのコードです。最長8分に収まるように無音分割します。

# ==== 設定 ====
$in = "meeting_16k_mono.mp3"   # 入力ファイル
$log = "silence.log"           # 無音検出ログ
$minLen = 240                  # 最短 4分
$maxLen = 480                  # 最長 8分
$outPrefix = "chunk_"          # 出力ファイル接頭語
# ==============

# 全体の長さを取得
$duration = [double](ffprobe -v error -show_entries format=duration `
  -of default=noprint_wrappers=1:nokey=1 "$in")

# 無音開始時刻を拾う
$starts = @()
Get-Content $log | ForEach-Object {
  if ($_ -match 'silence_start:\s*([0-9\.]+)') {
    $starts += [double]$matches[1]
  }
}

# 0 と duration も追加
$cuts = New-Object System.Collections.Generic.List[double]
$cuts.Add(0.0)
$starts | ForEach-Object { $cuts.Add($_) }
$cuts.Add($duration)
$cuts = $cuts | Sort-Object | Select-Object -Unique

# 分割実行
$segStart = 0.0
$idx = 0
foreach ($t in $cuts) {
  $len = $t - $segStart

  if ($len -ge $minLen) {
    # 4分以上たまった → この無音でカット
    $segEnd = $t
    $out = "{0}{1:D3}.mp3" -f $outPrefix, $idx
    ffmpeg -ss $segStart -to $segEnd -i "$in" -c copy "$out"
    $idx++
    $segStart = $segEnd
  }
  elseif ($len -ge $maxLen) {
    # 8分超える前に強制カット
    $segEnd = $segStart + $maxLen
    if ($segEnd -gt $duration) { $segEnd = $duration }
    $out = "{0}{1:D3}.mp3" -f $outPrefix, $idx
    ffmpeg -ss $segStart -to $segEnd -i "$in" -c copy "$out"
    $idx++
    $segStart = $segEnd
  }
}

# 残りがあれば最後に出力
if ($duration - $segStart -gt 5) {
  $out = "{0}{1:D3}.mp3" -f $outPrefix, $idx
  ffmpeg -ss $segStart -to $duration -i "$in" -c copy "$out"
}

文字起こし

  • 実行環境: RTX3060 + CUDA + whisper.cpp(small)
  • 処理速度: 1チャンク(5分程度)あたり約12秒
  • RTF(Real Time Factor): 平均0.04(=実時間の25倍速)
  • 総処理時間: 3時間54分の音声 → 約10分で完了

出力は out_ws\transcripts\chunk_xxx.txt に保存。さらに全文を結合して merged_transcript2.txt を作成しました。

処理ログの一例(抜粋):

chunk_000.mp3  dur=242.9s  time=11.1s  rtf=0.045
chunk_007.mp3  dur=349.7s  time=14.7s  rtf=0.042
chunk_011.mp3  dur=579.4s  time=28.0s  rtf=0.048
...
=== Summary ===
Total audio  : 3.90 h
Total time   : 9.87 min
Overall RTF  : 0.04

RTX3060で4時間の録音を10分で文字起こしできた

Faster-Whisper(smallモデル, CUDA版)を用いた結果、議会4時間分の音声を10分程度で文字起こしできました。さすがは軽量モデルというところ。RTX3060(12GB VRAM)環境においては、メモリ使用量も5GB以内で収まり、GPU計算を活かした効率的な処理が可能ですね。

誤変換の例

固有名詞や専門用語はやはり弱く、以下のような誤変換が散見されます。

  • 誤)精神病床への入院費は対障害となっております。
    正)精神病床への入院費は対象外となっております。
  • 誤)埼玉県議会でも前回一致でこの十度、新身障害者医療費女性制度
    正)埼玉県議会でも全会一致でこの重度心身障害者医療費助成制度
Chunk000 の文字起こしテキスト

ただいまから本日の会議を開きます。日程第1、議案第76号から議案第84号までに対する質疑を行います。
質疑の通告がありますので、順次発言を許します。最初に19番、鈴木和都市議員。
議席番号19番、鈴木和都市でございます。おはようございます。
それでは議案第81号、かすかべ市十度新進障害者医療費助成に関する条例の一部改正について質疑を行わせていただきます。
十度新進障害者医療費助成制度は、障害者とその家族の経済的負担を軽減するため医療機関を受信した場合の医療費の一部を県と市町村が助成する制度だと思っております。
現在のかすかべ市というか、埼玉県での精神保険福祉手帳保持者の対象者は一級保持者のみとなっておりまして、精神病床への入院費は対障害となっております。
これは実は身体障害や知的障害の手帳保持者と比較をしますと、女性対象が狭く、3障害の中で同等でない状況となっている事実がございます。
障害者への医療費助成や支援については、本来はどこの地域で暮らしていても同じ状況であることが必然であると私自身は強く思っております。
が、残念ながら現状では違っておりまして、これは国が積極的に動いていただくことが必須であると感じている一人でございます。
精神障害者が社会復帰するためには、医療機関での通院を継続していくことでの病状の安定化が何よりも重要であり、適正な医療を続けることで、病状の悪化を防ぐとともに安定した社会生活や社会復帰をすることができてくると思っております。
しかし、それには経済的な問題が大きく、障害者総合支援法により精神化医療には上限が設定されておりますけれども、
例えばそれ以外の病気になった場合などは経済的負担が本当に大きくなってしまい、しかも多くの場合はご家族で支えているのが現状だと思っております。
そんな中で、当事者の皆様は精神障害を抱えながらも何かと、何とか自分の人生を生きたい、できるなら人の役に達したいと願っていると思っております。
これまで、埼玉県議会でも前回一致でこの十度、
新身障害者医療費女性制度の拡充を求め、実は採決もされておるような状況がございました。
そんな中、本年の4月ごろ、王の埼玉県知事から今回の十度、新身障害者医療費女性制度の埼玉県での拡充が発表されたところでございます。
そこで、まずは本事業の概要と仮面子においての対象人数について伺っております。
なお、対象人数につきましては、実は今回の確診をおいては何か精神保険福祉長の二級保持者全員というわけではないようなので、
その辺を踏まえての人数を伺っております。
以上一回目です。
答弁を求めます。
とまり福祉部長。

改善されていた点

一方で、人間が喋る際に頻発する 言い直し・冗長表現・重複 については、比較的きれいに整形されていました。そのため、読みやすさという観点では十分実用的と感じます。

コストとユースケースの比較

市販の文字起こしサービスは、1分あたりおおよそ150円が相場とされています。仮に4時間分(240分)を処理した場合、36,000〜37,000円に達します。これに対してローカル環境であれば、初期セットアップ以降は追加コストが発生しないため、社内ミーティングや研修記録といった用途では圧倒的に有利です。

ただし、商用サービスが劣っているわけではありません。Webエディタ機能、話者ごとのラベル付け、タグ付けや検索といった便利な付加機能はローカル環境では得にくく、NDAやコンプライアンスに制約がない場面であれば、nottaなどのSaaSを利用するのも合理的な選択です。

短時間の打ち合わせや10分程度のミーティングであれば、スマートフォンで録音し、Google Speechnotes などの無料アプリを活用するだけでも十分実用的です。精度もおおむね良好で、手軽に記録を残す用途には向いています。

一方で、数時間規模の会議や講演のように長時間の素材を扱う場合には、従量課金制サービスではコストが膨らみがちです。外部への情報流出を避けたい場合や、長時間データを継続的に扱うケースでは、ローカル環境での文字起こしこそが最も安全で現実的な選択肢といえるでしょう。

まとめ

今回の検証では、RTX3060 + CUDA環境で whisper.cpp を動作させ、約4時間分の議会録音を10分程度で文字起こしできることを確認しました。処理速度・精度の両面で、ローカル環境でも十分に実用的であることがわかります。

もちろん、自動文字起こしは完璧ではありません。固有名詞の誤変換や言い直しの処理には限界があり、人力でのレビューや編集は欠かせません。しかし、そのうえで「素のテキストを迅速に得られる」という価値は大きく、従来は人手に頼っていた作業を効率化する強力な手段になります。

商用サービスが提供する付加機能やサポートを重視するか、あるいはローカル処理によるコスト削減と情報管理を優先するかは、ユースケース次第です。重要なのは、自動化に過度な期待を寄せるのではなく、録音環境やレビュー体制とセットで導入を検討することです。

文字起こしの民主化は確実に進んでおり、身近なGPUとオープンソースを組み合わせれば「自分たちの会議を、外に出さずに、すぐに文字化する」ことが現実に可能になりました。今後は、精度向上や要約機能の統合など、さらなる進化が期待されます。