OnnxRuntime EP-Kontext-Cache-Feature-Design

Inhalt

Hintergrund

Execution Provider (EPs) von ONNX Runtime ermöglichen Benutzern das Ausführen von ONNX-Modellen auf verschiedenen Hardwarebeschleunigern, die von Backend-SDKs (z. B. QNN, OpenVINO, Vitis AI usw.) angetrieben werden.
Execution Provider konvertieren das ONNX-Modell in das vom Backend-SDK benötigte Graphformat und kompilieren es in das vom Hardware benötigte Format.
Im NPU-Bereich kann dieser Konvertierungs- und Kompilierungsprozess zeitaufwändig sein, insbesondere für LLM-Modelle, und manchmal zig Minuten dauern. Dies beeinträchtigt die Benutzererfahrung während der Erstellung der Sitzung erheblich.
Um den wiederholten Overhead von Modellkonvertierung und -kompilierung zu eliminieren, bieten die meisten Backend-SDKs eine Funktion zum Speichern des vorkompilierten Modells in einer Binärdatei.

  • Das vorkompilierte Modell kann direkt vom Backend-SDK geladen und auf dem Zielgerät ausgeführt werden.
  • Dies reduziert die Zeit für die Sitzungserstellung erheblich und verbessert die Gesamtleistung. Zur Unterstützung dieser Optimierung hat ONNX Runtime einen beitragenden Operator namens EPContext im MS-Bereich eingeführt.

EPContext Op Schema

Op-Bereich: com.microsoft
Knoteneingänge & -ausgänge: variadisch

Attributtabelle unten

Attribute Datentyp Beschreibung
main_context int64 1 (Standard): Dieser Knoten referenziert EP-Kontextinhalte, die den mit diesem Knoten verbundenen Graphen enthalten.
0: Der Knoten referenziert keine EP-Kontextinhalte. Stattdessen erwartet er, den Graphen von einem anderen Knoten abzurufen, bei dem dieses Feld auf 1 gesetzt ist.
Einige EPs unterstützen einen einzigen Kontext, der mehrere Graphen enthält.
Der EPContext-Knoten mit main_context = 1 bezieht sich auf den primären Kontext.
Dieser Kontext enthält mehrere Graphen, die von anderen Knoten mit main_context = 0 referenziert werden können.
ep_cache_context string Die Nutzlast des EP-Kontexts, wenn embed_mode = 1 ist, oder der Pfad zur Kontextdatei, wenn embed_mode = 0 ist.
Der Pfad ist relativ zur ONNX-Modelldatei und kann entweder ein Dateiname oder ein Unterordner/Dateiname sein.
embed_mode int64 1 (Standard): ep_cache_context enthält die Nutzlast des Kontextinhalts.
0: ep_cache_context enthält den Dateipfad zur Kontext-Binärdatei.
ep_sdk_version string Optional. Die SDK-Version, die zum Erstellen dieses Knotens verwendet wurde.
onnx_model_filename string Optional. Ursprünglicher ONNX-Modelldateiname.
hardware_architecture string Optional. Hardware-Architektur.
partition_name string Optional. Name des partitionierten Graphen von OnnxRuntime.
source string Optional. Die Source-Identifikation, die zum Erstellen dieses Knotens verwendet wurde.
Dies sollte ein eindeutiger Schlüssel sein, der vom EP definiert wird, und ermöglicht es ONNX Runtime, mehrere EPContext-Knoten zu unterstützen, die mit verschiedenen EPs ausgeführt werden.
Zum Beispiel
QNN EP akzeptiert nur Knoten mit source = QNN oder QnnExecutionProvider.
OpenVINO EP akzeptiert nur Knoten mit source = OpenVINOExecutionProvider.
notes string Optional. Zusätzliche Informationen, die vom spezifischen EP benötigt werden.
max_size int64 Optional. Die maximale Größe im Kontext, deren Verwendung vom EP abhängt.
Standard ist 0.

EP Context node example

