Using custom configurations for neural sparse search
출처: 문서
본문
neural sparse 검색에 사용자 지정 구성 사용하기
자동으로 생성된 벡터 임베딩을 사용하는 neural sparse 검색은 doc-only와 bi-encoder 두 가지 모드로 동작해요. 자세한 내용은 스파스 벡터 임베딩 자동 생성하기를 참조하세요.
쿼리 시점에는 다음과 같은 방법으로 사용자 지정 모델을 사용할 수 있어요.
-
Bi-encoder 모드: 배포한 sparse encoding 모델을 사용해 쿼리 텍스트로부터 임베딩을 생성해요. 이때는 수집 시점에 사용한 것과 동일한 모델이어야 해요.
-
사용자 지정 토크나이저를 사용하는 doc-only 모드: 배포한 토크나이저 모델을 사용해 쿼리 텍스트를 토큰화해요. 토큰 가중치는 미리 계산된 룩업 테이블에서 가져와요.
다음은 neural sparse 검색에 사용자 지정 모델을 사용하는 전체 예제예요.
1단계: sparse encoding 모델/토크나이저 구성하기
bi-encoder 모드와 사용자 지정 토크나이저를 사용하는 doc-only 모드, 두 모드 모두에서 수집에 사용할 sparse encoding 모델을 구성해야 해요. bi-encoder 모드는 검색에도 같은 모델을 사용하고, doc-only 모드는 검색에 별도의 토크나이저를 사용해요.
1(a)단계: 검색 모드 선택하기
검색 모드와 적절한 모델/토크나이저 조합을 선택하세요:
-
Bi-encoder: 수집과 검색 모두에서
amazon/neural-sparse/opensearch-neural-sparse-encoding-v2-distill모델을 사용해요. -
사용자 지정 토크나이저를 사용하는 Doc-only: 수집 시에는
amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v3-distill모델을, 검색 시에는amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1토크나이저를 사용해요.
다음 표는 두 검색 모드의 사용 가능한 모든 조합에 대한 검색 관련성을 비교한 것이니, 사용 사례에 가장 적합한 조합을 선택할 때 참고하세요.
영어 모델
| 모드 | 수집 모델 | 검색 모델 | BEIR 평균 검색 관련성 | 모델 파라미터 |
|---|---|---|---|---|
| Doc-only | amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v1 |
amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1 |
0.49 | 133M |
| Doc-only | amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v2-distill |
amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1 |
0.504 | 67M |
| Doc-only | amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v2-mini |
amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1 |
0.497 | 23M |
| Doc-only | amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v3-distill |
amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1 |
0.517 | 67M |
| Doc-only | amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v3-gte |
amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1 |
0.546 | 133M |
| Bi-encoder | amazon/neural-sparse/opensearch-neural-sparse-encoding-v1 |
amazon/neural-sparse/opensearch-neural-sparse-encoding-v1 |
0.524 | 133M |
| Bi-encoder | amazon/neural-sparse/opensearch-neural-sparse-encoding-v2-distill |
amazon/neural-sparse/opensearch-neural-sparse-encoding-v2-distill |
0.528 | 67M |
다국어 모델
| 모드 | 수집 모델 | 검색 모델 | MIRACL 평균 검색 관련성 | 모델 파라미터 |
|---|---|---|---|---|
| Doc-only | amazon/neural-sparse/opensearch-neural-sparse-encoding-multilingual-v1 |
amazon/neural-sparse/opensearch-neural-sparse-tokenizer-multilingual-v1 |
0.629 | 168M |
1(b)단계: 모델/토크나이저 등록하기
두 모드 모두 sparse encoding 모델을 등록해야 해요. 사용자 지정 토크나이저를 사용하는 doc-only 모드에서는 sparse encoding 모델 외에 사용자 지정 토크나이저도 등록해야 해요.
Bi-encoder 모드
bi-encoder 모드를 사용할 때는 amazon/neural-sparse/opensearch-neural-sparse-encoding-v2-distill 모델만 등록하면 돼요.
sparse encoding 모델을 등록하세요:
POST /_plugins/_ml/models/_register?deploy=true
{
"name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-v2-distill",
"version": "1.0.0",
"model_format": "TORCH_SCRIPT"
}
{% include copy-curl.html %}
모델 등록은 비동기 작업이에요. OpenSearch는 등록하는 모델마다 작업 ID를 반환해요:
{
"task_id": "aFeif4oB5Vm0Tdw8yoN7",
"status": "CREATED"
}
Get ML Task API를 호출하면 작업 상태를 확인할 수 있어요:
GET /_plugins/_ml/tasks/aFeif4oB5Vm0Tdw8yoN7
{% include copy-curl.html %}
작업이 완료되면 작업 상태가 COMPLETED로 바뀌고, ML Tasks API 응답에 등록된 모델의 모델 ID가 포함돼요:
{
"model_id": "<bi-encoder model ID>",
"task_type": "REGISTER_MODEL",
"function_name": "SPARSE_ENCODING",
"state": "COMPLETED",
"worker_node": [
"4p6FVOmJRtu3wehDD74hzQ"
],
"create_time": 1694358489722,
"last_update_time": 1694358499139,
"is_async": true
}
생성한 모델의 model_id를 기록해 두세요. 이후 단계에서 필요해요.
사용자 지정 토크나이저를 사용하는 doc-only 모드
사용자 지정 토크나이저를 사용하는 doc-only 모드에서는 수집 시점에 사용할 amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v3-distill 모델과 검색 시점에 사용할 amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1 토크나이저를 등록해야 해요.
sparse encoding 모델을 등록하세요:
POST /_plugins/_ml/models/_register?deploy=true
{
"name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v3-distill",
"version": "1.0.0",
"model_format": "TORCH_SCRIPT"
}
{% include copy-curl.html %}
토크나이저를 등록하세요:
POST /_plugins/_ml/models/_register?deploy=true
{
"name": "amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1",
"version": "1.0.1",
"model_format": "TORCH_SCRIPT"
}
{% include copy-curl.html %}
bi-encoder 모드와 마찬가지로 Get ML Task API를 사용해 등록 작업 상태를 확인하세요. ML Tasks API 응답이 오면 작업 상태가 COMPLETED로 바뀌어요. 생성한 모델과 토크나이저의 model_id를 기록해 두세요. 이후 단계에서 필요해요.
2단계: 데이터 수집하기
bi-encoder 모드와 doc-only 모드 모두 수집 시점에 sparse encoding 모델을 사용해 스파스 벡터 임베딩을 생성해요.
2(a)단계: ingest 파이프라인 만들기
스파스 벡터 임베딩을 생성하려면 문서 필드의 텍스트를 벡터 임베딩으로 변환하는 sparse_encoding 프로세서가 포함된 ingest 파이프라인을 만들어야 해요. 프로세서의 field_map은 벡터 임베딩을 생성할 입력 필드와 임베딩을 저장할 출력 필드를 결정해요.
다음 예제 요청은 passage_text의 텍스트가 스파스 벡터 임베딩으로 변환되어 passage_embedding에 저장되는 ingest 파이프라인을 만들어요. 요청에 등록한 모델의 모델 ID를 입력하세요:
PUT /_ingest/pipeline/nlp-ingest-pipeline-sparse
{
"description": "An sparse encoding ingest pipeline",
"processors": [
{
"sparse_encoding": {
"model_id": "<bi-encoder or doc-only model ID>",
"prune_type": "max_ratio",
"prune_ratio": 0.1,
"field_map": {
"passage_text": "passage_embedding"
}
}
}
]
}
{% include copy-curl.html %}
긴 텍스트를 여러 passage로 나누려면 sparse_encoding 프로세서 앞에 text_chunking ingest 프로세서를 사용하세요. 자세한 내용은 Text chunking을 참조하세요.
2(b)단계: 수집용 인덱스 만들기
파이프라인에 정의한 sparse encoding 프로세서를 사용하려면 rank features 인덱스를 만들고, 이전 단계에서 만든 파이프라인을 기본 파이프라인으로 추가해야 해요. field_map에 정의된 필드가 올바른 타입으로 매핑되어 있는지 확인하세요. 예제를 이어서 보면, passage_embedding 필드는 rank_features로 매핑해야 해요. 마찬가지로 passage_text 필드는 text로 매핑해야 해요.
다음 예제 요청은 기본 ingest 파이프라인으로 구성된 rank features 인덱스를 만들어요:
PUT /my-nlp-index
{
"settings": {
"default_pipeline": "nlp-ingest-pipeline-sparse"
},
"mappings": {
"properties": {
"id": {
"type": "text"
},
"passage_embedding": {
"type": "rank_features"
},
"passage_text": {
"type": "text"
}
}
}
}
{% include copy-curl.html %}
디스크 공간을 절약하려면 다음과 같이 소스에서 임베딩 벡터를 제외할 수 있어요:
PUT /my-nlp-index
{
"settings": {
"default_pipeline": "nlp-ingest-pipeline-sparse"
},
"mappings": {
"_source": {
"excludes": [
"passage_embedding"
]
},
"properties": {
"id": {
"type": "text"
},
"passage_embedding": {
"type": "rank_features"
},
"passage_text": {
"type": "text"
}
}
}
}
{% include copy-curl.html %}
<token, weight> 쌍이 소스에서 제외되면 다시 복구할 수 없어요. 이 최적화를 적용하기 전에 애플리케이션에서 <token, weight> 쌍이 필요하지 않은지 확인하세요.
{: .important}
2(c)단계: 인덱스에 문서 수집하기
이전 단계에서 만든 인덱스에 문서를 수집하려면 다음 요청을 보내세요:
PUT /my-nlp-index/_doc/1
{
"passage_text": "Hello world",
"id": "s1"
}
{% include copy-curl.html %}
PUT /my-nlp-index/_doc/2
{
"passage_text": "Hi planet",
"id": "s2"
}
{% include copy-curl.html %}
문서가 인덱스에 수집되기 전에 ingest 파이프라인이 문서에 sparse_encoding 프로세서를 실행해 passage_text 필드의 벡터 임베딩을 생성해요. 색인된 문서에는 원본 텍스트가 담긴 passage_text 필드와 벡터 임베딩이 담긴 passage_embedding 필드가 포함돼요.
3단계: 데이터 검색하기
인덱스에서 neural sparse 검색을 수행하려면 Query DSL 쿼리에서 neural_sparse 쿼리 절을 사용하세요.
다음 예제 요청은 neural_sparse 쿼리를 사용해 원문 텍스트 쿼리로 관련 문서를 검색해요. bi-encoder 모드에서는 모델 ID를, 사용자 지정 토크나이저를 사용하는 doc-only 모드에서는 토크나이저 ID를 입력하세요:
GET my-nlp-index/_search
{
"query": {
"neural_sparse": {
"passage_embedding": {
"query_text": "Hi world",
"model_id": "<bi-encoder or tokenizer ID>"
}
}
}
}
{% include copy-curl.html %}
응답에는 일치하는 문서가 포함되어 있어요:
{
"took" : 688,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 30.0029,
"hits" : [
{
"_index" : "my-nlp-index",
"_id" : "1",
"_score" : 30.0029,
"_source" : {
"passage_text" : "Hello world",
"passage_embedding" : {
"!" : 0.8708904,
"door" : 0.8587369,
"hi" : 2.3929274,
"worlds" : 2.7839446,
"yes" : 0.75845814,
"##world" : 2.5432441,
"born" : 0.2682308,
"nothing" : 0.8625516,
"goodbye" : 0.17146169,
"greeting" : 0.96817183,
"birth" : 1.2788506,
"come" : 0.1623208,
"global" : 0.4371151,
"it" : 0.42951578,
"life" : 1.5750692,
"thanks" : 0.26481047,
"world" : 4.7300377,
"tiny" : 0.5462298,
"earth" : 2.6555297,
"universe" : 2.0308156,
"worldwide" : 1.3903781,
"hello" : 6.696973,
"so" : 0.20279501,
"?" : 0.67785245
},
"id" : "s1"
}
},
{
"_index" : "my-nlp-index",
"_id" : "2",
"_score" : 16.480486,
"_source" : {
"passage_text" : "Hi planet",
"passage_embedding" : {
"hi" : 4.338913,
"planets" : 2.7755864,
"planet" : 5.0969057,
"mars" : 1.7405145,
"earth" : 2.6087382,
"hello" : 3.3210192
},
"id" : "s2"
}
}
]
}
}
검색용 기본 모델 구성하기
사용자 지정 모델을 사용할 때는 인덱스 수준에서 기본 모델 ID를 구성해 쿼리를 단순화할 수 있어요. 이렇게 하면 매 쿼리마다 model_id를 지정할 필요가 없어요.
먼저 neural_query_enricher 프로세서가 포함된 search 파이프라인을 만드세요:
PUT /_search/pipeline/neural_search_pipeline
{
"request_processors": [
{
"neural_query_enricher" : {
"default_model_id": "<bi-encoder model/tokenizer ID>"
}
}
]
}
{% include copy-curl.html %}
그다음 이 파이프라인을 인덱스의 기본 파이프라인으로 설정하세요:
PUT /my-nlp-index/_settings
{
"index.search.default_pipeline" : "neural_search_pipeline"
}
{% include copy-curl.html %}
기본 모델을 구성하고 나면 쿼리를 실행할 때 model_id를 생략할 수 있어요.
인덱스에 기본 모델을 설정하는 방법, 또는 특정 필드에 기본 모델을 설정하는 방법에 대한 자세한 내용은 인덱스 또는 필드에 기본 모델 설정하기를 참조하세요.
다음 단계
- 튜토리얼을 살펴보고 AI 검색 애플리케이션을 만드는 방법을 알아보세요.