Usar un contenedor personalizado para la inferencia

Para personalizar cómo sirve Vertex AI las inferencias online de tu modelo con entrenamiento personalizado, puedes especificar un contenedor personalizado en lugar de un contenedor precompilado al crear un recurso Model. Cuando usas un contenedor personalizado, Vertex AI ejecuta un contenedor Docker de tu elección en cada nodo de inferencia.

Puedes usar un contenedor personalizado por cualquiera de los siguientes motivos:

  • Para ofrecer inferencias de un modelo de aprendizaje automático entrenado con un framework que no está disponible como contenedor predefinido
  • para preprocesar las solicitudes de inferencia o postprocesar las inferencias generadas por tu modelo
  • para ejecutar un servidor de inferencia escrito en el lenguaje de programación que elijas
  • para instalar las dependencias que quieras usar para personalizar las inferencias

En esta guía se describe cómo crear un modelo que use un contenedor personalizado. No proporciona instrucciones detalladas sobre cómo diseñar y crear una imagen de contenedor Docker.

Preparar una imagen de contenedor

Para crear un Model que use un contenedor personalizado, debes proporcionar una imagen de contenedor Docker como base de ese contenedor. Esta imagen de contenedor debe cumplir los requisitos que se describen en la sección Requisitos de los contenedores personalizados.

Si tienes previsto usar una imagen de contenedor creada por un tercero en el que confías, puede que puedas saltarte una o ambas de las siguientes secciones.

Crear una imagen de contenedor

Diseña y crea una imagen de contenedor Docker que cumpla los requisitos de la imagen de contenedor.

Para aprender los conceptos básicos del diseño y la creación de una imagen de contenedor Docker, consulta la guía de inicio rápido de la documentación de Docker.

Enviar la imagen de contenedor a Artifact Registry

Envía tu imagen de contenedor a un repositorio de Artifact Registry.

Consulta cómo enviar una imagen de contenedor a Artifact Registry.

Crear un Model

Para crear un Model que use un contenedor personalizado, haz una de las siguientes acciones:

En las siguientes secciones se muestra cómo configurar los campos de la API relacionados con los contenedores personalizados al crear un Model de una de estas formas.

Campos de la API relacionados con los contenedores

Cuando cree el Model, asegúrese de configurar el containerSpeccampo con los detalles de su contenedor personalizado, en lugar de con un contenedor prediseñado.

Debes especificar un ModelContainerSpec mensaje en el campo Model.containerSpec. En este mensaje, puedes especificar los siguientes subcampos:

imageUri (obligatorio)

El URI de Artifact Registry de tu imagen de contenedor.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-image-uri para especificar este campo.

command (opcional)

Matriz de un ejecutable y argumentos para anular la instrucción ENTRYPOINT del contenedor. Para obtener más información sobre cómo dar formato a este campo y cómo interactúa con el campo args, consulta la referencia de la API de ModelContainerSpec.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-command para especificar este campo.

args (opcional)

Es un array de un ejecutable y argumentos para anular el valor de CMD del contenedor. Para obtener más información sobre cómo dar formato a este campo y cómo interactúa con el campo command, consulta la referencia de la API de ModelContainerSpec.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-args para especificar este campo.

ports (opcional)

Es un array de puertos. Vertex AI envía comprobaciones de actividad, comprobaciones de estado y solicitudes de inferencia a tu contenedor en el primer puerto de la lista o en 8080 de forma predeterminada. Especificar puertos adicionales no tiene ningún efecto.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-ports para especificar este campo.

env (opcional)

Es un array de variables de entorno a las que pueden hacer referencia la instrucción ENTRYPOINT del contenedor, así como los campos command y args. Para obtener más información sobre cómo pueden hacer referencia otros campos a estas variables de entorno, consulta la referencia de la API de ModelContainerSpec.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-env-vars para especificar este campo.

healthRoute (opcional)

La ruta del servidor HTTP de tu contenedor a la que quieres que Vertex AI envíe comprobaciones de estado.

