이 페이지에서는 Spanner에서 전체 텍스트 및 벡터 하이브리드 검색을 수행하는 방법을 설명합니다. 하이브리드 검색은 키워드 일치(전체 텍스트 검색, FTS)의 정확성과 시맨틱 일치 (벡터 검색)의 재현율을 결합하여 관련성이 높은 검색 결과를 생성합니다.
Spanner는 다음과 같은 하이브리드 검색 패턴을 지원하며, 이는 세 가지 기본 카테고리로 나뉩니다.
| 카테고리 | 설명 | 기본 목표 |
| Fusion | Fusion은 키워드 및 벡터 검색을 사용하여 문서를 독립적으로 검색하고 순위를 지정한 다음 결과를 결합 (융합)합니다. | 여러 점수 신호를 결합하여 최대 리콜과 관련성을 달성하세요. |
| 필터링됨 | 키워드는 검색 공간을 필터링하거나 미세 조정합니다. | 의미론적 관련성을 활용하면서 키워드 일치가 요구사항인지 확인합니다. |
| ML 재순위 지정 | 머신러닝 모델은 최종적이고 더 정확한 순위를 위해 초기 후보 세트를 개선합니다. | 최종 결과의 작은 집합에 대해 가능한 가장 높은 정밀도를 달성합니다. |
Fusion 검색
융합 검색은 동일한 데이터 코퍼스에서 FTS와 벡터 검색을 독립적으로 실행하는 것을 말합니다. 그런 다음 결과를 병합하여 단일의 통합된 관련성 높은 순위 목록을 만듭니다.
클라이언트 측에서 독립적인 쿼리를 실행할 수 있지만 Spanner의 하이브리드 검색은 다음과 같은 이점을 제공합니다.
- 서버에서 병렬 요청 및 결과 병합을 관리하여 애플리케이션 로직을 간소화합니다.
- 잠재적으로 큰 중간 결과 집합을 클라이언트로 전송하지 않습니다.
SQL을 사용하여 Spanner에서 융합 메서드를 만들 수 있습니다. 이 섹션에서는 상호 순위 융합 및 상대 점수 융합의 예시를 제공합니다. 하지만 다양한 융합 전략을 평가하여 애플리케이션의 요구사항에 가장 적합한 전략을 결정하는 것이 좋습니다.
순위 기반 융합
서로 다른 공간에서 측정되므로 다양한 검색 방법(예: FTS 점수 및 벡터 거리)의 관련성 점수를 비교하거나 정규화하기 어려운 경우 순위 기반 융합을 사용합니다. 이 메서드는 각 리트리버의 각 문서의 순위 위치를 사용하여 최종 점수와 순위를 생성합니다.
상호 순위 융합 (RRF)은 순위 기반 융합 함수입니다. 문서의 RRF 점수는 여러 검색기에서 가져온 순위의 역수의 합이며 다음과 같이 계산됩니다.
\[ score\ (d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}(1\ /\ (\ 𝑘\ +\ ran{k}_{r}\ (𝑑)\ )\ )\ \]
각 항목의 의미는 다음과 같습니다.
- d는 문서입니다.
- R은 리트리버 (FTS 및 벡터 검색)의 집합입니다.
- k는 매우 높은 순위의 문서의 영향을 조절하는 데 사용되는 상수입니다 (일반적으로 60으로 설정됨).
- w는 리트리버 r의 문서 순위입니다.
Spanner 쿼리에서 RRF 구현
벡터 측정항목 (예: APPROX_DOT_PRODUCT)과 텍스트 검색 점수 (예: SCORE_NGRAMS)는 호환되지 않는 스케일에서 작동합니다. 이 문제를 해결하기 위해 다음 예에서는 원시 점수가 아닌 순위 위치를 기반으로 데이터를 정규화하는 RRF를 구현합니다.
이 쿼리는 UNNEST(ARRAY(...) WITH OFFSET를 사용하여 각 메서드의 상위 100개 후보에 순위를 할당합니다. 그런 다음 이러한 순위의 역수를 사용하여 표준화된 점수를 계산하고 결과를 집계하여 상위 5개 일치 항목을 반환합니다.
SELECT SUM(1 / (60 + rank)) AS rrf_score, key
FROM (
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY APPROX_DOT_PRODUCT(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
UNION ALL
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'foo')
ORDER BY SCORE_NGRAMS(text_tokens_ngrams, 'foo') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
)
GROUP BY key
ORDER BY rrf_score DESC
LIMIT 5;
점수 기반 융합
점수 기반 병합은 다양한 방법의 관련성 점수를 비교할 수 있거나 정규화할 수 있는 경우에 효과적이며, 이를 통해 각 방법의 실제 관련성 가중치를 통합하는 더 정확한 순위 지정이 가능할 수 있습니다.
상대 점수 융합 (RSF)은 각 메서드 내에서 최고 점수와 최저 점수를 기준으로 다양한 메서드의 점수를 정규화하는 점수 기반 메서드이며, 일반적으로 MIN() 및 MAX() 함수를 사용합니다. 리트리버 집합으로 가져온 문서의 RSF 점수는 다음과 같이 계산됩니다.
\[ score(d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}({w}_{r}*(scor{e}_{r}(d)\ -\ mi{n}_{r})\ /\ (ma{x}_{r\ }-mi{n}_{r})\ ) \]
각 항목의 의미는 다음과 같습니다.
- d는 문서입니다.
- R은 리트리버 (FTS 및 벡터 검색)의 집합입니다.
- w는 특정 리트리버에 할당된 가중치입니다.
Spanner 쿼리에서 RSF 구현
RSF를 구현하려면 벡터와 FTS의 점수를 공통 스케일로 정규화해야 합니다. 다음 예에서는 별도의 WITH 절에서 최소 점수와 최대 점수를 계산하여 정규화 요소를 도출합니다. 그런 다음 FULL OUTER JOIN을 사용하여 결과를 결합하고, 근사 최근접 이웃 (ANN) 검색 (cosine_distance에서 변환됨)과 FTS에서 정규화된 점수를 합산합니다.
WITH ann AS (
SELECT key, APPROX_COSINE_DISTANCE(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') AS cosine_distance,
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY cosine_distance
LIMIT 100
),
fts AS (
SELECT key, SCORE_NGRAMS(text_tokens_ngrams, 'Green') AS score,
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'Green')
ORDER BY score DESC
LIMIT 100
),
ann_min AS (
SELECT MIN(1 - cosine_distance) AS min
FROM ann
),
ann_max AS (
SELECT MAX(1 - cosine_distance) AS max
FROM ann
),
fts_min AS (
SELECT MIN(score) AS min
FROM fts
),
fts_max AS (
SELECT MAX(score) AS max
FROM fts
)
SELECT IFNULL(ann.key, fts.key),
IFNULL(((1 - ann.cosine_distance) - ann_min.min) /
(ann_max.max - ann_min.min), 0) +
IFNULL((fts.score - fts_min.min) /
(fts_max.max - fts_min.min), 0) AS score
FROM ann
FULL OUTER JOIN fts
ON ann.key = fts.key
CROSS JOIN ann_min
CROSS JOIN ann_max
CROSS JOIN fts_min
CROSS JOIN fts_max
ORDER BY score DESC
LIMIT 5;
필터링된 검색
필터링된 검색은 FTS를 사용하여 k-최근접 이웃 (KNN) 벡터 검색에 고려되는 문서 집합을 줄이는 필터를 만듭니다. 선택적으로 사전 정렬을 사용하여 결과 집합의 크기를 제한할 수 있습니다.
Spanner 쿼리에서 필터링된 검색 구현
이 섹션의 검색 예에서는 다음 단계를 통해 벡터 검색 공간을 키워드와 일치하는 데이터 하위 집합으로 좁힙니다.
SEARCH (text_tokens, 'Green')를 사용하여text_tokens열에Green텍스트가 포함된 행을 찾습니다. 상위 1,000개 행은 검색 색인에 정의된 재정렬 순서에 따라 반환됩니다.- 벡터 함수
DOT_PRODUCT(@vector, embedding)를 사용하여 쿼리 벡터 (@vector)와 저장된 문서 벡터(임베딩) 간의 유사성을 계산합니다. 그런 다음 결과를 정렬하고 최종 상위 10개 일치 항목을 반환합니다.
SELECT key
FROM (
SELECT key, embedding
FROM hybrid_search
WHERE SEARCH (text_tokens, 'Green')
ORDER BY presort
LIMIT 1000)
ORDER BY DOT_PRODUCT(@vector, embedding) DESC
LIMIT 10;
ML 재순위 지정
ML 기반 재순위 지정은 계산 집약적이지만 매우 정확한 접근 방식입니다. FTS, 벡터 검색 또는 이 두 가지의 조합으로 축소된 작은 후보 집합에 머신러닝 모델을 적용합니다. Spanner Vertex AI 통합에 대한 자세한 내용은 Spanner Vertex AI 통합 개요를 참고하세요.
배포된 Vertex AI 모델과 함께 Spanner ML.PREDICT 함수를 사용하여 ML 재순위 지정을 통합할 수 있습니다.
ML 기반 재순위 지정 구현
- HuggingFace와 같은 곳에서 리랭커 모델을 배포하여 Vertex AI 엔드포인트에 배포합니다.
Vertex AI 엔드포인트를 가리키는 Spanner
MODEL객체를 만듭니다. 예를 들어 다음Reranker모델 예시에서text ARRAY<string(max)>은 문서입니다.text_pair ARRAY<string(max)>은 예시의 질문 텍스트입니다.score는 텍스트 입력 쌍에 대해 ML 모델에서 할당한 관련성 점수입니다.
CREATE MODEL Reranker INPUT (text ARRAY<string(max)>, text_pair ARRAY<string(max)>) OUTPUT (score FLOAT32) REMOTE OPTIONS ( endpoint = '...' );하위 쿼리를 사용하여 초기 후보 (예: ANN 검색의 상위 100개 결과)를 검색하고 이를
ML.PREDICT에 전달합니다. 이 함수는 최종 순서 지정을 위한 새 점수 열을 반환합니다.SELECT key FROM ML.PREDICT( MODEL Reranker, ( SELECT key, text, "gift for 8-year-old" AS text_pair FROM hybrid_search WHERE embedding IS NOT NULL ORDER BY APPROX_DOT_PRODUCT(@vector, embedding, options=>JSON '{"num_leaves_to_search": 50}') DESC LIMIT 100) ) ORDER BY score DESC LIMIT 3;
다음 단계
- Spanner의 AI 기반 하이브리드 검색으로 검색엔진을 맞춤설정하세요.
- 전체 텍스트 검색에 대해 자세히 알아보세요.