Usar um contêiner personalizado para inferência

Para personalizar a maneira como a Agent Platform exibe inferências on-line do seu modelo treinado de forma personalizada, especifique um contêiner personalizado em vez de um contêiner pré-criado ao criar o Model atributo. Quando você usa um contêiner personalizado, a Agent Platform executa um contêiner do Docker de sua escolha em cada nó de inferência.

Convém usar um contêiner personalizado por um dos seguintes motivos:

  • para disponibilizar inferências de um modelo de ML treinado usando um framework que não está disponível como um contêiner pré-criado
  • para pré-processar solicitações de inferência ou pós-processar as inferências geradas pelo modelo;
  • para executar um servidor de inferência escrito em uma linguagem de programação de sua escolha;
  • para instalar as dependências que você quer usar para personalizar as inferências.

Este guia descreve como criar um modelo que usa um contêiner personalizado. Ele não fornece instruções detalhadas sobre como projetar e criar uma imagem de contêiner do Docker.

Preparar uma imagem do contêiner

Para criar um Model que usa um contêiner personalizado, forneça uma imagem de contêiner do Docker para ser a base do contêiner. Essa imagem do contêiner precisa atender aos requisitos descritos em Requisitos personalizados do contêiner.

Se você planeja usar uma imagem de contêiner atual criada por terceiros em quem confia, é possível pular uma ou as duas seções a seguir.

Criar uma imagem do contêiner

Projete e crie uma imagem de contêiner do Docker que atenda aos requisitos de imagem de contêiner.

Para aprender os princípios básicos de como projetar e criar uma imagem de contêiner do Docker, leia o guia de início rápido da documentação do Docker

Envie a imagem do contêiner para o Artifact Registry

Envie a imagem do contêiner para um repositório do Artifact Registry.

Saiba como enviar uma imagem de contêiner para o Artifact Registry.

Criar um Model

Para criar um Model que usa um contêiner personalizado, siga um destes procedimentos:

Nas seções a seguir, mostramos como configurar os campos da API relacionados a contêineres personalizados durante a criação de um Model.

Campos da API relacionados ao contêiner

Ao criar o Model, configure o campo containerSpec com os detalhes do seu contêiner personalizado, em vez de usar um contêiner pré-criado.

Você precisa especificar uma mensagem ModelContainerSpec no campo Model.containerSpec. Nessa mensagem, é possível especificar os subcampos a seguir:

imageUri (obrigatório)

O URI do Artifact Registry da imagem do seu contêiner.

Se você estiver usando o gcloud ai models upload comando, poderá usar a sinalização --container-image-uri para especificar o campo.

command (opcional)

Uma matriz de um executável e argumentos para modificar a instrução ENTRYPOINT do contêiner. Para saber mais sobre como formatar este campo e como ele interage com o campo args, leia a referência da API sobre ModelContainerSpec.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-command para especificar o campo.

args (opcional)

Uma matriz de um executável e argumentos para modificar o contêiner's CMD Para saber mais sobre como formatar este campo e como ele interage com o command campo, leia a referência da API para ModelContainerSpec.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-args para especificar o campo.

ports (opcional)

Uma matriz de portas: a Agent Platform envia verificações de atividade e de integridade e solicitações de inferência ao seu contêiner na primeira porta listada ou 8080 por padrão. A especificação de portas extras não tem efeito.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-ports para especificar o campo.

env (opcional)

Uma matriz de variáveis de ambiente que a instrução ENTRYPOINT do contêiner e os campos command e args podem referenciar. Para saber mais sobre como outros campos podem referenciar essas variáveis de ambiente, leia a referência da API para ModelContainerSpec.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-env-vars para especificar o campo.

healthRoute (opcional)

O caminho no servidor HTTP do contêiner em que a Agent Platform usará para enviar verificações de integridade.

