TheKoguryo's 기술 블로그

 Version 2026-04-20

OML4Py 설치 후 Text Embedding 모델 DB에 로드하기

OML4Py 2.1.1 설치

OML4Py 2.1.1 설치 요구사항

Python 3.13 설치

  1. 설치파일 다운로드

    wget https://www.python.org/ftp/python/3.13.5/Python-3.13.5.tgz
    
  2. 압축해제

    mkdir -p $HOME/python
    tar -xvzf Python-3.13.5.tgz --strip-components=1 -C $HOME/python
    
  3. 필요 패키지 설치

    sudo yum install openssl-devel bzip2-devel libffi-devel sqlite-devel
    sudo yum install perl-Env libffi-devel openssl openssl-devel tk-devel tcl-devel \
    xz-devel zlib-devel bzip2-devel readline-devel libuuid-devel ncurses-devel openblas libsqlite3-dev
    
  4. 빌드

    cd $HOME/python
    ./configure --enable-shared --prefix=$HOME/python
    
    make clean; make
    make altinstall
    
  5. 환경 변수 설정

    export PYTHONHOME=$HOME/python
    export PATH=$PYTHONHOME/bin:$PATH
    export LD_LIBRARY_PATH=$PYTHONHOME/lib:$LD_LIBRARY_PATH
    
  6. 링크

    cd $HOME/python/bin
    ln -s python3.13 python3
    
  7. 버전 확인

    $ python3.13 --version
    Python 3.13.5
    $ python3 --version
    Python 3.13.5
    