Session-Option Beschreibung
ep.context_enable Wird nur für die Generierung von EP-Kontextmodellen verwendet.
1: Ermöglicht ONNX Runtime das Speichern des Kontext-Cache-Modells.
0 (Standard): Deaktiviert das Speichern von Kontextmodellen.
ep.context_file_path Gibt den Dateipfad für das gespeicherte Modell an.
Standard: original_file_name_ctx.onnx für die Generierung von Kontextmodellen.
Für die Modellinferenz
Wenn der Benutzer das Modell aus einem Speicherpuffer lädt und sich die EP-Kontext-Binärdatei außerhalb des ONNX-Modells befindet, muss diese Option gesetzt werden.
ONNX Runtime EP verwendet diesen Pfad, um den Ordnerpfad zu bestimmen und kombiniert ihn mit ep_cache_context (der auf den Pfad der Kontext-Binärdatei verweist), um den absoluten Pfad zur Kontext-Binärdatei zu erstellen.
ep.context_embed_mode Wird nur für die Generierung von Kontextmodellen verwendet.
1: Speichert den EP-Kontextinhalt direkt in das ONNX-Modell, gespeichert im Attribut des ep_cache_context-Knotens.
0 (Standard): Speichert den EP-Kontextinhalt in eine separate Datei und speichert den Dateinamen im ONNX-Modell.
Der Dateipfad wird im Attribut des ep_cache_context-Knotens nachverfolgt.
ep.context_node_name_prefix Wird nur für die Generierung von Kontextmodellen verwendet.
Gibt das Präfix für den Namen des EPContext-Knotens an (wird auch als Attribut partition_name und interner Graphname verwendet).
Stellt Eindeutigkeit über Knoten hinweg sicher, wenn mehrere EPContext-Knoten zu einem einzigen Modell kombiniert werden, und verhindert Namenskonflikte.
Der EP kann dieses Präfix auch auf den ep_graph-Namen innerhalb der konvertierten EP-Kontext-Binärdatei anwenden.
session.model_external_initializers_file_folder_path Dies ist nicht spezifisch für das EPContext-Design. Im Allgemeinen verliert die Sitzung beim Laden des Modells aus einem Speicherpuffer für Modelle mit externen Daten den Überblick über den Namen und Pfad des Modells, was die Lokalisierung der externen Datendatei unmöglich macht. Verwenden Sie diese Konfiguration, um den Ordnerpfad für die externen Datendateien anzugeben.
Alle externen Datendateien sollten im selben Ordner abgelegt werden.
ep.context_model_external_initializers_file_name Wird nur für die Generierung von Kontextmodellen verwendet.
Diese Konfiguration wird verwendet, wenn einige Knoten auf dem CPU EP partitioniert sind und diese Knoten externe Initialisierer haben. Bei der Generierung des EP-Kontextmodells sollte das neue Modell nicht von der alten externen Datendatei abhängen, die vom ursprünglichen ONNX-Modell verwendet wurde.
Verwenden Sie diese Einstellung beim Speichern des EP-Kontextmodells mit einer Datei für externe Initialisierer.
Wenn angegeben, werden alle Initialisierer in die externe Datei eingefügt.
Andernfalls werden alle Initialisierer in die generierte ONNX-Datei eingebettet.
Standardmäßig ist diese Option nicht gesetzt, d. h. alle Initialisierer werden in die ONNX-Datei aufgenommen.

Workflow zur Generierung von EP-Kontext-Cache-Modellen

EP-Schnittstelle GetEpContextNodes() zur Generierung des EP-Kontext-Cache-Modells

Die Generierung des partitionierten Graphen direkt im Code des Execution Providers (EP) ist schwierig, da dem EP keine vollständige Sicht auf den gesamten partitionierten Graphen zur Verfügung steht. Um dies zu lösen, führt ONNX Runtime eine neue Execution Provider-Schnittstelle ein: GetEpContextNodes().

virtual const InlinedVector<const Node*> GetEpContextNodes() const {
  return InlinedVector<const Node*>();
}
  • Diese API gibt ein Array von Zeigern auf EPContext-Knoten zurück.
  • Execution Provider sollten diese Schnittstelle implementieren, wenn sie das Kontext-Cache-Modell generieren müssen. Andernfalls können sie sie unausgeführt lassen.
  • Es liegt in der Verantwortung des EP, die EPContext-Knoten zusammen mit ihren Abhängigkeiten zu erstellen (z. B. die Kontext-Binärdatei, wenn embed_mode = 0).
  • Der ONNX Runtime GraphPartitioner verwendet diese Schnittstelle, um die EPContext-Knoten abzurufen und das partitionierte ONNX-Modell zu generieren. Details zum Code für die Generierung von EP-Kontextmodellen hier

