Receber previsões de um modelo de classificação de vídeo

Nesta página, mostramos como receber previsões em lote de modelos de classificação de vídeo usando o console do Google Cloud ou a API Vertex AI. As previsões em lote são solicitações assíncronas. Solicite previsões em lote diretamente do recurso do modelo sem precisar implantá-lo em um endpoint.

Os modelos de vídeo do AutoML não dão suporte a previsões on-line.

Receba predições em lote

Para fazer uma previsão em lote, especifique uma origem de entrada e um formato de saída em que a Vertex AI armazena os resultados das previsões.

Requisitos de dados de entrada

A entrada de solicitações em lote especifica os itens que serão enviados ao seu modelo para previsão. As previsões em lote para o tipo de modelo de vídeo do AutoML usam um arquivo JSON Lines a fim de especificar uma lista de vídeos para fazer previsões e, em seguida, armazenam esse arquivo em um bucket do Cloud Storage. Especifique Infinity para o campo timeSegmentEnd para especificar o fim do vídeo. No exemplo a seguir, há uma única linha em um arquivo JSON Lines de entrada.

{'content': 'gs://sourcebucket/datasets/videos/source_video.mp4', 'mimeType': 'video/mp4', 'timeSegmentStart': '0.0s', 'timeSegmentEnd': '2.366667s'}

Solicitar uma predição em lote

Para solicitações de previsão em lote, use o Console do Google Cloud ou a API Vertex AI. Dependendo do número de itens de entrada enviados, uma tarefa de previsão em lote pode levar algum tempo para ser concluída.

Console do Google Cloud

Use o console do Google Cloud para solicitar uma previsão em lote.

  1. No console do Google Cloud, na seção Vertex AI, acesse a página Previsões em lote.

    Acessar a página "Previsões em lote"

  2. Clique em Criar para abrir a janela Nova previsão em lote e conclua as seguintes etapas:

    1. Insira um nome para a previsão em lote.
    2. Em Nome do modelo, selecione o nome do modelo a ser usado para a previsão em lote.
    3. Em Caminho de origem, especifique o local do Cloud Storage em que o arquivo de entrada das linhas JSON está localizado.
    4. Em Caminho de destino, especifique um local do Cloud Storage em que os resultados da predição em lote são armazenados. O formato da saída é determinado pelo objetivo do modelo. Os modelos do AutoML para objetivos de imagem geram arquivos de Linhas em JSON.

API

Use a API Vertex AI para enviar solicitações de previsão em lote.

REST

Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

  • LOCATION_ID: região em que o modelo está armazenado e o job de previsão em lote é executado. Por exemplo, us-central1.
  • PROJECT_ID: o ID do projeto
  • BATCH_JOB_NAME: nome de exibição do job em lote
  • MODEL_ID: o ID do modelo a ser usado para fazer previsões
  • THRESHOLD_VALUE (opcional): o modelo retorna apenas previsões que têm pontuações de confiança com pelo menos esse valor
  • SEGMENT_CLASSIFICATION (opcional): um valor booleano que determina se a classificação no nível do segmento será solicitada. A Vertex AI retorna rótulos e a pontuação de confiança de todo o segmento de tempo do vídeo que você especificou na instância de entrada. O padrão é true.
  • SHOT_CLASSIFICATION (opcional): um valor booleano que determina se é necessário solicitar a classificação no nível da tomada. A Vertex AI determina os limites de cada tomada de câmera em todo o segmento de tempo do vídeo que você especificou na instância de entrada. Em seguida, a Vertex AI retorna rótulos e as pontuações de confiança deles para cada tomada detectada, com o horário de início e término da tomada. O padrão é false.
  • ONE_SEC_INTERVAL_CLASSIFICATION (opcional): um valor booleano que determina se a classificação de um vídeo será solicitada em intervalos de um segundo. A Vertex AI retorna rótulos e as pontuações de confiança deles para cada segundo de todo o segmento de tempo do vídeo que você especificou na instância de entrada. O padrão é false.
  • URI: URI do Cloud Storage em que o arquivo de linhas JSON de entrada está localizado.
  • BUCKET: o bucket do Cloud Storage
  • PROJECT_NUMBER: o número do projeto gerado automaticamente

Método HTTP e URL:

POST https://LOCATION_ID-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION_ID/batchPredictionJobs

Corpo JSON da solicitação:

{
    "displayName": "BATCH_JOB_NAME",
    "model": "projects/PROJECT_ID/locations/LOCATION_ID/models/MODEL_ID",
    "modelParameters": {
      "confidenceThreshold": THRESHOLD_VALUE,
      "segmentClassification": SEGMENT_CLASSIFICATION,
      "shotClassification": SHOT_CLASSIFICATION,
      "oneSecIntervalClassification": ONE_SEC_INTERVAL_CLASSIFICATION
    },
    "inputConfig": {
        "instancesFormat": "jsonl",
        "gcsSource": {
            "uris": ["URI"],
        },
    },
    "outputConfig": {
        "predictionsFormat": "jsonl",
        "gcsDestination": {
            "outputUriPrefix": "OUTPUT_BUCKET",
        },
    },
}

Para enviar a solicitação, escolha uma destas opções:

curl

Salve o corpo da solicitação em um arquivo com o nome request.json e execute o comando a seguir:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION_ID-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION_ID/batchPredictionJobs"

PowerShell

Salve o corpo da solicitação em um arquivo com o nome request.json e execute o comando a seguir:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION_ID-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION_ID/batchPredictionJobs" | Select-Object -Expand Content

Você receberá uma resposta JSON semelhante a esta:

{
  "name": "projects/PROJECT_NUMBER/locations/us-central1/batchPredictionJobs/BATCH_JOB_ID",
  "displayName": "BATCH_JOB_NAME",
  "model": "projects/PROJECT_NUMBER/locations/us-central1/models/MODEL_ID",
  "inputConfig": {
    "instancesFormat": "jsonl",
    "gcsSource": {
      "uris": [
        "CONTENT"
      ]
    }
  },
  "outputConfig": {
    "predictionsFormat": "jsonl",
    "gcsDestination": {
      "outputUriPrefix": "BUCKET"
    }
  },
  "state": "JOB_STATE_PENDING",
  "createTime": "2020-05-30T02:58:44.341643Z",
  "updateTime": "2020-05-30T02:58:44.341643Z",
  "modelDisplayName": "MODEL_NAME",
  "modelObjective": "MODEL_OBJECTIVE"
}

É possível pesquisar o status da tarefa em lote usando BATCH_JOB_ID até que o job state seja JOB_STATE_SUCCEEDED.

Java

Antes de testar esse exemplo, siga as instruções de configuração para Java no Guia de início rápido da Vertex AI sobre como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Vertex AI para Java.

Para autenticar na Vertex AI, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


import com.google.cloud.aiplatform.util.ValueConverter;
import com.google.cloud.aiplatform.v1.BatchDedicatedResources;
import com.google.cloud.aiplatform.v1.BatchPredictionJob;
import com.google.cloud.aiplatform.v1.BatchPredictionJob.InputConfig;
import com.google.cloud.aiplatform.v1.BatchPredictionJob.OutputConfig;
import com.google.cloud.aiplatform.v1.BatchPredictionJob.OutputInfo;
import com.google.cloud.aiplatform.v1.BigQueryDestination;
import com.google.cloud.aiplatform.v1.BigQuerySource;
import com.google.cloud.aiplatform.v1.CompletionStats;
import com.google.cloud.aiplatform.v1.GcsDestination;
import com.google.cloud.aiplatform.v1.GcsSource;
import com.google.cloud.aiplatform.v1.JobServiceClient;
import com.google.cloud.aiplatform.v1.JobServiceSettings;
import com.google.cloud.aiplatform.v1.LocationName;
import com.google.cloud.aiplatform.v1.MachineSpec;
import com.google.cloud.aiplatform.v1.ManualBatchTuningParameters;
import com.google.cloud.aiplatform.v1.ModelName;
import com.google.cloud.aiplatform.v1.ResourcesConsumed;
import com.google.cloud.aiplatform.v1.schema.predict.params.VideoClassificationPredictionParams;
import com.google.protobuf.Any;
import com.google.protobuf.Value;
import com.google.rpc.Status;
import java.io.IOException;
import java.util.List;

public class CreateBatchPredictionJobVideoClassificationSample {

  public static void main(String[] args) throws IOException {
    String batchPredictionDisplayName = "YOUR_VIDEO_CLASSIFICATION_DISPLAY_NAME";
    String modelId = "YOUR_MODEL_ID";
    String gcsSourceUri =
        "gs://YOUR_GCS_SOURCE_BUCKET/path_to_your_video_source/[file.csv/file.jsonl]";
    String gcsDestinationOutputUriPrefix =
        "gs://YOUR_GCS_SOURCE_BUCKET/destination_output_uri_prefix/";
    String project = "YOUR_PROJECT_ID";
    createBatchPredictionJobVideoClassification(
        batchPredictionDisplayName, modelId, gcsSourceUri, gcsDestinationOutputUriPrefix, project);
  }

