コンテンツにスキップ

大規模モデルの操作

ONNXモデルのサイズは、モデルの複雑さとパラメータの数によって大きく異なります。数KBの小さなものから数GBの大きなものまであります。ONNX Runtime Webはブラウザで全てのモデルを実行するように設計されていますが、大規模モデルを操作する際にはいくつかの考慮事項があります。

  • TOC

ブラウザで大規模モデルを操作する際には、注意すべきプラットフォーム制限がいくつかあります:

JavaScriptではArrayBufferのサイズに厳格な制限はありませんが、各ブラウザには独自の制限があります。例えば、ChromeでのArrayBufferの最大サイズは0x7fe00000バイト(約2GB)です。fetch APIを使用して大規模モデルを読み込む際には、response.arrayBuffer()を大規模ファイルに対して呼び出すと失敗する可能性があるため注意してください。

ONNX Runtime Webはnew WebAssembly.Memory()を使用して2GBを超える配列バッファーを作成し、この制限を回避します。ただし、new WebAssembly.Memory()で作成されたArrayBufferインスタンスは転送可能ではないため、Proxy機能では動作しません。

ONNXモデルはprotobuf形式でシリアライズされます。protobufファイルの最大サイズは2GBです。ONNXモデルが2GBより大きい場合、通常は外部データとともに生成されます。詳細については外部データを参照してください。

WebAssemblyには4GBのメモリ制限があります。これは、32ビットアドレッシングのため、WebAssemblyモジュールがアクセスできるメモリの最大量です。現在、ONNX Runtime Webで4GBを超えるモデルを実行する方法はありません。将来的には、WASM64を使用するか、直接GPU重み読み込みを使用してサポートする可能性があります。

ページがリフレッシュされるたびにモデルを読み込まないように、Cache APIまたはOrigin private file systemを使用してモデルをキャッシュできます。これにより、モデルは毎回サーバーからフェッチされるのではなく、キャッシュから読み込まれます。

詳細についてはCache APIOrigin private file systemを参照してください。

大規模なONNXモデルを操作する場合、通常は外部データとともに生成されます。protobufファイルサイズ制限のため、2GBを超えるONNXモデルは外部データを使用する必要があります。外部データは1つ以上の別個のファイルで、通常はONNXエクスポーターによって生成されます。外部データは通常、ONNXモデルファイルと同じディレクトリに配置されます。

ONNX Runtimeは外部データを含むモデルの読み込みをサポートします。これはC/C++/Python APIでは自動的に行われ、追加の手順は必要ありません。これらの言語バインディングのONNX Runtimeはファイルシステムにアクセスできるためです。ただし、ブラウザではJavaScriptコードはファイルシステムに直接アクセスできません。したがって、外部データ情報をONNX Runtime Webに渡すための追加の手順が必要です。

詳細に入る前に、まずONNX Runtimeでの外部データの仕組みを理解しましょう。この情報は重要です。そうしないと、手順が混乱に見える可能性があります。

ONNXモデルは技術的にはprotobufファイルです。protobufファイルにはモデルグラフと重みが含まれます。ONNX仕様では、重みをprotobufファイルまたは外部データファイルに保存できます。重みがprotobufファイルに保存されている場合、それは完全にprotobufファイルに含まれます。重みが外部データファイルに保存されている場合、protobufファイルにはその特定の重みに関する以下の情報が含まれます:

  • “location”(文字列)- 外部データファイルの相対ファイルパスを指定
  • “offset”(整数)- 外部データファイル内の重みの開始位置のバイトオフセットを指定
  • “length”(整数)- 重みの長さをバイト単位で指定

“location”は通常、ONNXエクスポーターによって決定されます。例えば、エクスポーターはモデルファイルをmodel_a.onnxとして出力し、外部データファイルを同じディレクトリ内のmodel_a.dataとして出力します。モデル内のいくつかの重みがmodel_a.dataファイルに保存されているため、これらの重みの”location”は./model_a.dataに設定されます。この情報はファイルmodel_a.onnxに保存されます。

これにより、ネイティブプラットフォームでは外部データファイルを決して名前変更しないことが重要である理由が説明されます。外部データファイルの名前を変更すると、protobufファイル内の”location”が実際のファイル名と一致しなくなり、ONNX Runtimeはモデルの読み込みに失敗します。

ONNX Runtime Webの場合、外部データ情報を常にONNX Runtime Webに渡す必要があります。protobufファイルで定義された”location”は、実際の外部ファイルパスとは異なる概念であることを理解することが重要です。これら2つの異なる概念は、次のセクションのJavaScriptコードで”path”と”data”として表現されます。

ONNX Runtime Webで外部データを含むモデルを読み込む

Section titled “ONNX Runtime Webで外部データを含むモデルを読み込む”

ブラウザで外部データを含むONNXモデルを読み込む方法を例で説明しましょう。ONNXモデルmodel_a.onnxと外部データファイルmodel_a.dataがあると仮定します。次のコードは、ブラウザで外部データを含むモデルを読み込む方法を示しています:

const modelUrl = 'https://example.com/path/model_a.onnx';
const externalDataUrl = 'https://example.com/path/model_a.data';
const mySession = await ort.InferenceSession.create(modelUrl, {
...,
externalData: [
{
path: './model_a.data',
data: externalDataUrl
}
]
});

上記のコードでは、外部データ情報をInferenceSession.create()メソッドに渡します。externalDataはオブジェクトの配列で、各オブジェクトは1つの外部データファイルを表します。オブジェクトには2つのプロパティがあります:

  • path(文字列)- protobufファイル内の重みの”location”情報と一致する必要があります
  • data(文字列)- 外部データファイルを指定します。URL、Blob、またはUint8Arrayにすることができます。

モデルと外部データをIndexedDBに保存する場合、IndexedDBから外部データを含むモデルを読み込むことができます。次のコードは、IndexedDBから外部データを含むモデルを読み込む方法を示しています:

// loadFromIndexedDB()はアプリで実装された関数で、IndexedDBからデータを読み込むと仮定
// IndexedDBからモデルと外部データを読み込む
const modelBlob = await loadFromIndexedDB('model_a.onnx');
const externalDataBlob = await loadFromIndexedDB('model_a.data');
const mySession = await ort.InferenceSession.create(modelBlob, {
...,
externalData: [
{
path: './model_a.data',
data: externalDataBlob
}
]
});

詳細についてはONNX External Dataを参照してください。

このセクションは作成中です。