Richtlinien zur Generierung von EP-Kontext-Cache-Modellen

OnnxRuntime EPs sollten die folgenden Richtlinien befolgen, um das EP-Kontext-Cache-Modell zu erstellen und eine einheitliche Benutzeroberfläche beizubehalten.

  • Eigentümerschaft
    • Der Execution Provider (EP) ist verantwortlich für die Erstellung des EPContext-Knotens zusammen mit seinen Abhängigkeiten.
    • Das ONNX Runtime Framework ist verantwortlich für die Generierung des EP-Kontext-ONNX-Modells unter Verwendung der vom EP bereitgestellten EPContext-Knotenliste.
  • Lebensdauer
    • Die Lebensdauer der EPContext-Knoten beginnt mindestens, wenn der EP compile aufruft, und endet, wenn der EP zerstört wird.
  • ep.context_enable
    • ONNX Runtime erstellt das EP-Kontext-Cache-Modell, wenn ep.context_enable = 1 ist.
    • Andernfalls, wenn ep.context_enable = 0 (Standard) ist, folgt ONNX Runtime dem Standard-Workflow, ohne ein Cache-Modell zu generieren.
  • ep.context_file_path
    • Wenn ep.context_file_path nicht angegeben ist, generiert ONNX Runtime den Ausgabemodell-Dateinamen, indem .onnx im ursprünglichen Eingabemodell-Dateinamen durch _ctx.onnx ersetzt wird.
    • Wenn ep.context_file_path angegeben ist, verwendet ONNX Runtime den angegebenen Dateipfad. Der EP sollte diesen Pfad auch verwenden, um den Ordnerpfad für das Speichern der kompilierten EP-Kontext-Binärdatei zu bestimmen, wenn ep.context_embed_mode = 0 ist.
    • Hinweis: ep.context_file_path ist erforderlich, wenn das Modell aus einem Speicherpuffer geladen wird, da ONNX Runtime in diesem Szenario den ursprünglichen Modellpfad nicht abrufen kann.
  • ep.context_embed_mode
    • 1: Bettet den EP-Kontextinhalt direkt in das ONNX-Modell ein.
    • 0 (Standard): Speichert den EP-Kontextinhalt in eine separate Datei (EP-Kontext-Binärdatei).
      • Es sollte eine einzige EP-Kontext-Binärdatei geben, auch wenn mehrere partitionierte Teilgraphen vorhanden sind. Wenn der EP dies kurzfristig nicht erreichen kann, vermerken Sie dies bitte auf der EP-Webseite. In solchen Fällen müssen die Benutzer die notwendigen Dateien für die Produktionseinführung ermitteln, indem sie alle primären EPContext-Knoten (Knoten mit embed_mode=1) durchlaufen und die Dateipfade aus dem Knotenattribut ep_cache_context extrahieren.
      • Der Name der EP-Kontext-Binärdatei sollte [model_name]_[ep].bin sein.
      • Der EP zeichnet den Namen der Kontext-Binärdatei im EPContext-Knotenattribut ep_cache_context auf.
      • Die Kontext-Binärdatei muss sich im selben Verzeichnis wie die gespeicherte ONNX-Modelldatei befinden.
      • Der im EPContext-Knoten gespeicherte Dateipfad ist ein relativer Pfad zur ONNX-Modelldatei.
      • Hinweis: Unterordner sind zulässig.
  • ep.context_node_name_prefix
    • Wenn der Benutzer dem EPContext-Knotennamen ein benutzerdefiniertes Präfix hinzufügen möchte (wird auch auf das Attribut partition_name und den Graphennamen angewendet), sollte der EP diese Funktion bei der Generierung von EPContext-Knoten bereitstellen.
    • Dies ist nützlich, wenn mehrere EPContext-Knoten aus verschiedenen Modellen zu einem einzigen Modell kombiniert werden, bei dem die Gefahr von Knoten- oder Graphennamenskonflikten zwischen Modellen besteht.
    • Der EP sollte mehrere EP-Kontexte innerhalb eines einzigen Modells unterstützen, damit Benutzer EPContext-Knoten, die aus verschiedenen Modellen generiert wurden, zusammenführen und miteinander verbinden können.
  • Quellmodell mit externen Daten
    Wenn das Quellmodell auf eine externe Datendatei angewiesen ist, verwendet ONNX einen relativen Pfad, um diese Datei zu lokalisieren. Daher muss die externe Datendatei im selben Verzeichnis wie das Quellmodell liegen. Neu generierte Modelle dürfen jedoch nicht von ursprünglichen Quelldateien abhängen. Dieser Ansatz wird durch mehrere Überlegungen motiviert:
    • Alle neu generierten Dateien sollten sich im selben Verzeichnis befinden.
    • Es gibt keine Garantie, dass die Ausgabedateien im selben Verzeichnis wie die Quelldateien generiert werden.
    • Das EPContext-Design ermöglicht die Partitionierung eines Modells durch mehrere EPs, die jeweils ihre eigenen EPContext-Knoten kompilieren. Ein einheitlicher und standardisierter Prozess hilft, Datenredundanz zu vermeiden.
    • Einige EPs müssen möglicherweise Gewichte aus der Quelle in ihre Kontext-Binärdateien kopieren, um spezifische Datenlayoutanforderungen zu erfüllen.
    • Für Teilgraphen, die auf den ONNX Runtime CPU EP zurückfallen, werden alle Gewichtsdaten standardmäßig direkt in das neu generierte Modell [model_name]_ctx.onnx eingebettet. Wenn ep.context_model_external_initializers_file_name gesetzt ist, werden alle Gewichtsdaten stattdessen in die angegebene externe Datei für Initialisierer gespeichert.

