자체 벡터 사용

원본 보기

Elasticsearch에서 자체 dense 벡터 사용

Elasticsearch를 사용하면 콘텐츠의 수학적 표현인 임베딩 또는 벡터를 저장하고 검색할 수 있으며, 이는 AI 기반 관련성의 토대가 됩니다. 벡터 표현에는 densesparse 두 가지 유형이 있으며, 각각 서로 다른 쿼리와 사용 사례에 적합합니다(예: 유사한 이미지와 콘텐츠 찾기, 확장된 용어와 가중치 저장).

벡터 검색 입문 가이드에서는 Elasticsearch에 dense 벡터를 저장하고 검색합니다. 또한 k-최근접 이웃(kNN) 쿼리로 이러한 문서를 조회하는 문법도 배웁니다.

  • Elasticsearch Serverless를 사용 중이라면 샘플 데이터를 추가하기 위해 developer 또는 admin 사전 정의 역할이나 이에 상응하는 커스텀 역할이 있어야 합니다.
  • Elastic Cloud Hosted나 자체 관리 클러스터를 사용 중이라면 Elasticsearch와 Kibana를 시작하세요. 이 가이드의 단계를 완료하는 가장 간단한 방법은 superuser 내장 역할을 가진 사용자로 로그인하는 것입니다.

역할 기반 접근 제어에 대해 알아보려면 사용자 역할을 확인하세요.

Elasticsearch Serverless 프로젝트 프로필에 대해 알아보려면 Elasticsearch의 dense 벡터 검색 > 범용 프로젝트와 벡터 최적화 프로젝트를 참고하세요.

벡터를 생성할 때(즉, 데이터를 벡터화할 때) 복잡한 콘텐츠(텍스트, 이미지, 오디오, 비디오)를 다차원 수치 표현으로 변환하게 됩니다. 이러한 벡터는 효율적인 유사도 검색과 빠른 kNN 거리 계산을 가능하게 하는 특수 데이터 구조에 저장됩니다.

이 가이드에서는 dense 벡터 임베딩이 이미 포함된 문서를 사용합니다. Elasticsearch에 벡터 임베딩 모델을 배포하고 인덱싱 및 검색 시점에 벡터를 생성하려면 더 알아보기의 링크를 참고하세요.