  static void createBatchPredictionJobVideoClassification(
      String batchPredictionDisplayName,
      String modelId,
      String gcsSourceUri,
      String gcsDestinationOutputUriPrefix,
      String project)
      throws IOException {
    JobServiceSettings jobServiceSettings =
        JobServiceSettings.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 (JobServiceClient jobServiceClient = JobServiceClient.create(jobServiceSettings)) {
      String location = "us-central1";
      LocationName locationName = LocationName.of(project, location);

      VideoClassificationPredictionParams modelParamsObj =
          VideoClassificationPredictionParams.newBuilder()
              .setConfidenceThreshold(((float) 0.5))
              .setMaxPredictions(10000)
              .setSegmentClassification(true)
              .setShotClassification(true)
              .setOneSecIntervalClassification(true)
              .build();

      Value modelParameters = ValueConverter.toValue(modelParamsObj);

      ModelName modelName = ModelName.of(project, location, modelId);
      GcsSource.Builder gcsSource = GcsSource.newBuilder();
      gcsSource.addUris(gcsSourceUri);
      InputConfig inputConfig =
          InputConfig.newBuilder().setInstancesFormat("jsonl").setGcsSource(gcsSource).build();

      GcsDestination gcsDestination =
          GcsDestination.newBuilder().setOutputUriPrefix(gcsDestinationOutputUriPrefix).build();
      OutputConfig outputConfig =
          OutputConfig.newBuilder()
              .setPredictionsFormat("jsonl")
              .setGcsDestination(gcsDestination)
              .build();

      BatchPredictionJob batchPredictionJob =
          BatchPredictionJob.newBuilder()
              .setDisplayName(batchPredictionDisplayName)
              .setModel(modelName.toString())
              .setModelParameters(modelParameters)
              .setInputConfig(inputConfig)
              .setOutputConfig(outputConfig)
              .build();
      BatchPredictionJob batchPredictionJobResponse =
          jobServiceClient.createBatchPredictionJob(locationName, batchPredictionJob);

      System.out.println("Create Batch Prediction Job Video Classification Response");
      System.out.format("\tName: %s\n", batchPredictionJobResponse.getName());
      System.out.format("\tDisplay Name: %s\n", batchPredictionJobResponse.getDisplayName());
      System.out.format("\tModel %s\n", batchPredictionJobResponse.getModel());
      System.out.format(
          "\tModel Parameters: %s\n", batchPredictionJobResponse.getModelParameters());

      System.out.format("\tState: %s\n", batchPredictionJobResponse.getState());
      System.out.format("\tCreate Time: %s\n", batchPredictionJobResponse.getCreateTime());
      System.out.format("\tStart Time: %s\n", batchPredictionJobResponse.getStartTime());
      System.out.format("\tEnd Time: %s\n", batchPredictionJobResponse.getEndTime());
      System.out.format("\tUpdate Time: %s\n", batchPredictionJobResponse.getUpdateTime());
      System.out.format("\tLabels: %s\n", batchPredictionJobResponse.getLabelsMap());

      InputConfig inputConfigResponse = batchPredictionJobResponse.getInputConfig();
      System.out.println("\tInput Config");
      System.out.format("\t\tInstances Format: %s\n", inputConfigResponse.getInstancesFormat());

      GcsSource gcsSourceResponse = inputConfigResponse.getGcsSource();
      System.out.println("\t\tGcs Source");
      System.out.format("\t\t\tUris %s\n", gcsSourceResponse.getUrisList());

      BigQuerySource bigQuerySource = inputConfigResponse.getBigquerySource();
      System.out.println("\t\tBigquery Source");
      System.out.format("\t\t\tInput_uri: %s\n", bigQuerySource.getInputUri());

      OutputConfig outputConfigResponse = batchPredictionJobResponse.getOutputConfig();
      System.out.println("\tOutput Config");
      System.out.format(
          "\t\tPredictions Format: %s\n", outputConfigResponse.getPredictionsFormat());

      GcsDestination gcsDestinationResponse = outputConfigResponse.getGcsDestination();
      System.out.println("\t\tGcs Destination");
      System.out.format(
          "\t\t\tOutput Uri Prefix: %s\n", gcsDestinationResponse.getOutputUriPrefix());

      BigQueryDestination bigQueryDestination = outputConfigResponse.getBigqueryDestination();
      System.out.println("\t\tBig Query Destination");
      System.out.format("\t\t\tOutput Uri: %s\n", bigQueryDestination.getOutputUri());

      BatchDedicatedResources batchDedicatedResources =
          batchPredictionJobResponse.getDedicatedResources();
      System.out.println("\tBatch Dedicated Resources");
      System.out.format(
          "\t\tStarting Replica Count: %s\n", batchDedicatedResources.getStartingReplicaCount());
      System.out.format(
          "\t\tMax Replica Count: %s\n", batchDedicatedResources.getMaxReplicaCount());

      MachineSpec machineSpec = batchDedicatedResources.getMachineSpec();
      System.out.println("\t\tMachine Spec");
      System.out.format("\t\t\tMachine Type: %s\n", machineSpec.getMachineType());
      System.out.format("\t\t\tAccelerator Type: %s\n", machineSpec.getAcceleratorType());
      System.out.format("\t\t\tAccelerator Count: %s\n", machineSpec.getAcceleratorCount());

      ManualBatchTuningParameters manualBatchTuningParameters =
          batchPredictionJobResponse.getManualBatchTuningParameters();
      System.out.println("\tManual Batch Tuning Parameters");
      System.out.format("\t\tBatch Size: %s\n", manualBatchTuningParameters.getBatchSize());

      OutputInfo outputInfo = batchPredictionJobResponse.getOutputInfo();
      System.out.println("\tOutput Info");
      System.out.format("\t\tGcs Output Directory: %s\n", outputInfo.getGcsOutputDirectory());
      System.out.format("\t\tBigquery Output Dataset: %s\n", outputInfo.getBigqueryOutputDataset());

      Status status = batchPredictionJobResponse.getError();
      System.out.println("\tError");
      System.out.format("\t\tCode: %s\n", status.getCode());
      System.out.format("\t\tMessage: %s\n", status.getMessage());
      List<Any> details = status.getDetailsList();

      for (Status partialFailure : batchPredictionJobResponse.getPartialFailuresList()) {
        System.out.println("\tPartial Failure");
        System.out.format("\t\tCode: %s\n", partialFailure.getCode());
        System.out.format("\t\tMessage: %s\n", partialFailure.getMessage());
        List<Any> partialFailureDetailsList = partialFailure.getDetailsList();
      }

      ResourcesConsumed resourcesConsumed = batchPredictionJobResponse.getResourcesConsumed();
      System.out.println("\tResources Consumed");
      System.out.format("\t\tReplica Hours: %s\n", resourcesConsumed.getReplicaHours());

      CompletionStats completionStats = batchPredictionJobResponse.getCompletionStats();
      System.out.println("\tCompletion Stats");
      System.out.format("\t\tSuccessful Count: %s\n", completionStats.getSuccessfulCount());
      System.out.format("\t\tFailed Count: %s\n", completionStats.getFailedCount());
      System.out.format("\t\tIncomplete Count: %s\n", completionStats.getIncompleteCount());
    }
  }
}

