ClickHouse 벡터 검색
ClickHouse 벡터 검색 (Vector search)
ClickHouse에서 벡터 검색을 수행하는 방법을 소개해요. 이 가이드에서는 벡터 검색의 기본 개념부터 ANN(Approximate Nearest Neighbour), HNSW, 그리고 ClickHouse가 새로 도입한 QBit(Quantised Bit)까지 차근차근 설명하고, DBPedia 데이터셋으로 실제 벡터 검색을 실행해 봐요.
출처: 문서
본문
이 가이드에서 배울 내용:
- 벡터 검색을 간략히 소개
- ANN(Approximate Nearest Neighbours)과 HNSW(Hierarchical Navigable Small World) 알아보기
- QBit(Quantised Bit) 알아보기
- QBit를 사용해서 DBPedia 데이터셋으로 벡터 검색 수행하기
벡터 검색 입문 (Vector search primer)
수학과 물리학에서 벡터는 크기와 방향을 모두 가진 객체로 공식적으로 정의돼요. 종종 공간을 통과하는 선분이나 화살표 형태를 띠며 속도, 힘, 가속도 같은 양을 나타내는 데 쓰여요. 컴퓨터 과학에서 벡터는 숫자의 유한한 시퀀스예요. 다시 말해 숫자 값을 저장하는 데 사용하는 데이터 구조예요.
머신러닝에서 벡터는 컴퓨터 과학에서 이야기하는 것과 같은 데이터 구조지만, 저장된 숫자 값에는 특별한 의미가 있어요. 텍스트 블록이나 이미지를 가져와서 그 핵심 개념으로 정제하는 과정을 인코딩(encoding)이라고 불러요. 그 결과물은 해당 핵심 개념들을 숫자 형태로 표현한 머신의 표현이에요. 이것이 임베딩(embedding)이고, 벡터에 저장돼요. 다르게 말하면, 이 문맥적 의미가 벡터에 임베딩될 때 우리는 그것을 임베딩이라고 부를 수 있어요.
벡터 검색은 이제 어디에나 있어요. 음악 추천, 대규모 언어 모델의 답변을 개선하기 위해 외부 지식을 가져오는 RAG(검색 증강 생성)까지 벡터 검색이 동력을 공급하고, 심지어 구글 검색도 어느 정도 벡터 검색으로 작동해요. 사용자들은 전용 벡터 스토어의 장점에도 불구하고, 완전히 전문화된 벡터 스토어보다 임시 벡터 기능이 있는 일반 데이터베이스를 종종 선호해요.
ClickHouse는 완전 탐색 벡터 검색과 함께, ANN(근사 최근접 이웃) 검색 방법 — 고속 벡터 검색의 현재 표준인 HNSW를 포함해 —을 지원해요.
임베딩 이해하기 (Understanding embeddings)
벡터 검색이 어떻게 작동하는지 이해하기 위해 간단한 예시를 살펴볼게요. 단어의 임베딩(벡터 표현)을 생각해 봐요.
샘플 임베딩 몇 개로 아래 테이블을 만들어요:
CREATE TABLE fruit_animal
ENGINE = MergeTree
ORDER BY word
AS SELECT *
FROM VALUES(
'word String, vec Array(Float64)',
('apple', [-0.99105519, 1.28887844, -0.43526649, -0.98520696, 0.66154391]),
('banana', [-0.69372815, 0.25587061, -0.88226235, -2.54593015, 0.05300475]),
('orange', [0.93338752, 2.06571317, -0.54612565, -1.51625717, 0.69775337]),
('dog', [0.72138876, 1.55757105, 2.10953259, -0.33961248, -0.62217325]),
('horse', [-0.61435682, 0.48542571, 1.21091247, -0.62530446, -1.33082533])
);
주어진 임베딩에 가장 유사한 단어를 검색할 수 있어요:
SELECT word, L2Distance(
vec, [-0.88693672, 1.31532824, -0.51182908, -0.99652702, 0.59907770]
) AS distance
FROM fruit_animal
ORDER BY distance
LIMIT 5;
┌─word───┬────────────distance─┐
│ apple │ 0.14639757188169716 │
│ banana │ 1.9989613690076786 │
│ orange │ 2.039041552613732 │
│ horse │ 2.7555776805484813 │
│ dog │ 3.382295083120104 │
└────────┴─────────────────────┘
쿼리 임베딩은 "apple"에 가장 가까워요(거리가 가장 작음). 두 임베딩을 나란히 보면 이게 말이 되죠:
apple: [-0.99105519,1.28887844,-0.43526649,-0.98520696,0.66154391]
query embedding: [-0.88693672,1.31532824,-0.51182908,-0.99652702,0.5990777]
ANN (Approximate Nearest Neighbours)
대규모 데이터셋에서는 완전 탐색(brute-force)이 너무 느려져요. 이때 ANN(근사 최근접 이웃) 방법이 등장해요.
양자화 (Quantisation)
양자화는 더 작은 숫자 타입으로 다운캐스팅하는 것을 의미해요. 숫자가 작을수록 데이터가 작고, 데이터가 작을수록 거리 계산이 빨라져요. ClickHouse의 벡터화된 쿼리 실행 엔진은 연산당 프로세서 레지스터에 더 많은 값을 채울 수 있어서 처리량이 직접적으로 늘어나요. 두 가지 옵션이 있어요:
- 양자화된 복사본을 원래 열과 함께 유지하기 — 저장 공간이 두 배가 되지만, 항상 전체 정밀도로 되돌아갈 수 있어서 안전해요
- 원래 값을 완전히 대체하기(삽입 시 다운캐스팅) — 공간과 I/O를 아끼지만, 한 번 가면 되돌릴 수 없는 문이에요
HNSW (Hierarchical Navigable Small World)
HNSW는 여러 층의 노드(벡터)로 구성돼요. 각 노드는 하나 이상의 층에 무작위로 배정되며, 더 높은 층에 나타날 확률은 지수적으로 감소해요. 검색을 수행할 때는 최상위 층의 노드에서 시작해 가장 가까운 이웃을 향해 탐욕적으로 이동해요. 더 가까운 노드를 찾을 수 없으면 다음으로 더 조밀한 층으로 내려가요. 이 계층적 설계 덕분에 HNSW는 노드 수에 대해 로그 수준의 검색 복잡도를 달성해요.
HNSW 제한 사항 — 주요 병목은 메모리예요. ClickHouse는 usearch 구현의 HNSW를 사용하는데, 이는 인메모리 데이터 구조라 분할을 지원하지 않아요. 결과적으로 데이터셋이 클수록 그에 비례해 더 많은 RAM이 필요해요.
접근 방식 비교 (Comparison of approaches)
| 범주 | Brute-force | HNSW | QBit |
|---|---|---|---|
| 정밀도 (Precision) | 완벽 (Perfect) | 훌륭 (Great) | 유연 (Flexible) |
| 속도 (Speed) | 느림 (Slow) | 빠름 (Fast) | 유연 (Flexible) |
| 기타 (Others) | 양자화: 더 많은 공간 또는 되돌릴 수 없는 정밀도 손실 | 인덱스가 메모리에 들어가야 하고 구축해야 함 | 여전히 O(#records) |
QBit 심층 분석 (QBit deep dive)
QBit (Quantised Bit)
QBit는 부동소수점 숫자가 비트로 표현된다는 점을 활용해서 BFloat16, Float32, Float64 값을 저장할 수 있는 새로운 데이터 구조예요. QBit는 각 숫자를 통째로 저장하는 대신 값을 비트 평면(bit planes) 으로 분리해요: 첫 번째 비트들끼리, 두 번째 비트들끼리, 세 번째 비트들끼리, 이런 식으로요.
이 접근 방식은 기존 양자화의 주요 제한 사항을 해결해요. 중복 데이터를 저장하거나 값을 무의미하게 만들 위험이 없어요. 또한 QBit는 저장된 데이터로 직접 작업하기 때문에 인메모리 인덱스를 유지하지 않아 HNSW의 RAM 병목도 피해요.
이점 — 무엇보다 가장 중요한 점은 사전 결정이 필요 없다는 것이에요. 정밀도와 성능은 쿼리 시점에 동적으로 조정할 수 있어서, 사용자는 최소한의 마찰로 정확도와 속도 사이의 균형을 탐색할 수 있어요.
제한 사항 — QBit는 벡터 검색을 빠르게 만들지만 계산 복잡도는 여전히 O(n)이에요. 다시 말해, 데이터셋이 HNSW 인덱스를 RAM에 편안히 넣을 만큼 작다면 HNSW가 여전히 가장 빠른 선택이에요.
데이터 타입 (The data type)
QBit 열을 만드는 방법은 다음과 같아요:
SET allow_experimental_qbit_type = 1;
CREATE TABLE fruit_animal
(
word String,
vec QBit(Float64, 5)
)
ENGINE = MergeTree
ORDER BY word;
INSERT INTO fruit_animal VALUES
('apple', [-0.99105519, 1.28887844, -0.43526649, -0.98520696, 0.66154391]),
('banana', [-0.69372815, 0.25587061, -0.88226235, -2.54593015, 0.05300475]),
('orange', [0.93338752, 2.06571317, -0.54612565, -1.51625717, 0.69775337]),
('dog', [0.72138876, 1.55757105, 2.10953259, -0.33961248, -0.62217325]),
('horse', [-0.61435682, 0.48542571, 1.21091247, -0.62530446, -1.33082533]);
데이터가 QBit 열에 삽입되면, 모든 첫 번째 비트가 함께 정렬되고 모든 두 번째 비트가 함께 정렬되는 식으로 전치(transpose)돼요. 우리는 이것을 그룹(group) 이라고 불러요. 각 그룹은 별도의 FixedString(N) 열에 저장되는데, 이는 메모리에 구분자 없이 연속적으로 저장되는 N바이트의 고정 길이 문자열이에요. 이 모든 그룹은 함께 묶여 단일 Tuple을 형성하며, 이것이 QBit의 기본 구조가 돼요.
예시: 8×Float64 요소의 벡터로 시작하면 각 그룹은 8비트를 포함해요. Float64는 64비트이므로 결국 64개의 그룹(각 비트당 하나)이 생겨요. 따라서 QBit(Float64, 8)의 내부 레이아웃은 64×FixedString(1) 열의 Tuple처럼 보여요.
원래 벡터 길이가 8로 나누어떨어지지 않으면, 8에 맞춰 정렬되도록 보이지 않는 요소로 패딩돼요. 이는 전체 바이트 단위로만 작동하는 FixedString과의 호환성을 보장하기 위해서예요.
거리 계산 (The distance calculation)
QBit로 쿼리하려면 정밀도 매개변수를 가진 L2DistanceTransposed 함수를 사용해요:
SELECT
word,
L2DistanceTransposed(vec, [-0.88693672, 1.31532824, -0.51182908, -0.99652702, 0.59907770], 16) AS distance
FROM fruit_animal
ORDER BY distance;
┌─word───┬────────────distance─┐
│ apple │ 0.15196434766705247 │
│ banana │ 1.966091150410285 │
│ orange │ 1.9864477714218596 │
│ horse │ 2.7306267946594005 │
│ dog │ 3.2849989362383165 │
└────────┴─────────────────────┘
세 번째 매개변수(16)는 비트 단위의 정밀도 수준을 지정해요.
I/O 최적화 (I/O Optimisation)
거리를 계산하기 전에 필요한 데이터를 디스크에서 읽은 다음 전치를 풀어야 해요(그룹화된 비트 표현에서 전체 벡터로 다시 변환). QBit는 값을 정밀도 수준별로 비트 전치해서 저장하기 때문에, ClickHouse는 원하는 정밀도까지 숫자를 재구성하는 데 필요한 상위 비트 평면만 읽을 수 있어요. 위 쿼리에서는 정밀도 수준 16을 사용했어요. Float64가 64비트이므로 처음 16개의 비트 평면만 읽어서 데이터의 75%를 건너뛰게 돼요.
읽은 후에는 로드된 비트 평면에서 각 숫자의 상위 부분만 재구성하고, 읽지 않은 비트는 0으로 남겨둬요.
계산 최적화 (Calculation optimisation)
Float32나 BFloat16 같은 더 작은 타입으로 캐스팅하면 이 미사용 부분을 없앨 수 있지 않을까 궁금할 수 있어요. 실제로 효과가 있지만, 명시적 캐스팅은 모든 행에 적용될 때 비용이 커요. 대신 참조 벡터만 다운캐스트하고 QBit 데이터를 더 좁은 값을 가진 것처럼 취급할 수 있는데(일부 열의 존재를 "잊는" 것), 그 이유는 QBit의 레이아웃이 종종 그 타입의 잘린 버전에 해당하기 때문이에요.
BFloat16 최적화 (BFloat16 Optimization)
BFloat16은 절반으로 잘린 Float32예요. 부호 비트와 8비트 지수는 동일하지만 23비트 가수의 상위 7비트만 유지해요. 이 때문에 QBit 열에서 처음 16개의 비트 평면을 읽으면 사실상 BFloat16 값의 레이아웃이 재현돼요. 그래서 이 경우에는 참조 벡터를 안전하게 BFloat16으로 변환할 수 있고, 실제로 그렇게 해요.
Float64 복잡성 (Float64 Complexity)
하지만 Float64는 다른 이야기예요. 11비트 지수와 52비트 가수를 사용해서 단순히 비트가 두 배인 Float32가 아니에요. 구조와 지수 편향이 완전히 달라요. Float64를 Float32 같은 더 작은 포맷으로 다운캐스팅하려면 실제 IEEE-754 변환이 필요한데, 각 값이 가장 가까운 표현 가능한 Float32로 반올림돼요. 이 반올림 단계는 계산 비용이 커요.
QBit의 성능 요소에 대한 심층 분석에 관심이 있다면 "Let's vectorize"를 참고해요.
DBPedia 예시 (Example with DBpedia)
실제 사례인 DBPedia 데이터셋으로 QBit가 작동하는 모습을 살펴볼게요. 이 데이터셋은 Float32 임베딩으로 표현된 100만 개의 Wikipedia 문서를 담고 있어요.
셋업 (Setup)
먼저 테이블을 만들어요:
CREATE TABLE dbpedia
(
id String,
title String,
text String,
vector Array(Float32) CODEC(NONE)
) ENGINE = MergeTree ORDER BY (id);
커맨드 라인에서 데이터를 삽입해요:
for i in $(seq 0 25); do
echo "Processing file ${i}..."
clickhouse client -q "INSERT INTO dbpedia SELECT _id, title, text, \"text-embedding-3-large-1536-embedding\" FROM url('https://huggingface.co/api/datasets/Qdrant/dbpedia-entities-openai3-text-embedding-3-large-1536-1M/parquet/default/train/${i}.parquet') SETTINGS max_http_get_redirects=5,enable_url_encoding=0;"
echo "File ${i} complete."
done
데이터 삽입에는 시간이 걸릴 수 있어요. 커피 한 잔 할 시간이네요!
대안으로, 아래처럼 개별 SQL 문을 실행해서 각각의 25개 Parquet 파일을 로드할 수도 있어요:
INSERT INTO dbpedia SELECT _id, title, text, "text-embedding-3-large-1536-embedding" FROM url('https://huggingface.co/api/datasets/Qdrant/dbpedia-entities-openai3-text-embedding-3-large-1536-1M/parquet/default/train/0.parquet') SETTINGS max_http_get_redirects=5,enable_url_encoding=0;
INSERT INTO dbpedia SELECT _id, title, text, "text-embedding-3-large-1536-embedding" FROM url('https://huggingface.co/api/datasets/Qdrant/dbpedia-entities-openai3-text-embedding-3-large-1536-1M/parquet/default/train/1.parquet') SETTINGS max_http_get_redirects=5,enable_url_encoding=0;
...
INSERT INTO dbpedia SELECT _id, title, text, "text-embedding-3-large-1536-embedding" FROM url('https://huggingface.co/api/datasets/Qdrant/dbpedia-entities-openai3-text-embedding-3-large-1536-1M/parquet/default/train/25.parquet') SETTINGS max_http_get_redirects=5,enable_url_encoding=0;
dbpedia 테이블에 100만 행이 보이는지 확인해요:
SELECT count(*)
FROM dbpedia
┌─count()─┐
│ 1000000 │
└─────────┘
다음으로 QBit 열을 추가해요:
SET allow_experimental_qbit_type = 1;
-- Assuming you have a table with Float32 embeddings
ALTER TABLE dbpedia ADD COLUMN qbit QBit(Float32, 1536);
ALTER TABLE dbpedia UPDATE qbit = vector WHERE 1;
검색 쿼리 (Search query)
우주와 관련된 모든 검색어(Moon, Apollo 11, Space Shuttle, Astronaut, Rocket)와 가장 관련 깊은 개념을 찾아볼게요:
SELECT
title,
text,
COUNT(DISTINCT concept) AS num_concepts_matched,
MIN(distance) AS min_distance,
AVG(distance) AS avg_distance
FROM (
(
SELECT title, text, 'Moon' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Moon'), 5) AS distance
FROM dbpedia
WHERE title != 'Moon'
ORDER BY distance ASC
LIMIT 1000
)
UNION ALL
(
SELECT title, text, 'Apollo 11' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Apollo 11'), 5) AS distance
FROM dbpedia
WHERE title != 'Apollo 11'
ORDER BY distance ASC
LIMIT 1000
)
UNION ALL
(
SELECT title, text, 'Space Shuttle' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Space Shuttle'), 5) AS distance
FROM dbpedia
WHERE title != 'Space Shuttle'
ORDER BY distance ASC
LIMIT 1000
)
UNION ALL
(
SELECT title, text, 'Astronaut' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Astronaut'), 5) AS distance
FROM dbpedia
WHERE title != 'Astronaut'
ORDER BY distance ASC
LIMIT 1000
)
UNION ALL
(
SELECT title, text, 'Rocket' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Rocket'), 5) AS distance
FROM dbpedia
WHERE title != 'Rocket'
ORDER BY distance ASC
LIMIT 1000
)
)
WHERE title NOT IN ('Moon', 'Apollo 11', 'Space Shuttle', 'Astronaut', 'Rocket')
GROUP BY title, text
HAVING num_concepts_matched >= 3
ORDER BY num_concepts_matched DESC, min_distance ASC
LIMIT 10;
이 쿼리는 다섯 개 개념 각각에 대해 의미적으로 가장 유사한 상위 1000개 항목을 검색해요. 쿼리는 그 결과 중 적어도 세 곳에 나타나는 항목을, 매치된 개념 수와 그중 어느 것에 대한 최소 거리(원본 제외)로 순위를 매겨 반환해요.
단 5비트(부호 1비트 + 지수 4비트, 가수 0)만 사용했어요:
Row 1:
──────
title: Aintree railway station
text: For a guide to the various Aintree stations that have existed and their relationship to each other see Aintree Stations.Aintree railway station is a railway station in Aintree, Merseyside, England. It is on the Ormskirk branch of the Merseyrail network's Northern Line. Until 1968 it was known as Aintree Sefton Arms after a nearby public house. The station's design reflects the fact it is the closest station to Aintree Racecourse, where the annual Grand National horse race takes place.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 2:
──────
title: AP German Language
text: Advanced Placement German Language (also known as AP German Language or AP German) is a course and examination provided by the College Board through the Advanced Placement Program. This course is designed to give high school students the opportunity to receive credit in a college-level German language course.Originally the College Board had offered two AP German exams, one with AP German Language and another with AP German Literature.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 3:
──────
title: Adelospondyli
text: Adelospondyli is an order of elongate, presumably aquatic, Carboniferous amphibians. The skull is solidly roofed, and elongate, with the orbits located very far forward. The limbs are well developed. Most adelospondyls belong to the family Adelogyrinidae, although the adelospondyl Acherontiscus has been placed in its own family, Acherontiscidae. The group is restricted to the Mississippian (Serpukhovian Age) of Scotland.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 4:
──────
title: Adrien-Henri de Jussieu
text: Adrien-Henri de Jussieu (23 December 1797 – 29 June 1853) was a French botanist.Born in Paris as the son of botanist Antoine Laurent de Jussieu, he received the degree of Doctor of Medicine in 1824 with a treatise of the plant family Euphorbiaceae. When his father retired in 1826, he succeeded him at the Jardin des Plantes; in 1845 he became professor of organography of plants.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 5:
──────
title: Alan Taylor (footballer, born 1953)
text: Alan Taylor (born 14 November 1953) is an English former professional footballer best known for his goalscoring exploits with West Ham United in their FA Cup success of 1975, culminating in two goals in that season's final.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 6:
──────
title: Abstract algebraic logic
text: In mathematical logic, abstract algebraic logic is the study of the algebraization of deductive systemsarising as an abstraction of the well-known Lindenbaum-Tarski algebra, and how the resulting algebras are related to logical systems.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 7:
──────
title: Ahsan Saleem Hyat
text: General Ahsan Saleem Hayat (Urdu: احسن سلیم حیات; born 10 January 1948), is a retired four-star general who served as the vice chief of army staff of the Pakistan Army from 2004 until his retirement in 2007. Prior to that, he served as the operational field commander of the V Corps in Sindh Province and was a full-tenured professor of war studies at the National Defence University. He was succeeded by General Ashfaq Parvez Kayani on 8 October 2007.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 8:
──────
title: Al Wafa al Igatha al Islamia
text: There is another organization named Al Wafa (Israel), a charity, in Israel, devoted to womenThere is another organization Jamaiat Al-Wafa LiRayat Al-Musenin which is proscribed by the Israeli government.Al Wafa is an Islamic charity listed in Executive Order 13224 as an entity that supports terrorism.United States intelligence officials state that it was founded in Afghanistan by Adil Zamil Abdull Mohssin Al Zamil,Abdul Aziz al-Matrafi and Samar Khand.According to Saad Madai Saad al-Azmi's Combatant Status Review Tribunal Al Wafa is located in the Wazir Akhbar Khan area ofAfghanistan.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 9:
───────
title: Alex Baumann
text: Alexander Baumann, OC OOnt (born April 21, 1964) is a Canadian former competitive swimmer who won two gold medals and set two world records at the 1984 Summer Olympics in Los Angeles.Born in Prague (former Czechoslovakia), Baumann was raised in Canada after his family moved there in 1969 following the Prague Spring.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
Row 10:
───────
title: Alberni-Clayoquot Regional District
text: The Alberni-Clayoquot Regional District (2006 population 30,664) of British Columbia is located on west central Vancouver Island. Adjacent regional districts it shares borders with are the Strathcona and Comox Valley Regional Districts to the north, and the Nanaimo and Cowichan Valley Regional Districts to the east. The regional district offices are located in Port Alberni.
num_concepts_matched: 5
min_distance: 0.9971279086553189
avg_distance: 0.9972260772085877
10 rows in set. Elapsed: 0.542 sec. Processed 5.01 million rows, 1.86 GB (9.24 million rows/s., 3.43 GB/s.)
Peak memory usage: 327.04 MiB.
성능: 10 rows in set. Elapsed: 0.271 sec. Processed 8.46 million rows, 4.54 GB (31.19 million rows/s., 16.75 GB/s.) Peak memory usage: 739.82 MiB.
완전 탐색과 성능 비교하기
SELECT
title,
text,
COUNT(DISTINCT concept) AS num_concepts_matched,
MIN(distance) AS min_distance,
AVG(distance) AS avg_distance
FROM (
(
SELECT title, text, 'Moon' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Moon'), 5) AS distance
FROM dbpedia
WHERE title != 'Moon'
ORDER BY distance ASC
LIMIT 1000
)
UNION ALL
(
SELECT title, text, 'Apollo 11' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Apollo 11'), 5) AS distance
FROM dbpedia
WHERE title != 'Apollo 11'
ORDER BY distance ASC
LIMIT 1000
)
UNION ALL
(
SELECT title, text, 'Space Shuttle' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Space Shuttle'), 5) AS distance
FROM dbpedia
WHERE title != 'Space Shuttle'
ORDER BY distance ASC
LIMIT 1000
)
UNION ALL
(
SELECT title, text, 'Astronaut' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Astronaut'), 5) AS distance
FROM dbpedia
WHERE title != 'Astronaut'
ORDER BY distance ASC
LIMIT 1000
)
UNION ALL
(
SELECT title, text, 'Rocket' AS concept,
L2DistanceTransposed(qbit, (SELECT vector FROM dbpedia WHERE title = 'Rocket'), 5) AS distance
FROM dbpedia
WHERE title != 'Rocket'
ORDER BY distance ASC
LIMIT 1000
)
)
WHERE title NOT IN ('Moon', 'Apollo 11', 'Space Shuttle', 'Astronaut', 'Rocket')
GROUP BY title, text
HAVING num_concepts_matched >= 3
ORDER BY num_concepts_matched DESC, min_distance ASC
LIMIT 10;
Row 1:
──────
title: Apollo program
text: The Apollo program, also known as Project Apollo, was the third United States human spaceflight program carried out by the National Aeronautics and Space Administration (NASA), which accomplished landing the first humans on the Moon from 1969 to 1972. First conceived during Dwight D. Eisenhower's administration as a three-man spacecraft to follow the one-man Project Mercury which put the first Americans in space, Apollo was later dedicated to President John F.
num_concepts_matched: 4
min_distance: 0.82420665
avg_distance: 1.0207901149988174
Row 2:
──────
title: Apollo 8
text: Apollo 8, the second human spaceflight mission in the United States Apollo space program, was launched on December 21, 1968, and became the first manned spacecraft to leave Earth orbit, reach the Earth's Moon, orbit it and return safely to Earth.
num_concepts_matched: 4
min_distance: 0.8285278
avg_distance: 1.0357224345207214
Row 3:
──────
title: Lunar Orbiter 1
text: The Lunar Orbiter 1 robotic (unmanned) spacecraft, part of the Lunar Orbiter Program, was the first American spacecraft to orbit the Moon. It was designed primarily to photograph smooth areas of the lunar surface for selection and verification of safe landing sites for the Surveyor and Apollo missions. It was also equipped to collect selenodetic, radiation intensity, and micrometeoroid impact data.The spacecraft was placed in an Earth parking orbit on August 10, 1966 at 19:31 (UTC).
num_concepts_matched: 4
min_distance: 0.94581836
avg_distance: 1.0584313124418259
Row 4:
──────
title: Apollo (spacecraft)
text: The Apollo spacecraft was composed of three parts designed to accomplish the American Apollo program's goal of landing astronauts on the Moon by the end of the 1960s and returning them safely to Earth. The expendable (single-use) spacecraft consisted of a combined Command/Service Module (CSM) and a Lunar Module (LM).
num_concepts_matched: 4
min_distance: 0.9643517
avg_distance: 1.0367188602685928
Row 5:
──────
title: Surveyor 1
text: Surveyor 1 was the first lunar soft-lander in the unmanned Surveyor program of the National Aeronautics and Space Administration (NASA, United States). This lunar soft-lander gathered data about the lunar surface that would be needed for the manned Apollo Moon landings that began in 1969.
num_concepts_matched: 4
min_distance: 0.9738264
avg_distance: 1.0988530814647675
Row 6:
──────
title: Spaceflight
text: Spaceflight (also written space flight) is ballistic flight into or through outer space. Spaceflight can occur with spacecraft with or without humans on board. Examples of human spaceflight include the Russian Soyuz program, the U.S. Space shuttle program, as well as the ongoing International Space Station. Examples of unmanned spaceflight include space probes that leave Earth orbit, as well as satellites in orbit around Earth, such as communications satellites.
num_concepts_matched: 4
min_distance: 0.9831049
avg_distance: 1.060678943991661
Row 7:
──────
title: Skylab
text: Skylab was a space station launched and operated by NASA and was the United States' first space station. Skylab orbited the Earth from 1973 to 1979, and included a workshop, a solar observatory, and other systems. It was launched unmanned by a modified Saturn V rocket, with a weight of 169,950 pounds (77 t). Three manned missions to the station, conducted between 1973 and 1974 using the Apollo Command/Service Module (CSM) atop the smaller Saturn IB, each delivered a three-astronaut crew.
num_concepts_matched: 4
min_distance: 0.99155205
avg_distance: 1.0769911855459213
Row 8:
──────
title: Orbital spaceflight
text: An orbital spaceflight (or orbital flight) is a spaceflight in which a spacecraft is placed on a trajectory where it could remain in space for at least one orbit. To do this around the Earth, it must be on a free trajectory which has an altitude at perigee (altitude at closest approach) above 100 kilometers (62 mi) (this is, by at least one convention, the boundary of space). To remain in orbit at this altitude requires an orbital speed of ~7.8 km/s.
num_concepts_matched: 4
min_distance: 1.0075209
avg_distance: 1.085978478193283
Row 9:
───────
title: Dragon (spacecraft)
text: Dragon is a partially reusable spacecraft developed by SpaceX, an American private space transportation company based in Hawthorne, California. Dragon is launched into space by the SpaceX Falcon 9 two-stage-to-orbit launch vehicle, and SpaceX is developing a crewed version called the Dragon V2.During its maiden flight in December 2010, Dragon became the first commercially built and operated spacecraft to be recovered successfully from orbit.
num_concepts_matched: 4
min_distance: 1.0222818
avg_distance: 1.0942841172218323
Row 10:
───────
title: Space capsule
text: A space capsule is an often manned spacecraft which has a simple shape for the main section, without any wings or other features to create lift during atmospheric reentry.Capsules have been used in most of the manned space programs to date, including the world's first manned spacecraft Vostok and Mercury, as well as in later Soviet Voskhod, Soyuz, Zond/L1, L3, TKS, US Gemini, Apollo Command Module, Chinese Shenzhou and US, Russian and Indian manned spacecraft currently being developed.
num_concepts_matched: 4
min_distance: 1.0262821
avg_distance: 1.0882147550582886
성능: 10 rows in set. Elapsed: 1.157 sec. Processed 10.00 million rows, 32.76 GB (8.64 million rows/s., 28.32 GB/s.) Peak memory usage: 6.05 GiB.
핵심 통찰 (Key Insight)
결과? 그냥 좋은 게 아니라 놀랍도록 좋아요. 가수 전체와 지수의 절반이 제거된 부동소수점이 여전히 의미 있는 정보를 담고 있다는 것은 결코 당연한 일이 아니에요.
QBit의 핵심 통찰은, 중요하지 않은 비트를 무시해도 벡터 검색이 여전히 작동한다는 것이에요. 메모리 사용량을 6.05 GB에서 740 MB로 줄이면서도 뛰어난 의미 검색 품질을 유지했어요!
결론 (Conclusion)
QBit는 부동소수점을 비트 평면으로 저장하는 열 타입이에요. 벡터 검색 중 읽을 비트 수를 선택할 수 있어서, 데이터를 바꾸지 않고도 재현율(recall)과 성능을 조정할 수 있어요. 각 벡터 검색 방법에는 재현율, 정확도, 성능의 트레이드오프를 결정하는 자체 매개변수가 있어요. 보통 이런 값들은 미리 선택해야 해요. 잘못 고르면 많은 시간과 리소스가 낭비되고 나중에 방향을 바꾸는 게 고통스러워져요. QBit를 사용하면 초기 결정이 필요 없어요. 정밀도와 속도의 트레이드오프를 쿼리 시점에 직접 조정하면서, 균형을 찾아 탐색할 수 있어요.
Raufs Dunamalijevs의 블로그 포스트에서 발췌 — 2025년 10월 28일 게시