AI Platform Prediction: configuración del servidor de modelos directos para NVIDIA Triton Inference Server

En este documento, se muestra cómo implementar contenedores personalizados de AI Platform Prediction en el NVIDIA Triton Inference Server.

Este documento forma parte de una serie para ingenieros y arquitectos de aprendizaje automático (AA) que diseñan, compilan y mantienen una plataforma de entrega de modelos de alto rendimiento en Google Cloud:

El patrón arquitectónico de servidor de modelos directos que se explica en este documento se describe en detalle en “AI Platform Prediction: conceptos de contenedores personalizados”, que te recomendamos que leas antes de continuar con este documento. Este documento se debe usar junto con los notebooks para integrar Triton Inference Server en los contenedores personalizados en AI Platform Prediction.

Arquitectura del servidor de modelos directos

El patrón del servidor de modelos directos se comunica directamente con el servidor de modelos sin ninguna conexión intermedia. En el siguiente diagrama, se ilustra esta arquitectura:

El servidor de modelo se almacena en un contenedor personalizado, y los contenedores personalizados de AI Platform Prediction acceden a él directamente.

Para ayudar a determinar qué arquitectura de contenedor personalizada es la mejor opción para tu caso de uso, lee sobre los patrones de contenedores personalizados.

NVIDIA Triton Inference Server

Triton Inference Server es el servidor de modelos de AA de NVIDIA. Aunque Triton se ejecuta en CPU y GPU, está diseñado para aprovechar las capacidades de las GPU a través de funciones avanzadas, como el procesamiento por lotes dinámico, la ejecución simultánea de modelos, la priorización de modelos y la carga/descarga activa de modelos.. Triton incluye varios backends para admitir varios frameworks, incluidos los backends personalizados para obtener extensibilidad. Para ver un diagrama arquitectónico de Triton Inference Server, lee Ejecución simultánea de modelos.

Una instancia de Triton Inference Server admite la entrega de varios modelos y los mismos frameworks de backend, o bien otros frameworks de backend distintos. Cada modelo puede tener varias instancias. Este documento se centra en un solo modelo. Sin embargo, es importante identificar un equilibrio óptimo entre la capacidad de procesamiento y la latencia. Cuando se supera cierto grado de simultaneidad, la capacidad de procesamiento no aumenta, pero la latencia de la inferencia individual aumenta linealmente con la simultaneidad.

Implementación

En las secciones siguientes, se describe el proceso de implementación de una versión de contenedor personalizada. Si deseas ejecutar los notebooks en Google Cloud, sigue las instrucciones del archivo README.

Implementación de la API de REST

Esta sección está diseñada para leerse junto con el notebook triton-simple-setup-rest.ipynb, que está disponible en un formato de solo lectura.

Para crear una versión del modelo, debes proporcionar una especificación a AI Platform. Para implementar el patrón del servidor de modelos directos con Triton, este documento proporciona la siguiente especificación version_spec.json de muestra, que puedes encontrar en la sección “Crea la versión del modelo” del notebook. En la siguiente especificación, se indica a AI Platform Prediction cómo crear la versión del modelo:

{
  "name": "$VERSION_NAME",
  "deployment_uri": "$MODEL_BUCKET_PATH",
  "container": {
    "image": "${REGION}-docker.pkg.dev/$PROJECT_ID/$IMAGE:$VERSION",
    "args": ["tritonserver",
             "--model-repository=$(AIP_STORAGE_URI)"
    ],
    "env": [
    ],
    "ports": [
      { "containerPort": 8000 }
    ]
  },
  "routes": {
    "predict": "/v2/models/$MODEL_NAME/infer",
    "health": "/v2/models/$MODEL_NAME"
  },
  "machine_type": "n1-standard-4",
  "acceleratorConfig": {
    "count":1,
    "type":"nvidia-tesla-t4"
  },
  "autoScale": {
    "minNodes":1
  }
}

La siguiente es una parte de la solicitud de REST que crea la versión del modelo:

POST -d @version_spec.json \
    ...
    "${ENDPOINT}/projects/${PROJECT_ID}/models/${MODEL_NAME}/versions"

