다음을 통해 공유


Azure AI Search의 벡터 쿼리에 필터 추가

필터 식을 포함하는 벡터 쿼리 요청을 정의하여 쿼리에 포함 또는 제외 조건을 추가할 수 있습니다. 이 문서에서는 다음 방법을 알아봅니다.

이 문서에서는 설명을 위해 REST를 사용합니다. 다른 언어로 된 코드 샘플은 벡터 쿼리가 포함된 엔드투엔드 솔루션을 위한 azure-search-vector-samples GitHub 리포지토리를 참조하세요.

Azure Portal에서 검색 탐색기를 사용하여 벡터 콘텐츠를 쿼리할 수도 있습니다. JSON 보기를 사용하는 경우 필터를 추가하고 필터 모드를 지정할 수 있습니다.

벡터 쿼리에서 필터링이 작동하는 방식

필터는 필터 조건에 따라 검색 문서를 포함하거나 제외하기 위해 문자열 필드 또는 숫자인 filterable 비벡터 필드에 적용됩니다. 벡터 필드 자체는 필터링할 수 없지만 벡터 필드가 포함된 문서를 포함하거나 제외하는 등 동일한 인덱스의 다른 필드에 필터를 적용할 수 있습니다.

필터는 vectorFilterMode 매개 변수에 따라 쿼리 실행 전후에 적용됩니다.

필터 정의

필터는 벡터 쿼리의 범위를 결정합니다. 필터는 인덱스에서 filterable 특성이 있는 벡터가 아닌 문자열 및 숫자 필드에 대해 설정되고 반복되지만, 필터의 목적에 따라 벡터 쿼리가 실행되는 대상, 즉 쿼리 가능한 전체 공간 또는 검색 결과의 콘텐츠가 결정됩니다.

텍스트 또는 숫자 값이 있는 원본 필드가 없는 경우 메타데이터 필터에서 유용할 수 있는 LastModified 또는 CreatedBy 속성과 같은 문서 메타데이터를 확인합니다.

2024-07-01은 이 API의 안정적인 버전입니다. 여기에는:

  • 프리필더(기본값)용 vectorFilterMode 또는 필터링 모드 사후 필터
  • filter 에서는 조건을 제공합니다.

다음 예제에서 벡터는 "Azure 서비스에서 전체 텍스트 검색을 지원하는 항목"이라는 쿼리 문자열의 표현입니다. 쿼리는 contentVector 필드를 대상으로 합니다. 실제 벡터에는 1,536개의 임베딩이 있으므로 가독성을 위해 이 예제에서 잘립니다.

필터 조건은 검색 엔진이 벡터 쿼리를 실행하기 전에 필터링 가능한 텍스트 필드(이 예의 category)에 적용됩니다.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-07-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "count": true,
    "select": "title, content, category",
    "filter": "category eq 'Databases'",
    "vectorFilterMode": "preFilter",
    "vectorQueries": [
        {
            "kind": "vector",
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "exhaustive": true,
            "fields": "contentVector",
            "k": 5
        }
    ]
}

vectorFilterMode 설정

vectorFilterMode 쿼리 매개 변수는 필터가 벡터 쿼리 실행 전후에 적용되는지 여부를 결정합니다.

사전 필터링 모드 사용

사전 필터링은 쿼리 실행 전에 필터를 적용하여 벡터 검색 알고리즘이 유사한 콘텐츠를 찾는 검색 노출 영역을 줄입니다.

벡터 쿼리에서는 preFilter가 기본값입니다.

사전 필터 다이어그램.

사후 필터링 모드 사용

사후 필터링은 쿼리 실행 후 필터를 적용하여 검색 결과의 범위를 좁힙니다.

사후 필터 다이어그램.

벡터 필터 모드의 벤치마크 테스트

한 필터 모드가 다른 필터 모드보다 더 나은 성능을 보이는 조건을 이해하기 위해 일련의 테스트를 실행하여 소형, 중간 및 대형 인덱스에 대한 쿼리 결과를 평가했습니다.

  • 소형(문서 100,000개, 2.5GB 인덱스, 1536개차원)
  • 중형(문서 100만 개, 25GB 인덱스, 1536개 차원)
  • 대형(문서 10억 개, 1.9TB 인덱스, 96개 차원)

중소 규모 워크로드의 경우 파티션 1개와 복제본 1개가 있는 S2(표준 2) 서비스를 사용했습니다. 대규모 워크로드의 경우 파티션 12개와 복제본 1개가 있는 S3(표준 3) 서비스를 사용했습니다.