Node.js

Antes de testar essa amostra, siga as instruções de configuração para Node.js Guia de início rápido da Vertex AI: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Vertex AI para Node.js.

Para autenticar na Vertex AI, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

/**
 * TODO(developer): Uncomment these variables before running the sample.\
 * (Not necessary if passing values as arguments)
 */

// const batchPredictionDisplayName = 'YOUR_BATCH_PREDICTION_DISPLAY_NAME';
// const modelId = 'YOUR_MODEL_ID';
// const gcsSourceUri = 'YOUR_GCS_SOURCE_URI';
// const gcsDestinationOutputUriPrefix = 'YOUR_GCS_DEST_OUTPUT_URI_PREFIX';
//    eg. "gs://<your-gcs-bucket>/destination_path"
// const project = 'YOUR_PROJECT_ID';
// const location = 'YOUR_PROJECT_LOCATION';
const aiplatform = require('@google-cloud/aiplatform');
const {params} = aiplatform.protos.google.cloud.aiplatform.v1.schema.predict;

// Imports the Google Cloud Job Service Client library
const {JobServiceClient} = require('@google-cloud/aiplatform').v1;

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

// Instantiates a client
const jobServiceClient = new JobServiceClient(clientOptions);

async function createBatchPredictionJobVideoClassification() {
  // Configure the parent resource
  const parent = `projects/${project}/locations/${location}`;
  const modelName = `projects/${project}/locations/${location}/models/${modelId}`;

  // For more information on how to configure the model parameters object, see
  // https://cloud.google.com/ai-platform-unified/docs/predictions/batch-predictions
  const modelParamsObj = new params.VideoClassificationPredictionParams({
    confidenceThreshold: 0.5,
    maxPredictions: 1000,
    segmentClassification: true,
    shotClassification: true,
    oneSecIntervalClassification: true,
  });

  const modelParameters = modelParamsObj.toValue();

  const inputConfig = {
    instancesFormat: 'jsonl',
    gcsSource: {uris: [gcsSourceUri]},
  };
  const outputConfig = {
    predictionsFormat: 'jsonl',
    gcsDestination: {outputUriPrefix: gcsDestinationOutputUriPrefix},
  };
  const batchPredictionJob = {
    displayName: batchPredictionDisplayName,
    model: modelName,
    modelParameters,
    inputConfig,
    outputConfig,
  };
  const request = {
    parent,
    batchPredictionJob,
  };

  // Create batch prediction job request
  const [response] = await jobServiceClient.createBatchPredictionJob(request);

  console.log('Create batch prediction job video classification response');
  console.log(`Name : ${response.name}`);
  console.log('Raw response:');
  console.log(JSON.stringify(response, null, 2));
}
createBatchPredictionJobVideoClassification();

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 documentação de referência da API Python.

