Getting started with semantic and hybrid search
출처: 문서
본문
Getting started with semantic and hybrid search
기본적으로 OpenSearch는 Okapi BM25 알고리즘을 사용하여 문서 점수를 계산해요. BM25는 키워드 기반 알고리즘으로, 키워드가 포함된 쿼리에서는 좋은 성능을 보이지만 쿼리 용어의 의미를 포착하지는 못해요. 시맨틱 검색은 키워드 기반 검색과 달리 검색 맥락에서 쿼리의 의미를 고려해요. 따라서 시맨틱 검색은 쿼리에 자연어 이해가 필요할 때 좋은 성능을 보여요.
이 튜토리얼에서는 다음 검색 유형을 구현하는 방법을 배워요.
- 시맨틱 검색: 검색 맥락에서 사용자 쿼리의 의도를 파악하기 위해 의미를 고려하여 검색 관련성을 향상시켜요.
- 하이브리드 검색: 시맨틱 검색과 키워드 검색을 결합하여 검색 관련성을 향상시켜요.
시맨틱 검색을 위한 OpenSearch 구성 요소
이 튜토리얼에서는 다음 OpenSearch 구성 요소를 사용해요.
튜토리얼을 진행하면서 이러한 모든 구성 요소에 대한 설명을 확인할 수 있어요. 일부 구성 요소에 익숙하지 않더라도 걱정하지 마세요. 위 목록의 각 링크는 해당 구성 요소에 대한 문서 섹션으로 연결돼요.
사전 요구 사항
이 간단한 설정을 위해 OpenSearch에서 제공하는 머신러닝(ML) 모델과 전용 ML 노드가 없는 클러스터를 사용해요. 이 기본 로컬 설정이 작동하도록 하려면 다음 요청을 보내 ML 관련 클러스터 설정을 업데이트하세요.
PUT _cluster/settings
{
"persistent": {
"plugins.ml_commons.only_run_on_ml_node": "false",
"plugins.ml_commons.native_memory_threshold": "99"
}
}
{% include copy-curl.html %}
고급
사용자 지정 로컬 모델 설정의 경우 다음 요구 사항을 참고하세요.
- 사용자 지정 로컬 모델을 등록하려면 추가로
"allow_registering_model_via_url": "true"클러스터 설정을 지정해야 해요. - 프로덕션에서는 전용 ML 노드를 두어 워크로드를 분리하는 것이 좋아요. 전용 ML 노드가 있는 클러스터에서는 성능 향상을 위해
"only_run_on_ml_node": "true"를 지정하세요.
URL에서 모델을 등록할 때는 소스가 신뢰할 수 있는지 확인하세요. 신뢰할 수 없는 소스에서 모델을 로드하면 보안 위험이 발생할 수 있어요. 자세한 내용은 신뢰할 수 없는 모델에 대한 PyTorch 보안 지침을 참조하세요. {: .warning}
ML 관련 클러스터 설정에 대한 자세한 내용은 ML Commons 클러스터 설정을 참조하세요.
Tutorial
이 튜토리얼은 다음 단계로 구성되어 있어요:
{% include list.html list_items=page.steps%}
이 튜토리얼은 명령줄이나 OpenSearch Dashboards의 Dev Tools 콘솔을 사용해서 따라할 수 있어요.
튜토리얼의 일부 단계에는 선택적인 테스트해보기{: .text-delta} 섹션이 있어요. 이 섹션의 요청을 실행하여 단계가 성공적으로 완료되었는지 확인할 수 있어요.
작업을 마친 후에는 정리 섹션의 단계에 따라 생성된 모든 구성 요소를 삭제하세요.
1단계: 모델 선택하기
먼저, 텍스트 필드에서 벡터 임베딩을 생성하기 위해 언어 모델을 선택해야 해요. 이는 데이터 수집 시점과 쿼리 시점 모두에 필요해요.
이 튜토리얼에서는 Hugging Face의 DistilBERT 모델을 사용할 거예요. 이 모델은 OpenSearch에서 제공하는 사전 학습된 sentence transformer 모델 중 하나로, 벤치마킹 테스트에서 가장 좋은 결과를 보여준 모델 중 하나예요(자세한 내용은 이 블로그 게시물을 참조하세요). 모델을 등록하려면 이름, 버전, 차원이 필요해요. 이 정보는 사전 학습된 모델 테이블에서 모델의 TorchScript 아티팩트에 해당하는 config_url 링크를 선택하여 찾을 수 있어요.
- 모델 이름은
huggingface/sentence-transformers/msmarco-distilbert-base-tas-b예요. - 모델 버전은
1.0.3이에요. - 이 모델의 차원 수는
768이에요.
벡터 인덱스를 설정할 때 필요하므로 모델의 차원 수를 기록해 두세요. {: .important}
고급: 다른 모델 사용하기
또는 모델에 대해 다음 옵션 중 하나를 선택할 수 있어요:
- OpenSearch에서 제공하는 다른 사전 학습된 모델을 사용하세요. 자세한 내용은 OpenSearch 제공 사전 학습 모델을 참조하세요.
- 자신의 모델을 OpenSearch에 업로드하세요. 자세한 내용은 사용자 정의 로컬 모델을 참조하세요.
- 외부 플랫폼에 호스팅된 파운데이션 모델에 연결하세요. 자세한 내용은 원격 모델 연결을 참조하세요.
모델 선택에 대한 자세한 내용은 추가 자료를 참조하세요.
2단계: 모델 등록 및 배포하기
모델을 등록하고 배포하려면 등록 요청에 모델 그룹 ID를 제공하세요:
POST /_plugins/_ml/models/_register?deploy=true
{
"name": "huggingface/sentence-transformers/msmarco-distilbert-base-tas-b",
"version": "1.0.3",
"model_format": "TORCH_SCRIPT"
}
{% include copy-curl.html %}
모델 등록은 비동기 작업이에요. OpenSearch는 이 작업에 대한 작업 ID를 반환해요:
{
"task_id": "aFeif4oB5Vm0Tdw8yoN7",
"status": "CREATED"
}
OpenSearch는 URL에서 모델의 구성 파일과 모델 콘텐츠를 다운로드해요. 모델 크기가 10MB를 초과하기 때문에 OpenSearch는 모델을 최대 10MB 크기의 청크로 분할하여 모델 인덱스에 저장해요. Get ML Task API를 사용하여 작업 상태를 확인할 수 있어요:
GET /_plugins/_ml/tasks/aFeif4oB5Vm0Tdw8yoN7
{% include copy-curl.html %}
OpenSearch는 등록된 모델을 모델 인덱스에 저장해요. 모델을 배포하면 모델 인스턴스가 생성되고 모델이 메모리에 캐시돼요.
작업이 완료되면 작업 상태가 COMPLETED로 변경되고 Get ML Task API 응답에 배포된 모델의 model_id가 포함돼요(초기 task_id와 다름):
{
"model_id": "aVeif4oB5Vm0Tdw8zYO2",
"task_type": "REGISTER_MODEL",
"function_name": "TEXT_EMBEDDING",
"state": "COMPLETED",
"worker_node": [
"4p6FVOmJRtu3wehDD74hzQ"
],
"create_time": 1694358489722,
"last_update_time": 1694358499139,
"is_async": true
}
다음 몇 단계에서 배포된 모델을 사용하려면 model_id가 필요해요.
다양한 배포 상태에서 가능한 모든 응답 형식에 대한 자세한 내용은 Get ML Task API를 참조하세요. {: .tip}
테스트해보기
{: .text-delta}요청에 ID를 제공하여 새로 생성된 모델을 검색하세요:
GET /_plugins/_ml/models/aVeif4oB5Vm0Tdw8zYO2
{% include copy-curl.html %}
응답에는 모델이 포함돼요:
{
"name": "huggingface/sentence-transformers/msmarco-distilbert-base-tas-b",
"model_group_id": "Z1eQf4oB5Vm0Tdw8EIP2",
"algorithm": "TEXT_EMBEDDING",
"model_version": "1",
"model_format": "TORCH_SCRIPT",
"model_state": "REGISTERED",
"model_content_size_in_bytes": 266352827,
"model_content_hash_value": "acdc81b652b83121f914c5912ae27c0fca8fabf270e6f191ace6979a19830413",
"model_config": {
"model_type": "distilbert",
"embedding_dimension": 768,
"framework_type": "SENTENCE_TRANSFORMERS",
"all_config": """{"_name_or_path":"old_models/msmarco-distilbert-base-tas-b/0_Transformer","activation":"gelu","architectures":["DistilBertModel"],"attention_dropout":0.1,"dim":768,"dropout":0.1,"hidden_dim":3072,"initializer_range":0.02,"max_position_embeddings":512,"model_type":"distilbert","n_heads":12,"n_layers":6,"pad_token_id":0,"qa_dropout":0.1,"seq_classif_dropout":0.2,"sinusoidal_pos_embds":false,"tie_weights_":true,"transformers_version":"4.7.0","vocab_size":30522}"""
},
"created_time": 1694482261832,
"last_updated_time": 1694482324282,
"last_registered_time": 1694482270216,
"last_deployed_time": 1694482324282,
"total_chunks": 27,
"planning_worker_node_count": 1,
"current_worker_node_count": 1,
"planning_worker_nodes": [
"4p6FVOmJRtu3wehDD74hzQ"
],
"deploy_to_all_nodes": true
}
응답에는 모델 정보가 포함돼요. model_state가 REGISTERED인 것을 확인할 수 있어요. 또한 total_chunks 필드에 표시된 것처럼 모델이 27개의 청크로 분할되었어요.
고급: 사용자 정의 모델 등록하기
사용자 정의 모델을 등록하려면 등록 요청에 모델 구성을 제공해야 해요. 자세한 내용은 OpenSearch 내 ML 모델 사용을 참조하세요.
테스트해보기
{: .text-delta}요청에 ID를 제공하여 배포된 모델을 검색하세요:
GET /_plugins/_ml/models/aVeif4oB5Vm0Tdw8zYO2
{% include copy-curl.html %}
응답은 모델 상태가 DEPLOYED임을 보여줘요:
{
"name": "huggingface/sentence-transformers/msmarco-distilbert-base-tas-b",
"model_group_id": "Z1eQf4oB5Vm0Tdw8EIP2",
"algorithm": "TEXT_EMBEDDING",
"model_version": "1",
"model_format": "TORCH_SCRIPT",
"model_state": "DEPLOYED",
"model_content_size_in_bytes": 266352827,
"model_content_hash_value": "acdc81b652b83121f914c5912ae27c0fca8fabf270e6f191ace6979a19830413",
"model_config": {
"model_type": "distilbert",
"embedding_dimension": 768,
"framework_type": "SENTENCE_TRANSFORMERS",
"all_config": """{"_name_or_path":"old_models/msmarco-distilbert-base-tas-b/0_Transformer","activation":"gelu","architectures":["DistilBertModel"],"attention_dropout":0.1,"dim":768,"dropout":0.1,"hidden_dim":3072,"initializer_range":0.02,"max_position_embeddings":512,"model_type":"distilbert","n_heads":12,"n_layers":6,"pad_token_id":0,"qa_dropout":0.1,"seq_classif_dropout":0.2,"sinusoidal_pos_embds":false,"tie_weights_":true,"transformers_version":"4.7.0","vocab_size":30522}"""
},
"created_time": 1694482261832,
"last_updated_time": 1694482324282,
"last_registered_time": 1694482270216,
"last_deployed_time": 1694482324282,
"total_chunks": 27,
"planning_worker_node_count": 1,
"current_worker_node_count": 1,
"planning_worker_nodes": [
"4p6FVOmJRtu3wehDD74hzQ"
],
"deploy_to_all_nodes": true
}
Models Profile API 요청을 전송하여 클러스터의 모든 배포된 모델에 대한 통계를 받을 수도 있어요:
GET /_plugins/_ml/profile/models
3단계: 데이터 수집하기
OpenSearch는 언어 모델을 사용하여 텍스트를 벡터 임베딩으로 변환해요. 수집 중에 OpenSearch는 요청의 텍스트 필드에 대한 벡터 임베딩을 생성해요. 검색 중에는 동일한 모델을 적용하여 쿼리 텍스트에 대한 벡터 임베딩을 생성할 수 있으며, 이를 통해 문서에 대한 벡터 유사성 검색을 수행할 수 있어요.
3(a)단계: 수집 파이프라인 생성하기
이제 모델을 배포했으므로, 이 모델을 사용하여 문서가 인덱스에 수집되기 전에 문서 필드를 변환하는 하나의 프로세서(태스크)를 포함하는 수집 파이프라인을 구성할 수 있어요. 이 예제에서는 텍스트에서 벡터 임베딩을 생성하는 text_embedding 프로세서를 설정할 거예요. 이전 섹션에서 설정한 모델의 model_id와 텍스트를 가져올 필드 이름(text)과 임베딩을 기록할 필드 이름(passage_embedding)을 지정하는 field_map이 필요해요:
PUT /_ingest/pipeline/nlp-ingest-pipeline
{
"description": "An NLP ingest pipeline",
"processors": [
{
"text_embedding": {
"model_id": "aVeif4oB5Vm0Tdw8zYO2",
"field_map": {
"text": "passage_embedding"
}
}
}
]
}
{% include copy-curl.html %}
테스트해보기
{: .text-delta}Ingest API를 사용하여 생성된 수집 파이프라인을 검색하세요:
GET /_ingest/pipeline
{% include copy-curl.html %}
응답에는 수집 파이프라인이 포함돼요:
{
"nlp-ingest-pipeline": {
"description": "An NLP ingest pipeline",
"processors": [
{
"text_embedding": {
"model_id": "aVeif4oB5Vm0Tdw8zYO2",
"field_map": {
"text": "passage_embedding"
}
}
}
]
}
}
3(b)단계: 벡터 인덱스 생성하기
이제 이미지 설명을 포함하는 text 필드와 텍스트의 벡터 임베딩을 포함하는 passage_embedding이라는 knn_vector 필드가 있는 벡터 인덱스를 생성할 거예요. 또한 기본 수집 파이프라인을 이전 단계에서 생성한 nlp-ingest-pipeline으로 설정하세요:
PUT /my-nlp-index
{
"settings": {
"index.knn": true,
"default_pipeline": "nlp-ingest-pipeline"
},
"mappings": {
"properties": {
"id": {
"type": "text"
},
"passage_embedding": {
"type": "knn_vector",
"dimension": 768,
"space_type": "l2"
},
"text": {
"type": "text"
}
}
}
}
{% include copy-curl.html %}
벡터 인덱스를 설정하면 나중에 passage_embedding 필드에 대한 벡터 검색을 수행할 수 있어요.
테스트해보기
{: .text-delta}다음 요청을 사용하여 생성된 인덱스의 설정과 매핑을 가져오세요:
GET /my-nlp-index/_settings
{% include copy-curl.html %}
GET /my-nlp-index/_mappings
{% include copy-curl.html %}
3(c)단계: 인덱스에 문서 수집하기
이 단계에서는 여러 샘플 문서를 인덱스에 수집할 거예요. 샘플 데이터는 Flickr 이미지 데이터셋에서 가져왔어요. 각 문서에는 이미지 설명에 해당하는 text 필드와 이미지 ID에 해당하는 id 필드가 포함돼요:
PUT /my-nlp-index/_doc/1
{
"text": "A West Virginia university women 's basketball team , officials , and a small gathering of fans are in a West Virginia arena .",
"id": "4319130149.jpg"
}
{% include copy-curl.html %}
PUT /my-nlp-index/_doc/2
{
"text": "A wild animal races across an uncut field with a minimal amount of trees .",
"id": "1775029934.jpg"
}
{% include copy-curl.html %}
PUT /my-nlp-index/_doc/3
{
"text": "People line the stands which advertise Freemont 's orthopedics , a cowboy rides a light brown bucking bronco .",
"id": "2664027527.jpg"
}
{% include copy-curl.html %}
PUT /my-nlp-index/_doc/4
{
"text": "A man who is riding a wild horse in the rodeo is very near to falling off .",
"id": "4427058951.jpg"
}
{% include copy-curl.html %}
PUT /my-nlp-index/_doc/5
{
"text": "A rodeo cowboy , wearing a cowboy hat , is being thrown off of a wild white horse .",
"id": "2691147709.jpg"
}
{% include copy-curl.html %}
문서가 인덱스에 수집되면 text_embedding 프로세서가 벡터 임베딩을 포함하는 추가 필드를 생성하고 해당 필드를 문서에 추가해요. 인덱스된 예제 문서를 보려면 문서 1을 검색하세요:
GET /my-nlp-index/_doc/1
{% include copy-curl.html %}
응답에는 원래 text 및 id 필드와 추가된 passage_embedding 필드가 포함된 문서 _source가 포함돼요:
{
"_index": "my-nlp-index",
"_id": "1",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": {
"passage_embedding": [
0.04491629,
-0.34105563,
0.036822468,
-0.14139028,
...
],
"text": "A West Virginia university women 's basketball team , officials , and a small gathering of fans are in a West Virginia arena .",
"id": "4319130149.jpg"
}
}
4단계: 데이터 검색하기
이제 키워드 검색, 시맨틱 검색, 그리고 이 둘의 조합을 사용하여 인덱스를 검색할 거예요.
키워드 검색 사용하기
키워드 검색을 사용하려면 match 쿼리를 사용하세요. 결과에서 임베딩을 제외할 거예요:
GET /my-nlp-index/_search
{
"_source": {
"excludes": [
"passage_embedding"
]
},
"query": {
"match": {
"text": {
"query": "wild west"
}
}
}
}
{% include copy-curl.html %}
문서 3은 지정된 키워드를 포함하지 않기 때문에 반환되지 않아요. rodeo와 cowboy 단어를 포함하는 문서는 의미론적 의미가 고려되지 않아 점수가 낮게 매겨져요:
결과
{: .text-delta}{
"took": 647,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 4,
"relation": "eq"
},
"max_score": 1.7878418,
"hits": [
{
"_index": "my-nlp-index",
"_id": "1",
"_score": 1.7878418,
"_source": {
"text": "A West Virginia university women 's basketball team , officials , and a small gathering of fans are in a West Virginia arena .",
"id": "4319130149.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "2",
"_score": 0.58093566,
"_source": {
"text": "A wild animal races across an uncut field with a minimal amount of trees .",
"id": "1775029934.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "5",
"_score": 0.55228686,
"_source": {
"text": "A rodeo cowboy , wearing a cowboy hat , is being thrown off of a wild white horse .",
"id": "2691147709.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "4",
"_score": 0.53899646,
"_source": {
"text": "A man who is riding a wild horse in the rodeo is very near to falling off .",
"id": "4427058951.jpg"
}
}
]
}
}
시맨틱 검색 사용하기
시맨틱 검색을 사용하려면 neural 쿼리를 사용하고 이전에 설정한 모델의 모델 ID를 제공하여 쿼리 텍스트에 대한 벡터 임베딩이 수집 시 사용된 모델로 생성되도록 하세요:
GET /my-nlp-index/_search
{
"_source": {
"excludes": [
"passage_embedding"
]
},
"query": {
"neural": {
"passage_embedding": {
"query_text": "wild west",
"model_id": "aVeif4oB5Vm0Tdw8zYO2",
"k": 5
}
}
}
}
{% include copy-curl.html %}
이번에는 응답에 다섯 개의 문서가 모두 포함될 뿐만 아니라 시맨틱 검색이 의미론적 의미를 고려하기 때문에 문서 순서도 개선돼요:
결과
{: .text-delta}{
"took": 25,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 0.01585195,
"hits": [
{
"_index": "my-nlp-index",
"_id": "4",
"_score": 0.01585195,
"_source": {
"text": "A man who is riding a wild horse in the rodeo is very near to falling off .",
"id": "4427058951.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "2",
"_score": 0.015748845,
"_source": {
"text": "A wild animal races across an uncut field with a minimal amount of trees.",
"id": "1775029934.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "5",
"_score": 0.015177963,
"_source": {
"text": "A rodeo cowboy , wearing a cowboy hat , is being thrown off of a wild white horse .",
"id": "2691147709.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "1",
"_score": 0.013272902,
"_source": {
"text": "A West Virginia university women 's basketball team , officials , and a small gathering of fans are in a West Virginia arena .",
"id": "4319130149.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "3",
"_score": 0.011347735,
"_source": {
"text": "People line the stands which advertise Freemont 's orthopedics , a cowboy rides a light brown bucking bronco .",
"id": "2664027527.jpg"
}
}
]
}
}
하이브리드 검색 사용하기
하이브리드 검색은 키워드 검색과 시맨틱 검색을 결합하여 검색 관련성을 향상시켜요. 하이브리드 검색을 구현하려면 검색 시 실행되는 검색 파이프라인을 설정해야 해요. 구성할 검색 파이프라인은 중간 단계에서 검색 결과를 가로채서 normalization-processor를 적용해요. normalization-processor는 여러 쿼리 절의 문서 점수를 정규화하고 결합하여 선택한 정규화 및 결합 기술에 따라 문서의 점수를 재조정해요.
1단계: 검색 파이프라인 구성하기
normalization-processor를 사용하여 검색 파이프라인을 구성하려면 다음 요청을 사용하세요. 프로세서의 정규화 기술은 min_max로 설정되고 결합 기술은 arithmetic_mean으로 설정돼요. weights 배열은 각 쿼리 절에 할당된 가중치를 소수점 백분율로 지정해요:
PUT /_search/pipeline/nlp-search-pipeline
{
"description": "Post processor for hybrid search",
"phase_results_processors": [
{
"normalization-processor": {
"normalization": {
"technique": "min_max"
},
"combination": {
"technique": "arithmetic_mean",
"parameters": {
"weights": [
0.3,
0.7
]
}
}
}
}
]
}
{% include copy-curl.html %}
2단계: 하이브리드 쿼리로 검색하기
match 및 neural 쿼리 절을 결합하기 위해 hybrid 쿼리를 사용할 거예요. 이전에 생성한 nlp-search-pipeline을 요청의 쿼리 매개변수에 적용해야 해요:
GET /my-nlp-index/_search?search_pipeline=nlp-search-pipeline
{
"_source": {
"exclude": [
"passage_embedding"
]
},
"query": {
"hybrid": {
"queries": [
{
"match": {
"text": {
"query": "cowboy rodeo bronco"
}
}
},
{
"neural": {
"passage_embedding": {
"query_text": "wild west",
"model_id": "aVeif4oB5Vm0Tdw8zYO2",
"k": 5
}
}
}
]
}
}
}
{% include copy-curl.html %}
OpenSearch는 wild west의 의미론적 의미와 일치하는 문서를 반환할 뿐만 아니라, 와일드 웨스트 테마와 관련된 단어를 포함하는 문서도 다른 문서에 비해 더 높은 점수를 받아요:
결과
{: .text-delta}{
"took": 27,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 0.86481035,
"hits": [
{
"_index": "my-nlp-index",
"_id": "5",
"_score": 0.86481035,
"_source": {
"text": "A rodeo cowboy , wearing a cowboy hat , is being thrown off of a wild white horse .",
"id": "2691147709.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "4",
"_score": 0.7003,
"_source": {
"text": "A man who is riding a wild horse in the rodeo is very near to falling off .",
"id": "4427058951.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "2",
"_score": 0.6839765,
"_source": {
"text": "A wild animal races across an uncut field with a minimal amount of trees.",
"id": "1775029934.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "3",
"_score": 0.3007,
"_source": {
"text": "People line the stands which advertise Freemont 's orthopedics , a cowboy rides a light brown bucking bronco .",
"id": "2664027527.jpg"
}
},
{
"_index": "my-nlp-index",
"_id": "1",
"_score": 0.29919013,
"_source": {
"text": "A West Virginia university women 's basketball team , officials , and a small gathering of fans are in a West Virginia arena .",
"id": "4319130149.jpg"
}
}
]
}
}
모든 요청에서 검색 파이프라인을 지정하는 대신, 다음과 같이 인덱스의 기본 검색 파이프라인으로 설정할 수 있어요:
PUT /my-nlp-index/_settings
{
"index.search.default_pipeline" : "nlp-search-pipeline"
}
{% include copy-curl.html %}
이제 다양한 가중치, 정규화 기술 및 결합 기술을 실험해 볼 수 있어요. 자세한 내용은 normalization-processor 및 hybrid 쿼리 문서를 참조하세요.
고급
검색 템플릿을 사용하여 검색을 매개변수화할 수 있어요. 검색 템플릿은 구현 세부 정보를 숨겨 중첩 수준을 줄이고 쿼리 복잡성을 낮춰줘요. 자세한 내용은 검색 템플릿을 참조하세요.
자동화된 워크플로 사용하기
자동화된 워크플로를 사용하여 의미론적 검색이나 하이브리드 검색을 빠르게 설정할 수 있어요. 이 접근 방식은 필요한 모든 리소스를 자동으로 생성하고 프로비저닝해요. 자세한 내용은 워크플로 템플릿을 참조하세요.
자동화된 의미론적 검색 설정
OpenSearch는 기본 로컬 모델(huggingface/sentence-transformers/paraphrase-MiniLM-L3-v2)을 자동으로 등록하고 배포하며, 수집 파이프라인과 벡터 인덱스를 생성하는 워크플로 템플릿을 제공해요.
POST /_plugins/_flow_framework/workflow?use_case=semantic_search_with_local_model&provision=true
{% include copy-curl.html %}
의미론적 검색 워크플로 템플릿의 기본값을 검토하여 매개변수를 업데이트해야 하는지 확인해 보세요. 예를 들어, 다른 모델을 사용하려면 요청 본문에 모델 이름을 지정하세요.
POST /_plugins/_flow_framework/workflow?use_case=semantic_search_with_local_model&provision=true
{
"register_local_pretrained_model.name": "huggingface/sentence-transformers/msmarco-distilbert-base-tas-b"
}
{% include copy-curl.html %}
OpenSearch는 생성된 워크플로의 워크플로 ID로 응답해요.
{
"workflow_id" : "U_nMXJUBq_4FYQzMOS4B"
}
워크플로 상태를 확인하려면 다음 요청을 보내세요.
GET /_plugins/_flow_framework/workflow/U_nMXJUBq_4FYQzMOS4B/_status
{% include copy-curl.html %}
워크플로가 완료되면 state가 COMPLETED로 변경돼요. 워크플로는 다음 단계를 실행해요.
이제 3(c)단계로 인덱스에 문서를 수집하고 4단계로 데이터를 검색할 수 있어요.
정리
작업을 마친 후에는 이 튜토리얼에서 생성한 구성 요소를 클러스터에서 삭제하세요.
DELETE /my-nlp-index
{% include copy-curl.html %}
DELETE /_search/pipeline/nlp-search-pipeline
{% include copy-curl.html %}
DELETE /_ingest/pipeline/nlp-ingest-pipeline
{% include copy-curl.html %}
POST /_plugins/_ml/models/aVeif4oB5Vm0Tdw8zYO2/_undeploy
{% include copy-curl.html %}
DELETE /_plugins/_ml/models/aVeif4oB5Vm0Tdw8zYO2
{% include copy-curl.html %}
DELETE /_plugins/_ml/model_groups/Z1eQf4oB5Vm0Tdw8EIP2
{% include copy-curl.html %}
추가 자료
- OpenSearch 의미론적 검색의 기본에 대해 알아보려면 OpenSearch에서 의미론적 검색 엔진 구축을 읽어보세요.
- 키워드와 의미론적 검색의 결합, 정규화 및 결합 기법 옵션, 벤치마킹 테스트에 대해 알아보려면 OpenSearch 의미론적 검색의 ABC: 아키텍처, 벤치마크 및 결합 전략을 읽어보세요.
다음 단계
- OpenSearch에서 AI 검색을 살펴보세요.