
비대칭 양자화 (Asymmetric Quantization): 97%의 저장 공간 절감과 손실에 가까운 검색 성능 유지
요약
후기 상호작용(Late interaction) 모델의 대규모 벡터 저장 문제를 해결하기 위한 비대칭 양자화 기술을 소개합니다. 문서 벡터는 1비트로, 쿼리 벡터는 높은 정밀도로 유지하여 저장 공간을 97% 절감하면서도 검색 성능 손실을 최소화했습니다.
핵심 포인트
- 비대칭 양자화를 통해 문서당 저장 공간을 평균 32배 절감
- 검색 품질(NDCG@10)을 fp32 대비 거의 손실 없이 유지
- 대규모 문서 검색 엔진 Silo의 비용 및 성능 최적화 달성
- 문서 벡터는 1-bit, 쿼리 벡터는 int8로 처리하는 전략 사용
비대칭 양자화 (Asymmetric Quantization): 97%의 저장 공간 절감과 손실에 가까운 후기 상호작용 (Late interaction) 검색 성능 유지

Wholembed v3와 같은 후기 상호작용 (Late interaction) 모델은 전체 문서를 하나의 벡터로 압축하는 대신 세밀한 정보를 보존하기 때문에 검색을 훨씬 더 정밀하게 만듭니다. 하지만 이는 저장 경제성(storage economics)을 변화시킵니다. 단일 문서는 하나 이상의 임베딩 (embedding)을 생성하며, 문서의 복잡성에 따라 수백 또는 수천 개의 벡터를 생성할 수 있습니다. 각 벡터는 저장되어야 하며 나중에 검색을 위해 사용되어야 합니다.
Mixedbread Search는 수십억 개의 문서 규모에서 멀티모달 후기 상호작용 (multimodal late interaction)을 처리하는 검색 엔진인 Silo 위에서 실행됩니다. Silo는 25억 개 이상의 문서에 대한 벡터를 오브젝트 스토리지 (object storage)에 저장하고, 쿼리 (query)가 필요할 때 더 빠른 티어 (tier)로 수화 (hydrate)합니다. 이 정도 규모에서는 문서당 추가되는 모든 바이트가 수십억 번 반복되며, 이는 저장된 문서당 비용, 샤드 콜드 스타트 (shard cold-start) 시간, 그리고 각 쿼리가 읽어야 하는 바이트 수에 직접적인 영향을 미칩니다. 우리는 후기 상호작용 (late interaction)을 실행할 가치가 있게 만드는 품질을 유지하면서도 전체 시스템을 저렴하게 만드는 트레이드오프 (tradeoff)를 해결해야 합니다.
이 포스트에서는 후기 상호작용 (late interaction)을 프로덕션 환경에서 실용적으로 실행할 수 있게 만드는 최적화 기술 중 하나인 비대칭 양자화 (asymmetric quantization)에 대해 살펴봅니다. 우리는 쿼리 벡터 (query vectors)는 높은 정밀도로 유지하고, 문서 벡터 (document vectors)는 이진 부호 (binary signs)로 저장합니다. 우리의 내부 벤치마크 스위트 (benchmark suite)에 따르면, 문서당 원시 문서-벡터 저장 공간을 평균 32배(393 KiB에서 12.28 KiB로) 절감하면서도, 검색 품질은 fp32의 90.26 NDCG@10 대비 89.65 NDCG@10를 유지했습니다.
요약 (TL;DR):
문서는 오랫동안 저장되지만, 쿼리는 한 번 실행됩니다. 따라서 우리는 문서 벡터를 1비트 부호 (1-bit signs)로 저장하고 쿼리는 int8로 유지합니다. 이를 통해 문서당 저장 공간을 32배 줄이면서, 내부 벤치마크에서 단 0.61 NDCG@10 (90.26에서 89.65로)의 손실만 발생시켰습니다.
양자화 (Quantization)란 고정밀 부동 소수점 벡터 (high-precision floating point vectors)를 int8 또는 심지어 1비트 부호 (1-bit signs)와 같은 저정밀도 값으로 표현하는 것을 의미합니다. 목표는 페이로드 크기 (payload size)를 줄이면서 랭킹 품질 (ranking quality)을 보존하는 것입니다. 이는 특히 silo에 있어 매우 중요합니다. 객체 스토리지 (Object storage)는 내구성이 높고 저렴한 영속성 (persistence)을 제공합니다. 이를 실제 워크로드에 적합하게 만들기 위해서는 충분히 빠르게 서비스할 수 있는 컴팩트한 인덱스 (compact indexes)가 필요합니다. 그리고 문서 측면에서는 페이로드 크기가 비용을 결정짓는 핵심 요소입니다.
단순한 후기 상호작용 (Naive late interaction) 방식은 더 많은 벡터를 저장해야 하므로 비용이 많이 듭니다. 3072 차원의 fp32를 사용하는 표준 단일 벡터 임베딩 (single-vector embedding)은 문서당 12 KiB를 차지합니다. 128 차원의 벡터 786개로 구성된 다중 벡터 표현 (multi-vector representation)은 훨씬 더 많은 정보를 담고 있지만, 압축되지 않은 상태에서는 약 33배 더 큽니다.
| 표현 방식 (Representation) | 차원 (Dimensions) | 문서당 저장 공간 (Storage per document) | 3072-d fp32 단일 벡터 대비 |
|---|---|---|---|
| 단일 벡터, fp32 (Single vector, fp32) | 3072 | 12,288 B / 12 KiB | 1.0x |
| ... |
여기서 저장 공간 수치는 원시 벡터 페이로드 (raw vector payloads)만을 나타냅니다. 실제 운영 환경의 인덱스에는 문서 ID, 메타데이터 및 레이아웃 오버헤드 (layout overhead)도 포함됩니다.
이진 문서 벡터 (binary document vectors)를 사용하면, 786개 토큰을 가진 다중 벡터 문서는 3072 차원의 fp32 단일 벡터보다 약 2% 정도만 더 클 뿐입니다. 이는 단일 벡터 수준의 저장 비용만 지불하면서 후기 상호작용 (late interaction) 품질을 얻을 수 있음을 의미합니다. 이를 통해 우리는 트레이드오프 (tradeoff)를 바꿀 수 있습니다. 후기 상호작용은 이제 저장 공간을 정당화할 수 있는 특수한 경우에만 사용하는 것이 아니라, 기본적으로 실행 가능한 실용적인 기술이 됩니다.
이것은 후기 상호작용을 위한 새로운 방향은 아닙니다. ColBERTv2는 공격적인 압축 (aggressive compression)이 품질을 유지하면서도 후기 상호작용 모델의 점유 공간 (footprint)을 줄일 수 있음을 보여주었습니다. PLAID는 최적화된 검색 (retrieval) 및 가지치기 (pruning)를 사용하여 후기 상호작용 검색을 실용적인 지연 시간 (latency) 수준까지 설계할 수 있음을 보여주었습니다. 운영 시스템을 위해서는 이 두 가지 교훈이 모두 중요합니다. 모델은 정밀해야 하며, 표현 방식은 하드웨어를 통해 이동할 수 있을 만큼 충분히 저렴해야 합니다.
문서 벡터 (document vectors)를 압축하면 전체 코퍼스 (corpus)에 걸쳐 저장 공간, IO, 캐시 공간 및 콜드 스타트 (cold-start) 시간을 절약할 수 있습니다. 쿼리 벡터 (query vectors)를 압축하는 것은 쿼리가 작고 수명이 짧으며 인덱스에 저장되지 않기 때문에 절약되는 것이 거의 없습니다.
이것이 우리가 양측 모두를 이진화 (binarize)하지 않는 이유이기도 합니다. 완전 이진 검색 (Fully binary retrieval)은 가장 컴팩트한 옵션이지만, 쿼리를 단일 비트로 낮추면 랭킹 (ranking)에 의존하는 크기 정보 (magnitude information)를 버리게 되며, 이는 (나중에 보여주겠지만) 문서만 이진화할 때보다 훨씬 더 큰 품질 저하를 초래합니다.
따라서 우리는 쿼리는 int8로 유지하고, 문서 벡터만을 이진 부호 (binary signs)로 저장합니다. 쿼리는 랭킹을 보존할 수 있을 만큼 충분히 정밀하게 유지되는 반면, 문서 측은 서빙 (serving)에 중요한 저장 공간 절감 효과를 얻습니다.
이진 문서 벡터는 크기가 더 작으므로 저장 비용이 더 저렴합니다.
int8 x int8 스코어링 (scoring)의 경우, 최신 ARM CPU는 NEON 내적 (dot-product) 명령어를 통해 직접적인 지원을 제공합니다. 우리의 AArch64 커널은 SDOT를 사용하여 16개의 int8 곱셈을 int32 레인 (lanes)으로 누적한 다음, vaddvq_s32를 사용하여 결과를 수평적으로 축소 (horizontally reduces)합니다.
int8 x 이진 스코어링의 경우, 유용한 항등식 (identity)은 더 간단합니다. 각 문서 차원이 b_i ∈ {-1, +1}인 부호 비트로 저장된다면 다음과 같습니다:
따라서 스코어링을 위해 모든 차원에 대해 전체 곱셈을 수행할 필요는 없습니다. 양수 문서 비트에 의해 선택된 쿼리 값들의 합과 전체 쿼리 합이 필요할 뿐입니다.
커널 내에서 문서 부호는 비트로 패킹 (packed)됩니다. 128차원 경로의 경우, 쿼리 합과 8개의 쿼리 비트 평면 (bit-planes)을 미리 계산합니다. 각 문서 토큰은 16개의 패킹된 바이트로 로드되며, NEON 정수 연산을 통해 시프트 및 마스킹되어 8개의 0/1 마스크로 변환된 후, 쿼리 평면에 대해 SDOT로 스코어링됩니다. 최종 점수는 위의 항등식 2 * selected_query_sum - query_sum을 사용합니다.
이진 x 이진 (Binary x binary)은 해밍 거리 (hamming distance)를 사용할 수 있어 계산 비용이 훨씬 더 저렴하지만, 우리의 주요 검색 경로에 사용하기에는 품질 손실이 너무 큽니다.
우리는 내부 검색 벤치마크 제품군(benchmark suite) 전반에 걸쳐 여러 정밀도 조합(precision pairings)을 평가했습니다. 점수는 제품군 전체의 평균 NDCG@10이며, 0~100 범위로 스케일링되었습니다. NDCG@10 (Normalized Discounted Cumulative Gain at rank 10)은 상위 10개의 결과가 이상적인 순위와 비교하여 얼마나 잘 정렬되었는지를 측정하며, 관련 문서가 더 높은 순위에 나타날수록 더 높은 점수를 부여하며, 100점은 완벽한 순위를 의미합니다. Full-precision (전정밀도) 베이스라인의 평균은 90.26입니다. Binary (이진) 문서에 대한 Int8 쿼리는 평균 89.65로 0.61포인트 하락했지만, 문서 벡터 저장 공간을 32배 줄였습니다. 성능 저하가 최소화된 이유 중 하나는 Wholembed v3가 silo의 트레이드오프(tradeoff)를 염두에 두고 학습되어 양자화 (quantization)에 강건하기 때문입니다.
런타임(runtime)의 경우, 786 × 128 크기의 문서 1,000개 목록에 대해 33 × 128 쿼리를 사용하여 ARM 머신에서 스코어링 커널(scoring kernel)을 벤치마킹했습니다. 표에는 2회의 워밍업(warmup) 후 9회의 측정 실행에 대한 중앙값 지연 시간(median latency)과 fp32 베이스라인 대비 속도 향상(speedup)이 보고되어 있습니다.
| 쿼리 형식 (Query format) | 문서 형식 (Document format) | 평균 NDCG@10 | 베이스라인 대비 변화 (Δ vs baseline) | 문서당 저장 공간 (Doc storage per doc) | 중앙값 지연 시간 (Median latency) | fp32 대비 속도 향상 (Speedup vs fp32) |
|---|---|---|---|---|---|---|
| Float | Float | 90.26 | – | 393 KiB | 14.20 ms | 1.00x |
| ... |
두 가지 유용한 운영 지점(operating points)이 있습니다.
더 낮은 대역폭과 더 빠른 정수 스코어링(integer scoring)을 통해 최대 품질을 원하는 경우, 이 설정에서 int8 × int8은 본질적으로 손실이 없습니다 (lossless). 이 방식은 측정 오차 범위 내에서 fp32 베이스라인보다 약간 앞서 있으며, 문서 저장 공간을 4배 줄이는 동시에 이 벤치마크에서 3.2배 더 빠르게 작동합니다.
최고의 저장 경제성을 원하는 경우, int8 × binary가 더 흥미로운 지점입니다. 이 방식은 문서 벡터를 32배 축소하고 fp32보다 3.8배 빠르게 실행하면서도 순위 품질의 대부분을 유지합니다. 오브젝트 스토리지(object-storage) 기반 시스템의 경우, 이는 코퍼스(corpus) 측 바이트 수를 직접적으로 절감하는 효과를 가져옵니다.
Binary × binary 방식은 이론적으로는 매력적으로 보입니다. int8 × binary와 동일하게 12.28 KiB의 문서 저장 공간을 사용하며, 4.3배 더 빠른 이 방식은 여기서 가장 빠른 옵션입니다. 하지만 정확히 동일한 문서 바이트를 읽음에도 불구하고, baseline 대비 7.20포인트 하락하며 이는 int8 × binary의 하락 폭보다 10배 이상 큰 수치입니다. 유일하게 바뀐 것은 쿼리(query)뿐입니다. 실제로 이 방식은 쿼리 시그널(query signal)을 너무 많이 제거합니다.
비대칭 양자화 (Asymmetric quantization)가 작동하는 이유는 검색 시스템이 쿼리와 문서의 정밀도(precision)에 대해 동일한 방식으로 비용을 지불하지 않기 때문입니다. 문서 벡터 (document vectors)는 시스템의 장기적인 비용을 지배합니다. 이들은 저장되고, 복제되며, 캐싱(cached)되고, 제거(evicted)되며, 다시 로드(rehydrated)되고, 반복적으로 점수(scored)가 매겨집니다. 반면 쿼리 벡터 (query vectors)는 수명이 짧으므로, 쿼리에 몇 비트를 더 할애하고 저장된 모든 문서의 비트를 절약하는 것이 올바른 트레이드오프 (tradeoff)입니다.
Silo의 경우, 이는 대규모 환경에서 후기 상호작용 검색 (late interaction retrieval)을 훨씬 더 쉽게 서비스할 수 있게 해줍니다. 저장된 문서당 비용이 낮아지고, 샤드 콜드 스타트 (shard cold-start)가 빨라지며, 하드웨어 경로가 점수 매기기 (scoring)에 더 많은 시간을 할애할 수 있게 되어 더 높은 QPS (queries per second)를 달성하고 바이트를 이동시키는 데 드는 시간을 줄일 수 있습니다. 이를 통해 모든 문서를 거대한 fp32 객체로 취급하지 않고도 멀티 벡터 표현 (multi-vector representations)의 품질을 얻을 수 있습니다.
만약 이것이 당신이 해결하고 싶은 시스템 문제라면, 우리는 채용 중입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기