2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Oracle Autonomous AI Database に Rerank モデルを組み込んで、Rerank 処理を In-DB で行う

2
Last updated at Posted at 2026-08-28

はじめに

Oracle のデータベースは、ONNX フォーマットのモデルを取り込むことが可能です。
そのため、例えば Embedding モデルを ONNX フォーマットにエクスポートし、それをデータベースに取り込むことが出来ます。

結果として、ベクトル検索を実施する際に、外部の API を実行してテキスト データをベクトル変換する必要が無くなります。

データベースの中でベクトル化出来ることで、Rerank 処理時のクエリや候補文書を外部の Rerank API へ送信せずに済みます。

Embedding モデルをデータベースにインポートして利用する Qiita 記事は良く見るのですが、そう言えば Rerank モデルをインポートして利用する記事が無いなぁ……と思いました。

Embedding モデルを取り込む例 :

なので今回は実際に、Autonomous AI Database (ADB) に Rerank モデルを組み込んで、In-Database で Rerank 処理を行ってみたいと思います。

準備

ADB とスキーマの準備

ADB を作成します。
OCI 環境があれば簡単に作成出来ます。

次にテスト用のスキーマを作成します。
ADMIN ユーザーで下記のクエリを実行して、テスト用のスキーマを作成。
ADB のページから Database Actions を開いて、クエリを実行。

GRANT DWROLE, UNLIMITED TABLESPACE TO onnx_lab IDENTIFIED BY <パスワード>;
GRANT DB_DEVELOPER_ROLE TO onnx_lab;
GRANT CREATE MINING MODEL TO onnx_lab;
GRANT CREATE CREDENTIAL TO onnx_lab;

その後、作成したスキーマに対して REST サービスを有効化する。

image.png

次に作成したスキーマでログインして、下記のクエリを実行する。
Object Storage へアクセスして ONNX フォーマットのモデルをインポートするために必要だからです。
パラメーター値は適宜変更します。

BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL (
    credential_name   => 'OCI_CRED',
    user_ocid         => 'ocid1.user.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    tenancy_ocid      => 'ocid1.tenancy.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    private_key       => '-----BEGIN PRIVATE KEY-----
プライベート キーの値
-----END PRIVATE KEY-----',
    fingerprint       => '5d:d6:xxxxxxxxxxxx:3a'
  );
END;
/

ONNX フォーマットのモデルを作成

OML4Py Slim Client のインストール

Autonomous AI Database に ONNX フォーマットの Rerank モデルや Embedding モデルを取り込むには、モデルの作成が必要です。
作成するためには OML4Py Slim Client が必要なので、それを準備します。

こちらのサイトを見ると、Python 3.13.5 が必要とのこと。

私の WSL2 (Ubuntu) 環境にて、下記のコマンドを実施。

事前に uv はインストール済み。

mkdir oml4py-lab
cd oml4py-lab

uv python install 3.13.5
uv venv --python 3.13.5 .venv
source .venv/bin/activate

python --version を実行。
問題なくインストール出来ていることを確認。

image.png

下記のサイトから oml4py-client-linux-x86_64-2.1.1.zip を DL し、Ubuntu 環境へコピー。

unzip oml4py-client-linux-x86_64-2.1.1.zip を実行して解凍。

Oracle が OML4Py 2.1.1 Slim Client 用として指定している PyPI 側のバージョンはこちら。
こちらを実行して、必要なパッケージをインストール出来るようにする。

cat > requirements-slim.txt <<'EOF'
numpy==2.1.0
pillow==10.4.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
EOF

下記コマンドを実行して、必要なパッケージをインストール。

uv pip install \
  --torch-backend cpu \
  -r requirements-slim.txt

OML4Py Slim Client をインストールします。

uv pip install \
  --no-deps \
  ./client/slim/oml-2.1.1-cp313-cp313-linux_x86_64.whl

インストール出来たことを確認するため、下記のコマンドを実行。
問題なく出来てそうです。

python - <<'PY'
import oml

from oml.utils import ONNXPipeline
from oml.utils import ONNXPipelineConfig
from oml.utils import MiningFunction

print("OML4Py ONNX utilities: OK")
PY

image.png

早速 Rerank モデルを ONNX フォーマットにエクスポートする処理を Python スクリプトに実装します。
下記公開情報を見ると、このように記載があります。

