pgvector 이진 벡터 — bit와 이진 양자화

pgvector 이진 벡터 — bit와 이진 양자화

이미지 해시 같은 데이터는 비트(0/1)로 표현하는 게 자연스러워요. pgvector는 bit 타입으로 이진 벡터를 저장하고, 해밍·자카드 거리로 유사도를 비교할 수 있습니다.

출처: https://github.com/pgvector/pgvector#binary-vectors

bit로 저장하고 해밍 거리로 검색

CREATE TABLE items (id bigserial PRIMARY KEY, embedding bit(3));
INSERT INTO items (embedding) VALUES ('000'), ('111');

해밍 거리 연산자는 <~> 이고, 자카드 거리는 <%>를 씁니다.

SELECT * FROM items ORDER BY embedding <~> '101' LIMIT 5;

이진 양자화

실수 벡터를 이진 표현으로 줄여 인덱스하면 메모리를 극적으로 절약할 수 있어요. binary_quantize 함수를 표현식 인덱스로 쓰면 됩니다.

CREATE INDEX ON items USING hnsw ((binary_quantize(embedding)::bit(3)) bit_hamming_ops);
SELECT * FROM items ORDER BY binary_quantize(embedding)::bit(3) <~> binary_quantize('[1,-2,3]') LIMIT 5;

이진 양자화로 후보를 뽑고 recall을 높이려면 원본 벡터로 재정렬(re-rank)하면 좋아요. 넉넉한 후보(20개)를 이진으로 먼저 뽑고, 그 안에서 원본 벡터의 실제 거리로 다시 정렬하는 방식입니다.

SELECT * FROM (
    SELECT * FROM items ORDER BY binary_quantize(embedding)::bit(3) <~> binary_quantize('[1,-2,3]') LIMIT 20
) ORDER BY embedding <=> '[1,-2,3]' LIMIT 5;

더 알아보기