OpenVINO™ をアプリケーションと統合

ここで示す手順に従って、アプリケーションに典型的な OpenVINO™ ランタイム推論パイプラインを実装できます。続行する前に、OpenVINO ランタイムがインストールされていることを確認し、環境変数を設定してください (Linux* の場合は <INSTALL_DIR>/setupvars.sh を、Windows* の場合は setupvars.bat を実行します。そうしないと、OpenVINO_DIR 変数が find_package 呼び出しを渡すように構成されません)。

../../_images/IMPLEMENT_PIPELINE_with_API_C.svg

ステップ 1. OpenVINO ランタイムコアの作成

OpenVINO™ ランタイムで使用する次のファイルをインクルードします。

import openvino as ov
#include <openvino/openvino.hpp>
#include <openvino/c/openvino.h>

次のコードを使用して OpenVINO™ コアを作成し、利用可能なデバイスを管理し、モデル・オブジェクトを読み取ります。

core = ov.Core()
ov::Core core;
ov_core_t* core = NULL;
ov_core_create(&core);

ステップ 2. モデルをコンパイル

ov::CompiledModel クラスは、デバイス固有のコンパイル済みモデルを表します。ov::CompiledModel を使用すると、テンソル名またはインデックスによって情報の入力または出力ポートを取得できます。このアプローチは、ほとんどのフレームワークに適合しています。

ov::Core::compile_model() を使用して、特定のデバイス向けモデルをコンパイルします。

compiled_model = core.compile_model("model.xml", "AUTO")
compiled_model = core.compile_model("model.onnx", "AUTO")
compiled_model = core.compile_model("model.pdmodel", "AUTO")
compiled_model = core.compile_model("model.pb", "AUTO")
compiled_model = core.compile_model("model.tflite", "AUTO")
def create_model():
    # This example shows how to create ov::Function
    #
    # To construct a model, please follow 
    # https://docs.openvino.ai/latest/openvino_docs_OV_UG_Model_Representation.html
    data = ov.opset8.parameter([3, 1, 2], ov.Type.f32)
    res = ov.opset8.result(data)
    return ov.Model([res], [data], "model")

model = create_model()
compiled_model = core.compile_model(model, "AUTO")
ov::CompiledModel compiled_model = core.compile_model("model.xml", "AUTO");
ov::CompiledModel compiled_model = core.compile_model("model.onnx", "AUTO");
ov::CompiledModel compiled_model = core.compile_model("model.pdmodel", "AUTO");
ov::CompiledModel compiled_model = core.compile_model("model.pb", "AUTO");
ov::CompiledModel compiled_model = core.compile_model("model.tflite", "AUTO");
auto create_model = []() {
    std::shared_ptr<ov::Model> model;
    // To construct a model, please follow
    // https://docs.openvino.ai/2024/openvino-workflow/running-inference/integrate-openvino-with-your-application/model-representation.html
    return model;
};
std::shared_ptr<ov::Model> model = create_model();
compiled_model = core.compile_model(model, "AUTO");
ov_compiled_model_t* compiled_model = NULL;
ov_core_compile_model_from_file(core, "model.xml", "AUTO", 0, &compiled_model);
ov_compiled_model_t* compiled_model = NULL;
ov_core_compile_model_from_file(core, "model.onnx", "AUTO", 0, &compiled_model);
ov_compiled_model_t* compiled_model = NULL;
ov_core_compile_model_from_file(core, "model.pdmodel", "AUTO", 0, &compiled_model);
ov_compiled_model_t* compiled_model = NULL;
ov_core_compile_model_from_file(core, "model.pb", "AUTO", 0, &compiled_model);
ov_compiled_model_t* compiled_model = NULL;
ov_core_compile_model_from_file(core, "model.tflite", "AUTO", 0, &compiled_model);
// Construct a model
ov_model_t* model = NULL;
ov_core_read_model(core, "model.xml", NULL, &model);
ov_compiled_model_t* compiled_model = NULL;
ov_core_compile_model(core, model, "AUTO", 0, &compiled_model);

ov::Model オブジェクトは、OpenVINO™ ランタイム内のモデルを表します。詳細については、OpenVINO™ モデルの表現ご覧ください。

