Treten Sie der SIG TFX-Addons-Community bei und helfen Sie mit, TFX noch besser zu machen! SIG TFX-Addons beitreten

Erstellen eines Moduls, das neue wartbare Pfade erkennt

In diesem Dokument wird erläutert, wie Sie TensorFlow Serving erweitern können, um verschiedene Speichersysteme zu überwachen und neue (Versionen von) Modellen oder zu ermittelnde Daten zu ermitteln. Insbesondere wird erläutert, wie ein Modul erstellt und verwendet wird, das einen Speichersystempfad auf das Auftreten neuer Unterpfade überwacht, wobei jeder Unterpfad eine neue zu ladende Version darstellt. Diese Art von Modul wird als Source<StoragePath> , da es Objekte vom Typ StoragePath (typedefed to string ) ausgibt. Es kann mit einem SourceAdapter erstellt werden, der aus einem bestimmten Pfad, den die Quelle SourceAdapter , einen wartbaren Loader erstellt.

Zunächst ein Hinweis zur Allgemeinheit

Die Verwendung von Pfaden als Handles für zu wartende Daten ist nicht erforderlich. Es zeigt lediglich eine Möglichkeit, Servables in das System aufzunehmen. Selbst wenn Ihre Umgebung keine wartbaren Daten in Pfaden kapselt, werden Sie in diesem Dokument mit den wichtigsten Abstraktionen vertraut gemacht. Sie haben die Möglichkeit, die Module Source<T> und SourceAdapter<T1, T2> für Typen zu erstellen, die Ihrer Umgebung entsprechen (z. B. RPC- oder Pub / Sub-Nachrichten, Datenbankeinträge), oder einfach eine monolithische Source<std::unique_ptr<Loader>> zu erstellen Source<std::unique_ptr<Loader>> , der wartungsfähige Lader direkt ausgibt.

Unabhängig von der Art der Daten, die Ihre Quelle ausgibt (POSIX-Pfade, Google Cloud Storage-Pfade oder RPC-Handles), müssen natürlich Module enthalten sein, die darauf basierende Servables laden können. Solche Module heißen SourceAdapters . Das Erstellen eines benutzerdefinierten Dokuments wird im Dokument " Benutzerdefiniert" beschrieben . TensorFlow Serving enthält eine zum Instanziieren von TensorFlow-Sitzungen basierend auf Pfaden in Dateisystemen, die TensorFlow unterstützt. Sie können TensorFlow um Unterstützung für zusätzliche Dateisysteme erweitern, indem Sie die RandomAccessFile Abstraktion ( tensorflow/core/public/env.h ) erweitern.

Dieses Dokument konzentriert sich auf die Erstellung einer Quelle, die Pfade in einem von TensorFlow unterstützten Dateisystem ausgibt. Es endet mit einer Anleitung, wie Sie Ihre Quelle in Verbindung mit bereits vorhandenen Modulen verwenden, um TensorFlow-Modelle zu bedienen.

Erstellen Sie Ihre Quelle

Wir haben eine Referenzimplementierung einer Source<StoragePath> mit dem Namen FileSystemStoragePathSource (unter sources/storage_path/file_system_storage_path_source* ). FileSystemStoragePathSource überwacht einen bestimmten Dateisystempfad, sucht nach numerischen Unterverzeichnissen und meldet die neuesten als die Version, die geladen werden soll. In diesem Dokument werden die wichtigsten Aspekte von FileSystemStoragePathSource . Möglicherweise ist es zweckmäßig, eine Kopie von FileSystemStoragePathSource und diese dann an Ihre Anforderungen anzupassen.

Zunächst implementiert FileSystemStoragePathSource die Source<StoragePath> , eine Spezialisierung der Source<T> StoragePath wobei T an StoragePath gebunden StoragePath . Die API besteht aus einer einzelnen Methode SetAspiredVersionsCallback() , die einen Abschluss SetAspiredVersionsCallback() , den die Quelle aufrufen kann, um mitzuteilen, dass ein bestimmter Satz von wartbaren Versionen geladen werden soll.