Codebeispiele für Anwendungsszenarien

Generieren des EPContext-Modells durch Erstellung einer Sitzung aus einem Modellpfad

    Ort::SessionOptions so;

    // Enable EPContext ONNX model dumping
    so.AddConfigEntry(kOrtSessionOptionEpContextEnable, "1");

    // Add the execution provider (using QNN as an example)
    so.AppendExecutionProvider("QNN", provider_options);

    // Create the session to dump the `_ctx.onnx` model
    Ort::Session session1(env, "./model1.onnx", so);

Generieren des EPContext-Modells durch Erstellung einer Sitzung aus einem Modell im Speicherpuffer
Ähnlich wie bei der C-API CreateSessionFromArray erstellt das folgende Beispiel eine ONNX Runtime-Sitzung aus einem Modell, das in einem Speicherarray gespeichert ist, wodurch die Sitzung den Namen und Pfad des Modells verliert. Um das EPContext-Modell zu generieren, müssen Sie den Dateipfad angeben mit: ep.context_file_path.

    // Read model file into buffer array
    std::vector<char> buffer;
    ReadFileToBuffer("./model1.onnx", buffer);

    Ort::SessionOptions so;

    // Enable EPContext ONNX model dumping
    so.AddConfigEntry(kOrtSessionOptionEpContextEnable, "1");

    // Specify the generated EPContext model file path using option ep.context_file_path
    so.AddConfigEntry(kOrtSessionOptionEpContextFilePath, "./model_ctx.onnx");

    // Add the execution provider (using QNN as an example)
    so.AppendExecutionProvider("QNN", provider_options);


    // Create the session to dump the `_ctx.onnx` model
    Ort::Session session1(env, buffer.data(), buffer.size(), so);

Generieren des EPContext-Modells durch Erstellung einer Sitzung aus einem Modell im Speicherpuffer, und das Modell hat externe Gewichte
Erstellen der Sitzung aus einem Speicherarray, und das Modell hängt von externen Daten ab. Die Sitzung benötigt session.model_external_initializers_file_folder_path, um den Speicherort der externen Daten zu ermitteln, und wie im vorherigen Beispiel ep.context_file_path, um den Dateipfad für das generierte EPContext-Modell festzulegen.

    // Read model file into buffer array
    std::vector<char> buffer;
    ReadFileToBuffer("./model_folder/model1.onnx", buffer);

    Ort::SessionOptions so;

    // Enable EPContext ONNX model dumping
    so.AddConfigEntry(kOrtSessionOptionEpContextEnable, "1");

    // Specify the generated EPContext model file path using option ep.context_file_path
    so.AddConfigEntry(kOrtSessionOptionEpContextFilePath, "./model_folder/model_ctx.onnx");

    // Specify the external data folder path using option session.model_external_initializers_file_folder_path
    so.AddConfigEntry(kOrtSessionOptionsModelExternalInitializersFileFolderPath, "./external_data_folder/");

    // Add the execution provider (using QNN as an example)
    so.AppendExecutionProvider("QNN", provider_options);


    // Create the session to dump the `_ctx.onnx` model
    Ort::Session session1(env, buffer.data(), buffer.size(), so);