Si no especifica este campo, cuando implemente el Model como DeployedModel en un recurso Endpoint, se utilizará el valor predeterminado /v1/endpoints/ENDPOINT/deployedModels/DEPLOYED_MODEL, donde ENDPOINT se sustituye por el último segmento del campo name de Endpoint (después de endpoints/) y DEPLOYED_MODEL se sustituye por el campo id de DeployedModel.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-health-route para especificar este campo.

predictRoute (opcional)

La ruta del servidor HTTP de tu contenedor a la que quieres que Vertex AI reenvíe las solicitudes de inferencia.

Si no especifica este campo, cuando implemente el Model como DeployedModel en un recurso Endpoint, se utilizará el valor predeterminado /v1/endpoints/ENDPOINT/deployedModels/DEPLOYED_MODEL:predict, donde ENDPOINT se sustituye por el último segmento del campo name de Endpoint (después de endpoints/) y DEPLOYED_MODEL se sustituye por el campo id de DeployedModel.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-predict-route para especificar este campo.

invokeRoutePrefix (opcional)

Invoca el prefijo de ruta del contenedor personalizado. Si se asigna el valor "/*" a este campo, se habilita el enrutamiento arbitrario para el modelo. Una vez desplegada, se podrá acceder a cualquier ruta que no sea raíz en el servidor del modelo con una llamada HTTP de invocación. Por ejemplo, "/invoke/foo/bar" se reenviará como "/foo/bar" al servidor del modelo. Esta función está en fase de vista previa pública. Para crear un modelo con invocación habilitada, sigue las instrucciones para usar rutas personalizadas arbitrarias.

sharedMemorySizeMb (opcional)

Cantidad de memoria de la VM que se va a reservar en un volumen de memoria compartida para el modelo, en megabytes.

La memoria compartida es un mecanismo de comunicación entre procesos (IPC) que permite que varios procesos accedan a un bloque de memoria común y lo manipulen. La cantidad de memoria compartida necesaria, si la hay, es un detalle de implementación de tu contenedor y modelo. Consulta las directrices en la documentación del servidor de modelos.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-shared-memory-size-mb para especificar este campo.

startupProbe (opcional)

Especificación de la sonda que comprueba si se ha iniciado la aplicación del contenedor.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-startup-probe-exec, --container-startup-probe-period-seconds, --container-startup-probe-timeout-seconds para especificar este campo.

healthProbe (opcional)

Especificación de la sonda que comprueba si un contenedor está listo para aceptar tráfico.

Si usas el comando gcloud ai models upload, puedes usar la marca --container-health-probe-exec, --container-health-probe-period-seconds, --container-health-probe-timeout-seconds para especificar este campo.

Además de las variables que definas en el campo Model.containerSpec.env, Vertex AI define otras variables en función de tu configuración. Más información sobre cómo usar estas variables de entorno en estos campos y en la instrucción ENTRYPOINT del contenedor

Ejemplos de importación de modelos

En los siguientes ejemplos se muestra cómo especificar los campos de la API relacionados con el contenedor al importar un modelo.

personalizados.

gcloud

En el siguiente ejemplo se usa el comando gcloud ai models upload:

gcloud ai models upload \
  --region=LOCATION \
  --display-name=MODEL_NAME \
  --container-image-uri=IMAGE_URI \
  --container-command=COMMAND \
  --container-args=ARGS \
  --container-ports=PORTS \
  --container-env-vars=ENV \
  --container-health-route=HEALTH_ROUTE \
  --container-predict-route=PREDICT_ROUTE \
  --container-shared-memory-size-mb=SHARED_MEMORY_SIZE \
  --container-startup-probe-exec=STARTUP_PROBE_EXEC \
  --container-startup-probe-period-seconds=STARTUP_PROBE_PERIOD \
  --container-startup-probe-timeout-seconds=STARTUP_PROBE_TIMEOUT \
  --container-health-probe-exec=HEALTH_PROBE_EXEC \
  --container-health-probe-period-seconds=HEALTH_PROBE_PERIOD \
  --container-health-probe-timeout-seconds=HEALTH_PROBE_TIMEOUT \
  --artifact-uri=PATH_TO_MODEL_ARTIFACT_DIRECTORY