OML4Py 설치

  1. requirements.txt 파일 생성

    --extra-index-url https://download.pytorch.org/whl/cpu
    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
    
  2. 설치

    pip3.13 install --upgrade pip
    pip3.13 install -r requirements.txt
    
  3. Oracle Machine Learning for Python 사이트에서 OML4Py 2.1.1 클라이언트를 다운로드 받습니다.

  4. OML4Py 설치

    unzip oml4py-client-linux-x86_64-2.1.1.zip
    pip3.13 install client/oml-2.1.1-cp313-cp313-linux_x86_64.whl
    
  5. oml 패키지 설치 확인 및 pretrained embedding models 확인

    $ python3.13
    Python 3.13.5 (main, Jan 31 2026, 16:26:14) [GCC 8.5.0 20210514 (Red Hat 8.5.0-28.0.1)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from oml.utils import ONNXPipeline, ONNXPipelineConfig
    >>> all_preconfigured_models = ONNXPipelineConfig.show_preconfigured()
    >>> import json
    >>> print(json.dumps(sorted(all_preconfigured_models), indent=4))
    [
        "AdamCodd/vit-base-nsfw-detector",
        "BAAI/bge-base-en-v1.5",
        "BAAI/bge-large-en-v1.5",
        "BAAI/bge-reranker-base",
        "BAAI/bge-small-en-v1.5",
        "Falconsai/nsfw_image_detection",
        "Snowflake/snowflake-arctic-embed-l",
        "Snowflake/snowflake-arctic-embed-m",
        "Snowflake/snowflake-arctic-embed-s",
        "Snowflake/snowflake-arctic-embed-xs",
        "TaylorAI/gte-tiny",
        "WhereIsAI/UAE-Large-V1",
        "WinKawaks/vit-small-patch16-224",
        "WinKawaks/vit-tiny-patch16-224",
        "google/vit-base-patch16-224",
        "ibm-granite/granite-embedding-278m-multilingual",
        "intfloat/e5-base-v2",
        "intfloat/e5-small-v2",
        "intfloat/multilingual-e5-base",
        "intfloat/multilingual-e5-small",
        "microsoft/resnet-18",
        "microsoft/resnet-50",
        "mixedbread-ai/mxbai-embed-large-v1",
        "nateraw/vit-age-classifier",
        "openai/clip-vit-large-patch14",
        "rizvandwiki/gender-classification",
        "sentence-transformers/all-MiniLM-L12-v2",
        "sentence-transformers/all-MiniLM-L6-v2",
        "sentence-transformers/all-mpnet-base-v2",
        "sentence-transformers/distiluse-base-multilingual-cased-v2",
        "sentence-transformers/multi-qa-MiniLM-L6-cos-v1",
        "sentence-transformers/paraphrase-multilingual-mpnet-base-v2",
        "sentence-transformers/stsb-xlm-r-multilingual",
        "taylorAI/bge-micro-v2",
        "thenlper/gte-base",
        "thenlper/gte-large",
        "thenlper/gte-small",
        "trpakov/vit-face-expression"
    ]
    
  6. 이중 한국어를 지원하는 목록을 확인합니다.

    from oml.utils import ONNXPipeline, ONNXPipelineConfig
    all_preconfigured_models = ONNXPipelineConfig.show_preconfigured(include_properties=True)
    
    for model in all_preconfigured_models:
        for model_name, config in model.items():
            if "languages" in config and "ko" in config["languages"]:
                print(model_name)
    
    • 결과

      sentence-transformers/distiluse-base-multilingual-cased-v2
      sentence-transformers/paraphrase-multilingual-mpnet-base-v2
      intfloat/multilingual-e5-base
      intfloat/multilingual-e5-small
      
한국어 Embedding 모델 순위

인터넷 상에 아주 많은 모델이 검색되어, 어떤 모델이 좋은 지 판단이 필요합니다. 여기서는 HuggingFace mteb Embedding Leaderboard에서 2026년 3월 말 기준 한국어 모델 순위를 기준으로 하겠습니다. 그리고 모델의 평가 항목중 Retrieval, STS를 기준으로 정렬해봅니다.

OML4Py Preconfigured Models 임포트 준비

OML4Py에서 사전구성설정을 제공하는 모델입니다. 해당 모델은 쉽게 Oracle AI Database 26ai 버전에 임포트해서 사용할 수 있습니다. 해외 Oracle ACE Pro가 정리한 문서 및 제공하는 모델 링크를 활용하기 바랍니다.

  1. Python에서 다음을 실행합니다. Preconfigured Models은 이름만 입력하면 됩니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    
    pipeline = ONNXPipeline(model_name="sentence-transformers/distiluse-base-multilingual-cased-v2")
    pipeline.export2file("distiluse-base-multilingual-cased-v2")
    
    pipeline = ONNXPipeline(model_name="sentence-transformers/paraphrase-multilingual-mpnet-base-v2")
    pipeline.export2file("paraphrase-multilingual-mpnet-base-v2")
    
    pipeline = ONNXPipeline(model_name="intfloat/multilingual-e5-base")
    pipeline.export2file("multilingual-e5-base")
    
    pipeline = ONNXPipeline(model_name="intfloat/multilingual-e5-small")
    pipeline.export2file("multilingual-e5-small")
    
  2. 생성된 파일을 확인합니다.

    $ ls -lah
    -rw-rw-r--. 1 opc opc 131M Apr  2 02:47 distiluse-base-multilingual-cased-v2.onnx
    -rw-rw-r--. 1 opc opc 271M Apr  2 02:54 multilingual-e5-base.onnx
    -rw-rw-r--. 1 opc opc 118M Apr  2 02:50 multilingual-e5-small.onnx
    -rw-rw-r--. 1 opc opc 271M Apr  2 02:49 paraphrase-multilingual-mpnet-base-v2.onnx
    
  3. 다음 예시와 같이 OCI Object Storage에 업로드하여, DB에서 사용할 준비합니다.

    oci os object put --bucket-name onnx-models --file distiluse-base-multilingual-cased-v2.onnx
    oci os object put --bucket-name onnx-models --file multilingual-e5-base.onnx
    oci os object put --bucket-name onnx-models --file multilingual-e5-small.onnx
    oci os object put --bucket-name onnx-models --file paraphrase-multilingual-mpnet-base-v2.onnx
    
사전 구성되지 않은 일반 Embedding 모델 준비

OML4Py 2.1.1 Updates부터 Large ONNX Model Conversion을 지원합니다. Support For Large ONNX Format Model 설명을 보면 아래와 같은 내용이 있습니다.

  • 1GB 미만: 최적의 성능으로 지원됩니다.
  • 1GB ~ 2GB: 양자화(quantize_model=True)가 활성화된 경우 완벽한 지원이 제공되며, quantize_model=False인 경우에는 use_external_data=True 기본으로 ONNX 파일외 추가 파일들이 만들어집니다.
  • 0.4GB ~ 2GB: quantize_model=False인 경우, 성능 향상을 위해 양자화를 권장하는 경고 메시지가 표시됩니다.
  • 2GB 초과: quantize_model=False만 지원하고, ONNX 파일외 추가 파일들이 만들어집니다.

F2LLM-v2-8B

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=10000, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="codefuse-ai/F2LLM-v2-8B", config=config)
    pipeline.export2file("f2llm-v2-8b", output_dir=".")
    
    • 다음 오류 발생

      ValueError: Unsupported tokenizer <class 'transformers.models.qwen2.tokenization_qwen2.Qwen2Tokenizer'>
      
    • ONNX Pipeline Models: Text Embedding을 보면 OML4Py는 현재 Tokenizer로 BERT, GPT2, SENTENCEPIECE, CLIPor ROBERTA만 지원합니다.

    • F2LLM-v2-8B, F2LLM-v2-14B, F2LLM-v2-4B, F2LLM-v2-1.7B, inf-retriever-v1, inf-retriever-v1-1.5b 모델은 Qwen2Tokenizer를 사용하여, OML4Py 2.1.1에서 지원하지 않습니다.

