Arbeiten mit großen Modellen

Die Größe von ONNX-Modellen kann je nach Komplexität des Modells und der Anzahl der Parameter stark variieren. Sie können von wenigen KBs bis zu mehreren GBs reichen. Obwohl ONNX Runtime Web darauf ausgelegt ist, alle Modelle im Browser auszuführen, gibt es einige Überlegungen, die Sie bei der Arbeit mit großen Modellen beachten sollten.

Inhalt

Plattformbeschränkungen

Es gibt einige Plattformbeschränkungen, die Sie beachten sollten, wenn Sie mit großen Modellen im Browser arbeiten

Maximale Größe von ArrayBuffer

Obwohl es keine harte Grenze für die Größe eines ArrayBuffer in JavaScript gibt, hat jeder Browser seine eigenen Einschränkungen. Zum Beispiel beträgt die maximale Größe eines ArrayBuffer in Chrome 0x7fe00000 Bytes (ca. 2 GB). Seien Sie vorsichtig, wenn Sie die fetch API zum Laden großer Modelle verwenden, da dies fehlschlagen kann, wenn Sie response.arrayBuffer() für eine große Datei aufrufen.

ONNX Runtime Web erstellt Array Buffer > 2 GB mithilfe von new WebAssembly.Memory(), um diese Einschränkung zu umgehen. Ein von new WebAssembly.Memory() erstelltes ArrayBuffer-Objekt ist jedoch nicht übertragbar, sodass es nicht mit der Proxy-Funktion zusammenarbeiten kann.

Grenzwert für die Protobuf-Dateigröße

Das ONNX-Modell wird im Protobuf-Format serialisiert. Die maximale Größe einer Protobuf-Datei beträgt 2 GB. Wenn ein ONNX-Modell größer als 2 GB ist, wird es normalerweise mit externen Daten generiert. Weitere Details finden Sie unter Externe Daten.

Grenzwert für WebAssembly-Speicher

WebAssembly hat einen Speicherbeschränkung von 4 GB. Dies ist die maximale Speichermenge, auf die ein WebAssembly-Modul aufgrund der 32-Bit-Adressierung zugreifen kann. Derzeit gibt es keine Möglichkeit für ONNX Runtime Web, Modelle größer als 4 GB auszuführen. Wir könnten dies in Zukunft unterstützen, indem wir WASM64 verwenden oder die direkte Gewichtsladung über die GPU nutzen.

Cache das Modell

Um das Modell nicht jedes Mal neu laden zu müssen, wenn die Seite aktualisiert wird, können Sie das Modell mithilfe der Cache API oder des Origin Private File System cachen. Auf diese Weise kann das Modell aus dem Cache geladen werden, anstatt jedes Mal vom Server abgerufen zu werden.

Weitere Details finden Sie unter Cache API und Origin Private File System.

Externe Daten

Wenn Sie mit einem großen ONNX-Modell arbeiten, wird es normalerweise mit externen Daten generiert. Aufgrund der Beschränkung der Protobuf-Dateigröße müssen ONNX-Modelle, die größer als 2 GB sind, mit externen Daten arbeiten. Die externen Daten sind eine oder mehrere separate Dateien und werden normalerweise von einem ONNX-Exporter generiert. Die externen Daten werden normalerweise im selben Verzeichnis wie die ONNX-Modelldatei abgelegt.

ONNX Runtime unterstützt das Laden von Modellen mit externen Daten. Dies geschieht automatisch in C/C++/Python-APIs ohne zusätzliche Schritte, da ONNX Runtime für diese Sprachbindungen auf das Dateisystem zugreifen kann. Im Browser kann der JavaScript-Code jedoch nicht direkt auf das Dateisystem zugreifen. Daher benötigen Sie einen zusätzlichen Schritt, um die Informationen zu den externen Daten an ONNX Runtime Web zu übergeben.

Wie externe Daten funktionieren