Pre-processing for reranking pipeline includes tokenization. The tokenizer class: transformers.models.xlm_roberta.tokenization_xlm_roberta.XLMRobertaTokenizer is supported in OML4Py 2.1 for reranking models.

XLMRobertaTokenizer の Tokenizer がサポートしているとの事なので、日本語に対応していて XLMRobertaTokenizer の Tokenizer を使っている Rerank モデルを探します。
結果、hotchpotch/japanese-reranker-cross-encoder-xsmall-v1 を使ってみようと思います。

ONNX フォーマットでエクスポートするために、下記の Python スクリプトを作成します。

Hugging Faceで公開されているPyTorch形式のモデルを、OML4PyのONNXPipelineを使って、Tokenizerを含むOracle Database向けのONNXモデルへ変換します。

from oml.utils import (
    ONNXPipeline,
    ONNXPipelineConfig,
    MiningFunction,
)

MODEL_NAME = "hotchpotch/japanese-reranker-cross-encoder-xsmall-v1"
OUTPUT_NAME = "japanese-reranker-cross-encoder-xsmall-v1"

config = ONNXPipelineConfig.from_template(
    "text",
    max_seq_length=512,
)

print(f"Loading model: {MODEL_NAME}")

pipeline = ONNXPipeline(
    MODEL_NAME,
    config=config,
    function=MiningFunction.REGRESSION,
)

print("Exporting ONNX model...")

pipeline.export2file(
    OUTPUT_NAME,
    output_dir=".",
)

print(f"Done: {OUTPUT_NAME}.onnx")

ADB へモデルをインポート

まずは、Object Storage に作成した ONNX フォーマットのモデルをアップロードします。

次に、Database Actions からテスト用に作成したスキーマにログイン。
下記のコマンドを実行して、ONNX フォーマットのモデルをインポートします。

DECLARE
  l_result CLOB;
BEGIN
  l_result := DBMS_VECTOR_DATABASE.LOAD_MODEL(
    model_name => 'RERANK_MODEL',

    url => '<Object Storage にアップロードしたモデルの URL>',

    model_params => JSON(
      '{
        "credential": "OCI_CRED",
        "metadata": {
          "function": "regression",
          "regressionOutput": "output",
          "input": {
            "first_input": ["DATA1"],
            "second_input": ["DATA2"]
          }
        }
      }'
    )
  );

  DBMS_OUTPUT.PUT_LINE(l_result);
END;
/

これで Rerank モデルの取り込み完了です。

Rerank 処理を試す

実際に下記のクエリを実行し、ハイブリッド検索結果を模擬したデータに対してRerankを実行します。

WITH hybrid_results AS (
    /*
     * ハイブリッド検索によって取得された Top 5 を模擬。
     *
     * vector_score : ベクトル検索側のスコア
     * text_score   : キーワード検索側のスコア
     * hybrid_score : 両者を統合した検索スコア
     */
    SELECT
        101 AS doc_id,
        VECTOR('[0.91, 0.12, 0.31, 0.44]', 4, FLOAT32) AS vector_data,
        'CREATE VECTOR INDEX文を実行すると、ベクトル列に新しいベクトルインデックスを作成できます。'
            AS passage_text,
        0.94 AS vector_score,
        0.97 AS text_score,
        0.955 AS hybrid_score
    FROM dual

    UNION ALL

    SELECT
        102,
        VECTOR('[0.88, 0.15, 0.29, 0.41]', 4, FLOAT32),
        '既存のベクトルインデックスを削除するには、DROP INDEX文を実行します。',
        0.91,
        0.88,
        0.895
    FROM dual

    UNION ALL

    SELECT
        103,
        VECTOR('[0.81, 0.20, 0.34, 0.38]', 4, FLOAT32),
        'ベクトルインデックスの状態や名前はデータディクショナリから確認できます。',
        0.85,
        0.82,
        0.835
    FROM dual

    UNION ALL

    SELECT
        104,
        VECTOR('[0.74, 0.29, 0.27, 0.33]', 4, FLOAT32),
        'VECTOR_DISTANCE関数を使用すると、2つのベクトル間の距離を計算できます。',
        0.79,
        0.71,
        0.750
    FROM dual

    UNION ALL

    SELECT
        105,
        VECTOR('[0.62, 0.35, 0.18, 0.22]', 4, FLOAT32),
        '表そのものを削除する場合はDROP TABLE文を使用します。',
        0.68,
        0.63,
        0.655
    FROM dual
),

