Elastic Algorithm Service (EAS) SDK を使用すると、シンプルかつ安定した方法でモデルサービスを呼び出すことができます。このトピックでは、EAS SDK for Java のメソッドについて説明し、文字列の入力と出力、テンソルの入力と出力、キューサービス、リクエストデータの圧縮など、一般的なユースケースのサンプルコードを提供します。
依存関係の追加
プロジェクトに EAS SDK for Java を統合するには、eas-sdk 依存関係を pom.xml ファイルに追加します。SDK の最新バージョンについては、Maven リポジトリにアクセスしてください。サンプルコード:
<dependency>
<groupId>com.aliyun.openservices.eas</groupId>
<artifactId>eas-sdk</artifactId>
<version>2.0.20</version>
</dependency>バージョン 2.0.5 以降、SDK は、非同期リクエストの優先度を管理するキューサービスをサポートしています。互換性の問題なくキューサービスを使用するには、次の依存関係の必要なバージョンを追加します。
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>インターフェイス
PredictClient クラス
これはメインのクライアントクラスです。これを使用して、サービス情報を構成し、リクエストを送信し、予測結果を受信できます。
インターフェイス | 説明 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 説明: リクエストの URL をカスタマイズします。 |
|
|
|
|
|
|
|
|
|
|
|
|
HttpConfig クラス
基盤となる HTTP 接続パラメーター (タイムアウト、スレッド数、接続プールなど) を構成するために使用されます。
インターフェイス | 説明 |
|
|
|
|
|
|
|
|
|
|
|
|
| 最後の呼び出しのステータスコードを返します。 |
| 最後の呼び出しのエラーメッセージを返します。 |
TFRequest クラス
TensorFlow モデルの入力データを構築するために使用されます。
インターフェイス | 説明 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QueueClient クラス
EAS キューサービスと対話し、データを生成、消費、管理するために使用されます。
インターフェイス | 説明 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 説明: キューサービスを停止します。 |
DataFrame クラス
キューサービス内のデータ項目のカプセル化オブジェクト。
インターフェイス | 説明 |
|
|
|
|
|
|
デモ
[文字列の入力と出力の使用]
カスタムプロセッサを使用してモデル (Predictive Model Markup Language (PMML) モデルなど) をデプロイする場合、リクエストコンテンツは多くの場合、文字列としてフォーマットされます。サンプルコード:
import com.aliyun.openservices.eas.predict.http.PredictClient;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
public class TestString {
public static void main(String[] args) throws Exception {
// クライアントを開始して初期化します。PredictClient インスタンスは複数のリクエストで共有されます。リクエストごとに PredictClient インスタンスを作成しないでください。
PredictClient client = new PredictClient(new HttpConfig());
client.setToken("YWFlMDYyZDNmNTc3M2I3MzMwYmY0MmYwM2Y2MTYxMTY4NzBkNzdj****");
// VPC ダイレクト接続機能を使用するには、setDirectEndpoint メソッドを呼び出します。
// 例: client.setDirectEndpoint("pai-eas-vpc.cn-shanghai.aliyuncs.com");
// PAI コンソールで VPC ダイレクト接続機能を有効にし、vSwitch を構成する必要があります。この機能を有効にすると、ゲートウェイを介さずにサービスを呼び出すことができ、安定性とパフォーマンスが向上します。
// 注: ゲートウェイを使用してサービスを呼び出すには、ユーザー ID で始まるエンドポイントを使用します。エンドポイントを取得するには、EAS-Online Model Services ページで呼び出すサービスを見つけ、[サービスタイプ] 列の [呼び出し方法] をクリックします。表示されるダイアログボックスで、エンドポイントを表示できます。VPC ダイレクト接続機能を使用してサービスを呼び出すには、pai-eas-vpc.{region_id}.aliyuncs.com 形式のエンドポイントを使用します。
client.setEndpoint("182848887922****.vpc.cn-shanghai.pai-eas.aliyuncs.com");
client.setModelName("scorecard_pmml_example");
// 入力文字列を定義します。
String request = "[{\"money_credit\": 3000000}, {\"money_credit\": 10000}]";
System.out.println(request);
// EAS は文字列を返します。
try {
String response = client.predict(request);
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
// クライアントをシャットダウンします。
client.shutdown();
return;
}
}上記のサンプルコードは、次の手順を実行します:
PredictClientメソッドを呼び出して、サービスのクライアントを作成します。複数のサービスが関与している場合は、複数のクライアントを作成します。クライアントのトークン、エンドポイント、およびモデル名パラメーターを構成します。
入力として STRING 型の request 変数を作成し、
client.predictメソッドを呼び出して HTTP リクエストを送信します。サービスは response パラメーターを返します。
[TensorFlow の入力と出力の使用]
サービスが TensorFlow モデルを使用する場合、入力は TFRequest 形式を使用し、出力は TFResponse 形式を使用する必要があります。サンプルコード:
import java.util.List;
import com.aliyun.openservices.eas.predict.http.PredictClient;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
import com.aliyun.openservices.eas.predict.request.TFDataType;
import com.aliyun.openservices.eas.predict.request.TFRequest;
import com.aliyun.openservices.eas.predict.response.TFResponse;
public class TestTF {
public static TFRequest buildPredictRequest() {
TFRequest request = new TFRequest();
request.setSignatureName("predict_images");
float[] content = new float[784];
for (int i = 0; i < content.length; i++) {
content[i] = (float) 0.0;
}
request.addFeed("images", TFDataType.DT_FLOAT, new long[]{1, 784}, content);
request.addFetch("scores");
return request;
}
public static void main(String[] args) throws Exception {
PredictClient client = new PredictClient(new HttpConfig());
// VPC ダイレクト接続機能を使用するには、setDirectEndpoint メソッドを呼び出します。
// 例: client.setDirectEndpoint("pai-eas-vpc.cn-shanghai.aliyuncs.com");
// PAI コンソールで VPC ダイレクト接続機能を有効にし、vSwitch を構成する必要があります。この機能を有効にすると、ゲートウェイを介さずにサービスを呼び出すことができ、安定性とパフォーマンスが向上します。
// 注: ゲートウェイを使用してサービスを呼び出すには、ユーザー ID で始まるエンドポイントを使用します。エンドポイントを取得するには、EAS-Online Model Services ページで呼び出すサービスを見つけ、[サービスタイプ] 列の [呼び出し方法] をクリックします。表示されるダイアログボックスで、エンドポイントを表示できます。VPC ダイレクト接続機能を使用してサービスを呼び出すには、pai-eas-vpc.{region_id}.aliyuncs.com 形式のエンドポイントを使用します。
client.setEndpoint("182848887922****.vpc.cn-shanghai.pai-eas.aliyuncs.com");
client.setModelName("mnist_saved_model_example");
client.setToken("YTg2ZjE0ZjM4ZmE3OTc0NzYxZDMyNmYzMTJjZTQ1YmU0N2FjMTAy****");
long startTime = System.currentTimeMillis();
int count = 1000;
for (int i = 0; i < count; i++) {
try {
TFResponse response = client.predict(buildPredictRequest());
List<Float> result = response.getFloatVals("scores");
System.out.print("Predict Result: [");
for (int j = 0; j < result.size(); j++) {
System.out.print(result.get(j).floatValue());
if (j != result.size() - 1) {
System.out.print(", ");
}
}
System.out.print("]\n");
} catch (Exception e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("Spend Time: " + (endTime - startTime) + "ms");
client.shutdown();
}
}上記のサンプルコードは、次の手順を実行します:
PredictClientメソッドを呼び出して、サービスのクライアントを作成します。複数のサービスが関与している場合は、複数のクライアントを作成します。クライアントのトークン、エンドポイント、およびモデル名パラメーターを構成します。
TFRequest クラスを使用して入力をカプセル化し、TFResponse クラスを使用して出力をカプセル化します。
キューサービスの使用
QueueClient クラスを使用して、キューサービスを実装します。サンプルコード:
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
import com.aliyun.openservices.eas.predict.http.QueueClient;
import com.aliyun.openservices.eas.predict.queue_client.QueueUser;
import com.aliyun.openservices.eas.predict.queue_client.WebSocketWatcher;
public class DemoWatch {
public static void main(String[] args) throws Exception {
/** キューサービスのクライアントを作成します。 */
String queueEndpoint = "18*******.cn-hangzhou.pai-eas.aliyuncs.com";
String inputQueueName = "test_queue_service";
String sinkQueueName = "test_queue_service/sink";
String queueToken = "test-token";
/** 入力キューを作成します。入力キューにデータを追加すると、推論サービスは入力キューからリクエストデータを自動的に読み取ります。 */
QueueClient inputQueue =
new QueueClient(queueEndpoint, inputQueueName, queueToken, new HttpConfig(), new QueueUser());
/** 出力キューを作成します。推論サービスが入力データを処理した後、結果が出力キューに書き込まれます。 */
QueueClient sinkQueue =
new QueueClient(queueEndpoint, sinkQueueName, queueToken, new HttpConfig(), new QueueUser());
/** キュー内のデータをクリアします。注意して使用してください。 */
inputQueue.clear();
sinkQueue.clear();
/** 入力キューにデータを追加します。 */
int count = 10;
for (int i = 0; i < count; ++i) {
String data = Integer.toString(i);
inputQueue.put(data.getBytes(), null);
/** キューサービスは、複数優先度のキューをサポートしています。put メソッドを呼び出して、データの優先度を設定できます。デフォルトの優先度は 0 です。 */
// inputQueue.put(data.getBytes(), 0L, null);
}
/** watch メソッドを呼び出して、出力キューのデータをサブスクライブします。ウィンドウサイズは 5 です。 */
WebSocketWatcher watcher = sinkQueue.watch(0L, 5L, false, true, null);
/** WatchConfig パラメーターを構成して、再試行回数、再試行間隔 (秒単位)、および無期限に再試行するかどうかを指定できます。WatchConfig パラメーターを構成しない場合、デフォルトの再試行回数は 3、デフォルトの再試行間隔は 5 です。 */
// WebSocketWatcher watcher = sink_queue.watch(0L, 5L, false, true, null, new WatchConfig(3, 1));
// WebSocketWatcher watcher = sink_queue.watch(0L, 5L, false, true, null, new WatchConfig(true, 10));
/** 出力データを取得します。 */
for (int i = 0; i < count; ++i) {
try {
/** getDataFrame メソッドを呼び出して、DataFrame 型のデータを取得します。データが利用できない場合、メソッドはデータが利用可能になるまでブロックします。 */
byte[] data = watcher.getDataFrame().getData();
System.out.println("[watch] data = " + new String(data));
} catch (RuntimeException ex) {
System.out.println("[watch] error = " + ex.getMessage());
break;
}
}
/** ウォッチャーを閉じます。各クライアントは 1 つのウォッチャーしか持つことができません。ウォッチャーを閉じないと、キューサービスの別のクライアントを作成するときにエラーが報告されます。 */
watcher.close();
Thread.sleep(2000);
JSONObject attrs = sinkQueue.attributes();
System.out.println(attrs.toString());
/** クライアントをシャットダウンします。 */
inputQueue.shutdown();
sinkQueue.shutdown();
}
}上記のサンプルコードは、次の手順を実行します:
QueueClientメソッドを呼び出して、キューサービスのクライアントを作成します。推論サービスに必要な入力キューと出力キューを作成してください。put()メソッドを呼び出して入力キューにデータを送信し、watch()メソッドを呼び出して出力キューのデータをサブスクライブします。説明デモンストレーションの便宜上、この例では同じスレッドでデータを送信し、データをサブスクライブします。実際の実装では、異なるスレッドでデータを送信し、データをサブスクライブできます。
リクエストデータの圧縮
リクエストデータのサイズが大きい場合、EAS SDK を使用すると、データをサーバーに送信する前に Zlib または Gzip 形式で圧縮できます。データ圧縮機能を使用するには、サービスをデプロイするときに rpc.decompressor パラメーターを構成します。
サービスデプロイのサンプル構成:
"metadata": {
"rpc": {
"decompressor": "zlib"
}
}圧縮データを送信するためのサンプルコード:
package com.aliyun.openservices.eas.predict;
import com.aliyun.openservices.eas.predict.http.Compressor;
import com.aliyun.openservices.eas.predict.http.PredictClient;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
public class TestString {
public static void main(String[] args) throws Exception{
// クライアントを開始して初期化します。
PredictClient client = new PredictClient(new HttpConfig());
client.setEndpoint("18*******.cn-hangzhou.pai-eas.aliyuncs.com");
client.setModelName("echo_compress");
client.setToken("YzZjZjQwN2E4NGRkMDMxNDk5NzhhZDcwZDBjOTZjOGYwZDYxZGM2****");
// コンプレッサーを Compressor.Gzip に設定することもできます。
client.setCompressor(Compressor.Zlib);
// 入力文字列を定義します。
String request = "[{\"money_credit\": 3000000}, {\"money_credit\": 10000}]";
System.out.println(request);
// EAS は文字列を返します。
String response = client.predict(request);
System.out.println(response);
// クライアントをシャットダウンします。
client.shutdown();
return;
}
}参照
応答のステータスコードは、リクエストが成功したかどうかを示します。詳細については、「付録: サービスステータスコードと一般的なエラー」をご参照ください。
モデルサービスを呼び出す他の方法については、「サービス呼び出し方法」をご参照ください。