上記のコードは、モデル・オブジェクトから単一ハードウェア・デバイスに関連付けられたコンパイル済みモデルを作成します。必要な数のコンパイル済みモデルを作成し、それらを同時に使用することができます (ハードウェアの上限まで)。デバイス構成を変更する方法については、デバイス・プロパティーの照会を参照してください。

ステップ 3. 推論要求の作成

ov::InferRequest クラスは、OpenVINO™ ランタイムでのモデル推論のメソッドを提供します。次のコードを使用して推論要求を作成します (詳細については、InferRequest のドキュメントを参照してください)。

infer_request = compiled_model.create_infer_request()
ov::InferRequest infer_request = compiled_model.create_infer_request();
ov_infer_request_t* infer_request = NULL;
ov_compiled_model_create_infer_request(compiled_model, &infer_request);

ステップ 4. 入力をセット

外部メモリーを使用して ov::Tensor を作成し、ov::InferRequest::set_input_tensor メソッドを使用してこのテンソルをデバイスに配置できます。

# Create tensor from external memory
input_tensor = ov.Tensor(array=memory, shared_memory=True)
# Set input tensor for model with one input
infer_request.set_input_tensor(input_tensor)
// Get input port for model with one input
auto input_port = compiled_model.input();
// Create tensor from external memory
ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), memory_ptr);
// Set input tensor for model with one input
infer_request.set_input_tensor(input_tensor);
// Get input port for model with one input
ov_output_const_port_t* input_port = NULL;
ov_model_const_input(model, &input_port);
// Get the input shape from input port
ov_shape_t input_shape;
ov_const_port_get_shape(input_port, &input_shape);
// Get the the type of input
ov_element_type_e input_type;
ov_port_get_element_type(input_port, &input_type);
// Create tensor from external memory
ov_tensor_t* tensor = NULL;
ov_tensor_create_from_host_ptr(input_type, input_shape, memory_ptr, &tensor);
// Set input tensor for model with one input
ov_infer_request_set_input_tensor(infer_request, tensor);

テキストデータをモデル入力とする方法については、追加資料を参照してください。

ステップ 5. 推論を開始

OpenVINO™ ランタイムは、同期モードまたは非同期モードの推論をサポートします。非同期 API を使用すると、アプリケーションの全体的なフレームレートを向上させることができます。推論の完了を待機する代わりに、アクセラレーターがビジー状態でもアプリはホスト上で動作し続けることができます。ov::InferRequest::start_async を使用して非同期モードでモデル推論を開始し、ov::InferRequest::wait を呼び出して推論結果を待機することができます。

infer_request.start_async()
infer_request.wait()
infer_request.start_async();
infer_request.wait();
ov_infer_request_start_async(infer_request);
ov_infer_request_wait(infer_request);

このセクションでは、単純なパイプラインを示します。推論を実行する他の方法の詳細については、推論の実行をお読みください。

ステップ 6. 推論結果の処理

出力テンソルを調べて、推論結果を処理します。

# Get output tensor for model with one output
output = infer_request.get_output_tensor()
output_buffer = output.data
# output_buffer[] - accessing output tensor data
// Get output tensor by tensor name
auto output = infer_request.get_tensor("tensor_name");
const float *output_buffer = output.data<const float>();
// output_buffer[] - accessing output tensor data
ov_tensor_t* output_tensor = NULL;
// Get output tensor by tensor index
ov_infer_request_get_output_tensor_by_index(infer_request, 0, &output_tensor);

テキストデータをモデル出力とする方法については、追加資料を参照してください。

ステップ 7. 割り当てられたオブジェクトを解放 (C のみ)

メモリーリークを避けるために、C API で開発されたアプリケーションは、割り当てられたオブジェクトを順に解放する必要があります。

ov_shape_free(&input_shape);
ov_tensor_free(output_tensor);
ov_output_const_port_free(input_port);
ov_tensor_free(tensor);
ov_infer_request_free(infer_request);
ov_compiled_model_free(compiled_model);
ov_model_free(model);
ov_core_free(core);

関連情報