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에서 모델 다운로드하기
모델을 다운로드하려면 다음 단계를 따르세요:
-
아직 설치하지 않았다면 Git Large File Storage(LFS)를 설치하세요:
git lfs install{% include copy.html %}
-
모델 리포지토리를 클론하세요:
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. 링크