Semantic 필드 타입
Semantic 필드 타입
semantic 필드 타입은 OpenSearch에서 신경망 검색(neural search) 설정을 단순화하는 고수준 추상화예요. 모든 문자열 및 binary 필드를 포함한 다양한 필드 타입을 감쌀 수 있어요. semantic 필드 타입은 구성된 머신러닝(ML) 모델을 기반으로 시맨틱 색인과 쿼리를 자동으로 활성화해요.
전제 조건: semantic 필드 타입을 사용하기 전에 OpenSearch 클러스터에 호스팅된 로컬 ML 모델이나 클러스터에 연결된 외부 호스팅 모델을 구성해야 해요. 로컬 모델에 대한 자세한 내용은 OpenSearch 내에서 ML 모델 사용하기를, 외부 호스팅 모델에 대한 자세한 내용은 외부 호스팅 모델에 연결하기를 참고하세요.
출처: 문서
본문
예시: 밀집 임베딩 모델
semantic 필드 타입은 대칭(symmetric)과 비대칭(asymmetric) 임베딩 모델을 모두 지원해요. 대칭 모델은 문서와 쿼리 모두에 같은 임베딩 표현을 사용해요. 비대칭 모델(예: E5)은 수집 중에 문서 내용을 passage로 인코딩하고, 검색 시점에 쿼리 텍스트를 query로 인코딩해요.
모델을 구성하면 이를 사용해 semantic 필드가 있는 인덱스를 만들 수 있어요. 이 예시는 클러스터에 ID가 n17yX5cBsaYnPfyOzmQU인 밀집 임베딩 모델을 구성했다고 가정해요.
PUT /my-nlp-index
{
"settings": {
"index": {
"knn": true
}
},
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "n17yX5cBsaYnPfyOzmQU"
}
}
}
}
인덱스를 만든 뒤에는 매핑을 검색해 passage_semantic_info 필드가 자동으로 생성되었는지 확인할 수 있어요. passage_semantic_info 필드는 밀집 임베딩을 저장하기 위한 knn_vector 하위 필드와 모델 ID, 모델 이름, 모델 타입 같은 정보를 캡처하기 위한 추가 메타데이터 필드를 포함해요.
GET /my-nlp-index/_mapping
{
"my-nlp-index": {
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "n17yX5cBsaYnPfyOzmQU",
"raw_field_type": "text"
},
"passage_semantic_info": {
"properties": {
"embedding": {
"type": "knn_vector",
"dimension": 384,
"method": {
"engine": "faiss",
"space_type": "l2",
"name": "hnsw",
"parameters": {}
}
},
"model": {
"properties": {
"id": {
"type": "text",
"index": false
},
"name": {
"type": "text",
"index": false
},
"type": {
"type": "text",
"index": false
}
}
}
}
}
}
}
}
}
knn_vector 필드의 dimension과 space_type은 ML 모델 구성에 의해 결정돼요. 사전 훈련된 밀집 모델의 경우 이 정보는 기본 모델 구성에 포함돼요. 외부 호스팅 밀집 임베딩 모델의 경우, semantic 필드와 함께 모델을 사용하기 전에 모델 구성에서 dimension과 space_type을 명시적으로 정의해야 해요.
자동 생성된 knn_vector 하위 필드는 현재 semantic 필드에서 구성할 수 없는 추가 설정을 지원해요. 자세한 내용은 제한 사항(Limitations)을 참고하세요.
예시: 희소 인코딩 모델
모델을 구성하면 이를 사용해 semantic 필드가 있는 인덱스를 만들 수 있어요. 이 예시는 클러스터에 ID가 n17yX5cBsaYnPfyOzmQU인 희소 인코딩 모델을 구성했다고 가정해요.
PUT /my-nlp-index
{
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "nF7yX5cBsaYnPfyOq2SG"
}
}
}
}
인덱스를 만든 뒤에는 매핑을 검색해 rank_features 필드가 자동으로 생성되었는지 확인할 수 있어요.
GET /my-nlp-index/_mapping
{
"my-nlp-index": {
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "nF7yX5cBsaYnPfyOq2SG",
"raw_field_type": "text"
},
"passage_semantic_info": {
"properties": {
"embedding": {
"type": "rank_features"
},
"model": {
"properties": {
"id": {
"type": "text",
"index": false
},
"name": {
"type": "text",
"index": false
},
"type": {
"type": "text",
"index": false
}
}
}
}
}
}
}
}
}
파라미터 (Parameters)
semantic 필드 타입은 다음 파라미터를 지원해요.
| 파라미터 | 데이터 타입 | 업데이트 가능 | 필수/선택 | 설명 |
|---|---|---|---|---|
type |
String | 아니요 | 필수 | 반드시 semantic으로 설정해야 해요. |
raw_field_type |
String | 아니요 | 선택 | semantic 필드가 감싸는 기본 필드 타입이에요. 원시 입력은 semantic 필드의 경로에 이 타입으로 저장되어, 해당 타입의 표준 필드처럼 동작하게 해요. 유효 값은 text, keyword, match_only_text, wildcard, token_count, binary예요. 기본값은 text예요. 기본 필드 타입이 지원하는 어떤 파라미터든 사용할 수 있고, 그 파라미터들은 예상대로 동작해요. |
model_id |
String | 예 | 필수 | 색인 중 필드 값에서, 검색 중 쿼리 입력에서 임베딩을 생성하는 데 사용되는 ML 모델의 ID예요. |
search_model_id |
String | 예 | 선택 | 쿼리 시점 임베딩 생성에 특별히 사용되는 ML 모델의 ID예요. 지정하지 않으면 model_id가 사용돼요. semantic_field_search_analyzer와 함께 지정할 수 없어요. |
semantic_info_field_name |
String | 아니요 | 선택 | 임베딩과 모델 정보를 저장하는 내부 메타데이터 필드의 사용자 지정 이름이에요. 기본적으로 이 필드 이름은 semantic 필드 이름에 _semantic_info를 붙여 만들어져요. |
chunking |
Boolean 또는 Array of maps | 아니요 | 선택 | 수집 중에 긴 형식의 텍스트를 청킹(chunking)할 수 있게 해요. true로 설정하면 기본 고정 토큰 길이 전략을 사용하고, 여러 청킹 알고리즘을 순차적으로 적용하려면 전략 객체의 목록을 지정할 수 있어요. Text chunking을 참고하세요. |
semantic_field_search_analyzer |
String | 예 | 선택 | 희소 모델을 사용할 때 쿼리 입력을 토큰화하기 위한 analyzer를 지정해요. 유효 값은 standard, bert-uncased, mbert-uncased예요. search_model_id와 함께 사용할 수 없어요. 자세한 내용은 Analyzers를 참고하세요. |
dense_embedding_config |
Map | 아니요 | 선택 | semantic 필드가 밀집 임베딩 모델에 의해 뒷받침될 때 사용되는 기본 knn_vector 필드에 대한 사용자 지정 설정을 정의해요. 이는 벡터 색인 동작, 유사도 함수, 엔진 파라미터를 세밀하게 제어할 수 있게 해요. 생략하면 OpenSearch는 모델의 임베딩 차원과 엔진 기본값에 따라 기본 설정을 적용해요. 지원 파라미터는 Dense embedding config를 참고하세요. |
sparse_encoding_config |
Map | 아니요 | 선택 | 희소 모델을 사용할 때 semantic 필드에 대해 희소 벡터를 인코딩하는 방식을 구성해요. sparse_encoding 프로세서에서 사용 가능한 모든 프루닝(pruning) 전략을 지원해요. 생략하면 프루닝 비율 0.1의 max_ratio를 사용하는 기본 프루닝 전략이 적용돼요. 이는 희소 벡터의 가장 정보량이 많은 차원을 보존하면서 노이즈와 인덱스 크기를 줄이는 데 도움이 돼요. 지원 파라미터는 Sparse encoding config를 참고하세요. |
skip_existing_embedding |
Boolean | 예 | 선택 | semantic 필드의 임베딩 생성을 건너뛸지 여부를 결정해요. 활성화하면 OpenSearch는 기존 문서를 확인해 semantic 필드에 이미 임베딩이 있고 임베딩 생성에 사용된 ML 모델의 ID와 semantic 필드 값이 모두 변경되지 않았는지 확인해요. 두 조건이 모두 참이면 OpenSearch는 기존 임베딩을 재사용하고 생성을 건너뛰어요. 기본값은 false예요. |
텍스트 청킹 (Text chunking)
기본적으로 semantic 필드에서는 텍스트 청킹이 비활성화돼 있어요. 청킹을 활성화하려면 각 청크의 임베딩을 nested 객체에 저장해야 하므로 검색 지연 시간이 늘어날 수 있기 때문이에요. nested 객체를 검색하려면 자식 문서를 부모에 조인해야 하며, 추가적인 스코어링과 집계 로직이 필요해요. 매칭되는 자식 문서가 많을수록 잠재적 지연 시간은 더 높아져요.
긴 형식의 텍스트로 작업하고 검색 관련성을 개선하고 싶다면, semantic 필드의 chunking 파라미터를 통해 청킹을 활성화할 수 있어요.
기본 청킹 구성
기본 청킹 동작(모든 기본값을 사용한 고정 토큰 길이)을 활성화하려면 chunking을 true로 설정해요.
PUT /my-nlp-index
{
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "nF7yX5cBsaYnPfyOq2SG",
"chunking": true
}
}
}
}
이는 알고리즘을 fixed_token_length로 설정하는 것과 동일해요.
PUT /my-nlp-index
{
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "nF7yX5cBsaYnPfyOq2SG",
"chunking": [
{
"algorithm": "fixed_token_length"
}
]
}
}
}
}
청킹은 고정 토큰 길이 알고리즘을 사용해 수행돼요.
고급 청킹 구성
고급 청킹 구성을 설정하려면 chunking을 청킹 전략 목록으로 지정할 수 있어요. 각 전략은 semantic 필드에 순차적으로 적용돼요. 목록의 각 항목은 알고리즘과 그 파라미터를 지정해야 해요.
예를 들어 deliminator 알고리즘을 적용한 뒤 고정 토큰 청킹을 적용하려면 다음 요청을 사용해요. 텍스트는 먼저 문단 구분(\n\n)에서 분할되고, 각 결과 세그먼트는 고정 크기 토큰 청크로 나뉘어요.
PUT /my-nlp-index
{
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "nF7yX5cBsaYnPfyOq2SG",
"chunking": [
{
"algorithm": "delimiter",
"parameters": {
"delimiter": "\n\n"
}
},
{
"algorithm": "fixed_token_length",
"parameters": {
"token_limit": 128,
"overlap_rate": 0.2
}
}
]
}
}
}
}
이를 통해 입력 텍스트가 분할되는 방식을 더 잘 제어할 수 있고, 임베딩이 자연어 경계를 더 잘 반영하도록 보장해요.
지원 알고리즘
chunking 파라미터는 텍스트 청킹 ingest 프로세서가 지원하는 모든 알고리즘을 지원해요.
밀집 임베딩 구성 (Dense embedding configuration)
semantic 필드가 밀집 모델을 사용하면, OpenSearch는 임베딩을 저장하기 위한 동반 knn_vector 필드를 자동으로 생성해요. 인덱스 생성 중에 이 벡터 필드가 구성되는 방식을 사용자 지정하려면 dense_embedding_config 파라미터를 사용할 수 있어요.
dense_embedding_config의 구조는 표준 knn_vector 필드의 구성과 매우 유사해요. 이 파라미터를 사용해 k-NN 엔진과 색인 동작 같은 설정을 구성할 수 있어요.
dense_embedding_config의 모든 지원 파라미터는 k-NN vector 파라미터를 참고하세요. dense_embedding_config는 knn_vector와 같은 대부분의 옵션을 지원하지만, 다음 파라미터는 지원되지 않아요.
dimension: 임베딩 차원은 ML 모델의 출력 차원과 일치해야 하며model_id에서 자동으로 추론돼요. 올바른dimension은 필드 매핑이 아니라 모델 구성에 설정해야 해요.space_type: 유사도 공간(예:cosinesimil,l2,innerproduct)은 모델과 일치해야 하며 모델 구성에서 결정돼요.
다음 예시는 dense_embedding_config를 포함해요.
PUT /my-nlp-index
{
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "nF7yX5cBsaYnPfyOq2SG",
"dense_embedding_config": {
"method": {
"name": "hnsw",
"engine": "lucene",
"parameters": {
"ef_construction": 128,
"m": 32
}
}
}
}
}
}
}
희소 인코딩 구성 (Sparse encoding configuration)
semantic 필드가 희소 모델을 사용하면, OpenSearch는 희소 벡터 표현을 저장하기 위한 동반 필드를 자동으로 생성해요. 기본적으로 이 벡터는 차원을 줄이고 효율성을 개선하기 위해 프루닝(pruning)돼요.
sparse_encoding_config 파라미터는 전략과 그 파라미터를 지정함으로써 인코딩 중에 프루닝이 적용되는 방식을 제어할 수 있게 해요. 이는 희소 벡터가 색인되는 방식을 세밀하게 제어해 정확도와 저장/성능 사이의 균형을 잡아요.
sparse_encoding_config 객체는 희소 인코딩 ingest 프로세서에서 사용 가능한 모든 프루닝 전략을 지원해요.
다음 예시는 sparse_encoding_config를 포함해요. 희소 벡터에서 점수가 가장 높은 64개 용어만 유지해요.
PUT /my-nlp-index
{
"mappings": {
"properties": {
"passage": {
"type": "semantic",
"model_id": "nF7yX5cBsaYnPfyOq2SG",
"sparse_encoding_config": {
"prune_type": "top_k",
"prune_ratio": 64
}
}
}
}
}
Semantic 필드의 수집 배치 크기
semantic 필드가 포함된 인덱스에 문서를 수집할 때, OpenSearch는 시스템 생성 ingest 파이프라인을 사용해 기본 ML 모델을 호출하고 임베딩을 생성해요. 성능을 최적화하기 위해 이 연산들은 배치로 처리돼요.
이 단계에서 함께 처리되는 문서 수는 인덱스 수준의 동적 설정 index.neural_search.semantic_ingest_batch_size로 제어할 수 있어요. 이 설정은 수집 중에 semantic 필드의 임베딩을 생성할 때 함께 배치되는 문서 수를 지정해요(기본값은 10).
배치는 모델 추론 오버헤드를 줄여 처리량을 개선해요. 하지만 배치 크기를 늘리면 메모리 사용량도 늘어날 수 있어요. 모델의 성능 특성과 예상 수집량에 따라 이 설정을 튜닝해야 해요.
이 설정은 한 배치에서 함께 처리되는 문서 수를 제어하지만, 모델로 전송되는 입력의 크기를 직접 결정하지는 않아요.
단일 문서에 여러 semantic 필드가 있으면 각각에 대해 임베딩이 생성돼요.
semantic 필드에 텍스트 청킹이 활성화되어 있으면 내용이 여러 청크로 분할될 수 있고, 각 청크에 대해 임베딩이 생성돼요. 결과적으로 배치당 실제 모델 추론 호출 수와 총 임베딩 입력 수는 배치 크기 값보다 크게 높을 수 있어요.
다음 예시는 my-index 인덱스의 수집 배치 크기를 32로 업데이트해요. 변경은 즉시 적용되며, 이후 수집되는 semantic 필드를 포함한 모든 문서에 적용돼요.
PUT /my-index/_settings
{
"index": {
"neural_search.semantic_ingest_batch_size": 32
}
}
동적 설정 업데이트에 대한 자세한 내용은 Dynamic settings를 참고하세요.
제한 사항 (Limitations)
semantic 필드의 다음 제한 사항에 유의하세요.
- 원격 클러스터 지원:
semantic필드에 대한 신경망 쿼리는 cross-cluster 검색에서 지원되지 않아요. 원격 인덱스에서 문서를 검색할 수 있지만, 시맨틱 쿼리는 로컬 모델 구성과 인덱스 매핑에 대한 접근이 필요해요. 따라서 기존 쿼리 방법으로 임베딩 필드에 직접 쿼리를 실행해야 해요. - 매핑 제한:
semantic필드는 동적 매핑을 지원하지 않으며 인덱스 매핑에 명시적으로 정의되어야 해요. 또한 다른 필드의fields섹션에서semantic필드를 사용할 수 없으므로 멀티 필드 구성은 지원되지 않아요.
다음 단계 (Next steps)
- 시맨틱 검색을 위해 텍스트 임베딩 모델과 함께
semantic필드 사용하기 - 신경망 희소 검색을 위해 희소 인코딩 모델과 함께
semantic필드 사용하기