Elastic Algorithm Service (EAS) は、オンラインモデルサービスに送信された初期リクエストの処理に必要な時間を短縮するために、モデルウォームアップ機能を提供します。この機能は、モデルサービスがオンラインで公開される前にモデルをウォームアップします。これにより、モデルサービスはオンラインで公開された直後から期待どおりに動作します。このトピックでは、モデルウォームアップ機能の使用方法について説明します。
背景情報
初めてモデルにリクエストを送信する場合、さまざまなランタイムがさまざまな初期化プロセスを実行する可能性があり、初期リクエストのレイテンシが高くなり、タイムアウトが発生する可能性があります。たとえば、Java プロセッサを使用すると、Java 仮想マシン (JVM) のコールドスタートによって初期リクエストに時間がかかる場合があります。同様に、一部の TensorFlow モデルでは、最初の呼び出しでモデル関連のファイルまたはパラメーターをメモリにロードする必要があり、時間がかかる場合があり、最初のいくつかのリクエストの応答時間 (RT) が長くなり、408 タイムアウトまたは 450 エラーが発生する可能性があります。これを解決するために、EAS は、モデルサービスが公開される前にウォームアップできるモデルウォームアップ機能を提供し、デプロイ時にリクエストを迅速に処理できるようにします。
EAS サービスエンジンは、モデルサービスが公開される前に、自身にウォームアップリクエストを送信します。初期リクエストには時間がかかる場合がありますが、後続のリクエストは短時間で完了できます。
EAS モデルウォームアップ機能を使用するには、まずウォームアップリクエストファイルを生成します。次に、モデルサービスのデプロイに使用される JSON ファイルでこのリクエストファイルを指定します。モデルサービスのデプロイまたは更新中に、EAS サービスエンジンはウォームアップリクエストを送信します。モデルサービスは、これらのリクエストが正常に送信された後にのみ完全に開始されたと見なされます。
モデルウォームアップ機能を使用する
ウォームアップリクエストファイルを生成するには、モデルサービスがオンラインで公開された後に送信できるリクエストに基づいてリクエストファイルを構築する必要があります。ウォームアップリクエストファイルは、ウォームアッププロセス中に読み取られるか、呼び出されます。サービスの呼び出しに使用される EAS SDK を使用して、リクエストファイルを構築できます。詳細については、「SDK」をご参照ください。次の例では、モデルウォームアップ機能を使用して TensorFlow モデルをウォームアップする方法について説明します。
ウォームアップリクエストファイルを生成します。
次の例では、Python 用 EAS SDK と Java 用 EAS SDK を使用して、TensorFlow モデルサービスのリクエストファイルを構築する方法について説明します。他のタイプのモデルについては、同様の方法を参照できます。文字列を入力として使用するモデルサービスの場合、リクエストを文字列として TXT ファイルに保存できます。各 TXT ファイルには複数のリクエストを含めることができます。各リクエストは、TXT ファイルのデータ行を 1 つ占有します。EAS はファイル形式を自動的に識別し、さまざまな形式でウォームアップリクエストを送信します。
重要TensorFlow モデルのウォームアップに使用されるリクエストの入力と出力は、モデルサービスがオンラインで公開された後に送信されるリクエストの入力と出力と同じである必要があります。
次のサンプルコードは、SDK を使用して TensorFlow モデルサービスのリクエストファイルを構築する方法の例を示しています。
Python 用 SDK を使用する
#!/usr/bin/env python from eas_prediction import PredictClient from eas_prediction import StringRequest from eas_prediction import TFRequest if __name__ == '__main__': # サンプルのウォームアップリクエスト。実際の要件に基づいてウォームアップリクエストを構築します。ウォームアップに使用されるリクエストの入力と出力は、モデルサービスがオンラインで公開された後に送信されるリクエストの入力と出力と同じでなければなりません。 req = TFRequest('serving_default') req.add_feed('sentence1', [200, 15], TFRequest.DT_INT32, [1] * 200 * 15) req.add_feed('sentence2', [200, 15], TFRequest.DT_INT32, [1] * 200 * 15) req.add_feed('y', [200, 2], TFRequest.DT_INT32, [2] * 200 * 2) req.add_feed('keep_rate', [], TFRequest.DT_FLOAT, [0.2]) req.add_feed('images', [1, 784], TFRequest.DT_FLOAT, [1] * 784) req.add_fetch('sorted_labels') req.add_fetch('sorted_probs') # print(req.request_data) # リクエストデータを表示します。 with open("warm_up.bin", "wb") as fw : fw.write(req.to_string()) # warm_up.bin ファイルをウォームアップリクエストファイルとして保存します。Java 用 SDK を使用する
Maven プロジェクトで Java 用 EAS SDK を使用するには、eas-sdk 依存関係を pom.xml ファイルの <dependencies> に追加する必要があります。Maven リポジトリの最新バージョンが優先されます。サンプルコード:
<dependency> <groupId>com.aliyun.openservices.eas</groupId> <artifactId>eas-sdk</artifactId> <version>2.0.13</version> </dependency>Java 用 SDK のサンプルコード:
import java.io.File; import com.aliyun.openservices.eas.predict.request.TFDataType; import com.aliyun.openservices.eas.predict.request.TFRequest; import org.apache.commons.io.FileUtils; public class TestTf { public static void main(String[] args) throws Exception{ // サンプルのウォームアップリクエスト。実際の要件に基づいてウォームアップリクエストを構築します。 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"); try { // リクエストファイルを構築します。既存のファイルがない場合は、新しいファイルを作成します。 File writename = new File("/path/to/warm_up1.bin"); FileUtils.writeByteArrayToFile(writename, request.getRequest().toByteArray()); } catch (Exception ex) { } } }
リクエストファイルを確認します。
次のいずれかの方法を使用して、リクエストファイルを確認できます。
方法 1: 確認のためにサービスリクエストを送信する
次のコマンドを実行して、モデルサービスにリクエストを送信します。返された内容が大きすぎてターミナルに表示できない場合は、
--output <filePath>フィールドを追加して結果をファイルに保存できます。curl --data-binary @"</path/to/warmup.bin>" -H 'Authorization: <yourToken>' <serviceAddress>次のパラメーターを実際の値に置き換えます。
</path/to/warmup.bin>: 前の手順で生成されたウォームアップリクエストファイルのパス。
<yourToken>: モデルサービスへのアクセスに使用されるトークン。
<serviceAddress>: モデルサービスのエンドポイント。
方法 2: 確認のためにリクエストファイルを解析する
Python を使用する
from eas_prediction import TFRequest req = TFRequest() with open('/path/to/warm_up1.bin', 'rb') as wm: req.request_data.ParseFromString(wm.read()) print(req.request_data)Java を使用する
import com.aliyun.openservices.eas.predict.proto.PredictProtos; import org.apache.commons.io.FileUtils; import java.io.File; public class Test { public static void main(String[] args) throws Exception { File refile = new File("/path/to/warm_up1.bin"); byte[] data = FileUtils.readFileToByteArray(refile); PredictProtos.PredictRequest pb = PredictProtos.PredictRequest.parseFrom(data); System.out.println(pb); } }
モデルサービスを構成します。
生成されたウォームアップリクエストファイルを OSS にアップロードします。
モデルサービスのパラメーターを構成します。
JSON 形式のモデル記述ファイルで、モデルサービスのパラメーターを構成します。
{ "name":"warm_up_demo", "model_path":"oss://path/to/model", "warm_up_data_path":"oss://path/to/warm_up_test.bin", // OSS 内のウォームアップリクエストファイルのパス。 "processor":"tensorflow_cpu_1.15", "metadata":{ "cpu":2, "instance":1, "rpc": { "warm_up_count": 5, // 各ウォームアップリクエストが送信される回数。このパラメーターの値を指定しない場合、デフォルト値として 5 が使用されます。 } } }次のウォームアップパラメーターが使用されます。他のパラメーターについては、「JSON デプロイメントのパラメーター」をご参照ください。
warm_up_data_path: OSS 内のウォームアップリクエストファイルのパス。システムは自動的にファイルを検索し、モデルサービスがオンラインで公開される前に、ファイルを使用してモデルをウォームアップします。
warm_up_count: 各ウォームアップリクエストが送信される回数。このパラメーターの値を指定しない場合、デフォルト値として 5 が使用されます。
モデルサービスをデプロイまたは更新します。詳細については、「サービスを作成する」または「サービスを変更する」をご参照ください。
モデルサービスをデプロイまたは更新すると、EAS のサービスエンジンはウォームアップリクエストを送信して、モデルサービスをウォームアップします。
TensorFlow モデルのウォームアップに関するよくある質問
問題
実際のビジネスシナリオでは、TensorFlow モデルを更新すると、サービスが不安定になる可能性があります。プロセッサにウォームアップ機能を追加しても、この問題は解決しない場合があります。テストによると、個別の入力と出力の署名ごとに、モデルがウォームアップのためにファイルを再ロードする可能性があります。すべての署名がモデルにプリロードされている場合でも、特定のリクエストを送信すると、再ロードにかなりの時間がかかる場合があります。
原因
この問題は、TensorFlow 関数
session->Run(inputs, output_tensor_names, {}, &outputs)が inputs と output_tensor_names に対してハッシュ検証を実行するために発生します。入力または出力に変更があると、再読み込みがトリガーされます。次のサンプルコードは、サンプル TensorFlow モデルの入力を示しています。
Inputs: threshold: []; DT_FLOAT model_id: []; DT_STRING input_holder: [-1]; DT_STRING次のサンプルコードは、TensorFlow モデルの出力を示しています。
Outputs: model_version_id: []; DT_STRING sorted_labels: [-1, 3]; DT_STRING sorted_probs: [-1, 3]; DT_FLOAT次のサンプルウォームアップリクエストが送信されます。
request.addFeed("input_holder",TFDataType.DT_STRING, new long[]{1}, input); request.addFeed("threshold", TFDataType.DT_FLOAT, new long[] {}, th); request.addFeed("model_id", TFDataType.DT_STRING, new long[]{}, model_name); request.addFetch("sorted_labels"); request.addFetch("sorted_probs");TensorFlow モデルがウォームアップされた後、次のリクエストが送信されます。ウォームアップリクエストと比較して、次のリクエストの出力には追加のパラメーターが含まれています。この場合、リクエストファイルを再ロードする必要があります。
request.addFeed("input_holder",TFDataType.DT_STRING, new long[]{1}, input); request.addFeed("threshold", TFDataType.DT_FLOAT, new long[] {}, th); request.addFeed("model_id", TFDataType.DT_STRING, new long[]{}, model_name); request.addFetch("sorted_labels"); request.addFetch("sorted_probs"); request.addFetch("model_version_id"); // 追加のパラメーターが返されます。解決策
各サービスは、ウォームアップのために実際のビジネスリクエストを使用する必要があり、このウォームアッププロセスは、これらのリクエストの入力と出力に特に適用されます。したがって、EAS が提供するモデルウォームアップ機能では、実際のリクエストデータをアップロードする必要があります。
session->Runが実際のリクエストで一度正常に実行されれば十分です。したがって、ウォームアップファイルを 1 つだけアップロードし、ウォームアッププロセスが実際の呼び出しで使用される入力と出力に厳密に従うようにすることができます。