Cross-Origin Storage API を使った Transformers.js の実験

Cross-Origin Storage API を使った Transformers.js の実験

Cross‑Origin Storage (COS) API は、URL の代わりに暗号化ハッシュによって大きなファイルを保存および取得できるようにし、オリジンがブラウザーのオリジン分割キャッシュによるヒットブロックを回避してキャッシュされたリソースを共有できるようにします。Transformers.js で実験的なフラグを有効にすることで、開発者は各サイトで同じモデルの重みと Wasm ランタイムを再ダウンロードすることを避け、帯域幅とストレージを節約できます。

Transformers.js におけるキャッシュの分離問題

ブラウザーはタイミング攻撃を防ぐためにオリジン別に HTTP キャッシュを分離するため、異なるサイトから取得された同じリソースは別々に保存されます。Transformers.js のデモでは、https://googlechrome.github.io 上の ASR デモを訪問すると、Whisper モデル(約 177 MB)と ONNX Runtime Wasm ファイル(約 4,733 kB)がキャッシュされます。https://rawcdn.rawgit.net などの異なるオリジンから同じデモを読み込むと、バイトが同じでもブラウザーはそれらのリソースを再ダウンロードしてキャッシュします。

Cross‑Origin Storage API がそれをどう解決するか

COS は navigator.crossOriginStorage を導入し、ファイルを URL の代わりにハッシュ(例: SHA‑256)で識別します。サイトがハッシュでファイルをリクエストすると、そのハッシュがストアに既に存在する場合は API が FileSystemFileHandle を返し、存在しない場合はネットワークにフォールバックしてファイルを COS に書き込み、今後の使用に備えます。キーがハッシュであるため、以前に同じバイトを保存したあらゆるオリジンはキャッシュヒットを得て、重複ダウンロードがなくなります。

Transformers.js における COS の統合

Transformers.js provides an opt‑in backend that uses COS when the flag env.experimental_useCrossOriginStorage is set to true. The library computes the SHA‑256 hash of each Xet‑tracked model file (e.g., the ONNX weight files) from the raw pointer stored on the Hugging Face Hub and passes that hash to navigator.crossOriginStorage.requestFileHandle. If the file exists in COS it is read instantly; if not, it is downloaded and stored for the next caller. Enabling the feature requires only one line before the first pipeline call:

import { env, pipeline } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0\); // 👇 Opt in to the experimental Cross‑Origin Storage cache backend.
env.experimental_useCrossOriginStorage = true;
const asr = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en', { device: 'webgpu' });
const result = await asr('jfk.wav');
console.log(result);

COS を介してファイルを保存する際、開発者は origins オプションを指定できます。

  • origins: '*' はリソースをグローバルに利用可能にし、共有モデルの重みや Wasm ランタイムに適しています。
  • origins: ['https://write.example.com', 'https://calculate.example.com'] のようなリストは、アクセスをそれらのサイトに制限します。
  • origins を省略すると、ファイルは同一サイトオリジンに限定されます。 可視性はアップグレードのみ可能(たとえば、制限付きからグローバルへ)で、ダウングレードは決して行われません。これにより、悪意のあるサイトがパブリックリソースの対象ユーザーを縮小することを防ぎます。API は書き込み時に提供されたデータを宣言されたハッシュと照合し、不一致があるとエラーが発生し、追加コードなしで自動的な整合性チェックが行われます。

プライバシーに関する考慮事項

どのサイトでもハッシュでファイルをプローブできるため、COS には可用性ゲーティングが組み込まれており、ブラウザーはフィンガープリントを防ぐために、わずかなオリジンでしか見られていないファイルの存在を隠すことがあります。したがって、requestFileHandle からのエラーはファイルが存在しないことを definitively 意味するわけではなく、ブラウザーが確認を保留している可能性があります。アプリはこのエラーをキャッシュミスとして扱い、ネットワークにフォールバックすべきです。

試してみる

今日試すには、Chrome ウェブストアから Cross‑Origin Storage 拡張機能をインストールし、navigator.crossOriginStorage のポリフィルを注入します。拡張機能が有効な状態で、https://googlechrome.github.iochrome.googlechrome.github.io/samples/transformersjs-automatic-speech-recognition/index3.html の COS を有効にした ASR デモを開き、Whisper モデルの読み込みを待ちます。その後、同じデモを異なるオリジン(https://rawcdn.rawgit.net/GoogleChrome/samples/1e4f2b8c10adc394352c6ec8327bb503bac7aba1/transformersjs-automatic-speech-recognition/index3.html)から開きます。COS なしでは観察された 177 MB の再ダウンロードの代わりに、モデルはミリ秒単位で COS から提供されます。拡張機能のポップアップには、その SHA‑256 ハッシュで識別される共有リソースと、それを保存している 2 つのオリジンが表示されます。

行動への呼びかけ

Transformers.js アプリを構築している場合は、最初の pipeline() 呼び出しの前に env.experimental_useCrossOriginStorage = true を追加し、COS 拡張機能をインストールして、Network タブで重複ダウンロードがなくなったことを確認してください。オプトインを行うサイトは、他のすべてのサイトのユーザーにとって体験をより速く、より安価にします。オプトインはリスクフリーです:COS API が利用できない(拡張機能がない)場合は、コードはデフォルトの Cache API にフォールバックします。API に関するフィードバックは、GitHub 上の Cross‑Origin Storage リポジトリに送信できます。そこでは Chrome チームもネイティブ実装を検討しています。

Sources