snowflake-arctic-embed-l-v2.0

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=8192, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="Snowflake/snowflake-arctic-embed-l-v2.0", config=config)
    pipeline.export2file("snowflake-arctic-embed-l-v2.0", output_dir=".")
    
  2. 생성된 파일을 확인합니다. zip 파일로 생성되었습니다.

    $ ls -lah snowflake-arctic-embed-l-v2.0*
    -rw-rw-r--. 1 opc opc 2.2G Apr  1 03:14 snowflake-arctic-embed-l-v2.0.zip
    
  3. 압축 해제합니다.

    $ unzip snowflake-arctic-embed-l-v2.0.zip -d snowflake-arctic-embed-l-v2.0
    Archive:  snowflake-arctic-embed-l-v2.0.zip
     extracting: snowflake-arctic-embed-l-v2.0/snowflake-arctic-embed-l-v2.0_external_data.json
     extracting: snowflake-arctic-embed-l-v2.0/snowflake-arctic-embed-l-v2.0_largeTensor_0.data
     extracting: snowflake-arctic-embed-l-v2.0/snowflake-arctic-embed-l-v2.0_0.data
     extracting: snowflake-arctic-embed-l-v2.0/snowflake-arctic-embed-l-v2.0_1.data
     extracting: snowflake-arctic-embed-l-v2.0/snowflake-arctic-embed-l-v2.0.onnx
    
  4. 다음 예시와 같이 OCI Object Storage에 업로드하여, DB에서 사용할 준비합니다.

    oci os object bulk-upload --bucket-name onnx-models --src-dir snowflake-arctic-embed-l-v2.0
    

PwC-Embedding_expr

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=512, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="SamilPwC-AXNode-GenAI/PwC-Embedding_expr", config=config)
    pipeline.export2file("pwc-embedding_expr", output_dir=".")
    
    • 다음 오류 발생

      OSError: Unable to load vocabulary from file. Please check that the provided vocabulary is accessible and not corrupted.
      
  2. 커스텀 모델 로드 방식을 참고하여 연관된 상위 모델의 vocabulary 파일을 사용하여 우회합니다. 아래와 같이 다시 실행합니다.

    from huggingface_hub import hf_hub_download, snapshot_download
    
    hf_hub_download(
        repo_id="intfloat/multilingual-e5-large-instruct",
        filename="sentencepiece.bpe.model",
        local_dir="./SamilPwC-AXNode-GenAI/PwC-Embedding_expr",
    )
    
    snapshot_download(
        repo_id="SamilPwC-AXNode-GenAI/PwC-Embedding_expr",
        local_dir="./SamilPwC-AXNode-GenAI/PwC-Embedding_expr"
    )
    
    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=512, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(
        model_name="SamilPwC-AXNode-GenAI/PwC-Embedding_expr", 
        config=config, 
        settings={"local_model_path": "."}
    )
    pipeline.export2file("pwc-embedding_expr", output_dir=".")
    
  3. 생성된 파일을 확인합니다. zip 파일로 생성되었습니다.

    $ ls -lah pwc-embedding_expr*
    -rw-rw-r--. 1 opc opc 2.1G Apr  1 09:45 pwc-embedding_expr.zip
    
  4. 압축 해제합니다.

    $ unzip pwc-embedding_expr.zip -d pwc-embedding_expr
    Archive:  pwc-embedding_expr.zip
     extracting: pwc-embedding_expr/pwc-embedding_expr_external_data.json
     extracting: pwc-embedding_expr/pwc-embedding_expr_largeTensor_0.data
     extracting: pwc-embedding_expr/pwc-embedding_expr_0.data
     extracting: pwc-embedding_expr/pwc-embedding_expr_1.data
     extracting: pwc-embedding_expr/pwc-embedding_expr.onnx
    
  5. 다음 예시와 같이 OCI Object Storage에 업로드하여, DB에서 사용할 준비합니다.

    oci os object bulk-upload --bucket-name onnx-models --src-dir pwc-embedding_expr
    

jina-embeddings-v3

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=2048, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="jinaai/jina-embeddings-v3", config=config)
    pipeline.export2file("jina-embeddings-v3", output_dir=".")
    
    • 다음 오류 발생

      OSError: Unable to load vocabulary from file. Please check that the provided vocabulary is accessible and not corrupted.
      
  2. 오류를 최대한 우회하기 위해 아래와 같이 실행해 보았습니다.

    from huggingface_hub import hf_hub_download, snapshot_download
    
    hf_hub_download(
        repo_id="FacebookAI/xlm-roberta-base",
        filename="sentencepiece.bpe.model",
        local_dir="./jinaai/jina-embeddings-v3",
    )
    
    snapshot_download(
        repo_id="jinaai/jina-embeddings-v3",
        local_dir="./jinaai/jina-embeddings-v3"
    )
    
    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=2048, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(
        model_name="jinaai/jina-embeddings-v3", 
        config=config, 
        settings={"local_model_path": "."}
    )
    pipeline.export2file("jina-embeddings-v3", output_dir=".")
    
    • 해결할 수 없음 오류로 인해 본 모델은 export 실패함.

      ValueError: Could not download model.
      