La marca --container-image-uri es obligatoria. Todas las demás marcas que empiezan por --container- son opcionales. Para obtener información sobre los valores de estos campos, consulta la sección anterior de esta guía.

Java

Antes de probar este ejemplo, sigue las Java instrucciones de configuración de la guía de inicio rápido de Vertex AI con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Java de Vertex AI.

Para autenticarte en Vertex AI, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación en un entorno de desarrollo local.


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.aiplatform.v1.LocationName;
import com.google.cloud.aiplatform.v1.Model;
import com.google.cloud.aiplatform.v1.ModelContainerSpec;
import com.google.cloud.aiplatform.v1.ModelServiceClient;
import com.google.cloud.aiplatform.v1.ModelServiceSettings;
import com.google.cloud.aiplatform.v1.UploadModelOperationMetadata;
import com.google.cloud.aiplatform.v1.UploadModelResponse;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class UploadModelSample {
  public static void main(String[] args)
      throws InterruptedException, ExecutionException, TimeoutException, IOException {
    // TODO(developer): Replace these variables before running the sample.
    String project = "YOUR_PROJECT_ID";
    String modelDisplayName = "YOUR_MODEL_DISPLAY_NAME";
    String metadataSchemaUri =
        "gs://google-cloud-aiplatform/schema/trainingjob/definition/custom_task_1.0.0.yaml";
    String imageUri = "YOUR_IMAGE_URI";
    String artifactUri = "gs://your-gcs-bucket/artifact_path";
    uploadModel(project, modelDisplayName, metadataSchemaUri, imageUri, artifactUri);
  }

  static void uploadModel(
      String project,
      String modelDisplayName,
      String metadataSchemaUri,
      String imageUri,
      String artifactUri)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    ModelServiceSettings modelServiceSettings =
        ModelServiceSettings.newBuilder()
            .setEndpoint("us-central1-aiplatform.googleapis.com:443")
            .build();

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (ModelServiceClient modelServiceClient = ModelServiceClient.create(modelServiceSettings)) {
      String location = "us-central1";
      LocationName locationName = LocationName.of(project, location);

      ModelContainerSpec modelContainerSpec =
          ModelContainerSpec.newBuilder().setImageUri(imageUri).build();

      Model model =
          Model.newBuilder()
              .setDisplayName(modelDisplayName)
              .setMetadataSchemaUri(metadataSchemaUri)
              .setArtifactUri(artifactUri)
              .setContainerSpec(modelContainerSpec)
              .build();

      OperationFuture<UploadModelResponse, UploadModelOperationMetadata> uploadModelResponseFuture =
          modelServiceClient.uploadModelAsync(locationName, model);
      System.out.format(
          "Operation name: %s\n", uploadModelResponseFuture.getInitialFuture().get().getName());
      System.out.println("Waiting for operation to finish...");
      UploadModelResponse uploadModelResponse = uploadModelResponseFuture.get(5, TimeUnit.MINUTES);

      System.out.println("Upload Model Response");
      System.out.format("Model: %s\n", uploadModelResponse.getModel());
    }
  }
}

Node.js

Antes de probar este ejemplo, sigue las Node.js instrucciones de configuración de la guía de inicio rápido de Vertex AI con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Node.js de Vertex AI.

Para autenticarte en Vertex AI, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación en un entorno de desarrollo local.

/**
 * TODO(developer): Uncomment these variables before running the sample.\
 */

