2026/11/08AI業務効率化
AI活用

speech.cppで日本語の文字起こし|Macで72分を1分

speech.cppで日本語の文字起こし|Macで72分を1分

「打ち合わせの録音を文字起こししたいが、先方の話が入った音声をクラウドのサービスに上げたくない」「Macでwhisper.cppを回しているが、日本語の誤りが多くて要約に使えない」——録音を自分の手元だけで処理したいとき、多くの人がこの壁に当たります。

結論から言うと、Apple シリコンのMacなら、speech.cpp と日本語専用の音声認識モデル Haas-ja-v1.0 の組み合わせで、72分の録音を約1分15秒で文字起こしできました(M2 MacBook Air・2026年11月7日の実測)。精度はWhisper medium と同じくらいで、Whisper small よりはっきり良い結果でした。ただし「声の小さい側の短い返事が抜ける」という癖があり、区間を短く切り、音量をならして使う必要があります。

株式会社Fyveは、社内の打ち合わせ録音の文字起こしと要約を、外部に音声を出さない形で回しています。この記事では、私たちが whisper.cpp から speech.cpp + Haas-ja に乗り換えたときの手順と、正解の書き起こしが無い状態でエンジンを比べた方法、見つかった弱点と対処をそのままお伝えします。

speech.cppとHaas-ja-v1.0とは

まず2つの部品が何者かを整理します。記載はすべて2026年11月9日時点の公式リポジトリ・モデルカードの内容です。

speech.cpp:Macで音声認識を動かす土台

speech.cpp は、ggml(llama.cpp や whisper.cpp と同じ系統の計算ライブラリ)の上に作られた C++ の音声処理ツールです。音声認識・音声合成・話している区間の検出(VAD)・話者分けを、speech という1つのコマンドで扱えます。コードのライセンスは MIT で、モデルの重みはそれぞれの作者のライセンスに従います。

  • 動く環境: Apple シリコンの macOS は Metal(GPU)で動く。Windows x64・Linux x86-64 は Vulkan または CPU。Intel の Mac はソースからビルドが必要
  • 扱える認識モデル: haas-ja-v1.0(日本語)、reazonspeech-v2、parakeet-tdt_ctc-0.6b-ja、qwen3-asr、nemotron-3.5-transcribe など
  • モデルは初めて使うときに自動で取得される(speech pull で先に取っておくこともできる)

Haas-ja-v1.0:日本語専用の認識モデル

Haas-ja-v1.0 は Third Intelligence 社が公開した日本語の音声認識モデルです。NVIDIA の Parakeet-TDT を土台にした約6.16億パラメータのモデルで、ReazonSpeech・Common Voice・YODAS などの約46,000時間の音声で学習されています。ライセンスは Apache 2.0 です。

モデルカードによると、5つのデータセットをまとめた日本語の評価(asr-ja-bench v1.1・18,318発話)で、文字の誤り率は加重平均 6.12%。比べたオープンなモデルの中で最も良く、GPT-Transcribe(6.07%)と同じ水準とされています。speech.cpp 側の計測では、FLEURS の日本語で誤り率 約4.4%(parakeet-tdt_ctc-0.6b-ja は5.0%)でした。

ここで大事なのは、公式の Haas-ja は Linux + NVIDIA GPU 前提で、macOS に対応していないことです。これを Mac で動かせるようにしているのが speech.cpp です。Windows 向けの日本語音声入力アプリ OpenHinoVoice(MIT)も、中身で speech.cpp を使っています。私はこのアプリをきっかけに組み合わせを知りましたが、アプリ自体は Windows 用なので、Mac では部品の speech.cpp を直接呼んでいます。

なお、Whisper と Haas-ja を同じ条件で比べた公式の数字はありません。そこで私たちは、自分の録音で比べました(後の節で詳しく書きます)。

whisper.cppから乗り換えた理由

それまで私たちは、Mac 上の whisper.cpp(small モデル)で打ち合わせの録音を文字起こしし、その結果を Claude に渡して要約させていました。録音には先方の発言が入るので、音声を外部のサービスに上げない、というのが前提です。