이 고급 사용 사례는 임베딩과 인덱싱을 직접 제어하기 위해 dense_vector 필드 타입을 사용합니다. semantic_text 필드 타입을 사용하는 관리형 워크플로에 대해서는 텍스트 시맨틱 검색을 참고하세요. 두 방식을 비교하려면 시맨틱 검색과 벡터 검색을 참고하세요.

  1. dense 벡터 필드 매핑으로 인덱스 생성

    기본 데이터 세트의 각 문서는 다음을 포함합니다.

    • 리뷰: review_text 필드에 저장
    • 해당 리뷰의 임베딩: dense_vector 데이터 타입으로 정의된 review_vector 필드에 저장

    dense_vector 타입은 float 벡터를 검색할 때 메모리 사용량을 줄이기 위해 양자화를 자동으로 사용합니다. 기본 양자화 전략과 성능·정확도 균형에 대해서는 Dense 벡터 필드 타입에서 자세히 알아보세요.

    다음 API 요청은 review_textreview_vector 필드를 정의합니다.

    				PUT /amazon-reviews
    					{
      "mappings": {
        "properties": {
          "review_vector": {
            "type": "dense_vector",
            "dims": 8,
            "index": true,
            "similarity": "cosine"
          },
          "review_text": {
            "type": "text"
          }
        }
      }
    }
    		
    1. dims 파라미터는 임베딩 벡터의 길이와 일치해야 합니다. 지정하지 않으면 dims는 처음 인덱싱된 문서를 기준으로 동적으로 계산됩니다.
    2. index 파라미터는 knn 쿼리를 사용할 수 있도록 true로 설정합니다.
    3. similarity 파라미터는 쿼리 벡터와 문서 벡터를 비교하는 데 사용되는 유사도 함수를 정의합니다. cosine은 Elasticsearch에서 dense_vector 필드의 기본 유사도 함수입니다.

    여기서는 가독성을 위해 8차원 임베딩을 사용합니다. 신경망 모델이 다루는 벡터는 수백 또는 수천 차원에 이를 수 있으며, 이는 다차원 공간상의 한 점을 나타냅니다. 각 차원은 비정형 데이터의 특징이나 속성을 나타냅니다.

  2. 임베딩이 포함된 문서 추가

    먼저 문서 하나를 인덱싱해 문서 구조를 파악하세요.

    벡터는 두 가지 입력 형식으로 제공할 수 있습니다.

    • float 배열: 각 벡터 차원을 나타내는 수치 값의 JSON 배열입니다.
    • Base64 인코딩 문자열: 벡터의 Base64 인코딩 바이너리 표현입니다. float 배열보다 간결해 페이로드 크기를 줄이고 대용량 벡터와 대량 인덱싱의 효율을 높입니다. Python 클라이언트 dense 벡터 패킹 유틸리티를 사용해 float 배열을 Base64 인코딩 바이너리 표현으로 변환할 수 있습니다.
    				PUT /amazon-reviews/_doc/1
    					{
      "review_text": "This product is lifechanging! I'm telling all my friends about it.",
      "review_vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]
    }
    		
    1. review_vector 값은 8차원이며, 매핑에 지정된 dims 개수와 일치합니다.
    				PUT /amazon-reviews/_doc/1
    					{
      "review_text": "This product is lifechanging! I'm telling all my friends about it.",
      "review_vector": "PczMzT5MzM0+mZmaPszMzT8AAAA/GZmaPzMzMz9MzM0="
    }
    		
  3. 운영 환경에서는 _bulk 엔드포인트를 사용해 여러 문서를 한 번에 인덱싱하게 됩니다. 다음은 단일 _bulk 요청으로 여러 문서를 인덱싱하는 예시입니다.

    				POST /_bulk
    					{ "index": { "_index": "amazon-reviews", "_id": "2" } }
    { "review_text": "This product is amazing! I love it.", "review_vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8] }
    { "index": { "_index": "amazon-reviews", "_id": "3" } }
    { "review_text": "This product is terrible. I hate it.", "review_vector": [0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1] }
    { "index": { "_index": "amazon-reviews", "_id": "4" } }
    { "review_text": "This product is great. I can do anything with it.", "review_vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8] }
    { "index": { "_index": "amazon-reviews", "_id": "5" } }
    { "review_text": "This product has ruined my life and the lives of my family and friends.", "review_vector": [0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1] }
    		
    				POST /_bulk
    					{ "index": { "_index": "amazon-reviews", "_id": "2" } }
    { "review_text": "This product is amazing! I love it.", "review_vector": "PczMzT5MzM0+mZmaPszMzT8AAAA/GZmaPzMzMz9MzM0=" }
    { "index": { "_index": "amazon-reviews", "_id": "3" } }
    { "review_text": "This product is terrible. I hate it.", "review_vector": "P0zMzT8zMzM/GZmaPwAAAD7MzM0+mZmaPkzMzT3MzM0=" }
    { "index": { "_index": "amazon-reviews", "_id": "4" } }
    { "review_text": "This product is great. I can do anything with it.", "review_vector": "PczMzT5MzM0+mZmaPszMzT8AAAA/GZmaPzMzMz9MzM0=" }
    { "index": { "_index": "amazon-reviews", "_id": "5" } }
    { "review_text": "This product has ruined my life and the lives of my family and friends.", "review_vector": "P0zMzT8zMzM/GZmaPwAAAD7MzM0+mZmaPkzMzT3MzM0=" }
    		

이제 knn retriever를 사용해 이 문서 벡터들을 조회할 수 있습니다. knn은 쿼리 벡터와 가장 유사한 문서 k개를 찾는 벡터 유사도 검색의 한 종류입니다. 여기서는 시연을 위해 쿼리 텍스트로 원시 벡터를 사용합니다.

				POST /amazon-reviews/_search
					{
  "retriever": {
    "knn": {
      "field": "review_vector",
      "query_vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8],
      "k": 2,
      "num_candidates": 5
    }
  }
}
		
  1. 이 예시에서는 원시 벡터가 쿼리 텍스트 역할을 합니다. 실제 환경에서는 임베딩 모델을 사용해 쿼리 벡터를 생성하게 됩니다.
  2. k 파라미터는 반환할 결과 수를 지정합니다.
  3. num_candidates 파라미터는 선택 사항입니다. 검색 노드가 반환하는 후보 수를 제한합니다. 이를 통해 성능을 개선하고 비용을 줄일 수 있습니다.

Elasticsearch 클라이언트에서 비슷한 워크플로를 시도해 보려면 Elasticsearch Serverless, Elastic Cloud Hosted 또는 자체 관리 클러스터에서 다음 안내형 인덱스 워크플로를 사용하세요.

  • 내비게이션 메뉴 또는 전역 검색 필드를 사용해 Index Management 페이지로 이동합니다.
  • Create index를 선택합니다. 이름을 지정한 다음 Create my index를 선택합니다.
  • Vector Search 옵션을 선택하고 안내형 워크플로를 따릅니다.

테스트를 마치고 샘플 데이터 세트가 더 이상 필요 없으면 인덱스를 삭제하세요.

				DELETE /amazon-reviews
		

이 기본 예시들에서는 쿼리 텍스트로 원시 벡터를 전송합니다. 실제 환경에서는 쿼리 텍스트를 미리 알 수 없습니다. 문서 벡터를 생성한 것과 동일한 임베딩 모델을 사용해 쿼리 벡터를 즉석에서 생성하게 됩니다. 이를 위해 Elasticsearch에 텍스트 임베딩 모델을 배포하고 query_vector_builder 파라미터를 사용하세요. 또는 클라이언트 측에서 벡터를 생성해 검색 요청과 함께 직접 전송할 수도 있습니다.

파이프라인을 사용해 텍스트 임베딩을 생성하는 예시는 튜토리얼: 인제스트 파이프라인을 사용한 dense 및 sparse 워크플로를 확인하세요.

시맨틱, 전문 검색, 하이브리드 등 Elasticsearch의 검색 옵션에 대해 자세히 알아보려면 검색 방식을 참고하세요.