2025年8月5日火曜日

OML4Pyで作成したモデルをONNX形式でエクスポートし別の環境にOML4SQLでインポートする

OML4SQLでサポートされていないアルゴリズムでもOML4Pyで作成できるモデルであれば、ONNX形式でエクスポートし異なる環境にOML4SQLでインポートすることにより、トレーニングされたモデルを利用できます。

本記事では、オラクルの公式ブログの以下の記事に沿ってXGBoostのモデルをONNX形式でエクスポートして、異なる環境にインポートして動作確認を行います。

Deploy an XGBoost Model using OML Services

ONNXモデルを作成する環境は、以前の記事「OML4Py ServerとOML4Py ClientをOracle Database Freeのコンテナにインストールする」の手順で作成します。OML4Pyを利用できるのはx86_64のアーキテクチャに限定されています。今回の作業ではOML4Pyでデータベースに接続しないため、データベース・ユーザーの作成は不要です。

OML4Pyが構成されたコンテナoml4py-dbが作成済みとします。

コンテナoml4py-dbに接続します。

podman exec -it oml4py-db bash

% podman exec -it oml4py-db bash

bash-4.4$ 


OML4Pyのクライアントを利用するように、作業環境を設定します。

export LANG=en_US.UTF8
export PYTHONHOME=$HOME/python
export PATH=$PYTHONHOME/bin:$PATH
export LD_LIBRARY_PATH=$PYTHONHOME/lib:$LD_LIBRARY_PATH
unset PYTHONPATH


bash-4.4$ export LANG=en_US.UTF8

bash-4.4$ export PYTHONHOME=$HOME/python

bash-4.4$ export PATH=$PYTHONHOME/bin:$PATH

bash-4.4$ export LD_LIBRARY_PATH=$PYTHONHOME/lib:$LD_LIBRARY_PATH

bash-4.4$ unset PYTHONPATH

bash-4.4$ 


これからの作業に使用するPythonのパッケージをインストールします。

python3 -m pip install xgboost onnxmltools skl2onnx --user

bash-4.4$ python3 -m pip install xgboost onnxmltools skl2onnx --user

Collecting xgboost

  Downloading xgboost-3.0.3-py3-none-manylinux_2_28_x86_64.whl.metadata (2.1 kB)

Collecting onnxmltools

  Downloading onnxmltools-1.14.0-py2.py3-none-any.whl.metadata (8.1 kB)

Collecting skl2onnx

  Downloading skl2onnx-1.19.1-py3-none-any.whl.metadata (3.8 kB)

Requirement already satisfied: numpy in ./python/lib/python3.12/site-packages (from xgboost) (2.2.0)

Collecting nvidia-nccl-cu12 (from xgboost)

  Downloading nvidia_nccl_cu12-2.27.7-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.0 kB)

Requirement already satisfied: scipy in ./python/lib/python3.12/site-packages (from xgboost) (1.14.0)

Requirement already satisfied: onnx in ./python/lib/python3.12/site-packages (from onnxmltools) (1.18.0)

Requirement already satisfied: scikit-learn>=1.1 in ./python/lib/python3.12/site-packages (from skl2onnx) (1.5.1)

Requirement already satisfied: protobuf>=4.25.1 in ./python/lib/python3.12/site-packages (from onnx->onnxmltools) (6.31.1)

Requirement already satisfied: typing_extensions>=4.7.1 in ./python/lib/python3.12/site-packages (from onnx->onnxmltools) (4.14.1)

Requirement already satisfied: joblib>=1.2.0 in ./python/lib/python3.12/site-packages (from scikit-learn>=1.1->skl2onnx) (1.5.1)

Requirement already satisfied: threadpoolctl>=3.1.0 in ./python/lib/python3.12/site-packages (from scikit-learn>=1.1->skl2onnx) (3.6.0)

Downloading xgboost-3.0.3-py3-none-manylinux_2_28_x86_64.whl (253.8 MB)

   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 253.8/253.8 MB 3.6 MB/s  0:01:04

Downloading onnxmltools-1.14.0-py2.py3-none-any.whl (352 kB)

Downloading skl2onnx-1.19.1-py3-none-any.whl (315 kB)

Downloading nvidia_nccl_cu12-2.27.7-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (322.5 MB)

   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 322.5/322.5 MB 4.0 MB/s  0:01:19

Installing collected packages: nvidia-nccl-cu12, xgboost, onnxmltools, skl2onnx

Successfully installed nvidia-nccl-cu12-2.27.7 onnxmltools-1.14.0 skl2onnx-1.19.1 xgboost-3.0.3

bash-4.4$ 


XGBoostを使ったモデルの作成からONNX形式でのエクスポートまでを行なうスクリプトを、housing-onnx-export.pyとして作成します。スクリプトが行なっている処理の詳細については、記事「Deploy an XGBoost Model using OML Services」を参照してください。


スクリプトhousing-onnx-export.pyを実行します。Predictionの出力は別環境にONNXモデルをインポートした後に、動作確認のために参照します。

python3 housing-onnx-export.py

bash-4.4$ python3 housing-onnx-export.py 