困っていたのは、Whisper small の誤り方でした。制度の名前・会社の名前・一般的な言葉を、音の近い別の言葉に置き換えてしまうのです。文字が少し違うだけなら要約で吸収できますが、意味が変わる置き換えは要約の材料になりません。medium に上げれば精度は上がるものの、3分の音声に23秒かかり、1時間の録音なら約8分待つことになります。

「速さは small 並み、精度は medium 以上」を探していたところで見つけたのが、speech.cpp + Haas-ja の組み合わせでした。

動画の音声から要約までの流れ全体は、次の記事で扱っています。

Claude Codeで会議・セミナー動画を文字起こし要約
Claude CodeClaude Codeで会議・セミナー動画を文字起こし要約

speech.cppの入れ方と、日本語の文字起こしの動かし方

ここからは実際の手順です。Apple シリコンの Mac を前提にしています。

1. speech.cppを入れる

公式のインストーラを使います。ダウンロードしたファイルの SHA-256 を確かめたうえで、ホームフォルダに speech を置き、PATH に足してくれます。

curl -fsSL https://raw.githubusercontent.com/nyosegawa/speech.cpp/main/install.sh | sh
speech --version

更新するときは、同じインストーラをもう一度実行するか speech update を使います。音声の変換に ffmpeg も使うので、入っていなければ brew install ffmpeg で入れておきます。

2. 録音を16kHzモノラルにし、音量をならす

Haas-ja は 16kHz・モノラルの音声を受け取ります。ffmpeg で変換するとき、同時に 音量の差をならす処理をかけるのが私たちの設定です。理由は後の「弱点」の節で書きますが、声の小さい人の返事を拾いやすくするためです。

ffmpeg -i meeting.mp3 -ar 16000 -ac 1 -af "dynaudnorm=f=150:g=15" meeting.wav

3. 区間に分けて起こす

文字起こしの本体は1行です。

speech asr haas-ja-v1.0 --vad silero-vad --max-speech-duration-s 5 --timestamps meeting.wav > meeting.tsv
  • --vad silero-vad: 話している区間を検出し、区間ごとに認識する。speech.cpp のドキュメントには「長い音声をまとめて渡すと、文がまるごと抜けることがある」とあり、その対策が区間ごとの認識です。このオプションは外さないのが前提です
  • --max-speech-duration-s 5: 1回に起こす区間の長さの上限(秒)。既定は10秒で、これより長い区間はいちばん長い無音のところで切られます。私たちは5秒にしています
  • --timestamps: 区間ごとの時刻を付ける。後で「何分ごろの発言か」を録音で聞き直すのに使います

初回だけモデルの取得が入ります。私の環境では Haas-ja が約0.66GB、silero-vad が約1.2MB でした。2回目からは取得なしですぐ始まります。

1人が長く話す録音(セミナーや説明会)では、区間の上限を8秒程度に延ばしたほうが良い結果になりました。この差は後の比較表に出ています。

録音を外に出さずに文字起こしから要約まで回す流れ(ffmpegで16kHzと音量ならし→silero-vadで5秒以内の区間に分割→Haas-jaで認識→要約)

4. 固有名詞の辞書を使うとき

社名・人名・製品名が多い録音では、--keywords で「表記=読み」の辞書を渡せます。

speech asr haas-ja-v1.0 --vad silero-vad --max-speech-duration-s 5 \
  --keywords $'Claude Code=クロードコード\nFyve=ファイブ' meeting.wav > meeting.txt

ただし、私の環境では 辞書を指定すると時刻が付かなくなりました。時刻が必要な録音か、固有名詞の正確さが必要な録音かで使い分けています。辞書が実際の社名・人名でどこまで効くかは、まだ十分に確かめられていません。

正解の書き起こしが無いときの比べ方