def create_batch_prediction_job_sample(
    project: str,
    location: str,
    model_resource_name: str,
    job_display_name: str,
    gcs_source: Union[str, Sequence[str]],
    gcs_destination: str,
    sync: bool = True,
):
    aiplatform.init(project=project, location=location)

    my_model = aiplatform.Model(model_resource_name)

    batch_prediction_job = my_model.batch_predict(
        job_display_name=job_display_name,
        gcs_source=gcs_source,
        gcs_destination_prefix=gcs_destination,
        sync=sync,
    )

    batch_prediction_job.wait()

    print(batch_prediction_job.display_name)
    print(batch_prediction_job.resource_name)
    print(batch_prediction_job.state)
    return batch_prediction_job

Recuperar resultados de predição em lote

A Vertex AI envia a saída da previsão em lote para o destino especificado.

Quando uma tarefa de predição em lote é concluída, a saída da previsão é armazenada no bucket do Cloud Storage especificado na solicitação.

Exemplo de resultados de previsão em lote

Veja a seguir um exemplo de previsão em lote resultante de um modelo de classificação de vídeo.

{
  "instance": {
   "content": "gs://bucket/video.mp4",
    "mimeType": "video/mp4",
    "timeSegmentStart": "1s",
    "timeSegmentEnd": "5s"
  }
  "prediction": [{
    "id": "1",
    "displayName": "cat",
    "type": "segment-classification",
    "timeSegmentStart": "1s",
    "timeSegmentEnd": "5s",
    "confidence": 0.7
  }, {
    "id": "1",
    "displayName": "cat",
    "type": "shot-classification",
    "timeSegmentStart": "1s",
    "timeSegmentEnd": "4s",
    "confidence": 0.9
  }, {
    "id": "2",
    "displayName": "dog",
    "type": "shot-classification",
    "timeSegmentStart": "4s",
    "timeSegmentEnd": "5s",
    "confidence": 0.6
  }, {
    "id": "1",
    "displayName": "cat",
    "type": "one-sec-interval-classification",
    "timeSegmentStart": "1s",
    "timeSegmentEnd": "1s",
    "confidence": 0.95
  }, {
    "id": "1",
    "displayName": "cat",
    "type": "one-sec-interval-classification",
    "timeSegmentStart": "2s",
    "timeSegmentEnd": "2s",
    "confidence": 0.9
  }, {
    "id": "1",
    "displayName": "cat",
    "type": "one-sec-interval-classification",
    "timeSegmentStart": "3s",
    "timeSegmentEnd": "3s",
    "confidence": 0.85
  }, {
    "id": "2",
    "displayName": "dog",
    "type": "one-sec-interval-classification",
    "timeSegmentStart": "4s",
    "timeSegmentEnd": "4s",
    "confidence": 0.6
  }]
}