인덱스에는 키 필드 1개, 벡터 필드 1개, 텍스트 필드 1개, 필터링 가능한 숫자 필드 1개 등, 동일한 구조가 있습니다. 다음 인덱스는 2023-11-03 구문을 사용하여 정의됩니다.

def get_index_schema(self, index_name, dimensions):
    return {
        "name": index_name,
        "fields": [
            {"name": "id", "type": "Edm.String", "key": True, "searchable": True},
            {"name": "content_vector", "type": "Collection(Edm.Single)", "dimensions": dimensions,
              "searchable": True, "retrievable": True, "filterable": False, "facetable": False, "sortable": False,
              "vectorSearchProfile": "defaulthnsw"},
            {"name": "text", "type": "Edm.String", "searchable": True, "filterable": False, "retrievable": True,
              "sortable": False, "facetable": False},
            {"name": "score", "type": "Edm.Double", "searchable": False, "filterable": True,
              "retrievable": True, "sortable": True, "facetable": True}
        ],
      "vectorSearch": {
        "algorithms": [
            {
              "name": "defaulthnsw",
              "kind": "hnsw",
              "hnswParameters": { "metric": "euclidean" }
            }
          ],
          "profiles": [
            {
              "name": "defaulthnsw",
              "algorithm": "defaulthnsw"
            }
        ]
      }
    }

쿼리에서는 사전 필터링 및 사후 필터링 작업 모두에 동일한 필터를 사용했습니다. 간단한 필터를 사용하여 필터 복잡성이 아니라 필터링 모드로 인해 성능 변화가 있었는지 확인했습니다.

결과는 QPS(초당 쿼리 수)로 측정되었습니다.

핵심 내용

  • 성능이 거의 같은 소형 인덱스를 제외하고, 사전 필터링은 거의 항상 사후 필터링보다 느립니다.

  • 더 큰 데이터 세트의 경우 사전 필터링은 다양한 크기만큼 더 느려집니다.

  • 그렇다면 항상 속도가 더 느려지는데도 기본적으로 사전 필터링을 사용하는 이유는 무엇일까요? 사전 필터링은 k 결과가 인덱스에 있는 경우 항상 반환되도록 보장합니다. 여기서는 속도보다 재현율 및 정밀도 쪽으로 편향됩니다.

  • 사후 필터링은 다음을 수행하는 고객을 위한 것입니다.

    • 선택 사항보다 속도에 더 가치를 둡니다(사후 필터링은 k 결과보다 더 적은 결과를 반환할 수 있음).
    • 지나치게 선택적이지 않은 필터를 사용합니다.
    • 사전 필터링 성능이 허용되지 않을만큼 충분한 크기의 인덱스가 있습니다.

세부 정보

  • 1536개 차원에서 100,000개의 벡터가 있는 데이터 세트가 제공될 경우:

    • 데이터 세트의 30% 이상을 필터링할 때는 사전 필터링 및 사후 필터링이 비슷했습니다.
    • 데이터 세트의 0.1% 미만을 필터링할 때 사전 필터링은 사후 필터링보다 약 50% 더 느렸습니다.
  • 1,536개 차원에서 100만 개의 벡터가 있는 데이터 세트가 제공될 경우:

    • 데이터 세트의 30% 이상을 필터링할 때 사전 필터링 속도가 약 30% 더 느렸습니다.
    • 데이터 세트의 2% 미만을 필터링할 때 사전 필터링은 약 7배 더 느렸습니다.
  • 96개 차원에서 10억 개의 벡터가 있는 데이터 세트가 제공될 경우:

    • 데이터 세트의 5% 이상을 필터링할 때 사전 필터링 속도가 약 50% 더 느렸습니다.
    • 데이터 세트의 10% 미만을 필터링할 때 사전 필터링은 약 7배 더 느렸습니다.

다음 그래프는 사후 필터 QPS를 사전 필터 QPS로 나누어 계산한 사전 필터 상대 QPS를 보여 줍니다.

상대 QPS에 대한 소형, 중형, 대형 인덱스의 QPS 성능을 보여 주는 차트.

세로 축은 사후 필터링의 QPS 대비 사전 필터링의 QPS입니다. 예를 들어 값이 0.0이면 사전 필터링이 100% 더 느리고, 세로 축의 0.5는 사전 필터링이 50% 더 느리고, 1.0은 사전 필터링 및 사후 필터링이 동일하다는 것을 의미합니다.

가로 축은 필터링 속도 또는 필터를 적용한 후의 후보 문서 백분율을 나타냅니다. 예를 들어 1.00%는 검색 모음의 1%가 필터 조건에 의해 선택되었음을 의미합니다.