Bevor wir uns mit den Details befassen, wollen wir zunächst verstehen, wie externe Daten in ONNX Runtime funktionieren. Diese Informationen sind wichtig, da die Schritte sonst verwirrend erscheinen könnten.

Ein ONNX-Modell ist technisch eine Protobuf-Datei. Die Protobuf-Datei enthält den Modellgraphen und die Gewichte. Die ONNX-Spezifikation erlaubt die Speicherung der Gewichte entweder in der Protobuf-Datei oder in externen Datendateien. Wenn die Gewichte in der Protobuf-Datei gespeichert sind, sind sie vollständig in der Protobuf-Datei enthalten. Wenn die Gewichte in externen Datendateien gespeichert sind, enthält die Protobuf-Datei die folgenden Informationen zu diesem spezifischen Gewicht:

  • „location“ (eine Zeichenkette), die den relativen Dateipfad der externen Datendatei angibt
  • „offset“ (eine Ganzzahl), die den Byte-Offset in der externen Datendatei angibt, an dem das Gewicht beginnt
  • „length“ (eine Ganzzahl), die die Länge des Gewichts in Bytes angibt

Der „location“ wird normalerweise vom ONNX-Exporter bestimmt. Zum Beispiel kann ein Exporter die Modelldatei als model_a.onnx und die externe Datendatei als model_a.data im selben Verzeichnis ausgeben. Einige Gewichte im Modell sind in der Datei model_a.data gespeichert, sodass der „location“ dieser Gewichte auf ./model_a.data gesetzt ist. Diese Informationen werden in der Datei model_a.onnx gespeichert.

Dies erklärt, warum es auf nativen Plattformen wichtig ist, sicherzustellen, dass Sie die **externe Datendatei niemals umbenennen**. Wenn Sie die externe Datendatei umbenennen, stimmt der „location“ in der Protobuf-Datei nicht mit dem tatsächlichen Dateinamen überein, und ONNX Runtime kann das Modell nicht laden.

Für ONNX Runtime Web müssen Sie die Informationen zu den externen Daten immer an ONNX Runtime Web übergeben. Es ist wichtig zu verstehen, dass der in der Protobuf-Datei definierte „location“ ein anderes Konzept ist als der tatsächliche externe Dateipfad. Diese beiden unterschiedlichen Konzepte werden im folgenden Abschnitt als „path“ und „data“ im JavaScript-Code dargestellt.

Laden des Modells mit externen Daten in ONNX Runtime Web

Wir verwenden ein Beispiel, um zu veranschaulichen, wie ein ONNX-Modell mit externen Daten im Browser geladen wird. Angenommen, wir haben ein ONNX-Modell model_a.onnx und eine externe Datendatei model_a.data. Der folgende Code zeigt, wie das Modell mit externen Daten im Browser geladen wird.

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
        }
    ]
});

Im obigen Code übergeben wir die Informationen zu den externen Daten an die Methode InferenceSession.create(). externalData ist ein Array von Objekten, die jeweils eine externe Datendatei darstellen. Das Objekt hat zwei Eigenschaften:

  • path (eine Zeichenkette), die mit den „location“-Informationen der Gewichte in der Protobuf-Datei übereinstimmen sollte
  • data (eine Zeichenkette), die die externe Datendatei angibt. Dies kann eine URL, ein Blob oder ein Uint8Array sein.

Wenn Sie das Modell und die externen Daten in der IndexedDB speichern, können Sie das Modell mit externen Daten aus der IndexedDB laden. Der folgende Code zeigt, wie das Modell mit externen Daten aus der IndexedDB geladen wird.

// assume loadFromIndexedDB() is a function implemented by your app that loads the data from the IndexedDB

// Load the model and external data from the 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
        }
    ]
});

Weitere Details finden Sie unter ONNX External Data.

Fehlerbehebung

Dieser Abschnitt wird gerade erstellt.