エンジンを比べるとき、本来は「人が正しく書き起こした文」と並べて誤り率を出します。ただ、自分の打ち合わせ録音にそんなものはありません。72分を人手で起こすのは現実的ではないので、私たちは別の比べ方をしました。

「欠かせない語句」を数える

  1. 72分の録音から、性質の違う3分を2か所切り出す。A=2人の会話で相づちが多く、片方の声が小さい区間。B=ほぼ1人が話している区間
  2. それぞれの3分を聞き、内容を理解するのに欠かせない語句を21個ずつ選ぶ(制度の名前、数字、決まったこと、固有名詞など)
  3. 各エンジンの出力に、その21個が正しく入っているかを数える

要約の材料として使えるかどうかは、句読点や表記の揺れではなく「大事な言葉が正しく入っているか」で決まります。この数え方なら、書き起こしの全文を作らなくても、目的に沿った比較ができます。

文字の一致率を判断に使わなかった理由

最初は Whisper medium の出力を仮の正解にして、文字の一致率も計算しました。ところがこの方法だと、同じ Whisper 系の small が、話し言葉を書き言葉に直す癖やかなと漢字の選び方まで medium と似ているせいで、実際より良く見えてしまいます。基準に選んだエンジンと「書き方の癖が近い」ものが有利になるので、この数字は判断に使いませんでした。

仮の正解を別のエンジンで作る比べ方は手軽ですが、この偏りに気づかないと、誤りの多いエンジンを選んでしまいかねません。

Whisperと比べた結果

M2 MacBook Air で、2026年11月7日に測った結果です。数字は「欠かせない語句21個のうち、正しく入っていた数」と「3分の音声を起こすのにかかった時間」です。

エンジン・設定

A(2人の会話)

B(ほぼ1人)

3分あたりの時間

Whisper small

12/21

16/21

10秒

Whisper medium

20/21 相当

20/21

23秒

Haas-ja そのまま(区間の上限10秒)

15/21

20/21

3秒

Haas-ja+音量ならし+上限5秒(採用)

20/21

18/21

3秒

Haas-ja+音量ならし+上限8秒

18/21

19/21

3秒

Haas-ja+ノイズ除去(re-use)

20/21

—

257秒

ReazonSpeech v2

15/21

—

5秒

採用した設定で72分の全体を起こすと、1分15秒(1,320区間)でした。Whisper medium なら同じ録音に約9分かかる計算なので、待ち時間はおよそ7分の1です。

2人の会話の切り出しで、欠かせない語句21個のうち入っていた数と3分あたりの時間をWhisper small・medium・Haas-jaで比べた図

結果から読み取れること

  • Whisper small は要約の材料にならない。会話の区間で21個中12個。抜けた語句の多くは、音の近い別の言葉への置き換えでした
  • Haas-ja と Whisper medium は同じくらいの精度で、誤る場所が違うだけでした。Whisper medium が意味の通らない言葉にした箇所を、Haas-ja が正しく書いていた例もありました
  • 速さは Haas-ja が圧倒的。3分あたり3秒で、Whisper small(10秒)よりも速い
  • 設定で順位が入れ替わる。2人の会話では区間5秒が最も良く、1人が話す区間では8〜10秒のほうが良い。録音の種類で区間の上限を選べるようにしておく意味があります
  • ノイズ除去(speech.cpp の --enhance re-use)は取りこぼしがほぼ消えましたが、3分に257秒かかり、72分なら1時間以上です。日常の運用には向かないと判断しました

Haas-jaの弱点と対処

声の小さい側の短い返事が抜ける

使ってみて分かった最大の癖は、1つの区間の後半にある発言、とくに声の小さい側の短い返事を落とすことです。「はい」「そうですね」「それで大丈夫です」のような短い返事が、まるごと消えていました。

最初は区間の検出(VAD)が取りこぼしているのかと思いましたが、調べると区間自体は正しく取れていて、認識した本文だけが途中で終わっていました。つまり、モデル側が落としていたことになります。