Hinweis: Wenn es einen Teilgraph-Fallback auf dem CPU EP gibt, der von externen Daten abhängt, sollte das generierte EPContext-Modell nicht von der ursprünglichen externen Datendatei abhängen, die vom Basismodell verwendet wird. Standardmäßig bettet das EPContext-Modell alle externen Daten direkt in die generierte ONNX-Datei ein. Wenn Sie Gewichte in einer externen Datei speichern möchten, setzen Sie ep.context_model_external_initializers_file_name. Diese Option zwingt alle Initialisierer, in der angegebenen externen Datei gespeichert zu werden.

Inferenz-Workflow für EP-Kontext-Cache-Modelle

ONNX Runtime EPs, die das Laden von Modellen mit EPContext-Knoten unterstützen, sollten für die Modellinferenz dem folgenden Workflow und den Regeln folgen:

  • Modellidentifizierung
    • Der EP sollte zuerst feststellen, ob das Modell EPContext-Knoten enthält.
      • Wenn keine EPContext-Knoten vorhanden sind, folgt der EP seinem normalen Inferenz-Workflow.
      • Wenn das Modell EPContext-Knoten enthält
        • Der EP sollte das source-Knotenattribut aller EPContext-Knoten inspizieren, um zu überprüfen, ob einer davon für den aktuellen EP bestimmt ist (d.h. das source-Attribut stimmt mit dem vom EP erwarteten Schlüssel überein).
        • Der EP sollte nur die EPContext-Knoten partitionieren, bei denen das source-Attribut mit dem vom EP benötigten Schlüssel übereinstimmt.
        • Der EP lädt den Cache-Kontext aus den übereinstimmenden EPContext-Knoten.
  • Umgang mit externen Kontext-Binärdateien (embed_mode = 0) Wenn das EPContext-Cache-Modell mit embed_mode = 0 generiert wurde, wird die Kontext-Binärdatei als separate Datei neben dem ONNX-Modell im selben Ordner gespeichert.
    • ONNX Runtime ruft den relativen Pfad der Kontext-Binärdatei aus dem ep_cache_context-Attribut des EPContext-Knotens ab.
    • Für aus einem Dateipfad geladene Modelle
      • Der EP sollte den Ordnerpfad der Eingabemodell-Datei ermitteln und ihn mit dem relativen Pfad kombinieren, um den vollständigen Pfad zur Kontext-Binärdatei zu erstellen.
    • Für aus einem Speicherpuffer geladene Modelle
      • Da der EP den Ordnerpfad des Modells nicht ableiten kann, muss der Benutzer die Sitzungsoption ep.context_file_path angeben.
      • Der EP verwendet ep.context_file_path, um den Ordnerpfad zu bestimmen und kombiniert ihn mit dem relativen Pfad, um den vollständigen Pfad zur Kontext-Binärdatei zu erstellen.
  • Unterstützung für mehrere primäre EPContext-Knoten (main_context = 1)
    • Der EP sollte mehrere primäre EPContext-Knoten ohne Einschränkungen unterstützen.
    • Der EP muss in der Lage sein, alle in den ep_cache_context-Attributen der EPContext-Knoten angegebenen EP-Kontext-Binärpuffer/Dateien zu laden, sie zu deserialisieren, die ep_graphs zu verwalten und die richtige für die Ausführung auszuwählen.
  • Fehlerbehandlung beim Laden der EP-Kontext-Binärdatei

    Der EP oder sein Backend-SDK sollte in der Lage sein, häufige Fehlerszenarien zu erkennen (einschließlich, aber nicht beschränkt auf die folgenden). In solchen Fällen sollte der EP einen Status mit dem Fehlercode INVALID_GRAPH zurückgeben.

    • Erkennen von Diskrepanzen zwischen der Treiberversion und der vom EP-Kontext-Binärdatei benötigten Version; Fehler zurückgeben, wenn diese inkompatibel sind.
    • Erkennen von Diskrepanzen zwischen der Laufzeit-SDK-Version und der zum Erstellen der EP-Kontext-Binärdatei verwendeten Version; Fehler zurückgeben, wenn diese inkompatibel sind.
    • Fehler zurückgeben, wenn das Laden der EP-Kontext-Binärdatei aus irgendeinem Grund fehlschlägt.

