곱 양자화(Product Quantization, PQ)란? AI에서 벡터를 나눠 짧은 코드로 압축하는 방법
TL;DR
곱 양자화(Product Quantization, PQ)는 벡터를 여러 부분 벡터로 나누고 각 부분의 대표값 번호를 이어 짧은 코드로 저장하는 압축 방식입니다. Faiss의 IndexPQ는 이 코드로 근사 거리를 계산하고, IndexIVFPQ는 역파일 목록 탐색과 PQ 압축을 결합합니다. 벡터 메모리를 아끼는 대신 거리 추정 오차가 생길 수 있으므로 정확 검색과 비교해야 합니다.
핵심 3줄 요약
- 핵심 1
벡터를 부분별로 나눕니다. 각 부분에 따로 학습한 대표값 가운데 가까운 것을 고릅니다. - 핵심 2
대표값의 번호만 저장합니다. 번호를 이은 짧은 코드로 벡터를 근사해 검색합니다. - 핵심 3
압축과 정확도를 함께 봅니다. 코드가 짧아도 실제 이웃 순위가 달라질 수 있습니다.
이 글에서 다룰 내용
- 곱 양자화의 한 문장 정의와 벡터 압축의 뜻
- 문서 임베딩을 서랍에 나누는 쉬운 예시
- 부분 벡터·코드북·코드의 작동 순서
- IndexPQ·IndexIVFPQ의 차이
- IVFFlat·모델 양자화·스칼라 양자화와 구분
- 실제 검색 품질과 메모리를 검증하는 체크리스트
- 압축 오차·목록 누락·원본 벡터 보관 시 주의점과 자주 묻는 질문
곱 양자화를 한 문장으로 정의하면 무엇인가요?
곱 양자화는 고차원 벡터를 여러 부분으로 나누고 각 부분을 독립적으로 대표값에 매핑한 뒤, 대표값 번호를 조합해 벡터를 짧게 표현하는 압축 기법입니다.
Jégou·Douze·Schmid의 원 논문은 공간을 저차원 부분공간의 데카르트 곱으로 나누고 각 부분공간을 따로 양자화한다고 설명합니다. 데이터 벡터는 부분공간마다 선택한 대표값의 번호를 이어 만든 코드가 됩니다.
원래 수치를 모두 갖고 있는 벡터와 짧은 코드가 같은 정보량을 담지는 않습니다. 코드에서 재구성한 벡터는 원본의 근사치입니다. 이 차이가 거리 오차와 이웃 순위 변화로 이어질 수 있습니다.
여기서 말하는 곱은 모델 가중치를 곱해 연산한다는 뜻이 아닙니다. 부분공간마다 고른 코드북의 조합으로 많은 전체 벡터 위치를 표현한다는 개념입니다.
한 줄 정리: PQ는 임베딩 벡터의 각 부분을 따로 압축해 대표값 번호 여러 개로 저장하는 방식입니다.
쉬운 예시로 이해해 볼까요?
감자나라ai님이 문서의 임베딩으로 비슷한 글을 찾는다고 가정해 보겠습니다. 하나의 긴 숫자 목록을 여러 짧은 구간으로 나누고, 구간마다 자주 나타나는 모양에 번호를 붙입니다.
새 문서를 저장할 때는 구간의 숫자를 모두 적는 대신 가장 가까운 모양의 번호를 기록합니다. 다음 구간도 같은 방식으로 기록합니다. 여러 번호를 이어 놓은 것이 그 문서 벡터의 PQ 코드입니다.
질문과 가까운 문서를 찾을 때 코드의 번호를 보고 각 부분의 거리 기여를 합쳐 후보를 정렬합니다. 두 문서의 원래 벡터가 서로 조금 달라도 같은 대표값 번호를 받을 수 있습니다. 그런 경우 압축 전후의 순위가 달라지는지 확인해야 합니다.
쉬운 예시: 긴 숫자 목록을 나누어 구간별 대표 모양의 번호만 적는 방식입니다. 번호표는 원본 숫자 자체가 아닙니다.
왜 AI에서 곱 양자화가 중요한가요?
많은 임베딩을 더 적은 공간에 담습니다
RAG 문서 조각이나 이미지의 벡터가 늘수록 색인 메모리도 늘어납니다. Faiss의 인덱스 표는 IndexPQ의 벡터당 코드 크기를 부분 양자화기 수와 각 코드의 비트 수로 제시합니다. 실제 전체 메모리에는 코드뿐 아니라 코드북과 인덱스 구조도 포함됩니다.
어느 정도 절약되는지는 원본 벡터의 자료형, 코드 설정, ID와 주변 색인 구조를 포함해 측정해야 합니다. 코드 크기만 전체 서비스 메모리라고 말할 수는 없습니다.
압축된 표현으로 근사 거리를 비교합니다
원 논문은 질의 벡터를 양자화하지 않고 데이터 벡터의 코드와 비교하는 비대칭 거리 계산을 설명합니다. 부분공간마다 질의와 대표값 사이의 거리를 미리 계산해 놓고 코드 번호에 따라 해당 값을 모아 더합니다.
Faiss 구현 문서도 PQ 검색의 거리 테이블 조회를 설명합니다. 이는 원본 벡터의 거리를 모든 후보에 다시 계산한 것과 같지 않으며, 실제 속도는 인덱스 구성과 하드웨어 조건에 좌우됩니다.
검색 범위와 압축 손실을 나눠 살핍니다
Faiss의 IndexIVFPQ는 IVF가 방문할 목록을 좁히고 PQ가 목록 안의 벡터를 압축하는 결합입니다. 검색 품질이 떨어졌다면 목록 밖의 이웃을 놓친 것인지, 코드가 원본을 거칠게 표현해 순위가 바뀐 것인지 구분해야 합니다.
Faiss FAQ는 nprobe를 목록 수까지 올린 검색과 IndexIVFFlat 비교로 두 종류의 오차를 분리하는 점검법을 안내합니다. 이 실험은 같은 데이터와 거리 기준에서 진행해야 합니다.
핵심 인사이트: PQ는 저장 표현을 줄입니다. IVF는 검색할 목록을 줄입니다. 두 기능의 효과와 오류를 섞어 해석하지 않습니다.
PQ 코드는 어떤 순서로 만들어지나요?
1. 벡터를 부분공간으로 나눕니다
원 논문의 기본 PQ는 벡터의 차원을 여러 부분으로 분리합니다. 각 부분을 독립적으로 양자화하는 것이 핵심입니다. Faiss의 IndexPQ 설명에서도 부분 벡터를 별도로 양자화한다고 명시합니다.
분할 수는 코드 길이와 각 부분의 차원에 영향을 줍니다. 원하는 설정을 고르기 전에 벡터 차원과 구현의 분할 조건을 확인해야 합니다.
2. 부분별 코드북을 학습합니다
부분 벡터들의 분포를 보고 각각의 대표값 집합을 학습합니다. 원 논문은 데이터 벡터를 부분별 대표값 번호로 나타냅니다. Faiss FAQ는 IndexPQ 학습에 클러스터링 루틴이 사용된다고 밝힙니다.
학습 표본이 실제로 저장할 벡터를 잘 대표하지 못하면 코드가 원본을 거칠게 묘사할 수 있습니다. 임베딩 모델을 바꾼 뒤 기존 코드북을 그대로 쓰기보다 재학습과 재색인 필요성을 점검합니다.
3. 벡터마다 번호를 이어 코드로 저장합니다
각 부분에 가장 가까운 대표값의 번호를 붙이고 차례로 이어 하나의 코드로 만듭니다. Faiss의 인덱스 표에서는 IndexPQ가 원본 수치를 그대로 저장하는 IndexFlat과 다른 압축 형식임을 확인할 수 있습니다.
코드만 보유한 경우 원래 숫자를 정확히 복원할 수 있다고 가정하지 않습니다. 나중에 원본 거리로 재정렬하려면 해당 원본 벡터가 별도로 남아 있는지 확인해야 합니다.
부분 수와 비트 수는 무엇을 바꾸나요?
부분 수는 코드의 조각 수입니다
Faiss 문서에서 M은 부분 양자화기의 수입니다. 부분을 많이 나누면 각 부분에서 다루는 차원과 총 코드 길이가 함께 달라집니다. 설정을 바꾼 뒤 이웃 순위와 메모리의 변화는 실제 데이터로 비교해야 합니다.
동일한 전체 코드 길이라도 분할 방식에 따라 압축 오차가 같다고 보장되지는 않습니다. 단일 예시 설정을 모든 임베딩에 적용하지 않습니다.
부분별 비트 수는 선택할 대표값 수를 정합니다
Faiss의 인덱스 설명은 각 부분 코드에 쓸 비트 수를 nbits로 표시합니다. 비트 수가 늘면 각 부분이 구분할 대표값의 범위가 커지고, 코드와 학습 부담도 바뀝니다.
비트 수를 늘렸다고 모든 질의의 순위가 자동으로 좋아진다고 단정할 수 없습니다. 질의 세트의 정확 검색 결과와 비교해 확인합니다.
전체 코드 길이만으로 품질을 판단하지 않습니다
Faiss 인덱스 표는 PQ 코드의 바이트 수가 M과 nbits의 곱을 바이트로 올림한 값임을 보여 줍니다. IndexIVFPQ에서는 벡터 ID 등 IVF 저장 구조가 더해집니다.
코드북, 메타데이터, 필터에 필요한 저장 공간까지 포함한 총량을 따로 측정해야 합니다. 메모리가 줄어도 중요한 문서가 후보에서 사라진다면 업무 목적에 맞지 않습니다.
곱 양자화와 헷갈리는 용어는 무엇이 다른가요?
모델 가중치 양자화와 PQ의 차이
기존 양자화 Glossary 글은 AI 모델의 가중치나 활성값을 낮은 정밀도로 표현해 실행 메모리를 줄이는 방법을 설명합니다. 여기서는 검색할 데이터 벡터의 압축 코드를 만들고 거리 계산에 쓰는 PQ를 다룹니다.
둘 다 양자화라는 말을 쓰지만 대상과 평가 기준이 다릅니다. 모델 쪽은 추론 품질과 실행 자원, 벡터 검색 쪽은 이웃 재현율과 인덱스 메모리를 비교합니다.
스칼라 양자화와 PQ의 차이
Faiss는 IndexScalarQuantizer와 IndexPQ를 구분해 소개합니다. 스칼라 방식은 벡터 성분을 정해진 숫자 표현으로 양자화하고, PQ는 여러 차원을 부분 벡터로 묶어 각 부분의 대표값 코드를 학습합니다.
두 방식의 코드 크기와 거리 오차는 설정에 따라 달라집니다. 같은 비트 수처럼 보이는 이름만으로 속도와 결과 품질을 비교하지 않습니다.
IVFFlat과 IndexPQ의 차이
최근 IVFFlat Glossary 글의 주제는 대표점으로 역파일 목록을 만들고 일부 목록의 원본 벡터를 탐색하는 방식입니다. IndexPQ의 주제는 원본 벡터 대신 부분 벡터의 압축 코드를 보관하고 비교하는 방식입니다.
IndexPQ 자체를 설명할 때 IVF 목록 방문 수를 필수 단계라고 적으면 안 됩니다. Faiss는 별도로 IndexIVFPQ를 제공해 두 방식을 결합합니다.
IndexIVFPQ와 IndexPQ의 차이
Faiss의 IndexPQ는 PQ 코드 기반 인덱스이며 IndexIVFPQ는 IVF 목록과 PQ 코드를 합칩니다. 후자는 선택한 목록 밖의 벡터를 못 볼 가능성과 코드로 인한 거리 오차를 모두 다뤄야 합니다.
Faiss FAQ가 권하는 점검 순서를 따라 방문 목록 수를 늘려도 남는 오차를 살피면 압축이 끼친 영향의 단서를 얻습니다.
비교 정리: 모델 양자화는 모델 숫자 표현, PQ는 데이터 벡터 압축, IVFFlat은 IVF 목록의 원본 벡터 비교, IVFPQ는 목록 탐색과 PQ 압축의 결합입니다.
실전에서는 어디에 쓰이나요?
RAG 문서 후보 검색
문서 조각을 임베딩으로 저장하고 질문과 가까운 조각을 찾는 과정에서 PQ가 메모리 제약을 줄이는 선택지가 됩니다. 먼저 정답 근거가 후보에 포함되는지를 보고, 다음으로 생성 답변이 그 근거를 제대로 사용했는지 따로 확인합니다.
압축된 거리 순위만 보고 문서의 사실성이나 사용자의 읽기 권한을 판단하지 않습니다. 검색 결과의 접근 권한은 생성 모델로 전달하기 전 점검합니다.
유사 이미지와 추천 후보
원 논문은 대규모 이미지 특징 벡터의 가까운 이웃을 찾는 문제를 다룹니다. 이미지나 상품의 임베딩이 많을 때 저장 공간과 검색 지연을 함께 비교하는 데 PQ 기반 인덱스를 검토할 수 있습니다.
임베딩 모델, 벡터 차원, 거리 척도와 실제 질의 분포를 고정한 뒤 압축 전후의 결과를 비교합니다.
압축·탐색 설정의 비교 실험
Faiss의 IndexFlat을 정확 검색 기준으로 삼고 IndexPQ와 IndexIVFPQ를 같은 질의 집합에서 비교할 수 있습니다. 서로 다른 검색 범위와 저장 표현을 분리해 보면 어떤 조건에서 결과가 바뀌는지 알기 쉽습니다.
평균 지연만 볼 것이 아니라 인덱스 구축 시간, 실제 메모리, 반환된 결과 수와 중요한 문서의 누락을 함께 기록합니다.
실전 팁: 원본과 PQ 코드의 저장 크기만 비교하지 말고 같은 질문의 정확 검색 상위 결과와 검색 지연을 함께 확인하세요.
PQ 검색을 적용할 때 어떤 순서로 확인하나요?
1. 원본 벡터와 정확 검색 기준을 준비합니다
색인과 질의가 같은 임베딩 모델, 차원, 거리 기준을 쓰는지 먼저 확인합니다. 대표 질문으로 원본 벡터의 정확 검색 상위 결과를 저장해 비교 기준을 만듭니다.
사람에게 중요한 문서가 잘 나오는 질문만 고르면 누락을 알아채기 어렵습니다. 애매한 표현이나 비슷한 문서가 많은 질문도 포함합니다.
2. 코드북 학습과 코드 크기를 기록합니다
학습용 벡터가 실제 서비스 데이터와 비슷한지 확인하고 M과 부분별 비트 수를 기록합니다. Faiss의 인덱스 표에는 IndexPQ와 IndexIVFPQ의 코드 구조가 따로 제시됩니다.
원본 데이터, 코드, 코드북, ID와 IVF 구조를 포함해 총 메모리를 측정합니다. 코드 자체가 작아졌다는 사실만으로 전체 인덱스가 같은 비율로 줄었다고 단정하지 않습니다.
3. 압축 오차와 검색 범위 손실을 분리합니다
같은 벡터에서 정확 검색과 IndexPQ의 상위 결과 겹침을 비교합니다. IVF도 사용한다면 방문 목록을 바꾸고 IndexIVFFlat 같은 원본 벡터 비교 방식과 나란히 봅니다.
Faiss FAQ는 IVFPQ의 nprobe를 목록 전체로 높인 결과에 남은 오차를 PQ 압축에 연결해 진단합니다. 실제 실험에서는 설정마다 지연과 메모리도 함께 적습니다.
4. 재정렬에 필요한 원본 보관 여부를 확인합니다
압축 코드로 후보를 고른 다음 원본 거리로 다시 정렬하려면 정확한 원본 표현에 접근할 수 있어야 합니다. 코드만 저장해 놓고 원본 벡터로 재정렬했다고 기록하면 평가가 틀립니다.
원본을 따로 보관할수록 전체 저장 공간은 커집니다. 후보 검색과 재정렬의 지연, 품질 개선 여부를 각각 측정합니다.
한 줄 정리: 압축률, 정확 검색 대비 재현율, 지연 시간과 원본 보관 비용을 같은 데이터에서 함께 기록해야 합니다.
사용할 때 무엇을 주의해야 하나요?
첫째, PQ 코드를 원본 벡터로 취급하지 않습니다. 대표값 번호로 만든 코드는 근사 표현입니다. 원래 수치의 정확한 거리와 코드 기반 거리의 순위가 달라질 수 있습니다.
둘째, IndexPQ와 IndexIVFPQ를 구분합니다. PQ 자체는 압축 방식이며 IVFPQ는 목록 탐색을 더합니다. 목록 방문을 늘려도 코드 압축에 따른 오차가 사라지는 것은 아닙니다.
셋째, 예시 설정의 코드 크기를 전체 메모리로 오해하지 않습니다. 코드북, ID, 원본 벡터를 따로 보관하는지에 따라 실제 메모리가 달라집니다.
넷째, 학습 표본과 임베딩 버전을 기록합니다. 입력 분포가 바뀌면 기존 코드북과 압축 코드의 적합성이 달라질 수 있습니다. 모델 변경 후에는 다시 비교합니다.
다섯째, 권한 필터와 재정렬 단계를 함께 봅니다. 정답 근거가 압축 검색의 후보에서 빠지는지 확인하고, 권한 없는 자료는 생성 단계로 넘기지 않습니다.
주의: PQ는 저장 공간을 줄이는 수단이지 검색 정확도나 문서의 사실성을 보장하는 기능이 아닙니다.
자주 묻는 질문
Q1. PQ는 모델을 4비트로 바꾸는 양자화와 같나요?
아닙니다. 이 글의 PQ는 검색 데이터 벡터를 부분별 대표값 번호로 압축합니다. 모델 가중치 양자화는 실행할 모델의 숫자 표현을 줄이는 별도 주제입니다.
Q2. IndexPQ를 쓰려면 IVF가 반드시 필요한가요?
아닙니다. Faiss는 PQ 코드를 쓰는 IndexPQ와 IVF 목록을 함께 쓰는 IndexIVFPQ를 별도로 제공합니다. 둘의 오차 원인을 구분해야 합니다.
Q3. PQ 코드는 원본 임베딩을 정확히 복원하나요?
아닙니다. 부분마다 고른 대표값을 이어 만든 근사 표현입니다. 원본 거리로 다시 비교해야 한다면 원본 벡터의 별도 보관 여부를 확인하세요.
Q4. 부분 수를 늘리면 검색 정확도가 무조건 좋아지나요?
그렇지 않습니다. 코드 길이와 부분의 차원이 같이 바뀝니다. 비트 수, 학습 데이터와 질의 분포를 고정하고 정확 검색 결과와 비교해야 합니다.
Q5. IVFPQ에서 방문 목록을 모두 열면 정확 검색이 되나요?
아닙니다. 목록을 모두 방문해도 PQ의 압축 거리는 근사값입니다. Faiss FAQ는 이 상태에 남는 오차를 압축의 영향으로 살펴보라고 안내합니다.
Q6. RAG의 답변도 PQ만 잘 설정하면 정확해지나요?
아닙니다. PQ는 근거 후보를 찾는 검색 단계에 쓰입니다. 관련 문서의 누락, 권한, 문서 내용의 정확성과 생성 답변의 근거 사용을 따로 확인해야 합니다.
출처
마무리
곱 양자화는 긴 벡터를 여러 부분으로 나누어 각각의 대표값 번호를 저장하는 압축 기법입니다. Faiss에서는 IndexPQ로 코드 기반 거리를 비교하고 IndexIVFPQ로 IVF 목록 탐색과 결합할 수 있습니다. 원본 벡터 거리와 같다고 보장하지 않습니다.
처음 적용할 때는 원본 벡터의 정확 검색 결과를 먼저 보관하세요. 그다음 부분 수와 비트 수를 바꿔 인덱스 메모리, 지연, 정답 근거의 재현율을 비교하면 압축의 이득과 품질 손실을 함께 판단할 수 있습니다.