// const modelDisplayName = 'YOUR_MODEL_DISPLAY_NAME';
// const metadataSchemaUri = 'YOUR_METADATA_SCHEMA_URI';
// const imageUri = 'YOUR_IMAGE_URI';
// const artifactUri = 'YOUR_ARTIFACT_URI';
// const project = 'YOUR_PROJECT_ID';
// const location = 'YOUR_PROJECT_LOCATION';

// Imports the Google Cloud Model Service Client library
const {ModelServiceClient} = require('@google-cloud/aiplatform');

// Specifies the location of the api endpoint
const clientOptions = {
  apiEndpoint: 'us-central1-aiplatform.googleapis.com',
};

// Instantiates a client
const modelServiceClient = new ModelServiceClient(clientOptions);

async function uploadModel() {
  // Configure the parent resources
  const parent = `projects/${project}/locations/${location}`;
  // Configure the model resources
  const model = {
    displayName: modelDisplayName,
    metadataSchemaUri: '',
    artifactUri: artifactUri,
    containerSpec: {
      imageUri: imageUri,
      command: [],
      args: [],
      env: [],
      ports: [],
      predictRoute: '',
      healthRoute: '',
    },
  };
  const request = {
    parent,
    model,
  };

  console.log('PARENT AND MODEL');
  console.log(parent, model);
  // Upload Model request
  const [response] = await modelServiceClient.uploadModel(request);
  console.log(`Long running operation : ${response.name}`);

  // Wait for operation to complete
  await response.promise();
  const result = response.result;

  console.log('Upload model response ');
  console.log(`\tModel : ${result.model}`);
}
uploadModel();

Python

Para saber cómo instalar o actualizar el SDK de Vertex AI para Python, consulta Instalar el SDK de Vertex AI para Python. Para obtener más información, consulta la documentación de referencia de la API Python.

from typing import Dict, Optional, Sequence

from google.cloud import aiplatform
from google.cloud.aiplatform import explain


def upload_model_sample(
    project: str,
    location: str,
    display_name: str,
    serving_container_image_uri: str,
    artifact_uri: Optional[str] = None,
    serving_container_predict_route: Optional[str] = None,
    serving_container_health_route: Optional[str] = None,
    description: Optional[str] = None,
    serving_container_command: Optional[Sequence[str]] = None,
    serving_container_args: Optional[Sequence[str]] = None,
    serving_container_environment_variables: Optional[Dict[str, str]] = None,
    serving_container_ports: Optional[Sequence[int]] = None,
    instance_schema_uri: Optional[str] = None,
    parameters_schema_uri: Optional[str] = None,
    prediction_schema_uri: Optional[str] = None,
    explanation_metadata: Optional[explain.ExplanationMetadata] = None,
    explanation_parameters: Optional[explain.ExplanationParameters] = None,
    sync: bool = True,
):

    aiplatform.init(project=project, location=location)

    model = aiplatform.Model.upload(
        display_name=display_name,
        artifact_uri=artifact_uri,
        serving_container_image_uri=serving_container_image_uri,
        serving_container_predict_route=serving_container_predict_route,
        serving_container_health_route=serving_container_health_route,
        instance_schema_uri=instance_schema_uri,
        parameters_schema_uri=parameters_schema_uri,
        prediction_schema_uri=prediction_schema_uri,
        description=description,
        serving_container_command=serving_container_command,
        serving_container_args=serving_container_args,
        serving_container_environment_variables=serving_container_environment_variables,
        serving_container_ports=serving_container_ports,
        explanation_metadata=explanation_metadata,
        explanation_parameters=explanation_parameters,
        sync=sync,
    )

    model.wait()

    print(model.display_name)
    print(model.resource_name)
    return model

Para obtener más información, consulta la guía de importación de modelos.

Enviar solicitudes de inferencia

Para enviar una solicitud de inferencia online a tu Model, sigue las instrucciones de la sección Obtener inferencias de un modelo entrenado personalizado. Este proceso funciona igual independientemente de si usas un contenedor personalizado.

Consulta los requisitos de las solicitudes y respuestas de predicción para los contenedores personalizados.

Siguientes pasos