EP Context nodes with different EPs

Codebeispiele für Anwendungsszenarien

Erstellen einer Inferenzsitzung aus einem vorkompilierten EPContext-Modell
Erstellen der Sitzung aus einem Modell-Dateipfad. Wenn eine externe EP-Kontext-Binärdatei vorhanden ist, kann die Sitzung den Pfad zur Binärdatei aus dem Modell-Dateipfad ermitteln.

    Ort::SessionOptions so;

    // Add EP, take QNN for example
    so.AppendExecutionProvider("QNN", provider_options);

    // Create sessions to load from the _ctx.onnx model
    Ort::Session session1(env, "model1_ctx.onnx", so);

    session1.run(...);

Erstellen einer Inferenzsitzung aus einem vorkompilierten EPContext-Modell im Speicherpuffer
Das Erstellen einer Sitzung aus einem Speicherpuffer des Modells führt dazu, dass die Sitzung den Namen und Pfad des Modells verliert. Um dies zu beheben, müssen Sie setzen: ep.context_file_path.

  • Die Sitzung verwendet diesen Pfad, um den Speicherort zu identifizieren.
  • Mit dem Namen der EP-Kontext-Binärdatei aus dem EPContext-Knoten konstruiert die Sitzung den vollständigen Pfad zur endgültigen EP-Kontext-Binärdatei.
      // Read model file into buffer array
      std::vector<char> buffer;
      ReadFileToBuffer("./model_folder/model_ctx.onnx", buffer);
    
      Ort::SessionOptions so;
    
      // Specify the EPContext model file path using option ep.context_file_path
      so.AddConfigEntry(kOrtSessionOptionEpContextFilePath, "./model_path/model_ctx.onnx");
    
      // Add EP, take QNN for example
      so.AppendExecutionProvider("QNN", provider_options);
    
      // Create sessions to load from the buffer
      Ort::Session session1(env, buffer.data(), buffer.size(), so);
    
      session1.run(...);
    

EPContext mit Gewichtsfreigabe

Gewichtsfreigabe im ONNX-Bereich

In ONNX bezieht sich Gewichtsfreigabe auf mehrere ONNX-Modelle mit externen Gewichten, die auf dieselbe externe Gewichtsdatei verweisen. Diese Modelle verwenden dieselben Tensornamen, sodass sie auf dieselben Tensor-Daten verweisen können.

Weight sharing across Onnx models

Gewichtsfreigabe im EP-Bereich mit EPContext

Die EP-Gewichtsfreigabe wird mithilfe einer vorkompilierten EP-Kontext-Binärdatei/Blob aktiviert. Um dies zu tun, müssen Benutzer die Kontext-Binärdatei offline generieren (Ahead Of Time).

  • Einige EPs benötigen spezifische Plattformen, wie z. B. Linux x86_64 und/oder Windows x86_64. Bitte beachten Sie die spezifische EP-Seite für Details.
  • Die EP-Kontext-Binärdatei enthält mehrere Graphen, die sich die gleichen Tensoren teilen.

Weight sharing in EP context binary

Der EP oder das Backend-SDK sollte in der Lage sein, den Graphen wie oben beschrieben zu konvertieren und zu kompilieren.

  • Der EP oder das SDK sollte identische Gewichte aus dem bestehenden EP-Kontext, der von zuvor kompilierten Graphen generiert wurde, identifizieren.
  • Wenn neue Graphen in den EP-Kontext kompiliert werden, sollten sie vorhandene Gewichte wiederverwenden, wenn sie als identisch erkannt werden. Zum Beispiel in [model_name]_[ep].bin, tensor1_1 aus ep_graph1 und tensor2_1 aus ep_graph2 sind identisch und verweisen beide auf denselben Daten-Offset, tensor_data1.

