비고
strictPostFilter는 현재 공개 미리 보기 상태입니다. 이 미리 보기는 서비스 수준 계약 없이 제공되며 프로덕션 워크로드에는 권장되지 않습니다. 특정 기능이 지원되지 않거나 기능이 제한될 수 있습니다. 자세한 내용은 Microsoft Azure Preview에 대한 추가 사용 약관을 참조하세요.
prefilter 및 postfilter는 일반적으로 최신 안정 REST API 버전에서 사용할 수 있습니다.
Azure AI Search에서 필터 식을 사용하여 벡터 쿼리에 포함 또는 제외 조건을 추가할 수 있습니다. 필터를 적용하는 필터링 모드를 지정할 수도 있습니다.
- 쿼리 실행 전, 사전 필터링이라고 합니다.
- 쿼리 실행 후, 이를 사후 필터링이라고 합니다.
- 전역 상위
k결과가 식별된 후, 이를 엄격한 사후 필터링(미리 보기)이라고 합니다.
이 문서에서는 설명을 위해 REST를 사용합니다. 다른 언어로 작성된 코드 샘플과 벡터 쿼리를 포함하는 엔드투엔드 솔루션은 azure-search-vector-samples GitHub 리포지토리를 참조하세요.
Azure Portal에서 검색 탐색기를 사용하여 벡터 콘텐츠를 쿼리할 수도 있습니다. JSON 보기에서 필터를 추가하고 필터 모드를 지정할 수 있습니다.
벡터 쿼리에서 필터링이 작동하는 방식
Azure AI 검색은 ANN(근사 가장 인접한 항목) 검색을 위해 HNSW(Hierarchical Navigable Small World) 알고리즘을 사용하여 여러 분할에 걸쳐 HNSW 그래프를 저장합니다. 각 분할된 데이터베이스에는 전체 인덱스의 일부가 포함됩니다.
필터는 문자열이나 숫자인 filterable벡터가 아닌 필드에 적용되어 필터 조건에 따라 검색 문서를 포함하거나 제외합니다. 벡터 필드 자체는 필터링할 수 없지만 동일한 인덱스의 다른 필드에 대한 필터를 사용하여 벡터 검색으로 간주되는 문서의 범위를 좁힐 수 있습니다. 인덱스에 적합한 텍스트 또는 숫자 필드가 부족한 경우 필터링에 도움이 될 수 있는 LastModified 또는 CreatedBy 속성과 같은 문서 메타데이터를 확인하십시오.
매개 변수는 vectorFilterMode 검색 단계에서 필터 작업이 적용되는 위치를 제어하며, 이는 결과가 항목의 하위 집합(예: 범주, 태그 또는 기타 특성)으로 필터링되는 방식에 영향을 미치고 대기 시간, 회수 및 처리량에 영향을 줍니다. 세 가지 모드가 있습니다.
preFilter는 각 분할에서 HNSW 트래버스 중 필터를 적용합니다. 이 모드는 회수를 최대화하지만 더 많은 그래프를 트래버스하여 매우 선택적인 필터에 대한 CPU 및 대기 시간을 늘릴 수 있습니다.postFilter는 각 분할된 데이터베이스에 대해 독립적으로 HNSW 순회 및 필터링을 실행하고, 분할된 데이터베이스 수준에서 결과를 교차한 다음, 각 분할된 데이터베이스의 상위k를 전역 상위k로 집계합니다. 이 모드는 선택성이 높은 필터나 작은k값에 대해 가음성을 만들 수 있습니다.strictPostFilter(미리 보기)는 필터를 적용k필터링되지 않은 전역 상단 을 찾습니다. 이 모드는 매우 선택적인 필터 및 작은k값에 대해 위양성을 반환할 위험이 가장 높습니다.
이러한 모드에 대한 자세한 내용은 필터 모드 설정을 참조하세요.
필터 정의
필터는 벡터 쿼리의 범위를 결정하며 문서 - 검색 POST(REST API)을 사용하여 정의됩니다. 미리 보기 기능을 사용하지 않으려면 Search 서비스 REST API의 최신 안정 버전을 사용하여 요청을 작성합니다.
이 REST API는 다음을 제공합니다.
-
filter조건. -
vectorFilterMode벡터 쿼리 중에 필터가 적용되는 시기를 지정합니다. 지원되는 모드는 필터 모드 설정을 참조하세요.
POST https://{search-endpoint}/indexes/{index-name}/docs/search?api-version={api-version}
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,
. . . // Trimmed for readability
-0.02178128,
-0.00086512347
],
"fields": "contentVector",
"k": 50
}
]
}
이 예에서 벡터 포함은 contentVector 필드를 대상으로 하고 필터 조건은 필터링 가능한 텍스트 필드인 category에 적용됩니다.
preFilter 모드가 사용되므로 검색 엔진이 쿼리를 실행하기 전에 필터가 적용되므로 벡터 검색 중에 Databases 범주에 있는 문서만 고려됩니다.
필터 모드 설정
vectorFilterMode 매개 변수는 벡터 쿼리 실행과 관련하여 필터가 적용되는 시기와 방법을 결정합니다. 다음 모드를 사용할 수 있습니다.
-
preFilter(권장) postFilter-
strictPostFilter(미리 보기)
비고
preFilter 는 2023년 10월 15일 이후에 생성된 인덱스의 기본값입니다. 이 날짜 postFilter 이전에 만든 인덱스의 경우 기본값입니다. 벡터 압축과 같은 기타 고급 벡터 기능을 사용 preFilter 하려면 인덱스 다시 만들어야 합니다.
REST API 버전 이상에서 "vectorFilterMode": "preFilter" 벡터 쿼리 2023-10-01-preview 를 전송하여 호환성을 테스트할 수 있습니다. 쿼리가 실패하면, preFilter을(를) 인덱스가 지원하지 않습니다.
사전 필터링은 쿼리 실행 전에 필터를 적용하여 벡터 검색 알고리즘의 후보 집합을 줄입니다. 그런 다음 필터링된 집합에서 상위 k 결과가 선택됩니다.
벡터 쿼리에서는 preFilter가 기본 모드입니다. 대기 시간보다 재현율과 품질을 중시하기 때문입니다.
이 모드의 작동 방식
각 분할에서 HNSW 트래버스 중 필터 조건자를 적용하여
k개의 후보가 발견될 때까지 그래프를 확장합니다.각 분할에서 미리 필터링된 로컬 상위
k결과를 생성합니다.필터링된 결과를 전역 상위
k결과 집합으로 집계합니다.
이 모드의 효과
트래버스는 더 많은 필터링된 후보를 찾기 위해 검색 표면을 확장합니다. 특히 필터가 선택적일 경우 더욱 그렇습니다. 이렇게 하면 모든 분할된 데이터베이스에서 가장 유사한 상위k 결과가 생성됩니다. 각 샤드는 필터 조건을 k 충족하는 결과를 식별합니다.
사전 필터링은 인덱스에 k 있는 경우 결과가 반환되도록 보장합니다. 매우 선택적인 필터의 경우 이로 인해 그래프의 상당 부분이 트래버스되어 처리량을 줄이면서 계산 비용 및 대기 시간이 증가할 수 있습니다. 필터가 매우 선택적이면(일치하는 항목이 거의 없는 경우) exhaustive: true을 사용하여 철저한 검색을 고려해보세요.
비교 테이블
| Mode | 회수(필터링된 결과) | 계산 비용 | 가음성 위험 | 사용 시기 |
|---|---|---|---|---|
preFilter |
매우 높음 | 더 높아집니다(필터 선택성 및 복잡성에 따라 증가) | 위험 없음 |
모든 시나리오에 권장되는 기본값, 특히 회수가 중요한 경우(중요한 검색 도메인), 선택적 필터를 사용하는 경우 또는 작은 k를 사용하는 경우에 적합합니다. |
postFilter |
중간에서 높음(필터 선택성이 높아질수록 감소) | 필터링되지 않은 것과 유사하지만 필터 복잡성이 증가합니다. | 보통(분할당 일치 항목을 놓칠 수 있음) | 너무 선택적이지 않은 필터 및 상위k 쿼리에 대한 옵션입니다. |
strictPostFilter |
가장 낮음(필터 선택성을 사용하여 가장 빠르게 감소) | 필터링되지 않은 것과 유사 | 가장 높음(선택적 필터에 대해 0개의 결과를 반환할 수 있음 또는 작은 k) |
필터 적용 후 더 많은 결과를 표시하는 것이 거짓 부정의 위험보다 사용자 경험에 더 큰 영향을 미치는 패싯 검색 응용 프로그램을 위한 옵션입니다. 작은 k과 함께 사용하지 마세요. |
사전 필터링 및 사후 필터링의 벤치마크 테스트
중요합니다
이 섹션은 엄격한 사후 필터링이 아닌 사전 필터링과 사후 필터링에 적용됩니다.
한 필터 모드가 다른 필터 모드보다 더 나은 성능을 보이는 조건을 이해하기 위해 일련의 테스트를 실행하여 소형, 중간 및 대형 인덱스에 대한 쿼리 결과를 평가했습니다.
- 소형(문서 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결과보다 더 적은 결과를 반환할 수 있음).지나치게 선택적이지 않은 필터를 사용합니다.
사전 필터링 성능이 허용되지 않을만큼 충분한 크기의 인덱스가 있습니다.
세부 정보
1,536개 차원에서 100,000개의 벡터가 있는 데이터 세트가 제공될 경우:
데이터 세트의 30% 이상을 필터링할 때는 사전 필터링 및 사후 필터링이 비슷했습니다.
데이터 세트의 0.1% 미만을 필터링할 때 사전 필터링은 사후 필터링보다 약 50% 더 느렸습니다.
1,536개 차원에서 100만 개의 벡터가 있는 데이터 세트가 제공될 경우:
데이터 세트의 30% 이상을 필터링할 때 사전 필터링 속도가 약 30% 더 느렸습니다.
데이터 세트의 2% 미만을 필터링할 때 사전 필터링은 약 7배 더 느렸습니다.
96개 차원에서 10억 개의 벡터가 있는 데이터 세트가 제공될 경우:
데이터 세트의 5% 이상을 필터링할 때 사전 필터링 속도가 약 50% 더 느렸습니다.
데이터 세트의 10% 미만을 필터링할 때 사전 필터링은 약 7배 더 느렸습니다.
다음 그래프는 사후 필터 QPS를 사전 필터 QPS로 나누어 계산한 사전 필터 상대 QPS를 보여 줍니다.
세로 축은 QPS(초당 쿼리 수) 비율로 표현된, 사전 필터링과 사후 필터링의 상대적 성능을 나타냅니다. 다음은 그 예입니다.
-
0.0값은 사전 필터링이 사후 필터링보다 100% 느리다는 것을 의미합니다. -
0.5값은 사전 필터링이 50% 더 느리다는 것을 의미합니다. -
1.0값은 사전 필터링과 사후 필터링이 동등함을 의미합니다.
가로 축은 필터링 속도 또는 필터를 적용한 후의 후보 문서 백분율을 나타냅니다. 예를 들어, 1.00%의 비율은 필터 조건이 검색 모음의 1%를 선택했음을 의미합니다.