Stworzenie modułu, który odkrywa nowe serwowalne ścieżki

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Ten dokument wyjaśnia, jak rozszerzyć TensorFlow Serving, aby monitorować różne systemy pamięci masowej w celu wykrywania nowych (wersji) modeli lub danych do obsługi. W szczególności obejmuje sposób tworzenia i używania modułu, który monitoruje ścieżkę systemu pamięci masowej pod kątem pojawiania się nowych podścieżek, gdzie każda podścieżka reprezentuje nową serwowalną wersję do załadowania. Tego rodzaju modułu nazywamy Source<StoragePath> , ponieważ emituje obiekty typu StoragePath (typedefed do string ). Może ona składać się z SourceAdapter który tworzy servable Loader z danej ścieżki że odkrywa źródłowych.

Najpierw uwaga na temat ogólności

Używanie ścieżek jako uchwytów do serwowalnych danych nie jest wymagane; to jedynie ilustruje jeden ze sposobów na przyswajanie serwowalnych do systemu. Nawet jeśli Twoje środowisko nie zawiera serwowalnych danych w ścieżkach, ten dokument zapozna Cię z kluczowymi abstrakcjami. Użytkownik ma możliwość tworzenia Source<T> i SourceAdapter<T1, T2> Moduły dla typów w zależności od środowiska (np RPC lub pub / sub wiadomości, rekordy bazy danych) lub po prostu stworzyć monolityczny Source<std::unique_ptr<Loader>> emitujący servable ładowarki bezpośrednio.

Oczywiście bez względu na rodzaj danych emitowanych przez Twoje źródło (czy są to ścieżki POSIX, ścieżki Google Cloud Storage czy uchwyty RPC), muszą istnieć towarzyszące moduły, które będą w stanie załadować serwery na ich podstawie. Takie moduły są nazywane SourceAdapters . Tworzenie jednego niestandardowego opisany jest w Niestandardowe Servable dokumentu. TensorFlow Serving zawiera jeden do tworzenia instancji sesji TensorFlow na podstawie ścieżek w systemach plików obsługiwanych przez TensorFlow. Można dodać wsparcie dla dodatkowych systemów plików do TensorFlow rozszerzając RandomAccessFile abstrakcję ( tensorflow/core/public/env.h ).

Ten dokument koncentruje się na tworzeniu źródła, które emituje ścieżki w systemie plików obsługiwanym przez TensorFlow. Kończy się przewodnikiem, jak korzystać ze źródła w połączeniu z wcześniej istniejącymi modułami do obsługi modeli TensorFlow.

Tworzenie swojego źródła

Mamy implementację referencyjną o Source<StoragePath> , zwanego FileSystemStoragePathSource (w sources/storage_path/file_system_storage_path_source* ). FileSystemStoragePathSource monitoruje konkretną ścieżkę systemu plików, zegarki liczbowych podkatalogów i donosi najnowszy z nich jak w wersji on aspiruje do obciążenia. Ten dokument spacery aspektów wystające z FileSystemStoragePathSource . Może się okazać, że wygodnie zrobić kopię FileSystemStoragePathSource a następnie zmodyfikować go do własnych potrzeb.

Po pierwsze, FileSystemStoragePathSource implementuje Source<StoragePath> API, który jest specjalizacja Source<T> API z T związany StoragePath . API składa się z jednej metody SetAspiredVersionsCallback() , która dostarcza zamknięcie źródłem może powołać się komunikować, że chce dany zestaw wersjach servable być załadowany.

FileSystemStoragePathSource używa dążyli-versions callback w bardzo prosty sposób: okresowo kontroluje system plików (robi ls zasadniczo), a jeżeli stwierdzi jedną lub więcej ścieżek, które wyglądają jak wersje servable określa, który z nich jest najnowsza wersja i wywołuje wywołanie zwrotne z listą o rozmiarze jeden zawierającą tylko tę wersję (w domyślnej konfiguracji). Tak więc, w danym momencie FileSystemStoragePathSource wniosków co najwyżej jeden servable zostać załadowany, a jego realizacja korzysta z idempotentność o oddzwonienie, aby utrzymać się bezpaństwowcem (nie ma nic złego w powołując się kilkakrotnie zwrotnego z tymi samymi argumentami).

FileSystemStoragePathSource ma statyczny fabrykę inicjalizacji (The Create() metody), które odbędzie się komunikat Configuration Protocol. Komunikat konfiguracyjny zawiera szczegóły, takie jak podstawowa ścieżka do monitorowania i interwał monitorowania. Zawiera również nazwę serwowalnego strumienia do wyemitowania. (Podejścia alternatywne mogą wyodrębnić nazwę strumienia możliwego do wyświetlenia ze ścieżki podstawowej, aby wyemitować wiele strumieni możliwych do obsługi na podstawie obserwacji głębszej hierarchii katalogów; te warianty wykraczają poza zakres implementacji referencyjnej).

Większość implementacji składa się z wątku, który okresowo sprawdza system plików, wraz z pewną logiką do identyfikowania i sortowania wszelkich wykrytych podścieżek numerycznych. Nić jest uruchamiany wewnątrz SetAspiredVersionsCallback() (nie w Create() ), ponieważ jest to punkt, w którym źródło powinno „start” i wie, gdzie wysłać żądania aspirował-wersji.

Używanie źródła do ładowania sesji TensorFlow

Najprawdopodobniej chcesz korzystać z nowego modułu źródłowego w połączeniu z SavedModelBundleSourceAdapter ( servables/tensorflow/saved_model_bundle_source_adapter* ), który zinterpretuje Każda ścieżka emituje swoje źródło w eksporcie TensorFlow i konwertować każdą ścieżkę do ładowarki dla TensorFlow SavedModelBundle servable. Najprawdopodobniej podłączyć SavedModelBundle zasilacz do AspiredVersionsManager , która troszczy się o rzeczywiście ładuje i służenie servables. Dobrą ilustracją łańcuchowym te trzy rodzaje modułów ze sobą, aby uzyskać bibliotekę pracy serwera znajduje się w servables/tensorflow/simple_servers.cc . Oto przegląd głównego przepływu kodu (ze złą obsługą błędów; prawdziwy kod powinien być bardziej ostrożny):

Najpierw utwórz menedżera:

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

Następnie utwórz SavedModelBundle adapter źródłowego i podłączyć go do kierownika:

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());

Wreszcie, należy utworzyć źródło ścieżki i podłączyć go do SavedModelBundle adaptera:

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

ConnectSourceToTarget() funkcja (zdefiniowane w core/target.h ) po prostu wywołuje SetAspiredVersionsCallback() aby podłączyć Source<T> Do Target<T> (a Target jest modułem, który połowy dążyli-wersja żądania, czyli adapter lub zarządca ).