Workflow zur Generierung von EPContext-Modellen mit Gewichtsfreigabe

Weight sharing workflow

Jede ONNX Runtime-Sitzung ist mit einem ONNX-Modell verknüpft. Modelle, die Gewichte gemeinsam nutzen, werden in einer Modellgruppe zusammengefasst, während ONNX Runtime-Sitzungen mit gemeinsamen Eigenschaften in einer Sitzungsgruppe organisiert werden. ONNX Runtime führt zwei Sitzungsoptionen ein: ep.share_ep_contexts und ep.stop_share_ep_contexts, um die Sitzungsgruppierung zu erleichtern.

  • Alle ONNX Runtime-Sitzungen innerhalb der Sitzungsgruppe sollten ep.share_ep_contexts aktiviert haben.
  • Die endgültige ONNX Runtime-Sitzung verwendet ep.stop_share_ep_contexts, um anzuzeigen, dass sie die letzte Sitzung in der Gruppe ist. Hinweis: Ein einzelnes ONNX-Modell kann mehrere EPContext-Knoten enthalten, je nach Ergebnis der Graph-Partitionierung. Der Einfachheit halber wird hier jedoch jedes Modell mit nur einem EPcontext-Knoten dargestellt.

Implementierungsrichtlinien für die Generierung von EPContext-Modellen mit Gewichtsfreigabe

  • Erstellung eines gemeinsamen Arbeitsbereichs
    Die erste Sitzung erstellt einen gemeinsamen Arbeitsbereich (z. B. EP Singleton), um Ressourcen mit anderen Sitzungen zu teilen.
  • Benennung der EP-Kontext-Binärdatei
    Der Name der EP-Kontext-Binärdatei wird von der ersten Sitzung bestimmt und im gemeinsamen Arbeitsbereich (z. B. EP Singleton) für die Verwendung in Sitzungsgruppen gespeichert.
    Der Name der EP-Kontext-Binärdatei sollte [model1_name]_[ep].bin lauten.
  • Graphkompilierung
    Alle Sitzungen in der Sitzungsgruppe kompilieren ihre Graphen in die gemeinsame Ressource.
  • Generierung von EPContext-Modellen
    Jede Sitzung in der Sitzungsgruppe erstellt ein EPContext ONNX-Modell. Der EP generiert einen EPContext-Knoten, der auf den Namen der EP-Kontext-Binärdatei verweist. Das ONNX Runtime Framework speichert dann das EPContext ONNX-Modell.
  • Generierung der endgültigen EP-Kontext-Binärdatei
    Die letzte Sitzung (diejenige mit aktiviertem ep.stop_share_ep_contexts) in der Sitzungsgruppe generiert die endgültige EP-Kontext-Binärdatei unter Verwendung des im gemeinsamen Arbeitsbereich gespeicherten Namens.
  • Bereinigung des gemeinsamen Arbeitsbereichs
    Die letzte Sitzung löscht den gemeinsamen Arbeitsbereich. Ein leerer gemeinsamer Arbeitsbereich zeigt an, dass die nächste auszuführende Sitzung die erste Sitzung ist.
  • Anzahl der generierten Dateien
    Für N Quellmodelle, die Gewichte gemeinsam nutzen, sollten insgesamt N+1 Dateien generiert werden.
    Die generierten Dateien sind model1_ctx.onnx, ..., modeln_ctx.onnx, [model1_name]_[ep].bin.

Benutzer-Codebeispiel

    Ort::SessionOptions so;

    // Enable EPContext ONNX model dumping
    so.AddConfigEntry(kOrtSessionOptionEpContextEnable, "1");

    // Enable EP context sharing across sessions
    so.AddConfigEntry(kOrtSessionOptionShareEpContexts, "1");

    // Add the execution provider (using QNN as an example)
    so.AppendExecutionProvider("QNN", provider_options);

    // Create the first session to dump the model1_ctx.onnx file
    Ort::Session session1(env, "model1.onnx", so);

    // Mark the last session by enabling ep.stop_share_ep_contexts
    so.AddConfigEntry(kOrtSessionOptionStopShareEpContexts, "1");

    // Create the last session to dump the model2_ctx.onnx file and generate the [model1_name]_[ep].bin
    Ort::Session session2(env, "model2.onnx", so);