対処として効いたのは次の2つです。

  • 区間の上限を短くする(10秒→5秒)。区間が短いほど「後半」が少なくなり、拾える返事が増えました。ただし短くしすぎると、言葉の途中で区間が切れて別の誤りが出ます。私たちの録音では5秒が釣り合う点でした
  • 音量の差をならす(ffmpeg の dynaudnorm=f=150:g=15)。マイクから遠い人の声を持ち上げると、さらに少し拾えるようになりました

それでもゼロにはなりません。この癖は、次の節の「要約での使い方」に直結します。

話者分けは使っていない

speech.cpp には話者分けのモデル(nemotron-3-diarization)もあり、--diarize で区間ごとに話者を付けられます。試しましたが、2人の打ち合わせで一方の返事をもう一方の発言に入れるなど、取り違えが多く出ました。誰の発言かを取り違えた記録は、話者なしの記録より危ないので、私たちは使っていません。

要約に回すときの決まり

文字起こしの結果は、Claude に渡して議事録や要点にまとめています。このとき、Haas-ja の弱点を踏まえて1つ決まりを作りました。

「相手が同意した/しなかった」は、文字起こしだけで決めない。

抜けやすいのは、まさに「はい」「大丈夫です」のような短い返事です。文字起こしに同意の言葉が無くても、実際には返事をしていた可能性があります。要約で同意の有無を書くときは、前後の流れから判断し、決め手が無ければ「録音で要確認(◯分ごろ)」と書くようにしています。--timestamps を付けて起こしているのは、このとき該当箇所をすぐ聞き直せるようにするためです。

議事録の形や、どこまで自動化するかの決め方は、次の記事にまとめています。

会議の議事録を自動化する完全ガイド|形・録音環境・出口で決める
AI業務効率化会議の議事録を自動化する完全ガイド|形・録音環境・出口で決める

speech.cppで選べるほかの日本語モデル

speech.cpp は Haas-ja 専用の道具ではなく、モデルの名前を差し替えるだけで別の認識モデルも使えます。2026年11月9日時点の公式リポジトリに載っている、日本語に使えるものを整理します。

モデル名

特徴(公式の記載)

私たちの扱い

haas-ja-v1.0

日本語専用。FLEURS 日本語で誤り率 約4.4%

日本語の既定

parakeet-tdt_ctc-0.6b-ja

日本語。FLEURS 日本語で誤り率 5.0%

未比較

reazonspeech-v2

日本語。--timestamps の使用例あり

比較して不採用(会話の区間で15/21)

qwen3-asr(0.6b・1.7b)

--language ja と --prompt で手がかりを渡せる。1回に約20分まで

未比較

nemotron-3.5-transcribe

40言語。--speakers で話者も出せる。1回に約1時間まで

未比較

モデルごとに受け付けるオプションが違うので、試す前に speech info モデル名 で確かめるのが確実です。私たちが Haas-ja に決めたのは、自分の録音で比べた結果と速さの両方からで、表の未比較のモデルが劣ると確かめたわけではありません。録音の種類によっては、別のモデルのほうが合う可能性もあります。

うまく動かないときの確認

speech.cpp の終了コードは公式ドキュメントで次のように決まっています。シェルのスクリプトから呼ぶときは、ここで分岐させておくと原因を追いやすくなります。

  • 0: 正常に終わった
  • 1: 失敗。speech: <コード> (<オプション>): <メッセージ> の形で理由が出る
  • 2: コマンドの書き方が実行できない形(オプションの組み合わせの誤りなど)
  • 3: モデルの上限で認識が止まった(全ファイルの文字は書き出したうえで3を返す)

終了コード2が出たときは、オプションの組み合わせを見直します。たとえば --timestamps はマイクのライブ文字起こし(--live)とは一緒に使えず、話者を出す --speakers は --vad と組み合わせられないと公式に書かれています。エラーが出たら、まず組み合わせを疑うと早く解決します。

speech.cppとWhisperの使い分け

乗り換えた後の、私たちの使い分けは次のとおりです。

録音

使うもの

