Oracle AI Database 26aiは RU23.4 の頃から、ONNXフォーマットでエクスポートされた埋め込みモデルのインポート機能を提供してきました。
本機能により、埋め込みモデルを提供する外部サービスを使わずとも、DB内でベクトル化ができます。
主にクラウドサービス等を使えない、機密情報を扱うような分野で役立てて頂ける機能です。
ただしインポート出来るモデルのサイズ上限は、これまで 1GB という制約がありました。
日本語など多言語に対応しており、かつ精度が良い埋め込みモデルについては、量子化しても 1GB に収められない傾向にあります。
そのため本機能は日本語環境において実用化が難しい印象でした。
この度26年1月にリリースされた 23.26.1 では遂に1GB制約がなくなり、高精度の多言語対応モデルやマルチモーダル対応モデルのインポートが自由にできるよう強化されました。
詳細は以下ドキュメントをご参照ください。
https://docs.oracle.com/en/database/oracle/oracle-database/26/nfcoa/onnx-support.html#GUID-104970-1
Enable Larger ONNX-Format Models
先日リリースされたLinux x86-64向けオンプレ版26ai上で本機能の動作確認をしましたので、本記事に利用の流れをまとめたいと思います。
ちなみにオンプレ版26ai (23.26.1) はADBで提供されている SELECT AI RAG も使えるようになりました。
今回の検証でインポートしたEmbeddingモデルがせっかくあるので、ついでに SELECT AI RAG もオンプレ版26aiで動作確認しました。
そちらも別途記事にまとめる予定です。
目次
- 検証環境
- 26ai EE (Linux x86-64) インストール
- OML4Pyインストール (2.1.1)
- ONNXエクスポート
- DB事前準備
- ONNXインポート
- In-Memory Sharingの有効化
検証環境
- OCI Compute上に構築した26ai EE シングル構成を利用
- Shape: VM.Standard.E5.Flex (1 OCPU、32 GB RAM)
- OS: Oracle Linux 8
- Embeddingモデル: multilingual-e5-large
環境を準備する際の留意点
- ONNXエクスポートする際にそれなりのメモリが必要 (12GBでは不足した、24GBだと余裕あり)
- 26/2/27時点の OML4Py は最新の 2.1.1 含めOL8以下をサポート (OL9は不可)
- 26aiはOL9をサポートしており、乖離があるため注意
- 26ai freeはメモリの制限 (SGA+PGAで2GB) によりEmbeddingモデル
multilingual-e5-largeのONNXをインポートできず- EXECUTE DBMS_VECTOR.LOAD_ONNX_MODEL の際に以下エラーが発生
- ORA-04036: PGA memory used by the instance or PDB exceeds PGA_AGGREGATE_LIMIT.
- pga_aggregate_limit の不足で ORA-54466 発生?
- ORA-54466 ONNX操作に対するサイズ2235564032のMGAセグメントの割当てに失敗しました。
- VMのメモリを 24GB から 32GB に増やして、DBメモリも以下の通り拡張することで回避
alter system set pga_aggregate_limit=18G scope=spfile;
alter system set pga_aggregate_target=9G scope=spfile;
alter system set sga_max_size=10G scope=spfile;
alter system set sga_target=10G scope=spfile;
26ai EE (Linux x86-64) インストール
以下記事を参考に構築します。
(RAC向け手順ですが、GI関連の手順をSkipすればシングル構成で構築できます。)
OML4Pyインストール (2.1.1)
OSパッケージのインストール (root)
sudo su -
## 不足パッケージの確認
rpm -qa perl-Env
rpm -qa libffi-devel
rpm -qa openssl
rpm -qa openssl-devel
rpm -qa tk-devel
rpm -qa xz-devel
rpm -qa zlib-devel
rpm -qa bzip2-devel
rpm -qa readline-devel
rpm -qa libuuid-devel
rpm -qa ncurses-devel
## 不足分をインストール (以下はコマンド例)
dnf install perl-Env libffi-devel tk-devel bzip2-devel readline-devel libuuid-devel ncurses-devel
uvインストール (oracle)
(今回はPython仮想環境の管理にuvを使います。)
curl -LsSf https://astral.sh/uv/install.sh | sh
Python仮想環境作成 (oracle)
## 新しく仮想環境を作成
uv init lonnx -p 3.13.5
cd lonnx
## 仮想環境の初期化
uv venv
## lonnx仮想環境のアクティベート
source .venv/bin/activate
Pythonパッケージをインストール (oracle)
## requirementsl.txtを作成
vim requirements.txt
## 以下を追記
pandas==2.2.3
setuptools==80.8.0
scipy==1.14.1
matplotlib==3.10.0
oracledb==3.3.0
scikit-learn==1.6.1
numpy==2.1.0
pyarrow==19.0.0
onnxruntime==1.20.0
onnxruntime-extensions==0.14.0
onnx==1.18.0
torch==2.9.0
transformers==4.56.1
sentencepiece==0.2.1
## Pythonパッケージをインストール
uv pip install --upgrade -r requirements.txt --only-binary=:all:
uv add pip
OML4Pyを以下よりダウンロード (Oracleアカウントが必要)
https://www.oracle.com/database/technologies/oml4py-downloads.html
OML4Pyインストール (oracle)
mkdir oml4py
cd oml4py
unzip V1048628-01.zip
perl -Iclient client/client.pl
ONNXエクスポート
以下マニュアルを参考にONNXファイルをエクスポートします。
https://docs.oracle.com/en/database/oracle/machine-learning/oml4py/2-23ai/mlpug/support-large-onnx-format-model-support.html#GUID-F870A7AB-1B70-46D5-9D13-EA0FD913C3E6
from oml.utils import ONNXPipeline,ONNXPipelineConfig
config = ONNXPipelineConfig.from_template("text", max_seq_length=512, use_external_data=True)
pipeline = ONNXPipeline("intfloat/multilingual-e5-large", config)
pipeline.export2db("multilingual")
出力されたファイルを確認します。
$ ls -l
合計 4376952
-rw-r--r-- 1 oracle oinstall 5565702 2月 22 18:21 multilingual.onnx
-rw-r--r-- 1 oracle oinstall 2240996961 2月 22 18:22 multilingual.zip
-rw-r--r-- 1 oracle oinstall 993251328 2月 22 18:21 multilingual_0.data
-rw-r--r-- 1 oracle oinstall 218103808 2月 22 18:21 multilingual_1.data
-rw-r--r-- 1 oracle oinstall 67207 2月 22 18:21 multilingual_external_data.json
-rw-r--r-- 1 oracle oinstall 1024008192 2月 22 18:21 multilingual_largeTensor_0.data
各ファイルの役割は以下マニュアルに記載されています。
A .onnx file that holds the ONNX model referencing external data.
One or more .dat files containing raw tensor data values.
A single .json file describing the metadata of the external initializers. This JSON file includes the name, shape, offset, type, and size for each initializer.
DB事前準備
エクスポートされたONNXファイルをOracle AI DB 26aiにインポートします。
検証用DBユーザ作成
GRANT DB_DEVELOPER_ROLE TO lonnx identified by your_password;
GRANT CREATE MINING MODEL TO lonnx;
ALTER USER lonnx QUOTA UNLIMITED ON USERS;
ONNX用のディレクトリオブジェクト作成
CREATE OR REPLACE DIRECTORY onnx_dump AS 'your_path_to_onnx';
GRANT READ ON DIRECTORY onnx_dump TO lonnx;
GRANT WRITE ON DIRECTORY onnx_dump TO lonnx;
ONNXインポート
ONNXインポート実行
EXECUTE DBMS_VECTOR.LOAD_ONNX_MODEL( 'onnx_dump', 'multilingual.onnx', 'doc_model', JSON('{"function" : "embedding", "embeddingOutput" : "embedding", "input": {"input": ["DATA"]}}'));
インポートされたモデルを確認
set linesize 1000
set pagesize 1000
col MODEL_NAME for a20
col MINING_FUNCTION for a20
col ALGORITHM for a20
col ALGORITHM_TYPE for a20
SELECT MODEL_NAME, MINING_FUNCTION, ALGORITHM, ALGORITHM_TYPE, round(MODEL_SIZE/1024/1024) MB FROM user_mining_models;
MODEL_NAME MINING_FUNCTION ALGORITHM ALGORITHM_TYPE MB
-------------------- -------------------- -------------------- -------------------- ----------
DOC_MODEL EMBEDDING ONNX NATIVE 3289
ベクトル化できるか簡単に動作確認します。
SET ECHO ON
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 10000
SET LONG 10000
SELECT TO_VECTOR(VECTOR_EMBEDDING(doc_model USING 'hello' as data)) AS embedding;
EMBEDDING
--------------------------------------------------------------------------------
[2.22402979E-002,-4.5670867E-003,-1.39809772E-002,-5.86821362E-002,1.36979893E-0
02,-3.59046906E-002,-1.66482385E-002,3.06356922E-002,4.58771065E-002,-3.72102596
E-002,2.79148389E-002,1.4809153E-002,-4.95531522E-002,-4.62263748E-002,-4.963218
...(以下略)...
精度はEmbeddingモデルの選択に依存しますが、今回選んだ multilingual-e5-large によるベクトル検索の精度はそれなりに良さそうでした。
その辺りは別途オンプレ26ai向けSELECT AI RAGの検証記事で触れたいと思います。
In-Memory Sharingの有効化
サイズの大きいONNXを利用する際のメモリ効率を改善するため、In-Memory Sharingという機能が提供されています。
インポートしたEmbeddingモデルをGlobal Memoryに保持し、異なるセッション間で共有できるようにします。
逆に言うと、In-Memory Sharingを使わない限りセッション単位でONNX形式のEmbeddingモデルをメモリ上にロードする、という動作に読み取れます。。
(上記は実際に動作確認した訳ではありません。)
という訳でIn-Memory Sharingを有効化してみます。
External InitializerのIn-Memory Sharingで ORA-54484 発生
再現させる条件が分かっていないですが、以降の手順の初回実行時に ORA-54484 が発生しました。
ORA-54484: モデルのINMEMORY対応の設定に失敗しました: 十分なメモリーがありません: モデル・サイズ(3443583464バイト)がINMEMORY対応モデルの割当て済メモリー・サイズ(2576980377バイト)を超えています。
https://docs.oracle.com/error-help/db/ora-54484/
-- extensions initializerが必要なモデルの確認
SELECT model_name, EXTERNAL_DATA FROM all_mining_models;
MODEL_NAME EXT
-------------------- ---
DOC_MODEL YES
-- in-memory sharingの有効化
EXECUTE DBMS_DATA_MINING.INMEMORY_ONNX_MODEL('doc_model');
-- メモリ利用状況を確認 (sysかsystemで実行)
set linesize 1000
set pagesize 1000
col OWNER for a20
col NAME for a20
SELECT * FROM V$IM_ONNX_MODEL WHERE NAME = 'DOC_MODEL';
OWNER NAME SLOT# POPULATE_STAT METADATA_SIZE INITIALIZER_SIZE PREPACKED_SIZE PIN_COUNT CON_ID
-------------------- -------------------- ---------- ------------- ------------- ---------------- -------------- ---------- ----------
LONNX DOC_MODEL 0 ENABLED 227176 2235363328 1207992960 0 3
-- 動作確認
SQL> SET ECHO ON
SQL> SET FEEDBACK 1
SQL> SET NUMWIDTH 10
SQL> SET LINESIZE 80
SQL> SET TRIMSPOOL ON
SQL> SET TAB OFF
SQL> SET PAGESIZE 10000
SQL> SET LONG 10000
SQL> SELECT TO_VECTOR(VECTOR_EMBEDDING(doc_model USING 'hello' as data)) AS embedding;
EMBEDDING
--------------------------------------------------------------------------------
[2.22402979E-002,-4.5670867E-003,-1.39809772E-002,-5.86821362E-002,1.36979893E-0
02,-3.59046906E-002,-1.66482385E-002,3.06356922E-002,4.58771065E-002,-3.72102596
E-002,2.79148389E-002,1.4809153E-002,-4.95531522E-002,-4.62263748E-002,-4.963218
...(以下略)...
必要なくなったらIn-Memory Sharingを無効化してメモリを解放します。
-- in-memory sharingの無効化
EXECUTE DBMS_DATA_MINING.INMEMORY_ONNX_MODEL('doc_model', enable => FALSE);
-- メモリ利用状況を確認 (sysかsystemで実行)
set linesize 1000
set pagesize 1000
col OWNER for a20
col NAME for a20
SELECT * FROM V$IM_ONNX_MODEL WHERE NAME = 'DOC_MODEL';
レコードが選択されませんでした。
以上、サイズの大きいONNXフォーマット・モデルのインポート機能でした。
ベクトル検索を使いたい一方で、インターネット上の外部サービスの利用が難しいケースなどで是非ご活用ください!