記事一覧へ戻る
ライブラリ解説

transformers.js が ML モデルをブラウザで動かす仕組み

HuggingFace の transformers.js は ONNX Runtime Web を通じて、Whisper や RMBG-1.4 などの ML モデルをブラウザ内で実行します。モデルファイルはダウンロードしてキャッシュされますが、あなたの音声や画像はどこにも送信されません。

transformers.js と ONNX Runtime Web の関係

HuggingFace が開発する transformers.js は、Python の Transformers ライブラリをブラウザ向けに移植したものです。PyTorch / JAX で訓練されたモデルを ONNX (Open Neural Network Exchange) 形式に変換し、ブラウザで実行可能な ONNX Runtime Web (ortw) エンジンの上で動かします。ONNX という中間表現を挟むことで、元の訓練フレームワークに依存せず、同一の推論コードで複数のモデルアーキテクチャに対応できます。

ブラウザでの推論バックエンドは 2 種類あります。WebGPU が使えるデバイスでは GPU シェーダーを直接呼び出して並列演算を行い、対応していないデバイスでは WASM SIMD (WebAssembly の SIMD 拡張命令) にフォールバックします。NoSend Tools の Whisper ワーカーは起動時に `navigator.gpu.requestAdapter()` を呼んで WebGPU の可用性を検出し、アダプターが返れば WebGPU で、失敗すれば自動的に WASM に切り替えます。シェーダーコンパイル中に WebGPU が内部エラーを投げた場合も透過的に WASM へ降格するので、ユーザーがバックエンドを意識する必要はありません。

NoSend Tools が使う 2 つのモデル

音声文字起こしツール (voice-transcribe / audio-transcribe) は OpenAI が公開した Whisper の ONNX 変換版を使っています。選択できるサイズは tiny / base / small / turbo の 4 種で、tiny は WebGPU 約 95 MB / WASM 約 40 MB、small は WebGPU 約 299 MB / WASM 約 249 MB です。turbo (whisper-large-v3-turbo) はエンコーダーの fp32 重みが 2.5 GB を超えるため、ブラウザで扱えるよう q4 量子化済みのファイルを使っています。モデルファイルは `onnx-community` 名前空間から HuggingFace Hub の CDN 経由で初回のみダウンロードされ、その後は `CacheStorage` (キー `pwt-whisper-cache-v1`) にキャッシュされます。2 回目以降はネットワーク通信ゼロで推論が始まります。

背景除去ツール (image-bg-remove) は briaai が公開した RMBG-1.4 を使っています。入力画像を 1024x1024 にリサイズして encoder に通し、出力される 1 チャンネルのマスクテンソルを元解像度に戻して前景と背景を分離します。こちらも `pwt-rmbg-cache-v1` キーで CacheStorage にキャッシュされ、再訪問時は即座に起動します。どちらのモデルも `env.allowLocalModels = false` / `env.useBrowserCache = true` の設定で動作し、モデルの取得先と実行場所がコードに明記されています。

クラウド API との本質的な違い

OpenAI Whisper API のようなクラウド型の音声認識は、音声データをそのままサーバーへ送信します。処理はサーバー上で行われ、テキストが返ってきます。通信経路上には CDN キャッシュ・ロードバランサー・アクセスログがあり、送信した時点でデータはあなたの手から離れます。利用規約に「学習に使用しない」と書かれていても、それを後から確認する手段はユーザー側にはありません。

ブラウザ内 Whisper は逆の流れです。モデルファイル (ONNX 重み) は CDN からダウンロードしてキャッシュしますが、このダウンロードにあなたの音声は含まれていません。推論は Web Worker 内の ONNX Runtime Web が担当し、Float32Array として渡された波形データはブラウザのメモリから外に出ません。DevTools の Network タブを開いてモデルロード後に文字起こしを実行すると、音声を含むリクエストは 1 件も出ていないことを目視確認できます。初回にモデルをダウンロードする待機時間 (tiny で数秒、small で十数秒) がクラウド API より長い点はトレードオフですが、2 回目以降はキャッシュから瞬時に起動し、この問題は実質解消されます。

「モデルのダウンロード」と「データの送信」は別の話

transformers.js を使うツールを初めて開くと、モデルファイルのダウンロードが始まります。これは ffmpeg.wasm の初回ロードや kuromoji 辞書のダウンロードと同じ構造で、「ライブラリや重みをブラウザに取り込む」行為であり、「ユーザーの入力データをサーバーに届ける」行為ではありません。HuggingFace Hub CDN はモデルの配信元であり、あなたが処理しようとしている音声ファイルや画像の内容を受け取ることはありません。

この区別は、プライバシー観点で重要です。「CDN からファイルを取得した」という事実を「データを送信した」と誤解すると、オフラインキャッシュ後は送信ゼロで動作するという実態を見誤ります。NoSend Tools では `env.useBrowserCache = true` を設定してキャッシュを明示的に有効化し、一度ダウンロードしたモデルが再訪問時に CDN を経由しないようにしています。気になる方は DevTools の Application タブ → Cache Storage で `pwt-whisper-cache-v1` / `pwt-rmbg-cache-v1` のエントリが蓄積されていることを確認できます。