/*
 * Hybrid Search 時点での順位
 */
hybrid_ranked AS (
    SELECT
        h.*,
        ROW_NUMBER() OVER (
            ORDER BY hybrid_score DESC
        ) AS hybrid_rank
    FROM hybrid_results h
),

/*
 * Top 5 に対して Reranker を実行
 */
rerank_scored AS (
    SELECT
        h.*,

        PREDICTION(
            RERANK_MODEL
            USING
                '既存のベクトルインデックスを削除するにはどうすればよいですか?'
                    AS DATA1,
                passage_text
                    AS DATA2
        ) AS rerank_score

    FROM hybrid_ranked h
),

/*
 * Rerank 後の順位
 */
rerank_ranked AS (
    SELECT
        r.*,

        ROW_NUMBER() OVER (
            ORDER BY rerank_score DESC
        ) AS rerank_rank,

        1 / (1 + EXP(-rerank_score))
            AS rerank_sigmoid

    FROM rerank_scored r
)

SELECT
    hybrid_rank,
    rerank_rank,

    CASE
        WHEN rerank_rank < hybrid_rank
            THEN 'UP +' || (hybrid_rank - rerank_rank)

        WHEN rerank_rank > hybrid_rank
            THEN 'DOWN -' || (rerank_rank - hybrid_rank)

        ELSE 'SAME'
    END AS rank_change,

    doc_id,
    passage_text,

    ROUND(vector_score, 3) AS vector_score,
    ROUND(text_score, 3)   AS text_score,
    ROUND(hybrid_score, 3) AS hybrid_score,

    ROUND(rerank_score, 3)   AS rerank_score,
    ROUND(rerank_sigmoid, 3) AS rerank_sigmoid

FROM rerank_ranked
ORDER BY rerank_rank;

image.png

prediction(...) を実行することで Rerank 処理が行われます。
prediction(...) が返す値は、2 テキスト間の Rerank score (logit/未正規化の類似度スコア) です。
値の範囲は -∞ ~ +∞ で、値が大きいほど検索キーワードと候補文書の関連性が高いです。

上記のクエリですが、「ハイブリッド検索ではキーワード一致の強い誤候補が1位 → Rerank 後は質問意図に合う候補が1位」 というシナリオを想定してみました。

例えば RAG アーキテクチャでナレッジ検索を行う場合、下記のような流れかなと思います。

  1. ユーザーがナレッジとなる情報を保存する
  2. 保存のタイミングで、そのデータを「Chunking → Embedding → 保存」する (Pipeline 処理)
  3. ユーザーが自然言語で検索する
  4. バックエンド側でベクトル検索 or テキスト検索も含めたハイブリッド検索を実施、該当するナレッジ情報とともに LLM へ渡す

この時の工程 4 でもし誤ったナレッジ情報が上位の候補としてピックアップされると、期待どおりナレッジ検索が出来ないかなと思います。
そういう場合に Rerank 処理が精度向上の役に立ちます。それを、上記クエリで再現してみました。

個人的な感想

Embedding モデルと Rerank モデルを ADB に取り込むことで、外部へのデータ送信を最小限に出来るかなと思います。

ただ一方で、大量のユーザーがアクセスすることで Embedding 処理や Rerank 処理も大量に実行され、CPU リソースをバカ食いしちゃう可能性もあります。

そのため Resource Manager を用いて CPU の使用上限を指定したり、CPU / I/O の相対的な配分比率をコンシューマー グループごとで指定するなど対策が必要になるかもしれません。

あとは、ADB は MCP サーバーの機能が実装されています。

例えば MCP サーバーの Tool として、「ハイブリッド検索 と Rerank 処理を組み合わせた自然言語での検索ツール」を ADB に定義することで、AI エージェントとしても魅力的な機能を提供出来るかなぁと思います。

例えば Azure の話にはなりますが、Foundry IQ (元 Azure AI Search) のナレッジ ソースとして、MCP を指定することが可能です。

image.png

なので AI 用データ基盤として ADB (Autonomous Database@Azure とか) を利用。
ETL のようなデータ処理パイプラインでナレッジ情報などを ADB に保存。
今回の Rerank 処理や Embedding モデルの取り込みなどを組み合わせて、Microsoft Foundry に作成した AI Agent と連携させても面白いなと思いました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?