multilingual-e5-large-instruct

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=512, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="intfloat/multilingual-e5-large-instruct", config=config)
    pipeline.export2file("multilingual-e5-large-instruct")
    
  2. 생성된 파일을 확인합니다. zip 파일로 생성되었습니다.

    $ ls -lah multilingual-e5-large-instruct*
    -rw-rw-r--. 1 opc opc 2.1G Apr  1 10:17 multilingual-e5-large-instruct.zip
    
  3. 압축 해제합니다.

    $ unzip multilingual-e5-large-instruct.zip -d multilingual-e5-large-instruct
    Archive:  multilingual-e5-large-instruct.zip
     extracting: multilingual-e5-large-instruct/multilingual-e5-large-instruct_external_data.json
     extracting: multilingual-e5-large-instruct/multilingual-e5-large-instruct_largeTensor_0.data
     extracting: multilingual-e5-large-instruct/multilingual-e5-large-instruct_0.data
     extracting: multilingual-e5-large-instruct/multilingual-e5-large-instruct_1.data
     extracting: multilingual-e5-large-instruct/multilingual-e5-large-instruct.onnx
    
  4. 다음 예시와 같이 OCI Object Storage에 업로드하여, DB에서 사용할 준비합니다.

    oci os object bulk-upload --bucket-name onnx-models --src-dir multilingual-e5-large-instruct
    

STS-multilingual-mpnet-base-v2

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=128, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="Gameselo/STS-multilingual-mpnet-base-v2", config=config)
    pipeline.export2file("sts-multilingual-mpnet-base-v2", output_dir=".")
    
  2. 생성된 파일을 확인합니다. zip 파일로 생성되었습니다.

    $ ls -lah sts-multilingual-mpnet-base-v2*
    -rw-rw-r--. 1 opc opc 1.1G Apr  1 10:22 sts-multilingual-mpnet-base-v2.zip
    
  3. 파일사이즈가 2G이하입니다. quantize_model=True로 설정하여, Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=128, distance_metrics=["COSINE"], quantize_model=True)
    pipeline = ONNXPipeline(model_name="Gameselo/STS-multilingual-mpnet-base-v2", config=config)
    pipeline.export2file("sts-multilingual-mpnet-base-v2-q", output_dir=".")
    
  4. 생성된 파일을 확인합니다. 양자화된 파일은 .onnx 단일 파일로 생성됩니다.

    ls -lah sts-multilingual-mpnet-base-v2*
    -rw-rw-r--. 1 opc opc 271M Apr  1 10:24 sts-multilingual-mpnet-base-v2-q.onnx
    -rw-rw-r--. 1 opc opc 1.1G Apr  1 10:22 sts-multilingual-mpnet-base-v2.zip
    
  5. 압축 해제합니다.

    $ unzip sts-multilingual-mpnet-base-v2.zip -d sts-multilingual-mpnet-base-v2
    Archive:  sts-multilingual-mpnet-base-v2.zip
     extracting: sts-multilingual-mpnet-base-v2/sts-multilingual-mpnet-base-v2_external_data.json
     extracting: sts-multilingual-mpnet-base-v2/sts-multilingual-mpnet-base-v2_0.data
     extracting: sts-multilingual-mpnet-base-v2/sts-multilingual-mpnet-base-v2_1.data
     extracting: sts-multilingual-mpnet-base-v2/sts-multilingual-mpnet-base-v2.onnx
    
  6. 다음 예시와 같이 OCI Object Storage에 업로드하여, DB에서 사용할 준비합니다.

    oci os object put --bucket-name onnx-models --file sts-multilingual-mpnet-base-v2-q.onnx
    oci os object bulk-upload --bucket-name onnx-models --src-dir sts-multilingual-mpnet-base-v2
    

gte-Qwen2-7B-instruct

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=8192, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="Alibaba-NLP/gte-Qwen2-7B-instruct", config=config)
    pipeline.export2file("gte-qwen2-7b-instruct", output_dir=".")
    
    • 다음 오류 발생

      ValueError: Unsupported tokenizer <class 'transformers.models.qwen2.tokenization_qwen2.Qwen2Tokenizer'>
      
    • Qwen2Tokenizer를 사용하여, OML4Py 2.1.1에서 지원하지 않습니다.

bilingual-embedding-large

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=512, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="Lajavaness/bilingual-embedding-large", config=config)
    pipeline.export2file("bilingual-embedding-large", output_dir=".")
    
  2. 생성된 파일을 확인합니다. zip 파일로 생성되었습니다.

    $ ls -lah bilingual-embedding-large*
    -rw-rw-r--. 1 opc opc 2.1G Apr  1 10:36 bilingual-embedding-large.zip
    
  3. 압축 해제합니다.

    $ unzip bilingual-embedding-large.zip -d bilingual-embedding-large
    Archive:  bilingual-embedding-large.zip
     extracting: bilingual-embedding-large/bilingual-embedding-large_external_data.json
     extracting: bilingual-embedding-large/bilingual-embedding-large_largeTensor_0.data
     extracting: bilingual-embedding-large/bilingual-embedding-large_0.data
     extracting: bilingual-embedding-large/bilingual-embedding-large_1.data
     extracting: bilingual-embedding-large/bilingual-embedding-large.onnx
    
  4. 다음 예시와 같이 OCI Object Storage에 업로드하여, DB에서 사용할 준비합니다.

    oci os object bulk-upload --bucket-name onnx-models --src-dir bilingual-embedding-large
    