設定

日本語の打ち合わせ(2人以上の会話)

speech.cpp + Haas-ja

音量ならし・区間の上限5秒

日本語のセミナー・説明会(1人が長く話す)

speech.cpp + Haas-ja

音量ならし・区間の上限8秒

日本語以外

whisper.cpp

—(Haas-ja は日本語専用)

日本語でどうしても Whisper を使う場合

whisper.cpp

medium(small は使わない)

どちらもMacの中で完結するので、音声が外部に出ることはありません。文字起こしの結果も録音ファイルの横に出力し、共有フォルダやリポジトリには置かない運用にしています。

まだ確かめていないこと

この記事の数字は、72分の録音1本・3分の切り出し2か所で測ったものです。どんな録音でも同じ結果になるとは言えません。とくに次の条件は、まだ試していません。

  • オンライン会議の録画(圧縮された音声・回線による途切れ)
  • 3人以上が話す会議
  • 工事現場や店舗など、雑音の多い場所での録音
  • M2 Air 以外の Mac での速さ(速さの数字は M2 Air のもの)

自分の録音で採用を決めるときは、この記事と同じように3分を2か所切り出し、欠かせない語句を20個ほど選んで数えてみるのがおすすめです。30分もあれば、自分の録音に合うエンジンと区間の長さが分かります。

よくある質問

Intel の Mac でも使えますか

公式のインストーラは Apple シリコンの Mac と Linux(x86-64)向けです。Intel の Mac はソースからのビルドが必要と案内されています。私たちは Apple シリコンでしか試していません。

Windows で使いたい場合は

speech.cpp は Windows(x64・Vulkan)にも対応しており、PowerShell 用のインストーラがあります。音声入力として使いたいなら、中身に speech.cpp を使っている OpenHinoVoice のようなアプリも選択肢になります。

無料で使えますか

speech.cpp のコードは MIT、Haas-ja-v1.0 の重みは Apache 2.0 で公開されており、ソフトウェアの利用料はかかりません。手元の Mac で動くので、音声の長さに応じた課金もありません。商用で使う場合は、念のため各ライセンスの条件をご自身で確認してください。

文字起こしの整形はAIに任せられますか

任せられますが、「整形」と「要点の整理」は別の工程です。どこまでを AI に任せ、どこを人が見るかは次の記事で書いています。

文字起こしの整形はもう不要か|消えた工程と残る工程
AI業務効率化文字起こしの整形はもう不要か|消えた工程と残る工程

まとめ

  • speech.cpp を使うと、Linux + NVIDIA GPU 前提の日本語モデル Haas-ja-v1.0 を、Apple シリコンの Mac で Metal を使って動かせる
  • 72分の打ち合わせ録音を M2 Air で約1分15秒。欠かせない語句で比べた精度は Whisper medium と同じくらいで、Whisper small よりはっきり良い
  • 弱点は、声の小さい側の短い返事が抜けること。区間の上限を5秒にし、ffmpeg で音量をならすと減る
  • 正解の書き起こしが無いときは、「欠かせない語句」を選んで数えると、目的に沿った比較ができる
  • 要約で「同意した」を書くときは文字起こしだけで決めず、決め手が無ければ「録音で要確認」と書く

株式会社Fyveでは、このように外部に出せないデータを手元で処理する仕組みを、自社の業務で試しながら組み立てています。録音を外に出さずに文字起こししたい方は、まず3分の切り出しで Whisper と比べるところから始めてみてください。

AIを使う会社と、使わない会社。
その差は、開き始めています。

ここ数年でAIは急速に進化し、正しく導入できている企業とそうでない企業とでは、業務効率や人件費に大きな差が生まれ始めています。「AI導入に興味はあるが、実際に何ができて、どこから手をつければいいか分からない」——そんな方は、まずこの無料プレゼントに目を通してみてください。

無料プレゼント:様々な業種にAIを導入して分かった、成功の型と失敗パターン ― 無料でダウンロードする
← 記事一覧に戻る