Se você não especificar esse campo, então quando implantar o Model como um DeployedModel para um atributo Endpoint, o padrão será definido como /v1/endpoints/ENDPOINT/deployedModels/DEPLOYED_MODEL, em que ENDPOINT é substituído pelo último segmento do Endpoint's name campo (após endpoints/), e DEPLOYED_MODEL é substituído pelo DeployedModel's id campo.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-health-route para especificar o campo.

predictRoute (opcional)

O caminho no servidor HTTP do contêiner onde você deseja que a Agent Platform encaminhe solicitações de inferência.

Se você não especificar esse campo, então quando implantar o Model como um DeployedModel para um atributo Endpoint, o padrão será definido como /v1/endpoints/ENDPOINT/deployedModels/DEPLOYED_MODEL:predict, em que ENDPOINT é substituído pelo último segmento do Endpoint's name campo (após endpoints/) e DEPLOYED_MODEL é substituído pelo DeployedModel's id campo.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-predict-route para especificar o campo.

invokeRoutePrefix (opcional)

Prefixo da rota de invocação para o contêiner personalizado. Definir esse campo como "/*" ativa o roteamento arbitrário para o modelo. Depois de implantado, qualquer rota não raiz no servidor de modelo poderá ser acessada com a chamada HTTP de invocação. Por exemplo, "/invoke/foo/bar" seria encaminhado como "/foo/bar" para o servidor de modelo. Esse recurso está na fase de pré-lançamento público. Para criar um modelo ativado por invocação, siga as instruções para usar rotas personalizadas arbitrárias.

sharedMemorySizeMb (opcional)

A quantidade de memória da VM a ser reservada em um volume de memória compartilhada para o modelo em megabytes.

A memória compartilhada é um mecanismo de comunicação entre processos (IPC) que permite que vários processos acessem e manipulem um bloco comum de memória. A quantidade de memória compartilhada necessária, se houver, é um detalhe de implementação do contêiner e do modelo. Consulte as diretrizes na documentação do servidor de modelo.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-shared-memory-size-mb para especificar o campo.

startupProbe (opcional)

Especificação da sondagem que verifica se o aplicativo do contêiner foi iniciado.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-startup-probe-exec, --container-startup-probe-period-seconds, --container-startup-probe-timeout-seconds para especificar o campo.

healthProbe (opcional)

Especificação da sondagem que verifica se um contêiner está pronto para aceitar o tráfego.

Se você estiver usando o comando gcloud ai models upload, poderá usar a sinalização --container-health-probe-exec, --container-health-probe-period-seconds, --container-health-probe-timeout-seconds para especificar o campo.

Além das variáveis definidas no campo Model.containerSpec.env, a Agent Platform define várias outras variáveis com base na sua configuração. Saiba mais sobre como usar essas variáveis de ambiente nesses campos e na instrução ENTRYPOINT do contêiner.

Exemplos de importação de modelos

Nos exemplos a seguir, mostramos como especificar campos de API relacionados ao contêiner quando você importa um modelo.

gcloud

O exemplo a seguir usa o 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

A sinalização --container-image-uri é obrigatória, todas as outras sinalizações que começam com --container- são opcionais. Para saber mais sobre os valores desses campos, consulte a seção anterior deste guia.

Java

Antes de testar esta amostra, siga as instruções de configuração do Java no Guia de início rápido da Agent Platform: como usar bibliotecas de cliente.

Para autenticar na Agent Platform, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento 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 testar esta amostra, siga as instruções de configuração Node.js no Guia de início rápido da Agent Platform: como usar bibliotecas de cliente.

Para autenticar na Agent Platform, configure o Application Default Credentials. Se quiser mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento 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 como instalar o SDK da Vertex AI para Python, consulte Instalar o SDK da Vertex AI para Python. Para mais informações, consulte a Python documentação de referência da API.

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 mais contexto, leia o Guia de importação de modelos.

Enviar solicitações de inferência

Para enviar uma solicitação de inferência on-line ao Model, siga as instruções em Receber inferências de um modelo treinado personalizado: esse processo funciona, não importa se você usa um contêiner personalizado.

Leia sobre os requisitos de solicitação e resposta de previsão para contêineres personalizados.

A seguir