Machine Learning Platform for AI (PAI)-Bladeは、推論用に最適化されたモデルをデプロイするために使用できるC ++ 用のSDKを提供します。 このトピックでは、PAI-Blade SDKを使用してPyTorchモデルをデプロイする方法について説明します。
前提条件
PyTorchモデルは、PAI-Bladeを使用して最適化されます。 詳細については、「PyTorchモデルの最適化」をご参照ください。
SDKがインストールされ、認証トークンが取得されます。 これは、Pre-CXX11アプリケーションバイナリインターフェイス (ABI) および この例では、V3.7.0のdebパッケージを使用します。
説明PAI-Bladeを使用して最適化されたモデルは、対応するSDKがインストールされている場合にのみ正しく実行できます。
環境の配置
このトピックでは、PAI-Blade SDKを使用して、推論用のPyTorchモデルをデプロイする方法について説明します。 この例では、Ubuntu 18.04 64ビットがインストールされています。
サーバーを準備します。
次の仕様で設定されたElastic Compute Service (ECS) インスタンスを準備します。
インスタンスタイプ: ecs.gn6i-c4g1.xlarge、NVIDIA Tesla T4 GPU
オペレーティングシステム: Ubuntu 18.04 64ビット
デバイス: CUDA 10.0
GPU: ドライバ440.64.00
GPUコンピューティング加速パッケージ: cuDNN 7.6.5
Python 3をインストールします。
# Update pip. python3 -m pip install --upgrade pip # Install virtualenv, which is a virtual environment in which you can install PyTorch. pip3 install virtualenv==16.0 python3 -m virtualenv venv # Activate virtualenv. source venv/bin/activate
推論用のモデルのデプロイ
PAI-Blade SDKを使用して推論用に最適化されたモデルをロードおよびデプロイするには、元のコードロジックを変更する必要なく、推論コードをコンパイルするときにSDK内のライブラリをリンクできます。
モデルとテストデータを準備します。
この例では、最適化されたサンプルモデルが使用される。 次のコマンドを実行して、サンプルモデルをダウンロードします。 独自の最適化モデルを使用することもできます。 PAI-Bladeを使用してモデルを最適化する方法の詳細については、「PyTorchモデルの最適化」をご参照ください。
# Download the optimized sample model. wget http://pai-blade.oss-cn-zhangjiakou.aliyuncs.com/demo/sdk/pytorch/optimized_resnet50.pt # Download the test data. wget http://pai-blade.oss-cn-zhangjiakou.aliyuncs.com/demo/sdk/pytorch/inputs.pth
推論コードをダウンロードして表示します。
通常のPyTorchモデルと同じ方法で、PAI-Bladeを使用して最適化されたPyTorchモデルを実行できます。 余分なコードを記述したり、余分なパラメータを設定する必要はありません。 この例では、次のインターフェイスコードがダウンロードされます。
#include <torch/script.h> #include <torch/serialize.h> #include <chrono> #include <iostream> #include <fstream> #include <memory> int benchmark(torch::jit::script::Module &module, std::vector<torch::jit::IValue> &inputs) { // warmup 10-iter for (int k = 0; k < 10; ++ k) { module.forward(inputs); } auto start = std::chrono::system_clock::now(); // run 20-iter for (int k = 0; k < 20; ++ k) { module.forward(inputs); } auto end = std::chrono::system_clock::now(); std::chrono::duration<double> elapsed_seconds = end-start; std::time_t end_time = std::chrono::system_clock::to_time_t(end); std::cout << "finished computation at " << std::ctime(&end_time) << "\nelapsed time: " << elapsed_seconds.count() << "s" << "\navg latency: " << 1000.0 * elapsed_seconds.count()/20 << "ms\n"; return 0; } torch::Tensor load_data(const char* data_file) { std::ifstream file(data_file, std::ios::binary); std::vector<char> data((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); torch::IValue ivalue = torch::pickle_load(data); CHECK(ivalue.isTensor()); return ivalue.toTensor(); } int main(int argc, const char* argv[]) { if (argc != 3) { std::cerr << "usage: example-app <path-to-exported-script-module> <path-to-saved-test-data>\n"; return -1; } torch::jit::script::Module module; try { // Deserialize the ScriptModule from a file using torch::jit::load(). module = torch::jit::load(argv[1]); auto image_tensor = load_data(argv[2]); std::vector<torch::IValue> inputs{image_tensor}; benchmark(module, inputs); auto outputs = module.forward(inputs); } catch (const c10::Error& e) { std::cerr << "error loading the model" << std::endl << e.what(); return -1; } std::cout << "ok\n"; }
上記のサンプルコードをtorch_app.ccという名前のローカルファイルに保存します。
推論コードをコンパイルします。
コードをコンパイルするときは、LibTorchライブラリと、/usr/local/libディレクトリのlibtorch_blade.soおよびlibral_base_context.soファイルをリンクします。 次のコマンドを実行してコードをコンパイルします。
TORCH_DIR=$(python3 -c "import torch; import os; print(os.path.dirname(torch.__file__))") g++ torch_app.cc -std=c++14 \ -D_GLIBCXX_USE_CXX11_ABI=0 \ -I ${TORCH_DIR}/include \ -I ${TORCH_DIR}/include/torch/csrc/api/include \ -Wl,--no-as-needed \ -L /usr/local/lib \ -L ${TORCH_DIR}/lib \ -l torch -l torch_cuda -l torch_cpu -l c10 -l c10_cuda \ -l torch_blade -l ral_base_context \ -o torch_app
ビジネス要件に基づいて、次のパラメーターを変更できます。
torch_app.cc: 推論コードを含むファイルの名前。
/usr/local/lib: SDKのインストールパス。 ほとんどの場合、このパラメーターを変更する必要はありません。
torch_app: コンパイル後に生成される実行可能プログラムの名前。
システムとコンパイラの一部のバージョンでは、コード行
-Wl,-- no-as-needed \
を記述した場合にのみリンクが機能します。重要LibTorch ABIのバージョンに基づいて、
GLIBCXX_USE_CXX11_ABI
マクロの値を設定します。PAI-Bladeが提供するPyTorch for CUDA 10.0は、GNUコンパイラコレクション (GCC) 7.5を使用してコンパイルされます。 CXX11 ABIを使用する場合は、GCCのバージョンが7.5であることを確認してください。 Pre-CXX11 ABIを使用する場合、GCCのバージョンに制限はありません。
推論のモデルをローカルデバイスで実行します。
実行可能プログラムを使用して、最適化モデルをロードして実行します。 次のサンプルコードに例を示します。 この例では、実行可能プログラムtorch_appと最適化サンプルモデルoptimized_resnet50.ptが使用されます。
export BLADE_REGION=<region> # Region: cn-beijing, cn-shanghai for example. export BLADE_TOKEN=<token> export LD_LIBRARY_PATH=/usr/local/lib:${TORCH_DIR}/lib:${LD_LIBRARY_PATH} ./torch_app optimized_resnet50.pt inputs.pth
ビジネス要件に基づいて次のパラメーターを変更します。
<region>: PAI-Bladeを使用するリージョンです。 PAI-BladeユーザーのDingTalkグループに参加して、PAI-Bladeを使用できるリージョンを取得できます。
<token>: PAI-Bladeを使用するために必要な認証トークン。 PAI-BladeユーザーのDingTalkグループに参加して、認証トークンを取得できます。
torch_app: コンパイル後に生成される実行可能プログラム。
optimized_resnet50.pt: PAI-Bladeを使用して最適化されたPyTorchモデル。 この例では、ステップ1でダウンロードされた最適化されたサンプルモデルが使用されます。
inputs.pt h: テストデータ。 この例では、ステップ1でダウンロードされたテストデータが使用されます。
次のような情報がシステムに表示される場合、モデルは実行中です。
finished computation at Wed Jan 27 20:03:38 2021 elapsed time: 0.513882s avg latency: 25.6941ms ok