XGBRegressor(alpha=10, base_score=None, booster=None, callbacks=None,

             colsample_bylevel=None, colsample_bynode=None,

             colsample_bytree=0.3, device=None, early_stopping_rounds=None,

             enable_categorical=False, eval_metric=None, feature_types=None,

             feature_weights=None, gamma=None, grow_policy=None,

             importance_type=None, interaction_constraints=None,

             learning_rate=0.1, max_bin=None, max_cat_threshold=None,

             max_cat_to_onehot=None, max_delta_step=None, max_depth=5,

             max_leaves=None, min_child_weight=None, missing=nan,

             monotone_constraints=None, multi_strategy=None, n_estimators=10,

             n_jobs=None, ...)

Prediction:

 [[1.9012693]

 [1.9086367]

 [1.7791952]

 [1.7663374]

 [2.3076754]

 [2.4856815]

 [2.0629597]

 [2.0905418]

 [2.2301753]

 [2.2447908]]

Local predictions are: [1.9012694 1.9086368 1.7791953 1.7663375 2.3076756 2.4856815 2.0629597

 2.090542  2.2301757 2.2447908]

bash-4.4$ 


ONNX形式で出力されたモデルとメタデータを含んだZIPファイルが、~/onnx_test/onnx_xgboost.model.zipとして出力されます。OML4Pyの環境が手順に沿って作成されている場合は、~/work以下がホスト・コンピュータのディレクトリにマウントされています。ファイルをコンテナから取り出すために、onnx_xgboost.model.zip~/work以下にコピーします。

cp ~/onnx_test/onnx_xgboost.model.zip ~/work/

bash-4.4$ cp ~/onnx_test/onnx_xgboost.model.zip ~/work/

bash-4.4$ 


以上でのONNX形式でのモデルのエクスポートは完了です。

ZIPファイルonnx_xgboost.model.zipをインポートする環境にコピーし、ZIPを解凍します。

metadata.jsonxgboost_housing.onnxが作成されます。

onnx_xgboost.model % ls

metadata.json xgboost_housing.onnx

onnx_xgboost.model % 


ONNXモデルをインポートした後に、動作確認に使用するデータを準備します。

scikit-learnとpandasをインストールしたPythonの環境で、以下のスクリプトを実行します。ONNXモデルをエクスポートした環境でPredictionの出力に使用されたテスト・データが、X_test.csvに出力されます。このコードはOpenAIのGPT-4oに書いてもらいました。


これ以降はOracle APEXを使って作業を進めます。

最初にX_test.csvをデータベースにロードします。

SQLワークショップデータ・ワークショップを開き、データのロードを実行します。


ロードするファイルとしてX_test.csv選択します。


ロード先新規表表名HOUSINGとします。列見出し最初の行にヘッダーが含まれるチェックします。

単純なCSVファイルなので、その他は適切に自動認識されています。

以上でデータのロードをクリックします。


表HOUSINGに6192行のデータがロードされます。

これでテスト・データのロードは完了しました。


ONNXモデルをインポートするAPEXアプリケーションを作成します。

空のAPEXアプリケーションとしてImport ONNX Modelを作成し、インポートする機能をホーム・ページに実装します。

モデル名を設定するページ・アイテムをP1_MODEL_NAMEとして作成します。タイプテキスト・フィールドラベルModel Nameです。


ONNXのモデル・ファイルを選択するページ・アイテムをP1_FILEとして作成します。タイプファイルのアップロードラベルONNX Model Fileとします。

ストレージタイプ表APEX_APPLICATION_TEMP_FILESファイルをパージするタイミングリクエストの終わりとします。セッション・ステートストレージリクエストごと(メモリーのみ)を設定します。


ONNXモデルのインポート時に指定するJSON形式のメタデータを記述するページ・アイテムとして、P1_METADATAを作成します。タイプテキスト領域ラベルMetadataとします。


ONNXモデルのインポートを実行するボタンIMPORTを作成します。動作アクションはデフォルトのページの送信です。


ボタンIMPORTをクリックしたときに実行されるプロセスImportを作成します。実行されるコードとして、ソースPL/SQLコードに以下を記述します。


サーバー側の条件ボタン押下時IMPORTを設定します。


以上で準備は完了です。

ONNXモデルをデータベースにインポートし、動作確認を行います。

作成したアプリケーションを実行し、ホーム・ページを開きます。

Model NameXGBOOST_HOUSINGとし、ONNX Model Filexgboost_housing.onnxを選択します。

Metadataに以下を記述します。
{
  "function": "regression",
  "input": { "float_input": ["MedInc","HouseAge","AveRooms","AveBedrms","Population","AveOccup","Latitude","Longitude"]}
}
ボタンImportをクリックします。


エラーが発生しなければ、ONNXモデルのインポートは成功しています。

SQLワークショップのSQLコマンドを開き、動作確認を行います。

最初にインポートされたモデルを確認します。

select * from user_mining_models where model_name = 'XGBOOST_HOUSING'

MINING_FUNCTIONREGRESSIONALGORITHMONNXとなっていることが確認できます。


表HOUSINGのテスト・データを対象に、以下のSELECT文で予測を実行します。
select 
    to_char(prediction(XGBOOST_HOUSING using * ), '99.9999999') prediction
from housing
order by id asc
fetch first 10 rows only

モデルを作成したときに出力した予測と、上記の予測が一致することを確認します。

今回の記事は以上になります。

簡単なアプリケーションですが、今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/import-onnx-model.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。