SFR-Embedding-Mistral

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=4096, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="Salesforce/SFR-Embedding-Mistral", config=config)
    pipeline.export2file("sfr-embedding-mistral", output_dir=".")
    
    • 다음 오류 발생

      ValueError: Unsupported tokenizer <class 'transformers.models.llama.tokenization_llama.LlamaTokenizer'>
      
    • LlamaTokenizer를 사용하여, OML4Py 2.1.1에서는 아직 지원하지 않습니다.

multilingual-e5-large

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=512, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="intfloat/multilingual-e5-large", config=config)
    pipeline.export2file("multilingual-e5-large", output_dir=".")
    
  2. 생성된 파일을 확인합니다. zip 파일로 생성되었습니다.

    $ ls -lah multilingual-e5-large*
    -rw-rw-r--. 1 opc opc 2.1G Apr  1 10:45 multilingual-e5-large.zip
    
  3. 압축 해제합니다.

    $ unzip multilingual-e5-large.zip -d multilingual-e5-large
    Archive:  multilingual-e5-large.zip
     extracting: multilingual-e5-large/multilingual-e5-large_external_data.json
     extracting: multilingual-e5-large/multilingual-e5-large_largeTensor_0.data
     extracting: multilingual-e5-large/multilingual-e5-large_0.data
     extracting: multilingual-e5-large/multilingual-e5-large_1.data
     extracting: multilingual-e5-large/multilingual-e5-large.onnx
    
  4. 다음 예시와 같이 OCI Object Storage에 업로드하여, DB에서 사용할 준비합니다.

    oci os object bulk-upload --bucket-name onnx-models --src-dir multilingual-e5-large
    

추가 dragonkue-bge-m3-ko

  1. Python에서 다음을 실행합니다.

    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=8192, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(model_name="dragonkue/BGE-m3-ko", config=config)
    pipeline.export2file("bge-m3-ko", output_dir=".")
    
    • 다음 오류 발생

      OSError: Unable to load vocabulary from file. Please check that the provided vocabulary is accessible and not corrupted.
      
  2. 커스텀 모델 로드 방식을 참고하여 연관된 상위 모델의 vocabulary 파일을 사용하여 우회합니다. 아래와 같이 다시 실행합니다.

    from huggingface_hub import hf_hub_download, snapshot_download
    
    hf_hub_download(
        repo_id="BAAI/bge-m3",
        filename="sentencepiece.bpe.model",
        local_dir="./dragonkue/BGE-m3-ko",
    )
    
    snapshot_download(
        repo_id="dragonkue/BGE-m3-ko",
        local_dir="./dragonkue/BGE-m3-ko"
    )
    
    from oml.utils import ONNXPipeline,ONNXPipelineConfig
    config = ONNXPipelineConfig.from_template("text", max_seq_length=8192, distance_metrics=["COSINE"], quantize_model=False)
    pipeline = ONNXPipeline(
        model_name="dragonkue/BGE-m3-ko", 
        config=config, 
        settings={"local_model_path": "."}
    )
    pipeline.export2file("bge-m3-ko", output_dir=".")
    
  3. 생성된 파일을 확인합니다. zip 파일로 생성되었습니다.

    $ ls -lah bge-m3-ko*
    -rw-rw-r--. 1 opc opc 2.2G Apr  1 10:56 bge-m3-ko.zip
    
  4. 압축 해제합니다.

    $ unzip bge-m3-ko.zip -d bge-m3-ko
    Archive:  bge-m3-ko.zip
     extracting: bge-m3-ko/bge-m3-ko_external_data.json
     extracting: bge-m3-ko/bge-m3-ko_largeTensor_0.data
     extracting: bge-m3-ko/bge-m3-ko_0.data
     extracting: bge-m3-ko/bge-m3-ko_1.data
     extracting: bge-m3-ko/bge-m3-ko.onnx
    
  5. 다음 예시와 같이 OCI Object Storage에 업로드하여, DB에서 사용할 준비합니다.

    oci os object bulk-upload --bucket-name onnx-models --src-dir bge-m3-ko
    
