본문 바로가기
WIKI 기술 지식 베이스

Semantic search using an asymmetric embedding model

원문 보기 위키 갱신

출처: 문서

본문

비대칭 임베딩 모델을 사용한 시맨틱 검색

이 튜토리얼에서는 비대칭 임베딩 모델로 텍스트 임베딩을 생성해서 시맨틱 검색을 수행하는 방법을 알아봐요. 이 튜토리얼에서는 Hugging Face의 다국어 모델인 intfloat/multilingual-e5-small을 사용해요. 자세한 내용은 시맨틱 검색을 참고하세요.

your_ 접두사로 시작하는 플레이스홀더는 여러분의 값으로 바꾸세요. {: .note}

1단계: 클러스터 설정 업데이트

외부 URL을 사용해 모델을 등록하고 머신러닝(ML) 노드가 아닌 노드에서 모델을 실행할 수 있도록 클러스터를 구성하려면 다음 요청을 보내세요:

PUT _cluster/settings
{
  "persistent": {
    "plugins.ml_commons.allow_registering_model_via_url": "true",
    "plugins.ml_commons.only_run_on_ml_node": "false",
    "plugins.ml_commons.model_access_control_enabled": "true",
    "plugins.ml_commons.native_memory_threshold": "99"
  }
}

{% include copy-curl.html %}

URL에서 모델을 등록할 때는 그 소스가 신뢰할 수 있는 곳인지 꼭 확인하세요. 신뢰할 수 없는 소스에서 모델을 로드하면 보안 위험이 생길 수 있어요. 자세한 내용은 신뢰할 수 없는 모델을 위한 PyTorch 보안 가이드라인을 참고하세요. {: .warning}

2단계: OpenSearch에서 사용할 모델 준비하기

이 튜토리얼에서는 Hugging Face의 intfloat/multilingual-e5-small 모델을 사용해요. 다음 단계를 따라 모델을 준비하고 OpenSearch에서 사용할 수 있도록 zip 파일로 압축하세요.

2.1단계: Hugging Face에서 모델 다운로드하기

모델을 다운로드하려면 다음 단계를 따르세요:

  1. 아직 설치하지 않았다면 Git Large File Storage(LFS)를 설치하세요:

    git lfs install
    

    {% include copy.html %}

  2. 모델 리포지토리를 클론하세요:

    git clone https://huggingface.co/intfloat/multilingual-e5-small
    

    {% include copy.html %}

이제 모델 파일들이 로컬 머신의 디렉터리에 다운로드되어 있어요.

2.2단계: 모델 파일 압축하기

모델을 OpenSearch에 업로드하려면 필요한 모델 파일들(model.onnx, sentencepiece.bpe.model, tokenizer.json)을 압축해야 해요. 이 파일들은 클론한 리포지토리의 onnx 디렉터리에서 찾을 수 있어요.

파일을 압축하려면 해당 파일들이 있는 디렉터리에서 다음 명령어를 실행하세요:

zip -r intfloat-multilingual-e5-small-onnx.zip model.onnx tokenizer.json sentencepiece.bpe.model

{% include copy.html %}

이제 파일들이 intfloat-multilingual-e5-small-onnx.zip이라는 이름의 zip 파일로 아카이브되어 있어요.

2.3단계: 모델 파일의 해시 계산하기

모델을 등록하기 전에 zip 파일의 SHA-256 해시를 계산해야 해요. 다음 명령어를 실행해서 해시를 생성하세요:

shasum -a 256 intfloat-multilingual-e5-small-onnx.zip

{% include copy.html %}

해시 값을 적어 두세요. 모델을 등록할 때 필요하거든요.

2.4단계: Python HTTP 서버로 모델 파일 서빙하기

OpenSearch가 모델 파일에 접근할 수 있도록 HTTP를 통해 파일을 서빙할 수 있어요. 이 튜토리얼은 로컬 개발 환경을 사용하기 때문에 Python에 내장된 HTTP 서버 명령어를 사용할 수 있어요.

zip 파일이 있는 디렉터리로 이동한 다음 다음 명령어를 실행하세요:

python3 -m http.server 8080 --bind 0.0.0.0

{% include copy.html %}

그러면 zip 파일이 http://0.0.0.0:8080/intfloat-multilingual-e5-small-onnx.zip에서 서빙돼요. 모델 등록이 끝난 후에는 Ctrl+C를 눌러 서버를 중지할 수 있어요.

3단계: 모델 그룹 등록하기

모델 자체를 등록하기 전에 먼저 모델 그룹을 만들어야 해요. 모델 그룹을 사용하면 OpenSearch에서 모델을 체계적으로 관리할 수 있어요. 다음 요청을 실행해서 새 모델 그룹을 만드세요:

POST /_plugins/_ml/model_groups/_register
{
  "name": "Asymmetric Model Group",
  "description": "A model group for local asymmetric models"
}

{% include copy-curl.html %}

응답으로 반환된 모델 그룹 ID를 적어 두세요. 모델을 등록할 때 사용하게 돼요.

4단계: 모델 등록하기

이제 모델 zip 파일과 모델 그룹 ID가 있으니 OpenSearch에 모델을 등록할 수 있어요:

POST /_plugins/_ml/models/_register
{
    "name": "e5-small-onnx",
    "version": "1.0.0",
    "description": "Asymmetric multilingual-e5-small model",
    "model_format": "ONNX",
    "model_group_id": "your_group_id",
    "model_content_hash_value": "your_model_zip_content_hash_value",
    "model_config": {
        "model_type": "bert",
        "embedding_dimension": 384,
        "framework_type": "sentence_transformers",
        "query_prefix": "query: ",
        "passage_prefix": "passage: ",
        "all_config": "{ \"_name_or_path\": \"intfloat/multilingual-e5-small\", \"architectures\": [ \"BertModel\" ], \"attention_probs_dropout_prob\": 0.1, \"hidden_size\": 384, \"num_attention_heads\": 12, \"num_hidden_layers\": 12, \"tokenizer_class\": \"XLMRobertaTokenizer\" }",
        "additional_config": {
            "space_type": "cosinesimil"
        }
    },
    "url": "http://localhost:8080/intfloat-multilingual-e5-small-onnx.zip"
}

{% include copy-curl.html %}

your_group_id와 your_model_zip_content_hash_value는 앞선 단계에서 얻은 값으로 바꾸세요. 그러면 모델 등록 프로세스가 시작되고, 응답에서 태스크 ID를 받게 돼요.

등록 상태를 확인하려면 다음 요청을 실행하세요:

GET /_plugins/_ml/tasks/your_task_id

{% include copy-curl.html %}

태스크가 완료되면 모델 ID를 적어 두세요. 배포와 추론에 필요하거든요.

5단계: 모델 배포하기

모델이 등록되면 다음 요청을 실행해서 배포하세요:

POST /_plugins/_ml/models/your_model_id/_deploy

{% include copy-curl.html %}

태스크 ID를 사용해서 배포 상태를 확인하세요:

GET /_plugins/_ml/tasks/your_task_id

{% include copy-curl.html %}

모델이 성공적으로 배포되면 상태가 DEPLOYED로 변경되고 사용할 준비가 완료돼요.

6단계: 임베딩 생성하기

모델이 배포됐으니 이제 이 모델을 사용해서 쿼리와 패시지 양쪽에 대한 텍스트 임베딩을 생성할 수 있어요.

패시지 임베딩 생성하기

패시지에 대한 임베딩을 생성하려면 다음 요청을 사용하세요:

POST /_plugins/_ml/_predict/text_embedding/your_model_id
{
  "parameters": {
    "content_type": "passage"
  },
  "text_docs": [
    "Today is Friday, tomorrow will be my break day. After that, I will go to the library. When is lunch?"
  ],
  "target_response": ["sentence_embedding"]
}

{% include copy-curl.html %}

응답에는 생성된 임베딩이 담겨 있어요:

{
  "inference_results": [
    {
      "output": [
        {
          "name": "sentence_embedding",
          "data_type": "FLOAT32",
          "shape": [384],
          "data": [0.0419328, 0.047480892, ..., 0.31158513, 0.21784715]
        }
      ]
    }
  ]
}

{% include copy-curl.html %}

쿼리 임베딩 생성하기

같은 방식으로 쿼리에 대한 임베딩도 생성할 수 있어요:

POST /_plugins/_ml/_predict/text_embedding/your_model_id
{
  "parameters": {
    "content_type": "query"
  },
  "text_docs": ["What day is it today?"],
  "target_response": ["sentence_embedding"]
}

{% include copy-curl.html %}

응답에는 생성된 임베딩이 담겨 있어요:

{
  "inference_results": [
    {
      "output": [
        {
          "name": "sentence_embedding",
          "data_type": "FLOAT32",
          "shape": [384],
          "data": [0.2338349, -0.13603798, ..., 0.37335885, 0.10653384]
        }
      ]
    }
  ]
}

{% include copy-curl.html %}

7단계: 시맨틱 검색 실행하기

이제 semantic 필드 타입을 사용해서 시맨틱 검색을 실행해 볼 거예요.

7.1단계: semantic 필드가 포함된 인덱스 생성하기

배포한 비대칭 모델을 참조하는 semantic 필드가 포함된 인덱스를 만드세요. OpenSearch는 지정된 모델을 사용해 색인과 검색 시점에 임베딩을 자동으로 생성해요:

PUT nyc_facts
{
  "settings": {
    "index.knn": true
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "description": {
        "type": "semantic",
        "model_id": "your_model_id"
      }
    }
  }
}

{% include copy-curl.html %}

your_model_id를 4단계의 모델 ID로 바꾸세요. 모델이 passage_prefix와 query_prefix로 구성되어 있기 때문에, semantic 필드는 문서(passage 콘텐츠 타입)와 쿼리(query 콘텐츠 타입)에 대한 임베딩을 생성할 때 알맞은 접두사를 자동으로 적용해요.

7.2단계: 데이터 색인하기

인덱스에 문서를 색인하세요. 색인하는 동안 semantic 필드가 description 필드에 대한 패시지 임베딩을 자동으로 생성해요:

POST /_bulk
{ "index": { "_index": "nyc_facts" } }
{ "title": "Central Park", "description": "A large public park in the heart of New York City, offering a wide range of recreational activities." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Empire State Building", "description": "An iconic skyscraper in New York City offering breathtaking views from its observation deck." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Statue of Liberty", "description": "A colossal neoclassical sculpture on Liberty Island, symbolizing freedom and democracy in the United States." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Brooklyn Bridge", "description": "A historic suspension bridge connecting Manhattan and Brooklyn, offering pedestrian walkways with great views." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Times Square", "description": "A bustling commercial and entertainment hub in Manhattan, known for its neon lights and Broadway theaters." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Yankee Stadium", "description": "Home to the New York Yankees, this baseball stadium is a historic landmark in the Bronx." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "The Bronx Zoo", "description": "One of the largest zoos in the world, located in the Bronx, featuring diverse animal exhibits and conservation efforts." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "New York Botanical Garden", "description": "A large botanical garden in the Bronx, known for its diverse plant collections and stunning landscapes." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Flushing Meadows-Corona Park", "description": "A major park in Queens, home to the USTA Billie Jean King National Tennis Center and the Unisphere." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Citi Field", "description": "The home stadium of the New York Mets, located in Queens, known for its modern design and fan-friendly atmosphere." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Rockefeller Center", "description": "A famous complex of commercial buildings in Manhattan, home to the NBC studios and the annual ice skating rink." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Queens Botanical Garden", "description": "A peaceful, beautiful botanical garden located in Flushing, Queens, featuring seasonal displays and plant collections." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Arthur Ashe Stadium", "description": "The largest tennis stadium in the world, located in Flushing Meadows-Corona Park, Queens, hosting the U.S. Open." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Wave Hill", "description": "A public garden and cultural center in the Bronx, offering stunning views of the Hudson River and a variety of nature programs." }
{ "index": { "_index": "nyc_facts" } }
{ "title": "Louis Armstrong House", "description": "The former home of jazz legend Louis Armstrong, located in Corona, Queens, now a museum celebrating his life and music." }

{% include copy-curl.html %}

7.3단계: 쿼리 실행하기

neural 쿼리 타입을 사용해서 시맨틱 검색 쿼리를 실행하세요. OpenSearch가 알맞은 쿼리 접두사로 쿼리 임베딩을 자동으로 생성하고, 그 밑에 있는 벡터 필드를 대상으로 검색해요:

GET /nyc_facts/_search
{
  "_source": {
    "excludes": [
      "description_semantic_info"
    ]
  },
  "query": {
    "neural": {
      "description": {
        "query_text": "What are some places for sports in NYC?",
        "k": 3
      }
    }
  }
}

{% include copy-curl.html %}

응답에는 상위 세 개의 일치하는 문서가 담겨 있어요:

{
  "took": 45,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 3,
      "relation": "eq"
    },
    "max_score": 0.921239,
    "hits": [
      {
        "_index": "nyc_facts",
        "_id": "SqziBZ4BzPm71JsNgo5J",
        "_score": 0.921239,
        "_source": {
          "description": "A large public park in the heart of New York City, offering a wide range of recreational activities.",
          "title": "Central Park"
        }
      },
      {
        "_index": "nyc_facts",
        "_id": "U6ziBZ4BzPm71JsNgo5J",
        "_score": 0.9106568,
        "_source": {
          "description": "The home stadium of the New York Mets, located in Queens, known for its modern design and fan-friendly atmosphere.",
          "title": "Citi Field"
        }
      },
      {
        "_index": "nyc_facts",
        "_id": "T6ziBZ4BzPm71JsNgo5J",
        "_score": 0.91063917,
        "_source": {
          "description": "Home to the New York Yankees, this baseball stadium is a historic landmark in the Bronx.",
          "title": "Yankee Stadium"
        }
      }
    ]
  }
}

참고 자료

  • Wang, Liang, et al. (2024). Multilingual E5 Text Embeddings: A Technical Report. arXiv preprint arXiv:2402.05672. 링크

더 알아보기 (Learn more)