Allgemeines Werkzeug zur Generierung von EPContext-Modellen mit Gewichtsfreigabe

OnnxRuntime stellt das Tool ep_weight_sharing_ctx_gen zur Verfügung, um den Gewichtsfreigabe-Workflow zu automatisieren. Dieses Tool kümmert sich um den gesamten Prozess. Dieses Tool ist speziell für Gewichtsfreigabe-Szenarien konzipiert und optimiert den Prozess der Generierung von EPContext-Modellen. Beispiel-Befehlszeile

./ep_weight_sharing_ctx_gen -e qnn -i "soc_model|60 htp_graph_finalization_optimization_mode|3" ./model1.onnx,./model2.onnx

Es erstellt zwei Onnx-Modelle (model1_ctx.onnx, model2_ctx.onnx) und eine QNN-Kontext-Binärdatei ([model1_name]_[ep].bin).

Inferenz-Sitzungen aus EPContext-Modellen mit Gewichtsfreigabe

Um die gespeicherten EPContext-Modelle mit aktivierter Gewichtsfreigabe zu verwenden, müssen ONNX Runtime-Inferenzsitzungen die Ressourcenfreigabe aktiviert haben. Dies geschieht durch Setzen der Sitzungsoption

    ep.share_ep_contexts = 1

Implementierungsrichtlinien für die Inferenz aus EPContext-Modellen mit Gewichtsfreigabe

  • Erstellen der ersten OnnxRuntime-Inferenzsitzung
    • Setzen der Sitzungsoption: ep.share_ep_contexts=1.
    • Laden des Modells model1_ctx.onnx.
    • Der gemeinsame Arbeitsbereich ist zunächst leer.
    • Der EP lädt [model1_name]_[ep].bin und deserialisiert die Binärdatei, um alle Graphen abzurufen (z. B. ep_graph1, ep_graph2).
    • Der EPContext-Knoten in model1_ctx.onnx gibt die Verwendung von ep_graph1 an.
    • Die Sitzung verwendet ep_graph1 für die Inferenz.
    • Die verbleibenden Graphen (ep_graph2) werden in den gemeinsamen Arbeitsbereich für zukünftige Sitzungen verschoben.
  • Erstellen der zweiten ONNX Runtime-Inferenzsitzung
    • Setzen der Sitzungsoption: ep.share_ep_contexts=1.
    • Laden des Modells model2_ctx.onnx.
    • Der EPContext-Knoten in model2_ctx.onnx gibt die Verwendung von ep_graph2 an.
    • Der gemeinsame Arbeitsbereich enthält bereits ep_graph2.
    • Der EP überspringt das Laden von [model1_name]_[ep].bin, da der benötigte Graph bereits im gemeinsamen Arbeitsbereich verfügbar ist.
    • Die Sitzung verschiebt ep_graph2 vom gemeinsamen Arbeitsbereich in die aktuelle Sitzung, wodurch sie nicht mehr zugänglich vom gemeinsamen Arbeitsbereich ist.
  • Best Practices für die Sitzungsbereinigung
    • Um Probleme bei der parallelen Ausführung zu vermeiden, wird empfohlen, die Sitzungen in umgekehrter Reihenfolge zu zerstören (d.h. die zweite Sitzung vor der ersten Sitzung zerstören).
    • Dies gewährleistet eine ordnungsgemäße Ressourcenverwaltung und verhindert potenzielle Konflikte mit gemeinsamen Ressourcen.

Benutzer-Codebeispiel

    Ort::SessionOptions so;
    // enable ep.share_ep_contexts
    so.AddConfigEntry(kOrtSessionOptionShareEpContexts, "1");

    // Add EP, take QNN for example
    so.AppendExecutionProvider("QNN", provider_options);

    // Create sessions to load from the _ctx.onnx models with resource sharing enabled
    Ort::Session session1(env, "model1_ctx.onnx", so);	
    Ort::Session session2(env, "model2_ctx.onnx", so);

    session1.run(...);
    session2.run(...);