La especificación y la solicitud de REST para NVIDIA Triton Inference Server requieren los siguientes parámetros. Los requisitos de la especificación pueden variar según el servidor de modelos que uses.

  • REGION: La región de Google Cloud donde se encuentra la imagen de contenedor.
  • VERSION_NAME: El nombre de esta versión del modelo, por ejemplo, v2.
  • MODEL_BUCKET_PATH: La ubicación desde la que AI Platform copia los artefactos del modelo para esta versión del modelo.
  • PROJECT_ID: El ID del proyecto de Google Cloud donde se encuentra la imagen de contenedor.
  • IMAGE:VERSION: El nombre de la imagen y la versión del contenedor.
  • MODEL_NAME: El nombre de un modelo en los artefactos del modelo (el valor y el nombre deben coincidir). En este documento, configurarás un solo modelo, y este valor y nombre determinará en qué línea de ejecución se ejecutarán las solicitudes de predicciones.
  • ports: El puerto de AI Platform usa para comunicarse con Triton. De forma predeterminada, Triton escucha las solicitudes HTTP en el puerto 8000.
  • machine_type: Para esta implementación, n1-standard-4 y una GPU nvidia-tesla-t4.
  • AIP_STORAGE_URI: La ubicación en la que se pegan los artefactos del modelo cuando se crea la versión del modelo. AI Platform proporciona esta variable de entorno. El contenido proviene de deployment_uri. Si el servidor de tu modelo requiere una ubicación para recuperar artefactos del modelo, usa AIP_STORAGE_URI y no deployment_uri.

Implementación del SDK de Cloud

También puedes implementar una versión personalizada del contenedor desde la línea de comandos mediante el SDK de Cloud. La siguiente especificación YAML, que puedes encontrar en la sección Crea la versión del modelo del notebook, indica a AI Platform Prediction cómo crear la versión del modelo:

config.yaml:

container:
  args:
  - tritonserver
  - --model-repository=$(AIP_STORAGE_URI)
  env: []
  image: gcr.io/$PROJECT_ID/$IMAGE:$VERSION
  ports:
    containerPort: 8000
deploymentUri: $MODEL_BUCKET/path/
machineType: n1-standard-4
routes:
  health: /v2/models/$MODEL_NAME
  predict: /v2/models/$MODEL_NAME/infer
autoScaling:
  minNodes: 1

El siguiente es el comando de gcloud que crea la versión del modelo:

gcloud beta ai-platform versions create $VERSION_NAME \
    --model $MODEL_NAME \
    --accelerator count=1,type=nvidia-tesla-t4 \
    --config config.yaml

Para obtener información detallada sobre los parámetros de especificación disponibles, consulta Crea una versión del modelo.

Prepara solicitudes de inferencia

La versión 20.06 de Triton Inference Server se admite en la versión 2 de KFServing, el protocolo de entrega de modelos que adopta este documento. En este documento, se abarcan dos situaciones que tienen estructuras de carga útil ligeramente diferentes:

  • Datos no binarios: La versión 2 de KFServing especifica un formato JSON que encapsula las características de la solicitud de predicción en el cuerpo JSON, como se muestra en el siguiente ejemplo. :

    POST /v2/models/mymodel/infer HTTP/1.1
    Host: localhost:8000
    Content-Type: application/json
    Content-Length: <xx>
    {
      "id" : "42",
      "inputs" : [
        {
          "name" : "input0",
          "shape" : [ 2, 2 ],
          "datatype" : "UINT32",
          "data" : [ 1, 2, 3, 4 ]
        },
        ...
      ],
      "outputs" : [
        {
          "name" : "output0"
        }
      ]
    }
    
  • Datos binarios: el protocolo de la versión 2 de KFServing no especifica cómo se manejan los datos binarios. Cada creador del servidor de modelos proporciona esa especificación. Triton implementa una extensión de formato binario en el protocolo KFServing v2, como se muestra en la siguiente especificación de ejemplo:

    POST /v2/models/mymodel/infer HTTP/1.1
    Host: localhost:8000
    Content-Type: application/octet-stream
    Inference-Header-Content-Length: <xx>
    Content-Length: <xx+19>
    {
      "model_name" : "mymodel",
      "inputs" : [
        {
          "name" : "input0",
          "shape" : [ 2, 2 ],
          "datatype" : "UINT32",
          "parameters" : {
            "binary_data_size" : 16
          }
        },
        {
          "name" : "input1",
          "shape" : [ 3 ],
          "datatype" : "BOOL",
          "parameters" : {
            "binary_data_size" : 3
          }
        }
      ],
      "outputs" : [
        {
          "name" : "output0",
          "parameters" : {
            "binary_data" : true
          }
        }
      ]
    }
    <16 bytes of data for input0 tensor>
    <3 bytes of data for input1 tensor>
    

    La extensión de Triton de datos binarios adjunta los datos binarios después del cuerpo JSON. Observa el encabezado agregado Inference-Header-Content-Length. Con este encabezado, se indica a Triton dónde termina la parte JSON del cuerpo y dónde comenzar a leer los datos binarios. Se debe calcular el valor de este desplazamiento.

Si deseas que una secuencia de comandos cree un cuerpo de solicitud, consulta el repositorio que acompaña a este documento.

¿Qué sigue?