使用例 - 前処理ステップを IR に統合して保存#
前のセクションでは、前処理ステップとレイアウト API の概要について説明しました。
多くのアプリケーションでは、モデルの読み取り/読み込み時間を最小限に抑えることも重要です。したがって、ov::runtime::Core::read_model
の後、アプリケーションの起動時に毎回前処理ステップの統合を実行するのは不便に思えるかもしれません。この場合、前処理ステップと後処理ステップを追加した後、新しい実行モデルを OpenVINO 中間表現 (OpenVINO IR、.xml 形式) に保存すると便利です。
利用可能な前処理ステップのほとんどは、ovc
を使用してコマンドライン・オプションからも実行できます。コマンドライン・オプションの詳細については、モデル変換を参照してください。
サンプルコード - 前処理を含むモデルを OpenVINO IR に保存#
次の例を参照してください:
元の ONNX モデルが、
{1, 3, 224, 224}
形状、RGB
チャネル順序、および平均/スケール値が適用された 1 つのfloat32
入力を受け取る例を考えてみます。アプリケーションは、非固定サイズの
BGR
画像バッファーと入力画像を 2 つのバッチとして提供します。
以下は、この場合にモデル準備スクリプトに適用できるモデル変換コードです。
インクルード / インポート
from openvino.preprocess import PrePostProcessor, ColorFormat, ResizeAlgorithm
from openvino import Core, Layout, Type, set_batch
from openvino import serialize
#include <openvino/runtime/core.hpp>
#include <openvino/core/preprocess/pre_post_process.hpp>
#include <openvino/pass/serialize.hpp>
OpenVINO IR コードへの前処理と保存。
# ======== ステップ 0: オリジナルモデルをリード =========
core = Core()
model = core.read_model(model=model_path)
# ======== ステップ 1: 前処理 ================
ppp = PrePostProcessor(model)
# 希望するアプリケーションの入力形式のセクションを宣言
ppp.input().tensor() \
.set_element_type(Type.u8) \
.set_spatial_dynamic_shape() \
.set_layout(Layout('NHWC')) \
.set_color_format(ColorFormat.BGR)
# 実際のモデルレイアウトを指定
ppp.input().model().set_layout(Layout('NCHW'))
# 明示的な前処理手順: レイアウト変換は最後のステップとして自動的に行われます
ppp.input().preprocess() \
.convert_element_type() \
.convert_color(ColorFormat.RGB) \
.resize(ResizeAlgorithm.RESIZE_LINEAR) \
.mean([123.675, 116.28, 103.53]) \ .scale([58.624, 57.12, 57.375])
# Dump preprocessor
print(f'Dump preprocessor: {ppp}')
model = ppp.build()
# ======== ステップ 2: バッチサイズを変更 ================
# この例では、スループットを向上させるためにバッチサイズも変更
set_batch(model, 2)
# ======== ステップ 3: モデルを保存 ================
serialize(model, serialized_model_path)
// ======== ステップ 0: オリジナルモデルをリード =========
ov::Core core;
std::shared_ptr<ov::Model> model = core.read_model("/path/to/some_model.onnx");
// ======== ステップ 1: 前処理 ================
ov::preprocess::PrePostProcessor prep(model);
// 希望するアプリケーションの入力形式のセクションを宣言
prep.input().tensor()
.set_element_type(ov::element::u8)
.set_layout("NHWC")
.set_color_format(ov::preprocess::ColorFormat::BGR)
.set_spatial_dynamic_shape();
// 実際のモデルレイアウトを指定
prep.input().model()
.set_layout("NCHW");
// 明示的な前処理手順: レイアウト変換は最後のステップとして自動的に行われます
prep.input().preprocess()
.convert_element_type()
.convert_color(ov::preprocess::ColorFormat::RGB)
.resize(ov::preprocess::ResizeAlgorithm::RESIZE_LINEAR)
.mean({123.675f, 116.28f, 103.53f}) // 色変換後均等に減算
.scale({58.624f, 57.12f, 57.375f});
// Dump preprocessor
std::cout << "Preprocessor: " << prep << std::endl;
model = prep.build();
// ======== ステップ 2: バッチサイズを変更 ================
// この例では、スループットを向上させるためにバッチサイズも変更
ov::set_batch(model, 2);
// ======== ステップ 3: モデルを保存 ================
std::string xml = "/path/to/some_model_saved.xml";
std::string bin = "/path/to/some_model_saved.bin";
ov::serialize(model, xml, bin);
アプリケーション・コード - モデルをターゲットデバイスにロード#
次に、アプリケーション・コードは保存されたファイルをロードし、前処理を停止できます。この場合、モデルのキャッシュを有効にして、キャッシュされたモデルが使用可能なときにロード時間を最小限に抑えます。
core = Core()
core.set_property({props.cache_dir(): path_to_cache_dir})
# 前処理が不要である場合、モデルをターゲットデバイスに直接ロードできます
# キャッシュされたモデルを利用すれば、元のモデルを読み込む時間も節約できます
compiled_model = core.compile_model(serialized_model_path, 'CPU')
ov::Core core;
core.set_property(ov::cache_dir("/path/to/cache/dir"));
// 前処理が不要である場合、モデルをターゲットデバイスに直接ロードできます
// キャッシュされたモデルを利用すれば、元のモデルを読み込む時間も節約できます
ov::CompiledModel compiled_model = core.compile_model("/path/to/some_model_saved.xml", "CPU");
関連情報#
ov::preprocess::PrePostProcessor C++ クラスのドキュメント
ov::pass::Serialize - モデルを XML/BIN にシリアル化するために渡す
ov::set_batch
- 特定のモデルのバッチ次元を更新