Crear un módulo que descubre nuevas rutas de servicio

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Este documento explica cómo extender TensorFlow Serving para monitorear diferentes sistemas de almacenamiento y descubrir nuevos (versiones de) modelos o datos para entregar. En particular, cubre cómo crear y usar un módulo que monitorea la ruta del sistema de almacenamiento para detectar la aparición de nuevas subrutas, donde cada subruta representa una nueva versión servible para cargar. Ese tipo de módulo se denomina una Source<StoragePath> , porque emite objetos de tipo StoragePath (typedefed de string ). Puede estar compuesto con un SourceAdapter que crea un servable Loader de un camino dado que los descubridores de origen.

Primero, una nota sobre la generalidad

No se requiere el uso de rutas como identificadores de datos servibles; simplemente ilustra una forma de incorporar servibles en el sistema. Incluso si su entorno no encapsula datos servibles en rutas, este documento lo familiarizará con las abstracciones clave. Usted tiene la opción de crear Source<T> y SourceAdapter<T1, T2> módulos para los tipos que se adapten a su entorno (por ejemplo, RPC o pub / sub mensajes, registros de base de datos), o simplemente crear una monolítica Source<std::unique_ptr<Loader>> que emite cargadores se pueden publicar y directa.

Por supuesto, sea cual sea el tipo de datos que emita su fuente (ya sean rutas POSIX, rutas de Google Cloud Storage o identificadores de RPC), es necesario que haya módulos adjuntos que puedan cargar servidores basados ​​en eso. Tales módulos se denominan SourceAdapters . La creación de una costumbre se describe en el servable personalizada documento. TensorFlow Serving viene con uno para crear instancias de sesiones de TensorFlow según las rutas en los sistemas de archivos que admite TensorFlow. Se puede añadir soporte para sistemas de archivos adicionales para TensorFlow extendiendo el RandomAccessFile abstracción ( tensorflow/core/public/env.h ).

Este documento se centra en la creación de una fuente que emite rutas en un sistema de archivos compatible con TensorFlow. Termina con un recorrido sobre cómo usar su fuente junto con módulos preexistentes para entregar modelos de TensorFlow.

Creando tu Fuente

Tenemos una implementación de referencia de una Source<StoragePath> , llamado FileSystemStoragePathSource (en sources/storage_path/file_system_storage_path_source* ). FileSystemStoragePathSource supervisa una ruta del sistema de archivo en particular, para relojes numéricos subdirectorios, e informa del último de ellos como la versión aspira a la carga. Este documento explica los aspectos más destacados de FileSystemStoragePathSource . Puede que le resulte conveniente hacer una copia de FileSystemStoragePathSource y luego modificarlo para adaptarlo a sus necesidades.

En primer lugar, FileSystemStoragePathSource implementa la Source<StoragePath> API, que es una especialización de la Source<T> API con T obligados a StoragePath . La API consta de un solo método SetAspiredVersionsCallback() , que suministra un cierre de la fuente puede invocar para comunicar que quiere un conjunto particular de versiones se pueden publicar y que se debe cargar.

FileSystemStoragePathSource utiliza los-versiones aspirado devolución de llamada de una manera muy simple: se inspecciona periódicamente el sistema de archivos (haciendo un ls , esencialmente), y si encuentra una o más rutas que se parecen a las versiones se pueden publicar y se determina cuál es la versión más reciente e invoca la devolución de llamada con una lista de tamaño uno que contiene solo esa versión (bajo la configuración predeterminada). Así, en un momento dado FileSystemStoragePathSource solicitudes a lo sumo uno servible para ser cargado, y su aplicación se aprovecha de la idempotencia de la devolución de llamada para mantenerse sin estado (no hay daño en la invocación de la devolución de llamada en varias ocasiones con los mismos argumentos).

FileSystemStoragePathSource tiene una fábrica estática de inicialización (el Create() método), que toma un mensaje de protocolo de configuración. El mensaje de configuración incluye detalles como la ruta base a monitorear y el intervalo de monitoreo. También incluye el nombre de la secuencia servible que se va a emitir. (Los enfoques alternativos pueden extraer el nombre de la secuencia servible de la ruta base, para emitir múltiples secuencias servibles según la observación de una jerarquía de directorios más profunda; esas variantes están más allá del alcance de la implementación de referencia).

La mayor parte de la implementación consiste en un hilo que examina periódicamente el sistema de archivos, junto con cierta lógica para identificar y clasificar las subrutas numéricas que descubre. El hilo se puso en marcha en el interior SetAspiredVersionsCallback() (no en Create() ) ya que es el punto en el que la fuente debe "empezar" y sabe a dónde enviar las peticiones de la versión aspirado.

Usar tu fuente para cargar sesiones de TensorFlow

Es probable que desee utilizar su nuevo módulo de origen junto con SavedModelBundleSourceAdapter ( servables/tensorflow/saved_model_bundle_source_adapter* ), que interpretará cada ruta de sus emite la fuente como una exportación TensorFlow, y convertir cada ruta a un cargador para un TensorFlow SavedModelBundle servable. Es probable que se conecte el SavedModelBundle adaptador en una AspiredVersionsManager , que se encarga de la carga de realidad y servir los servables. Un buen ejemplo de encadenamiento de estos tres tipos de módulos en conjunto para obtener una biblioteca de servidor de trabajo se encuentra en servables/tensorflow/simple_servers.cc . Aquí hay un recorrido por el flujo del código principal (con un mal manejo de errores; el código real debe ser más cuidadoso):

Primero, cree un administrador:

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

A continuación, crear una SavedModelBundle adaptador de fuente y conectarlo a la gerente:

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

Por último, crear el origen de ruta y conectarlo a la SavedModelBundle adaptador:

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

El ConnectSourceToTarget() función (definido en core/target.h ) simplemente invoca SetAspiredVersionsCallback() para conectar una Source<T> a un Target<T> (a Target es un módulo que las capturas aspiraban-versión solicitudes, es decir, un adaptador o gerente ).