CLIPを使用したマルチモーダル埋込みの生成

この項では、OML4Pyクライアントのインストールから、CLIPを使用したマルチモーダル埋込みの生成までのエンドツーエンドの手順について説明します。

これらの手順では、/etc/yum.repos.dでOracle Linux 8リポジトリを構成し、Autonomous Databaseを使用している場合はウォレットを構成し、必要に応じてプロキシを設定していることを前提としています。
  1. Pythonのインストール:
    sudo yum install libffi-devel openssl openssl-devel tk-devel xz-devel zlib-devel bzip2-devel readline-devel libuuid-devel ncurses-devel libaio
    mkdir -p $HOME/python
    wget https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tgz
    tar -xvzf Python-3.12.3.tgz --strip-components=1 -C $HOME/python
    cd $HOME/python
    ./configure --prefix=$HOME/python
    make clean; make
    make altinstall
  2. 変数PYTHONHOMEPATHおよびLD_LIBRARY_PATHを設定します:
    export PYTHONHOME=$HOME/python
    export PATH=$PYTHONHOME/bin:$PATH
    export LD_LIBRARY_PATH=$PYTHONHOME/lib:$LD_LIBRARY_PATH
  3. python3およびpip3のシンボリックリンクを作成します:
    cd $HOME/python/bin
    ln -s python3.12 python3
    ln -s pip3.12 pip3
  4. Pythonからデータベースに埋込みモデルをエクスポートする場合は、Oracle Instantクライアントをインストールします。ファイルにエクスポートする場合は、ステップ4と5をスキップして、ステップ6の環境変数のノートを確認します。
    cd $HOME
    wget https://download.oracle.com/otn_software/linux/instantclient/2340000/instantclient-basic-linux.x64-23.4.0.24.05.zip
    unzip instantclient-basic-linux.x64-23.4.0.24.05.zip
  5. 変数LD_LIBRARY_PATHを設定します:
    export LD_LIBRARY_PATH=$HOME/instantclient_23_4:$LD_LIBRARY_PATH
  6. PythonおよびOracle Instantクライアントの環境変数を定義し、各OML4Pyクライアント・セッションの前にこれらの環境変数をソースとするenv.shなどの環境ファイルを作成します。または、ユーザーがLinuxマシンにログインしたときに定義されるように、環境変数定義を.bashrcに追加します。
    # Environment variables for Python
    export PYTHONHOME=$HOME/python
    export PATH=$PYTHONHOME/bin:$PATH
    export LD_LIBRARY_PATH=$PYTHONHOME/lib:$LD_LIBRARY_PATH

    ノート:

    Oracle Instant Clientの環境変数 - モデルをデータベースにエクスポートするためにOracle Instant Clientがインストールされている場合のみ。

    export LD_LIBRARY_PATH=$HOME/instantclient_23_4:$LD_LIBRARY_PATH

  7. 次に示す必要なサードパーティ・パッケージを含むrequirements.txtという名前のファイルを作成します。
    --extra-index-url https://download.pytorch.org/whl/cpu
    pandas==2.1.1
    setuptools==68.0.0
    scipy==1.12.0
    matplotlib==3.8.4
    oracledb==2.2.0
    scikit-learn==1.4.1.post1
    numpy==1.26.4
    onnxruntime==1.17.0
    onnxruntime-extensions==0.10.1
    onnx==1.16.0
    torch==2.2.0+cpu
    transformers==4.38.1
    sentencepiece==0.2.0
  8. pip3をアップグレードし、requirements.txtにリストされているパッケージをインストールします。
    pip3 install --upgrade pip
    pip3 install -r requirements.txt
  9. OML4Pyクライアントをインストールします。OML4Pyダウンロード・ページからOML4Py 2.0.1クライアントをダウンロードし、Linuxマシンにアップロードします。
    unzip oml4py-client-linux-x86_64-2.0.1.zip
    pip3 install client/oml-2.0-cp312-cp312-linux_x86_64.whl
  10. すべての事前構成済モデルのリストを取得します。Pythonを起動し、oml.utilsからONNXPipelineConfigをインポートします。
    python3
    
    from oml.utils import ONNXPipelineConfig
    
    ONNXPipelineConfig.show_preconfigured()
    ['sentence-transformers/all-mpnet-base-v2',
    'sentence-transformers/all-MiniLM-L6-v2',
    'sentence-transformers/multi-qa-MiniLM-L6-cos-v1',
    'sentence-transformers/distiluse-base-multilingual-cased-v2',
    'sentence-transformers/all-MiniLM-L12-v2',
    'BAAI/bge-small-en-v1.5',
    'BAAI/bge-base-en-v1.5',
    'taylorAI/bge-micro-v2',
    'intfloat/e5-small-v2',
    'intfloat/e5-base-v2',
    'thenlper/gte-base',
    'thenlper/gte-small',
    'TaylorAI/gte-tiny',
    'sentence-transformers/paraphrase-multilingual-mpnet-base-v2',
    'intfloat/multilingual-e5-base',
    'intfloat/multilingual-e5-small',
    'sentence-transformers/stsb-xlm-r-multilingual',
    'Snowflake/snowflake-arctic-embed-xs',
    'Snowflake/snowflake-arctic-embed-s',
    'Snowflake/snowflake-arctic-embed-m',
    'mixedbread-ai/mxbai-embed-large-v1',
    'openai/clip-vit-large-patch14',
    'google/vit-base-patch16-224',
    'microsoft/resnet-18',
    'microsoft/resnet-50',
    'WinKawaks/vit-tiny-patch16-224',
    'Falconsai/nsfw_image_detection',
    'WinKawaks/vit-small-patch16-224',
    'nateraw/vit-age-classifier',
    'rizvandwiki/gender-classification',
    'AdamCodd/vit-base-nsfw-detector',
    'trpakov/vit-face-expression',
    'BAAI/bge-reranker-base']
  11. OML4Pyを使用して、マルチモーダル・モデルをデータベースにロードします。
    • OML4Py以外の代替の方法を使用するには、このステップをスキップしてステップ12に進みます。
    事前構成済の埋込みモデルをデータベースにエクスポートします。omlライブラリをインポートし、oml.utilsからONNXPipelineおよびONNXPipelineConfigをインポートします。これにより、ONNX形式モデルがローカル・ファイル・システムにエクスポートされます。以降の手順では、プレースホルダを独自の資格証明に置き換えてください。
    import oml
    from oml.utils import ONNXPipeline, ONNXPipelineConfig

    Oracle Databaseがオンプレミスにある場合は、埋込みモードをfalseに設定します。このステップは、Oracle Autonomous Databaseではサポートされていないか、必須ではありません。

    oml.core.methods.__embed__ = False

    データベース接続を作成します。

    • オンプレミスでのOracle Databaseの使用:
      oml.connect("<user>", "<password>", port=<port number> host="<hostname>", 
      service_name="<service name>")
      
      pipeline = ONNXPipeline(model_name="openai/clip-vit-large-patch14")
      pipeline.export2db("CLIP")
    • Oracle Autonomous Databaseの使用:
      oml.connect(user="<user>", password="<password>", dsn="myadb_low")
      
      pipeline = ONNXPipeline(model_name="openai/clip-vit-large-patch14")
      pipeline.export2db("CLIP")
      

    このステップが完了すると、「CLIP_TXT」および「CLIP_IMG」という2つのモデルがデータベースにロードされます。

  12. 事前構成済の埋込みモデルをローカル・ファイルにエクスポートします。

    これにより、ONNX形式モデルがローカル・ファイル・システムにエクスポートされます:

    # Export to file
    pipeline = ONNXPipeline(model_name="openai/clip-vit-large-patch14")
    pipeline.export2file("clip",output_dir="/tmp/models")

    ONNXファイルをデータベース・サーバー上のディレクトリに移動し、ファイル・システムおよびデータベースにインポート用のディレクトリを作成します。

    mkdir -p /tmp/models
    sqlplus / as sysdba
    alter session set container=<name of pluggable database>;

    必要な権限を適用します。

    -- directory to store ONNX files for import
    CREATE DIRECTORY ONNX_IMPORT AS '/tmp/models';
    -- grant your OML user read and write permissions on the directory
    GRANT READ, WRITE ON DIRECTORY ONNX_IMPORT to OMLUSER;
    -- grant to allow user to import the model
    GRANT CREATE MINING MODEL TO OMLUSER;

    DBMS_VECTOR.LOAD_ONNX_MODELプロシージャを使用して、OMLユーザー・スキーマにモデルをロードします。この例では、このプロシージャによって、clip_txt.onnxおよびclip_img.onnxという名前のONNXモデル・ファイルがONNX_IMPORTディレクトリからデータベースにそれぞれCLIP_TXTおよびCLIP_IMGという名前のモデルとしてロードされます。

    BEGIN
        DBMS_VECTOR.LOAD_ONNX_MODEL(
        directory => 'ONNX_IMPORT',
        file_name => 'clip_txt.onnx',
        model_name => 'CLIP_TXT',
        metadata => JSON('{"function" : "embedding", "embeddingOutput" : "embedding", "input": {"input": ["DATA"]}}'));
    END;
    BEGIN
        DBMS_VECTOR.LOAD_ONNX_MODEL(
        directory => 'ONNX_IMPORT',
        file_name => 'clip_img.onnx',
        model_name => 'CLIP_IMG',
        metadata => JSON('{"function" : "embedding", "embeddingOutput" : "embedding", "input": {"input": ["DATA"]}}'));
    END;
  13. SQLを使用してモデルが存在することを確認します。
    sqlplus $USER/pass@PDBNAME;
    SELECT model_name, algorithm, mining_function
    FROM user_mining_models
    WHERE model_name='CLIP_TXT' OR model_name='CLIP_IMG';
    --------------------------------------------------------
    MODEL_NAME          ALGORITHM            MINING_FUNCTION
    --------------------------------------------------------
    CLIP_TXT            ONNX                 EMBEDDING
    CLIP_IMG            ONNX                 EMBEDDING
  14. Pythonを使用して、エクスポートされたモデルで埋込みを生成します。
    from oracledb import DB_TYPE_BLOB
    with open('cat.jpg', 'rb') as f:
        img = f.read()
    cr = oml.cursor()
    blob = cr. var(DB_TYPE_BLOB)
    blob.setvalue(0, img)
    data = cr.execute("select vector_embedding(CLIP_TXT using 'RES' as DATA) from dual")
    txt_embed = data.fetchall()
    data = cr.execute("select vector_embedding(CLIP_IMG using to_blob(:1) as DATA) from dual", [blob])
    img_embed = data.fetchall()

    Pythonを使用してイメージとテキストの類似度を計算します:

    from oracledb import DB_TYPE_BLOB
    with open('cat.jpg', 'rb') as f:
        img = f.read()
    cr = oml.cursor()
    blob = cr.var(DB_TYPE_BLOB)
    blob.setvalue(0, img)
    data = cr.execute("""select 1-vector_distance(vector_embedding(CLIP_TXT using 'RES' as DATA), 
                        vector_embedding(CLIP_IMG using to_blob(:1) as DATA)) from dual""", [blob])
    data.fetchall()

    結果:

    [(0.1637756726800217,)]

    SQLを使用して、エクスポートされたモデルで埋込みを生成します:

    • SELECT VECTOR_EMBEDDING(CLIP_TXT USING 'RES' as DATA) AS embedding;

      結果の例を次の抜粋に示します:

      EMBEDDING
      --------------------------------------------------------------------------------
      [2.86132172E-002,-5.59654366E-003,8.66401661E-003,-1.4299524E-002,1.02012949E-00
      2,6.00034464E-003,1.86244473E-002,-7.81036681E-003, ...
    • SELECT VECTOR_EMBEDDING(CLIP_IMG USING TO_BLOB(BFILENAME('ONNX_IMPORT', 'cat.jpg')) as DATA) AS embedding;

      結果の例を次の抜粋に示します:

      EMBEDDING
      --------------------------------------------------------------------------------
      [-2.2028232E-002,1.29058748E-003,-2.0222881E-004,4.58140159E-003,1.98919605E-002
      ,-9.51210782E-003,8.22519697E-003,1.06151737E-002, ...

    SQLを使用して、イメージとテキストの類似度を計算します:

    SELECT 1-VECTOR_DISTANCE(VECTOR_EMBEDDING(
                CLIP_IMG USING TO_BLOB(BFILENAME('ONNX_IMPORT', 'cat.jpg')) as DATA),
                VECTOR_EMBEDDING(CLIP_TXT USING 'RES' as DATA)) AS similarity;

    結果の例:

    SIMILARITY
    ----------
    1.638E-001