ガイド

Mac が音声をオンデバイスで文字起こしするとき、実際に何が起きているのか

オンデバイス AI は、具体的でなかなか興味深いエンジニアリングに付けられたマーケティング上の言葉です。ここでは、ファイルからテキストまでのパイプライン全体を説明します。

いまやどのアプリも「オンデバイス」で処理すると言います。それが実際に何を含むのかを知っておく価値があります。ひとつには、ローカルの文字起こしがこれほど急速に良くなった理由を説明してくれるからで、もうひとつには、それが検証できる主張とできない主張の分かれ目だからです。

以下がその順を追ったパイプラインです。

ステップ 1: すべてが 16 kHz モノラルになる #

これらのアプリのほぼすべてが使う音声認識モデル Whisper は、たった 1 種類の入力しか受け取りません。毎秒 16,000 サンプル、1 チャンネル、-1 から 1 の浮動小数点数です。

したがって、どの文字起こしツールも最初にすることは、音声の大半を捨てることです。48 kHz のステレオ録音はダウンミックスされ、サンプリングレートを落とされます。動画ファイルは音声トラックが抽出され、映像は破棄されます。

破壊的に聞こえますが、ほとんどはそうではありません。人間の発話は 8 kHz より下にあり、ナイキストの定理により 16 kHz のサンプリングレートでそのすべてを捉えられます。失われるのは音楽としての品質であって、聞き取りやすさではありません。

実際の帰結として、高価な 96 kHz の録音はこの段階では何の得にもならず、ひどく圧縮されたファイルがここで救われることもありません。

ステップ 2: 音声区間検出が、文字起こしする価値のある部分を決める #

もっと小さい 2 つ目のモデルが先に動き、音声のどの部分に人の発話が含まれるかを示します。

一般に使われているのが Silero VAD で、1 メガバイト未満のモデルが、細かい時間の刻みで「発話か、そうでないか」という 1 つの問いに答えます。

これが存在する理由は 2 つあります。ひとつは高速化で、無音のデコードは無駄な作業だからです。より重要なのは、発話を含まない音声を渡された Whisper がそれでもテキストを生成してループするという失敗を防ぐことです。現代のローカル文字起こしが、同じ表現の繰り返しで何ページも埋めるのをやめたのは VAD のおかげです。

ステップ 3: 音声が画像になる #

Whisper は波形を受け取りません。受け取るのは log-Mel スペクトログラムです。横軸が時間、縦軸が人間の聴覚に合わせた尺度の周波数、明るさがエネルギーを表す 2 次元の画像です。

これが現代の音声認識における実質的な概念上の飛躍です。音声がいったん画像になれば、コンピュータービジョンのために作られた仕組みをそのまま使えます。そして次に起きるのが、まさにそれです。

ステップ 4: エンコーダーが、理想的には Neural Engine 上で動く #

Whisper は 2 つの半分からなるトランスフォーマーです。エンコーダーはスペクトログラムを読み、話された内容の密な数値表現に変えます。こちらが処理の重い側で、固定サイズの入力に対する規則的で大量の行列積です。

そしてこれこそ、Apple の Neural Engine が想定している用途です。チップ上の専用ブロックが、狭い種類の演算を極めて高速に、非常に低い消費電力で行います。汎用ではなく、任意のコードを走らせることはできませんが、トランスフォーマーのエンコーダーはまさにその形にはまります。

エンコーダーをそこに載せるには、モデルを事前に Core ML の形式(.mlmodelc)にコンパイルしておく必要があります。これを行うアプリはモデルの重みと並べて Core ML のエンコーダーを同梱していて、同じハードウェア上で速いローカル文字起こしアプリと遅いものを分ける最大の要因がここにあります。

ステップ 5: デコーダーが GPU 上で動く #

デコーダーは実際のテキストを 1 トークンずつ生成し、各トークンはそれ以前のすべてに条件づけられます。

