스칼라 양자화(Scalar Quantization)란? AI에서 벡터의 숫자를 낮은 정밀도로 압축하는 방법
TL;DR
스칼라 양자화는 벡터의 각 숫자를 따로 낮은 정밀도의 값으로 바꾸는 압축 방법입니다. 검색용 임베딩을 float32 대신 8비트 코드로 표현하면 벡터 코드만 놓고는 필요한 공간이 줄어듭니다. 대신 원래 숫자와 거리 계산이 달라져 검색 순위가 바뀔 수 있습니다. 곱 양자화(PQ)처럼 여러 차원을 묶어 대표 벡터를 고르는 방식과 구분하고, 실제 자료에서 재현율·메모리·속도를 함께 확인해야 합니다.
핵심 3줄 요약
- 핵심 1
성분을 하나씩 압축합니다. 벡터의 차원마다 숫자 표현을 바꾸며 차원 자체를 삭제하지는 않습니다. - 핵심 2
8비트 코드에는 손실이 있습니다. 정밀도를 낮추면 벡터 사이의 거리가 달라질 수 있습니다. - 핵심 3
검색 품질을 다시 측정합니다. 원본 벡터 재점수화 여부와 실제 인덱스 메모리를 함께 봅니다.
이 글에서 다룰 내용
- 스칼라 양자화의 한 문장 정의
- 작은 임베딩 예시로 이해하는 숫자 변환
- 벡터 검색에서 메모리와 거리 계산이 중요한 이유
- 8비트 코드·구간·검색 후보·재점수화의 관계
- 곱 양자화·모델 가중치 양자화·이진 양자화와의 차이
- 검색 품질과 저장 공간을 확인하는 체크리스트
- 범위 밖 값과 원본 벡터 보관 시 주의점
- 자주 묻는 질문
스칼라 양자화를 한 문장으로 정의하면 무엇인가요?
스칼라 양자화(Scalar Quantization, SQ)는 벡터의 각 차원에 있는 수치를 독립적으로 정해진 수의 표현값이나 코드로 바꾸는 손실 압축 기법입니다.
여기서 스칼라는 벡터의 한 성분을 이루는 숫자 하나를 말합니다. 문서 임베딩이 수백 개 숫자로 이루어졌다면 각 위치의 숫자를 지정된 정밀도로 표현합니다. 벡터를 저장하는 방식과 가까운 문서를 고르는 거리 계산에 모두 영향을 줄 수 있습니다. 값을 압축했다고 임베딩 모델이 다른 뜻을 학습하는 것은 아닙니다.
Faiss는 IndexScalarQuantizer에서 8비트·6비트·4비트 정수 코드와 16비트 부동소수점 코드를 구별하고, PQ는 별도 인덱스로 설명합니다. Weaviate의 SQ 설명도 float32 성분을 8비트 정수 버킷으로 옮기는 사례를 듭니다. 따라서 스칼라 양자화라는 말만으로 모든 구현의 코드 폭, 범위 학습법, 검색 속도를 똑같이 가정하면 안 됩니다.
한 줄 정리: 차원 수를 줄이는 PCA와 달리 각 차원의 값을 더 거칠게 표현합니다. 원래 좌표축을 유지한 채 숫자 표현이 달라진다고 생각하면 이해하기 쉽습니다.
쉬운 예시로 이해해 볼까요?
감자나라ai님이 네 문서의 임베딩을 검색한다고 해 보겠습니다. 각 문서의 벡터에는 위치마다 연속된 소수값이 들어 있습니다. 저장 공간을 줄이려고 각 성분을 몇 개의 번호 중 하나로 나타내면, 원래 숫자 대신 짧은 코드로 문서를 보관할 수 있습니다.
- 원본 단계: 임베딩의 첫째·둘째·셋째 차원에 각각 소수값이 들어 있습니다.
- 압축 단계: 설정한 범위와 구간 규칙에 따라 각 숫자를 가까운 코드에 대응시킵니다.
- 검색 단계: 질문 벡터와 압축된 문서 벡터의 거리를 비교해 후보를 찾습니다.
소수값이 구간의 경계 양쪽에 걸쳐 있으면 원래는 가깝던 두 점이 서로 다른 코드로 바뀔 수 있습니다. 반대로 약간 달랐던 값이 같은 코드로 모이기도 합니다. 설명을 위한 비유이지 모든 엔진이 같은 구간을 만들거나 같은 거리 계산을 쓰는 것은 아닙니다.
Weaviate의 문서에서는 학습 데이터의 성분별 최솟값과 최댓값에서 버킷 경계를 얻고 8비트 번호로 변환합니다. 이 방식에서는 범위를 잡은 데이터가 실제 검색 데이터와 다르면 압축 오차를 별도로 확인해야 합니다.
쉬운 예시: 파일 크기가 줄었다는 것과 검색 품질이 유지됐다는 것은 다른 주장입니다. 검색 후보의 순위를 원본과 비교해 확인해야 합니다.
왜 AI 벡터 검색에서 스칼라 양자화가 중요한가요?
임베딩을 저장하는 메모리 부담을 낮춥니다
float32의 한 성분은 32비트이고 8비트 코드는 한 성분에 8비트를 씁니다. 그래서 이 두 표현의 벡터 코드 부분만 비교하면 8비트 쪽이 4분의 1 크기입니다. Qdrant와 Weaviate의 공식 문서는 각각 이 비교를 압축 예시로 제시합니다. 다만 실제 인덱스에는 식별자, 그래프, 메타데이터와 선택적으로 원본 벡터도 들어가므로 전체 저장 공간이 똑같이 4분의 1이 된다는 뜻은 아닙니다.
거리 계산이 압축 오차의 영향을 받습니다
검색은 질문과 문서 벡터가 얼마나 가까운지 비교합니다. 성분을 거친 값으로 바꾸면 근접한 후보의 거리 순서가 바뀔 수 있습니다. 특히 비슷한 거리의 문서끼리 경쟁할 때 원본 벡터의 상위 결과와 압축 인덱스의 상위 결과가 달라지는지를 살펴봐야 합니다. 이때 중요한 수치는 압축률 하나가 아니라 검색 재현율과 질의 지연 시간입니다.
원본 벡터로 후보를 다시 평가할 수 있습니다
Weaviate는 SQ로 후보를 넉넉히 찾은 다음 원본 벡터로 거리를 다시 계산하는 재점수화를 설명합니다. Qdrant도 양자화 검색의 rescoring과 oversampling을 조정할 수 있습니다. 재점수화는 일단 후보에 든 문서의 순위를 고쳐 주지만, 압축 단계에서 찾지 못한 문서를 자동으로 되살리지는 않습니다. 원본 벡터를 저장하거나 읽는 비용까지 포함해 평가해야 합니다.
핵심 인사이트: 압축 벡터를 얼마나 많이 보관할 수 있는지, 정답 이웃을 얼마나 놓치는지, 원본 재점수화가 얼마나 걸리는지를 한 실험에서 함께 기록합니다.
스칼라 양자화는 어떻게 작동하나요?
각 차원의 숫자 범위를 정합니다
8비트 구간 방식은 먼저 대표할 숫자 범위를 정하고 그 사이를 유한한 수준으로 나눕니다. Weaviate는 학습 벡터에서 최솟값과 최댓값을 구해 버킷 경계를 설정한다고 안내합니다. 훈련 자료에 드문 극단값이 많거나 이후 입력 분포가 크게 바뀌면 같은 버킷 배치가 맞는지 다시 검토해야 합니다. 구현별로 범위를 추정하는 방식은 다를 수 있습니다.
성분을 코드에 대응시킵니다
원래 숫자를 가장 가까운 표현값이나 구간 번호에 할당하면 벡터의 각 위치에 짧은 코드가 남습니다. 8비트는 성분별로 표현할 수 있는 번호가 한정돼 있으므로 서로 다른 소수값이 같은 번호로 모일 수 있습니다. Faiss는 SQ8, SQ6, SQ4 같은 인덱스 형식을 따로 명시합니다. 코드를 더 짧게 하면 저장 공간은 줄 수 있지만 손실과 검색 품질의 관계는 데이터에 따라 측정해야 합니다.
인덱스 구조와 압축 형식을 따로 봅니다
Faiss 인덱스 표에는 IndexScalarQuantizer와 IndexIVFScalarQuantizer가 별개로 나옵니다. 앞쪽의 IVF는 벡터를 찾을 후보 목록을 좁히는 구조이고, 뒤쪽의 SQ는 그 안에서 벡터 숫자를 어떻게 표현할지에 관한 설정입니다. Faiss의 index factory는 HNSW와 SQ8을 조합한 예도 보여 줍니다. 검색 구조와 저장 코드를 같은 이름으로 뭉뚱그리면 어느 설정이 속도나 메모리를 바꿨는지 알기 어렵습니다.
실전 팁: 벡터 성분의 숫자 변환과 후보 탐색 구조는 두 층의 문제입니다. 어느 인덱스와 어떤 양자화 설정을 함께 쓰는지 기록하세요.
스칼라 양자화와 헷갈리는 용어는 무엇이 다른가요?
곱 양자화(PQ)와 스칼라 양자화의 차이
최근 곱 양자화 Glossary 글은 여러 차원을 부분 벡터로 묶어 각 묶음의 대표값 번호를 저장하는 방식을 설명합니다. 스칼라 양자화는 각 차원의 숫자를 개별적으로 변환합니다. 둘 다 검색용 벡터를 압축하지만 만드는 코드와 거리 근사 방식이 다릅니다. PQ 글에서 스칼라 방식을 비교 문단으로 다뤘더라도 각 성분의 구간 설정, SQ 인덱스 종류와 재점수화 검증이라는 질문에는 답하지 않습니다.
모델 가중치 양자화와 검색 벡터 양자화의 차이
기존 양자화 Glossary 글의 주제는 AI 모델 가중치와 활성값을 낮은 정밀도로 표현해 추론 자원을 절약하는 방법입니다. 이 글에서는 이미 만들어진 검색용 임베딩의 숫자를 압축합니다. 같은 8비트라는 표현이 등장해도 어느 데이터를 바꾸는지, 무엇을 측정하는지가 다릅니다. 모델 정확도와 추론 속도를 측정하는 실험을 검색 이웃의 재현율 측정으로 대신할 수 없습니다.
이진 양자화와 스칼라 양자화의 차이
Qdrant와 Weaviate는 이진 양자화와 스칼라 양자화를 별도 방법으로 소개합니다. 이진 방식은 벡터 성분을 훨씬 적은 비트로 표현하고, 스칼라 방식의 8비트 사례는 더 많은 수치 수준을 남깁니다. 더 작은 코드가 언제나 더 나은 검색 결과를 준다고 보장할 수 없으며, 둘 중 무엇이 알맞은지는 임베딩 분포와 필요한 재현율에 따라 시험해야 합니다.
IVFFlat·HNSW와 스칼라 양자화의 차이
IVFFlat은 대표점별 목록을 찾아 일부 벡터만 비교하는 탐색 방식이고 HNSW는 이웃 그래프를 따라 후보를 찾습니다. 스칼라 양자화는 저장된 벡터 성분의 수치 표현을 바꿉니다. Faiss가 IVF와 SQ를 조합하고 index factory가 HNSW와 SQ를 조합할 수 있다고 안내하는 이유도 두 역할이 달라서입니다. 전체 지연 시간에는 탐색 구조와 코드 표현이 함께 작용합니다.
비교 정리: 스칼라 양자화는 성분별 값 표현, PQ는 부분 벡터별 대표 코드, IVF·HNSW는 후보 탐색 구조입니다.
실전에서는 어디에 쓰이나요?
문서 임베딩을 많이 저장하는 RAG 검색
RAG에서는 검색할 문서 조각마다 임베딩을 붙일 수 있습니다. 저장할 벡터가 늘어나면 SQ로 코드의 메모리 부담을 줄이는 방안을 검토합니다. 바꾸기 전에는 실제 질문과 정답 문서로 검색 결과를 기록합니다. 압축 뒤에도 근거 문서가 상위 후보에 남는지 봐야 생성 답변의 출처가 달라지는 일을 발견할 수 있습니다.
이미지·상품 벡터의 근접 검색
이미지나 상품의 유사 항목을 고를 때도 각 대상의 임베딩을 인덱스에 넣습니다. 상위 항목의 점수가 비슷한 경우 코드의 작은 오차가 순서를 바꿀 수 있습니다. 특정 카테고리나 인기 항목만 시험하지 말고 드문 항목과 범위 밖 입력도 함께 검토합니다. 검색 결과의 평가는 실제 사용 목적에 맞춘 정답 집합으로 진행해야 합니다.
인덱스 설계와 저장 자원 비교
정확 검색, IVF, HNSW 같은 후보 탐색 구조의 차이를 볼 때 SQ를 함께 시험할 수 있습니다. 비교 실험에서는 같은 임베딩, 같은 거리 기준, 같은 필터 조건을 쓰고 탐색 파라미터만 한 번에 하나씩 바꿉니다. 벡터 코드 크기와 인덱스 전체 크기를 따로 적으면 메타데이터나 원본 보관 때문에 압축 효과가 작아진 이유를 추적하기 쉽습니다.
실전 팁: 작은 샘플 인덱스에서 압축 전후 상위 문서의 ID를 비교하고, 결과가 달라진 질문을 따로 읽어 보세요.
도입할 때 어떤 순서로 확인하나요?
1. 기준 검색을 먼저 저장합니다
압축을 켜기 전에 float32 원본 벡터로 같은 질문 목록의 정답 이웃과 상위 검색 결과를 저장합니다. 질문과 문서의 임베딩 모델 및 버전, 거리 함수, 필터 조건도 기록합니다. 기준이 없으면 이후 순위 변화가 압축 때문인지 다른 설정 때문인지 구분할 수 없습니다.
2. 엔진의 코드 형식과 인덱스를 확인합니다
Faiss의 SQ8·SQ6·SQ4처럼 형식마다 코드 폭이 다릅니다. 선택한 제품의 인덱스가 해당 압축 방식과 함께 작동하는지 공식 문서를 확인합니다. 같은 제품 안에서도 인덱스 종류와 버전에 따라 설정 가능한 범위가 다를 수 있으므로 실제 컬렉션 설정을 읽어 봅니다.
3. 실제 분포로 범위를 학습합니다
구간 경계를 학습하는 구현이라면 운영에 가까운 훈련 벡터를 씁니다. 새 문서의 숫자 범위가 학습 자료보다 크게 벗어나는지도 확인합니다. 일부 드문 값에만 맞추면 자주 쓰는 값의 구간이 지나치게 거칠어질 수 있으므로 압축 오류를 대표 질문에서 측정합니다.
4. 재현율과 지연 시간을 함께 잽니다
원본 인덱스의 상위 이웃을 기준으로 압축 검색이 놓친 문서 비율을 비교합니다. 후보를 더 많이 뽑아 원본 벡터로 재점수화하면 순위가 좋아질 수 있지만 읽기 비용도 늘 수 있습니다. 초당 질의 수와 지연 시간의 대표값 및 느린 요청을 함께 보고 판단합니다.
5. 코드와 전체 저장 공간을 따로 적습니다
float32 대 8비트라는 숫자는 벡터 코드 자체의 비교입니다. 실제 운영에서는 인덱스 구조, 문서 ID, 메타데이터, 원본 벡터 보관 여부를 포함한 전체 공간을 재야 합니다. 압축 데이터뿐 아니라 원본을 유지하는 선택이 검색 품질과 비용에 어떤 영향을 주는지도 확인합니다.
한 줄 정리: 압축 설정 이름이 같아도 질문 분포, 데이터 갱신 주기, 필터와 원본 벡터 보관 정책이 다르면 결과는 달라집니다.
사용할 때 무엇을 주의해야 하나요?
첫째, 4배라는 수치를 전체 인덱스 비용으로 옮겨 쓰지 않습니다. float32 성분과 8비트 코드의 비트 수 비교는 성분 저장분을 설명합니다. 제품별 메타데이터와 그래프, 원본 보관까지 더한 공간은 별개입니다. 실제 배포 환경에서 사용량을 읽어야 합니다.
둘째, 원본 벡터가 없어도 재점수화된다고 가정하지 않습니다. Weaviate는 압축 후보를 찾은 뒤 원본 벡터를 가져와 재점수화하는 흐름을 설명합니다. 해당 엔진에서 원본 벡터가 어디에 있고 얼마나 빨리 읽히는지 확인해야 합니다. 원본을 저장하지 않는 구성에 같은 절차를 적용할 수는 없습니다.
셋째, 학습 범위와 새 데이터의 차이를 점검합니다. 일정한 구간으로 숫자를 코드에 배치하는 방식은 학습에 쓴 값의 범위에 영향을 받습니다. 임베딩 모델을 바꾸거나 문서 종류가 달라지면 기존 양자화 규칙을 그대로 유지할지 재평가합니다. 데이터가 몰리는 구간과 드문 극단값을 함께 봅니다.
넷째, 동일한 검색 조건에서 품질을 비교합니다. 원본 검색은 전체 벡터를 보고 압축 검색은 일부 목록만 본다면 인덱스 탐색 차이가 끼어듭니다. 필터, 탐색 폭과 거리 함수를 기록하고 단계별로 변수를 분리해야 SQ의 효과를 해석할 수 있습니다. 압축 코드를 작게 만들었다는 사실만으로 정답 문서를 놓치지 않았다고 결론 내리지 않습니다.
다섯째, 제품별 옵션을 섞어 쓰지 않습니다. Faiss의 SQ8은 인덱스 형식의 이름이고 Weaviate의 재점수화 설정이나 Qdrant의 quantile·rescore 옵션은 각각 그 제품의 기능입니다. 문서의 예시 설정을 다른 엔진의 기본 동작처럼 설명하지 말고 사용 중인 제품의 설정값과 문서 버전을 함께 확인합니다.
주의: 압축 검색에서 놓친 후보는 후보 내부의 순서를 다시 매겨도 돌아오지 않습니다. 검색 정답 집합을 기준으로 후보 누락과 최종 순위를 나눠 확인하세요.
자주 묻는 질문
Q1. 스칼라 양자화와 곱 양자화는 같은 말인가요?
아닙니다. SQ는 각 차원의 숫자를 개별적으로 코드화하고 PQ는 여러 차원을 묶은 부분 벡터를 대표 코드에 연결합니다. 두 방법 모두 근사 오차가 있지만 코드가 만들어지는 단위가 다릅니다. 저장 공간이나 속도는 같은 자료와 검색 조건에서 비교하세요.
Q2. SQ8을 쓰면 저장 공간이 무조건 4분의 1이 되나요?
float32 벡터 성분을 8비트로 바꾼 코드 부분만 보면 그 비율이 맞습니다. 전체 인덱스에는 ID와 탐색 구조가 있고 원본 벡터까지 보관할 수도 있으므로 총 메모리·디스크 사용량은 다르게 나타납니다.
Q3. 값의 개수인 차원도 줄어드나요?
보통은 아닙니다. SQ의 목적은 벡터의 각 차원에 있는 숫자의 표현 정밀도를 낮추는 것입니다. PCA 같은 차원 축소는 새로운 축으로 옮겨 차원 수를 줄이는 다른 작업입니다. 둘을 함께 사용할지는 별도 설계 문제입니다.
Q4. 원본 벡터로 재점수화하면 정답 이웃을 모두 되찾나요?
그렇지 않습니다. 재점수화는 압축 검색이 먼저 뽑은 후보 안에서 원본 거리로 순서를 다시 계산합니다. 후보 집합에 들어오지 못한 정답은 이 단계만으로 복원할 수 없습니다. 후보 수와 누락률을 함께 측정해야 합니다.
Q5. 어떤 기준으로 SQ 사용 여부를 결정하나요?
같은 임베딩과 질문에서 원본 대비 검색 재현율, 지연 시간, 전체 인덱스 공간을 비교하세요. 필터 조건과 원본 보관 여부를 기록하고, 압축으로 줄인 자원이 답변에 필요한 근거 문서를 놓칠 위험보다 중요한지 실제 데이터로 판단합니다.
출처
마무리
스칼라 양자화는 AI 검색용 벡터의 각 숫자를 더 짧은 코드로 표현합니다. 같은 임베딩이라도 저장분을 줄이는 대신 근사 오차가 생기며, 검색 결과의 순서와 후보 누락에 영향을 줄 수 있습니다. PQ처럼 여러 차원을 묶어 대표값을 고르는 방식과는 구분해야 합니다.
처음 적용한다면 원본 검색 결과를 저장하고 SQ 코드의 크기와 전체 인덱스 사용량을 따로 확인하세요. 실제 질문에서 근거 문서가 얼마나 남는지 재현율을 재고, 원본 벡터 재점수화에 드는 시간까지 더해 결정하는 것이 안전합니다.