Oracle AI Database 26ai에 모델 로드하기
  1. 사용할 유저 생성 및 권한 부여합니다. <YOUR_PASSWORD>는 각자 사용하는 값으로 변경

    --CREATE TABLESPACE USERS DATAFILE 'USERS' SIZE 64M AUTOEXTEND ON;
    CREATE USER vector IDENTIFIED BY <YOUR_PASSWORD> DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA UNLIMITED ON users;
    GRANT CONNECT, RESOURCE TO vector;
    
    -- ONNX 모델 업로드 권한 부여
    GRANT CREATE MINING MODEL TO vector;
    CREATE OR REPLACE DIRECTORY AI_ASSETS_DIR as 'AI_ASSETS_DIR';
    GRANT READ,WRITE ON DIRECTORY AI_ASSETS_DIR to vector;
    
    -- dba_directories 테이블 접근 권한 부여
    GRANT SELECT_CATALOG_ROLE TO vector;
    
    -- OCI 서비스 접속을 위한 생성 권한 부여
    GRANT EXECUTE ON DBMS_CLOUD TO vector;
    
  2. 임포트할 ADB 유저로 접속하여 파일을 다운로드 받습니다. (미리 업로드해둔 파일을 이용합니다. 필요하면, 본인의 Object Storage 로 변경합니다)

    DECLARE
        TYPE t_str_array IS TABLE OF VARCHAR2(200);
        v_base_url VARCHAR2(200);
        v_arr t_str_array := t_str_array('bge-m3-ko.onnx', 'bge-m3-ko_0.data', 'bge-m3-ko_1.data', 'bge-m3-ko_external_data.json', 'bge-m3-ko_largeTensor_0.data',
            'bilingual-embedding-large.onnx', 'bilingual-embedding-large_0.data', 'bilingual-embedding-large_1.data', 'bilingual-embedding-large_external_data.json', 'bilingual-embedding-large_largeTensor_0.data',
            'multilingual-e5-large-instruct.onnx', 'multilingual-e5-large-instruct_0.data', 'multilingual-e5-large-instruct_1.data', 'multilingual-e5-large-instruct_external_data.json', 'multilingual-e5-large-instruct_largeTensor_0.data', 
            'multilingual-e5-large.onnx', 'multilingual-e5-large_0.data', 'multilingual-e5-large_1.data', 'multilingual-e5-large_external_data.json', 'multilingual-e5-large_largeTensor_0.data', 
            'pwc-embedding_expr.onnx', 'pwc-embedding_expr_0.data', 'pwc-embedding_expr_1.data', 'pwc-embedding_expr_external_data.json', 'pwc-embedding_expr_largeTensor_0.data',
            'snowflake-arctic-embed-l-v2.0.onnx', 'snowflake-arctic-embed-l-v2.0_0.data', 'snowflake-arctic-embed-l-v2.0_1.data', 'snowflake-arctic-embed-l-v2.0_external_data.json', 'snowflake-arctic-embed-l-v2.0_largeTensor_0.data',
            'sts-multilingual-mpnet-base-v2-q.onnx', 
            'sts-multilingual-mpnet-base-v2.onnx', 'sts-multilingual-mpnet-base-v2_0.data', 'sts-multilingual-mpnet-base-v2_1.data', 'sts-multilingual-mpnet-base-v2_external_data.json',
            'distiluse-base-multilingual-cased-v2.onnx',
            'multilingual-e5-base.onnx',
            'multilingual-e5-small.onnx',
            'paraphrase-multilingual-mpnet-base-v2.onnx'        
        );
        v_object_uri VARCHAR2(200);
    BEGIN
        v_base_url := 'https://objectstorage.ap-chuncheon-1.oraclecloud.com/n/apackrsct01/b/onnx-models/o/';
        FOR i IN 1 .. v_arr.COUNT LOOP
            v_object_uri := v_base_url || v_arr(i);
    
            DBMS_OUTPUT.PUT_LINE(v_object_uri);
            dbms_cloud.get_object(
                object_uri      => v_object_uri,
                directory_name  => 'AI_ASSETS_DIR'
            );        
        END LOOP;
    END;
    /
    
  3. 다운로드 받는 파일들을 확인합니다.

    select * from DBMS_CLOUD.LIST_FILES('AI_ASSETS_DIR');
    
  4. 다운받은 파일로 모델을 로드합니다.

    BEGIN
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'bge-m3-ko.onnx',
            model_name => 'BGE_M3_KO');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'bilingual-embedding-large.onnx',
            model_name => 'BILINGUAL_EMBEDDING_LARGE');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'multilingual-e5-large-instruct.onnx',
            model_name => 'MULTILINGUAL_E5_LARGE_INSTRUCT');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'multilingual-e5-large.onnx',
            model_name => 'MULTILINGUAL_E5_LARGE');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'pwc-embedding_expr.onnx',
            model_name => 'PWC_EMBEDDING_EXPR');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'snowflake-arctic-embed-l-v2.0.onnx',
            model_name => 'SNOWFLAKE_ARCTIC_EMBED_L_V2');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'sts-multilingual-mpnet-base-v2-q.onnx',
            model_name => 'STS_MULTILINGUAL_MPNET_BASE_V2_Q');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'sts-multilingual-mpnet-base-v2.onnx',
            model_name => 'STS_MULTILINGUAL_MPNET_BASE_V2');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'distiluse-base-multilingual-cased-v2.onnx',
            model_name => 'DISTILUSE_BASE_MULTILINGUAL_CASED_V2');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'multilingual-e5-base.onnx',
            model_name => 'MULTILINGUAL_E5_BASE');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'multilingual-e5-small.onnx',
            model_name => 'MULTILINGUAL_E5_SMALL');
    
        DBMS_VECTOR.LOAD_ONNX_MODEL(
            directory => 'AI_ASSETS_DIR',
            file_name => 'paraphrase-multilingual-mpnet-base-v2.onnx',
            model_name => 'PARAPHRASE_MULTILINGUAL_MPNET_BASE_V2');        
    END;
    /
    
  5. 로드된 모델을 확인합니다.

    SQL> SELECT model_name, mining_function, algorithm, model_size, external_data, inmemory FROM user_mining_models order by model_size;
    
    MODEL_NAME                               MINING_FUNCTION    ALGORITHM       MODEL_SIZE EXTERNAL_DATA    INMEMORY    
    ________________________________________ __________________ ____________ _____________ ________________ ___________ 
    MULTILINGUAL_E5_SMALL                    EMBEDDING          ONNX             123086356 NO               NO          
    DISTILUSE_BASE_MULTILINGUAL_CASED_V2     EMBEDDING          ONNX             136472418 NO               NO          
    MULTILINGUAL_E5_BASE                     EMBEDDING          ONNX             283211967 NO               NO          
    STS_MULTILINGUAL_MPNET_BASE_V2_Q         EMBEDDING          ONNX             283211977 NO               NO          
    PARAPHRASE_MULTILINGUAL_MPNET_BASE_V2    EMBEDDING          ONNX             283211998 NO               NO          
    STS_MULTILINGUAL_MPNET_BASE_V2           EMBEDDING          ONNX            1454997716 YES              NO          
    PWC_EMBEDDING_EXPR                       EMBEDDING          ONNX            3449151655 YES              NO          
    MULTILINGUAL_E5_LARGE                    EMBEDDING          ONNX            3449152823 YES              NO          
    MULTILINGUAL_E5_LARGE_INSTRUCT           EMBEDDING          ONNX            3449156358 YES              NO          
    BILINGUAL_EMBEDDING_LARGE                EMBEDDING          ONNX            3449197584 YES              NO          
    BGE_M3_KO                                EMBEDDING          ONNX            3480666946 YES              NO          
    SNOWFLAKE_ARCTIC_EMBED_L_V2              EMBEDDING          ONNX            3480674941 YES              NO          
    
    12 rows selected.
    
  6. EXTERNAL_DATA=YES인 외부 초기화를 사용하는 모델에 대해서 인메모리 공유를 활성화합니다.

    • 외부 초기값(initializers)을 가진 ONNX 모델에 대해 인메모리 공유를 활성화하면, 데이터베이스는 모델의 초기값을 공유 메모리에 한 번만 로드합니다. 그 결과, 해당 모델을 사용하는 모든 세션에서 전체 메모리 사용량이 감소하는 이점을 얻을 수 있습니다.
    exec DBMS_VECTOR.INMEMORY_ONNX_MODEL('STS_MULTILINGUAL_MPNET_BASE_V2');
    exec DBMS_VECTOR.INMEMORY_ONNX_MODEL('PWC_EMBEDDING_EXPR');
    exec DBMS_VECTOR.INMEMORY_ONNX_MODEL('MULTILINGUAL_E5_LARGE');
    exec DBMS_VECTOR.INMEMORY_ONNX_MODEL('MULTILINGUAL_E5_LARGE_INSTRUCT');
    exec DBMS_VECTOR.INMEMORY_ONNX_MODEL('BILINGUAL_EMBEDDING_LARGE');
    exec DBMS_VECTOR.INMEMORY_ONNX_MODEL('BGE_M3_KO');
    exec DBMS_VECTOR.INMEMORY_ONNX_MODEL('SNOWFLAKE_ARCTIC_EMBED_L_V2');
    