この半分は逐次的なので、バッチ処理を前提とした Neural Engine の設計には合いません。代わりに Metal を通して GPU 上で動きます。Apple Silicon ではその GPU が CPU とメモリを共有しているため、モデルの重みをバス越しにコピーする必要がありません。Apple Silicon がローカル推論で実力以上の働きをする理由の大きな部分がこれです。

ステップ 6: タイムスタンプは同じ処理から出てくる #

Whisper は、単語の間に特別なタイムスタンプトークンを挟んで出力します。テキストの塊ではなく、妥当なタイミングの付いた SRT が得られるのはこのためです。タイミングの情報は別のアライメント工程からではなく、同じデコードの過程から落ちてきます。

VAD が無音を飛ばしている場合、タイミングは元の録音上に対応づけ直す必要があります。そうしなければ、最初の空白より後のタイムスタンプはすべて狂ってしまいます。

モデルと、それが思ったより小さい理由 #

Whisper の Base モデルは 7,400 万パラメータです。完全な精度では約 140 MB になりますが、この用途ではその多くが冗長です。

量子化は、各重みをより少ないビット数で保存します。q5_1 のモデルでは、重みは 5 ビットに加えてブロックごとの小さなスケールとオフセットを持ち、1 つの重みあたり 16 ビットではなくおよそ 6 ビットになります。結果は約 60 MB で、通常の発話では精度の差を検出するのが難しいほどです。

これはスマートフォンにとって重要です。140 MB のダウンロードとそれに見合うメモリは、現実のコストだからです。「どのモデルを使うべきか」への正直な答えがたいてい人の想像より小さいものになるのも、これが理由です。

長いファイルと、メモリが難所である理由 #

Whisper の API は、連続した 1 つのサンプルのバッファを受け取ります。16 kHz の 2 時間は float で約 470 MB あり、それに加えて同程度のサイズのスペクトログラムが必要です。

Mac なら問題ありません。iPhone では、それだけでアプリがシステムに強制終了されるのに十分です。一部のモバイル文字起こしアプリが黙ってファイル長を制限しているのはこのためです。

解決策は、ウィンドウ単位で文字起こしすることです。デコード済みの音声はディスク上に置き、一度に 1 つの区間だけをマップして文字起こしし、解放します。そうすればピーク時のメモリはファイルではなくウィンドウで決まります。難しいのはどこで切るかで、単語の途中で分割すると境界ごとに壊れた文ができてしまいます。そこで、まともな実装は重なりの区間の中で最も静かな点を選んで切り、各ウィンドウのタイムスタンプを元のタイムライン上に戻します。

これがあなたにとって重要な理由 #

上のパイプラインから導かれる、宣伝文句ではない 3 つのことがあります。

ネットワークなしで動きます。 上のどの工程にもネットワークは必要ありません。これは 30 秒で確認でき、その方法を書きました。私たちを信頼しなくてもできるテストも含めてあります。

あなたの録音は誰の学習データにもなりません。 ローカルのアプリがあなたの音声で学習しないと約束している、という話ではありません。あなたの音声が、そうなり得る場所に一度も存在しなかったという話です。

速度は自分のハードウェア次第で、誰かの待ち行列には左右されません。 ローカルの文字起こしは Apple Silicon 上で実時間の数倍の速さで、一貫して、日曜の午前 3 時でも、レート制限なしに動きます。

まとめ #

音声は 16 kHz モノラルにダウンサンプリングされ、音声検出が発話のない部分を取り除き、残りがスペクトログラムになり、トランスフォーマーのエンコーダーが Neural Engine 上でそれを処理し、デコーダーが GPU 上でタイムスタンプを挟みながらテキストを生成し、量子化によってモデルはこれらすべてがスマートフォンに収まる大きさになります。

どの工程にもサーバーは要りません。それがすべての要点です。

Offline Transcriptionを入手

音声も動画も、すべてお使いのMacの中だけで文字起こしします。アップロードは一切なく、アカウントも不要、分単位の従量課金もありません。

macOS 13.0 or higher · iOS 16.4 or higher