FileSystemStoragePathSource verwendet den Rückruf der angestrebten Versionen auf sehr einfache Weise: Es überprüft regelmäßig das Dateisystem (im Wesentlichen ein ls ) und ermittelt einen oder mehrere Pfade, die wie wartbare Versionen aussehen, und ermittelt, welche Version die neueste ist, und ruft auf der Rückruf mit einer Liste der Größe eins, die nur diese Version enthält (in der Standardkonfiguration). Zu jedem Zeitpunkt fordert FileSystemStoragePathSource höchstens einen Dienst zum Laden an, und seine Implementierung nutzt die Idempotenz des Rückrufs, um sich selbst zustandslos zu halten (es schadet nicht, den Rückruf wiederholt mit denselben Argumenten aufzurufen).

FileSystemStoragePathSource verfügt über eine statische Initialisierungsfactory (die Create() -Methode), die eine Konfigurationsprotokollnachricht entgegennimmt. Die Konfigurationsnachricht enthält Details wie den zu überwachenden Basispfad und das Überwachungsintervall. Es enthält auch den Namen des zu sendenden servable Streams. (Alternative Ansätze können den Namen des servable Streams aus dem Basispfad extrahieren, um mehrere servable Streams basierend auf der Beobachtung einer tieferen Verzeichnishierarchie auszugeben. Diese Varianten gehen über den Rahmen der Referenzimplementierung hinaus.)

Der Großteil der Implementierung besteht aus einem Thread, der das Dateisystem regelmäßig überprüft, sowie einer Logik zum Identifizieren und Sortieren aller erkannten numerischen Unterpfade. Der Thread wird in SetAspiredVersionsCallback() (nicht in Create() ) gestartet, da an diesem Punkt die Quelle "starten" soll und weiß, wohin Anforderungen für die gewünschte Version gesendet werden sollen.

Verwenden Ihrer Quelle zum Laden von TensorFlow-Sitzungen

SavedModelBundleSourceAdapter möchten Sie Ihr neues SavedModelBundleSourceAdapter in Verbindung mit SavedModelBundleSourceAdapter ( servables/tensorflow/saved_model_bundle_source_adapter* ) verwenden, das jeden von Ihrer Quelle servables/tensorflow/saved_model_bundle_source_adapter* Pfad als TensorFlow-Export interpretiert und jeden Pfad in einen Loader für einen TensorFlow SavedModelBundle konvertiert. Sie werden wahrscheinlich den SavedModelBundle Adapter an einen AspiredVersionsManager , der sich um das tatsächliche Laden und Bereitstellen der Servables kümmert. Ein gutes Beispiel für die Verkettung dieser drei Arten von Modulen, um eine funktionierende servables/tensorflow/simple_servers.cc zu erhalten, finden Sie in servables/tensorflow/simple_servers.cc . Hier ist ein Überblick über den Hauptcodefluss (mit schlechter Fehlerbehandlung; echter Code sollte vorsichtiger sein):

Erstellen Sie zunächst einen Manager:

std::unique_ptr<AspiredVersionsManager> manager = ...;

Erstellen Sie dann einen SavedModelBundle und schließen Sie ihn an den Manager an:

std::unique_ptr<SavedModelBundleSourceAdapter> bundle_adapter;
SavedModelBundleSourceAdapterConfig config;
// ... populate 'config' with TensorFlow options.
TF_CHECK_OK(SavedModelBundleSourceAdapter::Create(config, &bundle_adapter));
ConnectSourceToTarget(bundle_adapter.get(), manager.get());

Zuletzt erstellen Sie Ihre SavedModelBundle und schließen sie an den SavedModelBundle Adapter an:

auto your_source = new YourPathSource(...);
ConnectSourceToTarget(your_source, bundle_adapter.get());

Die Funktion ConnectSourceToTarget() (definiert in core/target.h ) ruft lediglich SetAspiredVersionsCallback() auf, um eine Source<T> mit einem Target<T> (ein Target ist ein Modul, das Anforderungen der gewünschten Version abfängt, dh einen Adapter oder Manager ).