Search code examples
node.jspython-3.xgoogle-cloud-platformgoogle-cloud-vertex-aivertex-ai-pipeline

Call Vertex AI Endpoint with Node.js - Error: 3 INVALID_ARGUMENT: Failed to parse input instances


I am calling a customized model (Two Towers for retrieval) in Vertex AI endpoint with Node.js with the following code:

const axios = require('axios');
const { GoogleAuth } = require('google-auth-library');

const project = '1234567';
const endpointId = '8888888888';
const location = 'us-central1';

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


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


// Instantiates a client
const predictionServiceClient = new PredictionServiceClient(clientOptions);


async function predictCustomTrainedModel() {
  // Configure the parent resource
  const endpoint = `projects/${project}/locations/${location}/endpoints/${endpointId}`;

  const instance = [{"input_1": ["disenador grafico experiencia montaje planchas".split()]}];

  const instances = [instance]

  const request = {
    endpoint,
    instances
  };

  const response = await predictionServiceClient.predict(request);

  console.log('Predict custom trained model response');
  console.log(`\tDeployed model id : ${response.deployedModelId}`);
  const predictions = response.predictions;
  console.log('\tPredictions :');
  for (const prediction of predictions) {
    console.log(`\t\tPrediction : ${JSON.stringify(prediction)}`);
  }
}
predictCustomTrainedModel();

This returns an error and 400 code in Endpoints monitoring:

(node:84871) UnhandledPromiseRejectionWarning: Error: 3 INVALID_ARGUMENT: Failed to parse input instances.
    at callErrorFromStatus (/home/theone/Downloads/other_models/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
    at Object.onReceiveStatus (/home/theone/Downloads/other_models/node_modules/@grpc/grpc-js/build/src/client.js:192:76)
    at Object.onReceiveStatus (/home/theone/Downloads/other_models/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:360:141)
    at Object.onReceiveStatus (/home/theone/Downloads/other_models/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:323:181)
    at /home/theone/Downloads/other_models/node_modules/@grpc/grpc-js/build/src/resolving-call.js:94:78
    at processTicksAndRejections (internal/process/task_queues.js:79:11)
for call at
    at ServiceClientImpl.makeUnaryRequest (/home/theone/Downloads/other_models/node_modules/@grpc/grpc-js/build/src/client.js:160:34)
    at ServiceClientImpl.<anonymous> (/home/theone/Downloads/other_models/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
    at /home/theone/Downloads/other_models/node_modules/@google-cloud/aiplatform/build/src/v1/prediction_service_client.js:217:29
    at /home/theone/Downloads/other_models/node_modules/google-gax/build/src/normalCalls/timeout.js:44:16
    at OngoingCallPromise.call (/home/theone/Downloads/other_models/node_modules/google-gax/build/src/call.js:67:27)
    at NormalApiCaller.call (/home/theone/Downloads/other_models/node_modules/google-gax/build/src/normalCalls/normalApiCaller.js:34:19)
    at /home/theone/Downloads/other_models/node_modules/google-gax/build/src/createApiCall.js:84:30

It's interesting, because the same payload in Python works perfectly:

import os
from google.cloud import aiplatform
from google.protobuf import json_format
from google.protobuf.struct_pb2 import Value
from typing import Dict, List, Union
from google.oauth2 import service_account

credentials = service_account.Credentials. from_service_account_file('/home/user/key.json')

aip_endpoint_name = (
    f"projects/1245678/locations/us-central1/endpoints/8888888888888"
)

endpoint = aiplatform.Endpoint(aip_endpoint_name,credentials=credentials)

instances_list = [{"input_1": ["disenador grafico experiencia montaje planchas".split()]}]


results = endpoint.predict(instances=instances_list)

Any ideas on how to solve this issue ?


Solution

  • I solved the problem with the Helpers .toValue:

    const axios = require('axios');
    const { GoogleAuth } = require('google-auth-library');
    
    const project = '12345678';
    const endpointId = '8888888888';
    const location = 'us-central1';
    const serviceAccountKeyFile = '/home/user/key.json';
    
    const aiplatform = require('@google-cloud/aiplatform');
    const {instance,prediction} =
      aiplatform.protos.google.cloud.aiplatform.v1.schema.predict;
    
    // Imports the Google Cloud Prediction Service Client library
    const {PredictionServiceClient} = aiplatform.v1;
    
    // Specifies the location of the api endpoint
    const clientOptions = {
      apiEndpoint: 'us-central1-aiplatform.googleapis.com',
      project: project,
      credentials: { key.json here  }
      
    };
    
    
    // Instantiates a client
    const predictionServiceClient = new PredictionServiceClient(clientOptions);
    
    const {helpers} = aiplatform;
    
    async function predictCustomTrainedModel() {
      // Configure the parent resource
      const endpoint = `projects/${project}/locations/${location}/endpoints/${endpointId}`;
    
      const instance = helpers.toValue({ "input_1": [["disenador", "grafico", "experiencia", "montaje", "planchas"]] });
    
      const instances = [instance];
    
      
    
      const request = {
        endpoint,
        instances
      };
    
      const [response] = await predictionServiceClient.predict(request);
    
      console.log('Predict custom trained model response');
      console.log(`\tDeployed model id : ${response.deployedModelId}`);
      const predictions = response.predictions;
      console.log('\tPredictions :');
      for (const prediction of predictions) {
        console.log(`\t\tPrediction : ${JSON.stringify(prediction)}`);
      }
    }
    predictCustomTrainedModel();
    

    Predictions