✅ 概要
ONNX(Open Neural Network Exchange)は、さまざまな機械学習フレームワークのモデルを共通フォーマットで保存・再利用できる仕組みです。
本記事では以下をステップごとに実現します:
- Pythonで機械学習モデルを学習・ONNX形式で出力(IRバージョン対応済み)
- macOS上でC++ + ONNX Runtimeを使い爆速で推論実行
- REST不要・Python不要・エッジ端末にも展開可能な構成
🔧 STEP1:Pythonでモデル学習 → ONNX形式に変換
ライブラリインストール
pip install scikit-learn skl2onnx onnx
学習&ONNX出力コード(※ IRバージョン対応)
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
# データ準備&学習
X, y = load_iris(return_X_y=True)
model = RandomForestClassifier()
model.fit(X, y)
# ONNX変換(互換性を保つために opset 11 を指定)
initial_type = [('input', FloatTensorType([None, 4]))]
onnx_model = convert_sklearn(model, initial_types=initial_type, target_opset=11)
# 保存
with open("rf_model.onnx", "wb") as f:
f.write(onnx_model.SerializeToString())
🧰 STEP2:ONNX Runtime (macOS用) を導入
最新安定版(v1.17.1)を取得
curl -L -o onnxruntime-osx-universal2.tgz \
https://github.com/microsoft/onnxruntime/releases/download/v1.17.1/onnxruntime-osx-universal2-1.17.1.tgz
tar -xvzf onnxruntime-osx-universal2.tgz
展開後のディレクトリは onnxruntime-osx-universal2-1.17.1
です。
⚙️ STEP3:C++でONNXモデルを実行
C++コード(main.cpp)
#include <iostream>
#include <vector>
#include <onnxruntime_cxx_api.h>
int main() {
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "ONNXExample");
Ort::SessionOptions session_options;
session_options.SetIntraOpNumThreads(1);
// モデル読み込み
const char* model_path = "rf_model.onnx";
Ort::Session session(env, model_path, session_options);
Ort::AllocatorWithDefaultOptions allocator;
Ort::AllocatedStringPtr input_name = session.GetInputNameAllocated(0, allocator);
Ort::AllocatedStringPtr output_name = session.GetOutputNameAllocated(0, allocator);
std::vector<float> input_data = {5.1f, 3.5f, 1.4f, 0.2f};
std::vector<int64_t> input_shape = {1, 4};
Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
memory_info, input_data.data(), input_data.size(),
input_shape.data(), input_shape.size()
);
std::vector<const char*> input_names = {input_name.get()};
std::vector<const char*> output_names = {output_name.get()};
auto output_tensors = session.Run(Ort::RunOptions{nullptr},
input_names.data(), &input_tensor, 1,
output_names.data(), 1);
float* result = output_tensors.front().GetTensorMutableData<float>();
std::cout << "予測クラスID: " << static_cast<int>(result[0]) << std::endl;
return 0;
}
🔨 STEP4:ビルド&実行(macOS)
コンパイル
g++ -std=c++17 main.cpp -o onnx_infer \
-I./onnxruntime-osx-universal2-1.17.1/include \
-L./onnxruntime-osx-universal2-1.17.1/lib -lonnxruntime
実行(ライブラリパス指定)
export DYLD_LIBRARY_PATH=./onnxruntime-osx-universal2-1.17.1/lib:$DYLD_LIBRARY_PATH
./onnx_infer
実行結果(例)
予測クラスID: 0
Iris-setosa
に対応する予測結果が表示されます(モデルによって異なります)。
📌 トラブル回避のポイント
問題 | 解決策 |
---|---|
onnxruntime_cxx_api.h not found |
-I オプションで include を正しく指定 |
Unsupported model IR version: 10 |
Pythonで target_opset=11 を指定してONNX変換 |
dyld: Library not loaded: |
export DYLD_LIBRARY_PATH=... を忘れずに実行前に指定 |
✅ まとめ
ステップ | 内容 |
---|---|
Python | 学習+ONNX変換(互換性に配慮) |
ONNX形式 | 軽量・高互換なモデル交換形式 |
C++ | 高速・ネイティブ・REST不要な推論 |
この構成により、macOSやエッジ環境でも超高速かつ軽量なAI推論が可能になります。
参考資料