테스트
  1. 벡터 임베딩을 테스트 해 봅니다.

    $ SELECT TO_VECTOR(VECTOR_EMBEDDING(STS_MULTILINGUAL_MPNET_BASE_V2 USING 'hello' as data)) AS embedding;
    
    --------------------------------------------------------------------------------
    [2.47946754E-003,5.18687144E-002,-1.21183312E-002,8.14371463E-003,4.05915678E-002,5.59453992E-003,6.18041027E-003,
    
  2. 양자화된 모델로 벡터 임베딩을 테스트 해 봅니다.

    $ SELECT TO_VECTOR(VECTOR_EMBEDDING(STS_MULTILINGUAL_MPNET_BASE_V2_Q USING 'hello' as data)) AS embedding;
    
    --------------------------------------------------------------------------------
    [8.90885945E-004,5.45100681E-002,-1.22425444E-002,3.97114782E-003,3.96228954E-002,3.26337409E-003,2.04377738E-003,
    
  3. 단 건이지만, 각 모델별로 호출 시간을 테스트해봅니다.

    DECLARE
      v_sql              VARCHAR2(4000);
      v_start            NUMBER;
      v_end              NUMBER;
      v_total            NUMBER;
      v_avg              NUMBER;
      v_embedding        VECTOR;
    BEGIN
      FOR r IN (
        SELECT model_name, model_size
        FROM user_mining_models
        ORDER BY model_size
      )
      LOOP
        v_sql := 'SELECT VECTOR_EMBEDDING(' || r.model_name || ' USING ''서울특별시 중구에서 가 볼 만한 식당을 찾으신다면? 신당역 근처에 있는 "1번지 닭갈비"를 추천합니다! 배달 가능한 매장입니다.'' as data) AS embedding';
    
        v_total := 0;
    
        FOR i IN 1 .. 10 LOOP    
            v_start := DBMS_UTILITY.GET_TIME;
            EXECUTE IMMEDIATE v_sql INTO v_embedding;
            v_end := DBMS_UTILITY.GET_TIME;
    
            v_total := v_total + (v_end - v_start);
        END LOOP;
    
        v_avg := v_total / 10;
    
        DBMS_OUTPUT.PUT_LINE(LPAD(r.model_name, 40) || ' | ' || LPAD(TO_CHAR(r.model_size, 'FM999,999,999,999'), 13) || ' | Elapsed (sec): ' || LPAD(TO_CHAR((v_avg)/100, 'FM9990.000'), 8));
    
      END LOOP;
    END;
    
    • 실행결과 예시 - ATP, 2ECPU, 서비스 HIGH에서 테스트 결과로 단순 참고사항입니다.

                         MULTILINGUAL_E5_SMALL |   123,086,356 | Elapsed (sec):    0.093
          DISTILUSE_BASE_MULTILINGUAL_CASED_V2 |   136,472,418 | Elapsed (sec):    0.049
                          MULTILINGUAL_E5_BASE |   283,211,967 | Elapsed (sec):    0.127
              STS_MULTILINGUAL_MPNET_BASE_V2_Q |   283,211,977 | Elapsed (sec):    0.116
         PARAPHRASE_MULTILINGUAL_MPNET_BASE_V2 |   283,211,998 | Elapsed (sec):    0.117
                STS_MULTILINGUAL_MPNET_BASE_V2 | 1,454,997,716 | Elapsed (sec):    0.258
                            PWC_EMBEDDING_EXPR | 3,449,151,655 | Elapsed (sec):    0.655
                         MULTILINGUAL_E5_LARGE | 3,449,152,823 | Elapsed (sec):    0.573
                MULTILINGUAL_E5_LARGE_INSTRUCT | 3,449,156,358 | Elapsed (sec):    0.575
                     BILINGUAL_EMBEDDING_LARGE | 3,449,197,584 | Elapsed (sec):    0.612
                                     BGE_M3_KO | 3,480,666,946 | Elapsed (sec):    0.600
                   SNOWFLAKE_ARCTIC_EMBED_L_V2 | 3,480,674,941 | Elapsed (sec):    0.650
      
추가 테스트
DECLARE
  v_sql              VARCHAR2(4000);
  v_start            NUMBER;
  v_end              NUMBER;
  v_total            NUMBER;
  v_avg              NUMBER;
BEGIN
  FOR r IN (
    SELECT model_name, model_size
    FROM user_mining_models
    --WHERE ROWNUM <= 1
    ORDER BY model_size
  )
  LOOP
    v_sql := 'UPDATE rstr_info_test
              SET vector_description =
                  VECTOR_EMBEDDING(' || r.model_name || ' USING description AS data)
              WHERE ROWNUM <= 10';

    v_total := 0;

    FOR i IN 1 .. 2 LOOP
        v_start := DBMS_UTILITY.GET_TIME;
        EXECUTE IMMEDIATE v_sql;
        v_end := DBMS_UTILITY.GET_TIME;

        v_total := v_total + (v_end - v_start);
    END LOOP;

    v_avg := v_total / 2;

    DBMS_OUTPUT.PUT_LINE(LPAD(TO_CHAR((v_avg)/100, 'FM9990.000'), 8));
    --DBMS_OUTPUT.PUT_LINE(LPAD(r.model_name, 40) || ' | Elapsed (sec): ' || LPAD(TO_CHAR((v_avg)/100, 'FM9990.000'), 8));
    --DBMS_OUTPUT.PUT_LINE(TO_CHAR(v_embedding));

    COMMIT;

  END LOOP;
END;
ONNX 모델로 변환된 모델 정리

변환된 모델을 다음 주소에서 확인할 수 있습니다.



이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다.