TRENDSHIFT 딥다이브 · 일간 #4 · 2026-06-18

zvec 딥다이브
— 서버 없이 앱 안에 박아 쓰는 '초고속 인프로세스 벡터 DB'

zvec(지벡)은 알리바바가 공개한 오픈소스 인프로세스(in-process) 벡터 데이터베이스다. SQLite가 별도 DB 서버 없이 그냥 라이브러리로 앱에 박혀 도는 것처럼, zvec도 서버·도커·네트워크 없이 라이브러리 하나로 내 프로그램 안에서 직접 도는 벡터 검색 엔진이다. 알리바바 그룹 내부에서 실전 검증을 거쳤고, C++로 짠 코어가 수십억 개 벡터를 밀리초 단위로 유사도 검색한다. HNSW·IVF·DiskANN 등 다양한 인덱스, 밀집/희소 벡터, 전문 검색(FTS), 하이브리드 검색, WAL 영속성까지 갖췄다. (저장소: alibaba/zvec · C++ 79% / Python · ★9.7k · Apache-2.0 · 최신 v0.5.0 · pip install zvec)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어/시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

한 문장으로 이 프로젝트가 뭘 하는지부터.

zvec = "벡터 검색계의 SQLite — 서버를 띄울 필요 없이, 라이브러리로 앱에 박아 쓰는 초고속 벡터 데이터베이스." 보통 벡터 DB(Milvus·Qdrant·Weaviate)는 별도 서버 프로세스를 띄우고, 도커로 올리고, 네트워크로 붙어 쓴다. zvec은 그 발상을 뒤집어 서버도 도커도 설정도 없이 pip install zvec 한 줄로 깔고, import zvec 해서 내 코드 안에서 곧바로 호출한다. 데이터는 로컬 디스크 폴더 하나에 저장되고, 검색 연산은 내 프로세스의 CPU에서 그대로 돈다.

🧩 한 줄 비유

"검색 전용 서버를 따로 세우는" 게 아니라, "앱 안에 벡터 검색 엔진을 통째로 심는" 것

일반 벡터 DB는 식당 옆에 '창고 건물'을 따로 짓는 것과 같다 — 건물을 세우고(서버 구축), 직원을 두고(프로세스 관리), 주문이 올 때마다 사람이 창고로 달려가(네트워크 왕복) 물건을 가져온다. 빠르고 크지만 무겁다.

zvec은 주방 서랍에 검색 엔진을 그냥 넣어 두는 식이다. 건물도 직원도 필요 없이, 손만 뻗으면(함수 호출) 바로 꺼낸다. 네트워크 왕복이 0이라 지연이 거의 없고, 노트북·CLI 도구·엣지 기기 어디서든 코드가 도는 곳이면 함께 돈다.

용어
벡터 데이터베이스 (Vector Database)
글·이미지·소리를 AI가 숫자 배열(=벡터, 임베딩)로 바꾼 뒤, "이 벡터와 가장 비슷한 벡터들"을 찾아 주는 DB. "강아지" 사진과 비슷한 사진, 내 질문과 의미가 가까운 문서를 찾는 식이다. RAG·추천·이미지 검색의 심장이다.
용어
인프로세스 / 임베디드 (In-process / Embedded)
DB가 별도 서버 프로세스가 아니라 내 프로그램과 '같은 프로세스 안에서' 라이브러리로 도는 방식. SQLite·DuckDB가 대표 예. 서버 설치·네트워크·인증이 사라져 설정이 0에 가깝고, 함수 호출처럼 빠르다.
용어
유사도 검색 / ANN (Similarity Search / Approximate Nearest Neighbor)
수억 개 벡터 중 질의 벡터와 '가장 가까운 k개'(Top-k)를 찾는 작업. 전부 일일이 비교하면 느리므로, 살짝 부정확해도 훨씬 빠른 근사(Approximate) 방식(HNSW·IVF 등)을 쓴다. zvec의 핵심 기능.

한 가지 짚을 것 — zvec은 알리바바 그룹 내부에서 이미 실전(production)에 쓰이며 검증된(battle-tested) 엔진을 오픈소스로 푼 것이다. Python뿐 아니라 Node.js·Go·Rust·Dart/Flutter SDK까지 제공하고, 리눅스·macOS·Windows를 모두 지원한다. 즉 "가볍지만 장난감은 아닌" 프로덕션급 임베디드 벡터 엔진이라는 점이 핵심이다.

2왜 주목받는가

TrendShift 일간 4위 — 별 1만 개를 향해 달리는 이유.

2024~2026년은 "모든 앱이 AI 검색을 품는" 시대다. 챗봇은 RAG로 문서를 찾고, 추천은 임베딩으로 비슷한 걸 고르고, 에이전트는 '기억(memory)'을 벡터로 저장한다. 그런데 이걸 하려고 매번 Milvus 서버를 띄우고 도커를 관리하는 건 과하다. zvec은 "서버 없이, 라이브러리로, 그러나 프로덕션급 속도로"라는 빈자리를 정확히 노린다. 이유를 다섯으로 정리한다.

① 설정 0 — pip install 하고 바로 검색

가장 큰 매력. 도커·서버·스키마 마이그레이션·네트워크 인증이 전부 없다. pip install zvecimport zveccreate_and_open()insert()query(). 5줄이면 끝난다. 데이터는 로컬 폴더 하나(./zvec_example)에 담기고, 그 폴더를 통째로 복사하면 그게 곧 백업이다.

② C++ 코어 — "수십억 벡터를 밀리초에"

마케팅 구호가 아니라 설계가 받쳐 준다. 코어의 79%가 C++이고, x86의 AVX2/AVX-512 SIMD 명령어, RaBitQ 양자화, mmap 기반 저장까지 동원해 거리 계산을 극한으로 최적화했다. Python은 얇은 바인딩일 뿐, 실제 무거운 연산은 전부 네이티브 코드가 처리한다.

③ 인덱스 백화점 — FLAT부터 DiskANN까지

경쟁작이 한두 개 인덱스만 주는 데 비해, zvec은 FLAT(완전탐색)·HNSW·HNSW+RaBitQ·IVF·DiskANN·Vamana를 모두 제공한다. 데이터가 작으면 메모리 인덱스(HNSW), 메모리에 다 안 들어가면 디스크에 인덱스를 두는 DiskANN으로 — 규모에 맞춰 갈아 끼운다. 메모리 한 줌으로 수억 벡터를 다루는 길이 열려 있다.

④ 벡터만? 아니다 — FTS·하이브리드·필터까지

v0.5.0에서 전문 검색(Full-Text Search)이 네이티브로 들어왔다. 외부 검색엔진(Elasticsearch) 없이 문자열 필드에 키워드 검색을 건다. 게다가 한 번의 MultiQuery밀집 벡터 + 희소 벡터 + 스칼라 필터 + 키워드를 동시에 섞는 하이브리드 검색이 가능하다. "의미는 비슷하면서, 가격은 1만 원 이하, '방수' 단어 포함"을 한 방에 처리한다.

⑤ 영속성과 동시성 — 진짜 'DB'답다

임베디드라고 데이터가 휘발되지 않는다. WAL(Write-Ahead Logging) 덕에 프로세스가 죽거나 정전이 나도 데이터를 잃지 않는다. 또 여러 프로세스가 같은 컬렉션을 동시에 읽을 수 있다(쓰기는 한 프로세스 전용). 캐시가 아니라 '내구성 있는 DB'로 설계됐다.

접근법형태한계 / 강점
Milvus · Qdrant · Weaviate독립 서버(도커/클러스터)대규모·분산에 강하지만, 서버 구축·운영 부담이 크다.
FAISS인프로세스 라이브러리빠르지만 '인덱스 라이브러리'에 가까움 — 영속성·필터·메타데이터·FTS는 직접 짜야 함.
Chroma · sqlite-vec임베디드/경량쉽지만 인덱스 종류·초대규모 성능·SIMD 최적화 면에서 한계.
zvec인프로세스 + 풀 DB 기능서버 0 + C++ 속도 + 다양한 인덱스 + WAL + FTS + 하이브리드를 한 패키지에.
강점
"FAISS의 속도 + SQLite의 편의 + 진짜 DB 기능"의 교집합

FAISS는 빠르지만 메타데이터·필터·영속성을 직접 구현해야 하고, Chroma는 쉽지만 초대규모에서 약하다. zvec은 "FAISS급 C++ 속도를 SQLite처럼 쉽게, 그러면서 WAL·FTS·하이브리드 같은 DB 기능까지" 한 번에 주는 지점을 노린다. RAG·에이전트 메모리를 가볍게 시작했다가 수억 벡터까지 키울 수 있는 게 진짜 가치다.

냉정하게 보기
만능은 아니다 — 인프로세스의 구조적 한계

임베디드 설계는 쓰기가 '단일 프로세스 전용(single-writer)'이다. 여러 서버가 동시에 같은 데이터에 쓰는 분산 쓰기 워크로드라면 zvec 단독으론 맞지 않는다(이땐 Milvus 같은 서버형이 정답). 또 검색이 내 앱과 같은 프로세스에서 도므로 무거운 검색이 앱의 CPU·메모리를 함께 먹는다. 초대규모를 여러 노드로 수평 확장하는 시나리오도 서버형 DB의 영역이다. zvec은 '한 노드에 박아 쓰는 강력한 엔진'이지, '분산 클러스터'가 아니다.

3기술 스택 전체 지도

CMakeLists.txt · pyproject.toml · .gitmodules · 소스 트리에서 직접 확인한 실제 구성.

zvec의 정체는 "C++ 코어 + 다국어 얇은 바인딩"이다. GitHub 언어 통계가 이를 명확히 보여준다 — C++ 79.3% · Python 7.9% · SWIG 7.7% · C 3.6%. 즉 엔진의 실체는 C++이고, Python·Node·Go 등은 그 위에 씌운 껍데기다. 빌드는 CMake로 묶고, 18개나 되는 서드파티 라이브러리를 git submodule로 끌어온다.

ⓐ 코어 엔진 (C++17)

구성요소무엇역할
C++17코어 언어CMakeLists.txtCC_CXX_STANDARD 17. 모든 인덱싱·검색·저장 로직.
CMake (≥3.13)빌드 시스템리눅스/macOS/Windows(MSVC)/iOS/Android까지 크로스 컴파일.
SIMD (AVX2 / AVX-512)벡터 가속거리 계산을 한 번에 8~16개씩. setup_compiler_march로 CPU 자동 감지.
ailego자체 기반 라이브러리src/ailego/ — 수학·해시·버퍼·병렬·IO 등 코어가 의존하는 토대.

ⓑ 인덱스 알고리즘 (src/core/algorithm)

인덱스특징언제
FLAT완전탐색(brute force)데이터 적을 때. 100% 정확, 인덱스 학습 불필요.
HNSW그래프 기반 메모리 인덱스가장 일반적. 빠르고 정확. 메모리에 다 올릴 때.
HNSW + RaBitQHNSW + 양자화 압축메모리를 더 아끼고 싶을 때(RaBitQ 비트 압축).
IVF클러스터(역색인) 기반대용량에서 후보를 좁혀 탐색.
DiskANN / Vamana디스크 상주 그래프 인덱스메모리에 안 들어가는 초대규모. 인덱스를 디스크에 둠.

ⓒ 저장 · 영속성 (src/db/index/storage)

구성요소역할
WAL (Write-Ahead Log)쓰기를 먼저 로그에 기록 → 크래시·정전에도 데이터 보존.
mmap forward store벡터 원본을 메모리 맵으로 — OS 페이지 캐시를 활용해 빠른 읽기.
Apache Arrow / Parquet컬럼형 저장 포맷(IPC·Parquet writer)으로 메타데이터·필드 저장.
RocksDB키-값 저장 엔진(서드파티) — 내부 메타/인덱스 저장에 활용.
LZ4고속 압축으로 디스크 사용량 절감.

ⓓ 질의 엔진 & FTS (src/db/sqlengine)

구성요소역할
ANTLR4 SQL 엔진sqlengine/ — 스칼라 필터를 SQL 비슷한 표현식으로 파싱(parser→analyzer→planner).
cppjieba중국어/혼합 텍스트 토크나이저 — FTS(전문 검색)의 단어 분리.
FastPFOR역색인 정수 압축(전문 검색 posting list 압축).
reranker여러 검색 결과를 융합·재정렬(하이브리드 검색의 RRF 등).

ⓔ 바인딩 — 한 코어, 여러 언어

언어설치비고
Python 3.10~3.14pip install zvecpybind11/SWIG 바인딩. _zvec 네이티브 모듈 + 순수 Python 래퍼.
Node.jsnpm install @zvec/zvec공식 npm 패키지.
Go / Rust별도 SDK 저장소v0.5.0에서 공식 Go·Rust 바인딩 추가.
Dart/Flutterflutter pub add zvecFFI 바인딩. Android(arm64)·iOS(arm64) 모바일 지원.
C API소스 빌드src/include/zvec/c_api.h — 다른 언어 바인딩의 토대.
용어
SIMD (AVX2 / AVX-512)
한 번의 CPU 명령으로 여러 숫자를 동시에 계산하는 기술(Single Instruction, Multiple Data). 벡터 거리 계산은 곱셈·덧셈의 반복이라 SIMD로 8~16개씩 묶어 처리하면 몇 배 빨라진다. zvec이 '밀리초 검색'을 내는 비결 중 하나.
용어
양자화 (Quantization) · RaBitQ / SQ8
벡터의 각 숫자를 32비트 실수(float)에서 더 적은 비트(8비트 정수 등)로 압축해 메모리·디스크를 아끼는 기술. 약간의 정확도를 내주고 큰 용량 절감을 얻는다. zvec은 FP16·INT8(SQ8)·RaBitQ 등 여러 양자화를 지원한다.
용어
git submodule (서브모듈)
한 git 저장소 안에 다른 git 저장소를 '링크'로 끼워 넣는 기능. zvec은 RocksDB·Arrow·protobuf·gflags·ANTLR·cppjieba 등 18개를 .gitmodules로 끌어와 함께 빌드한다. "거인의 어깨"를 코드 레벨에서 빌려 쓰는 셈.

4아키텍처 심화 분석

벡터 하나가 들어가 검색 결과로 나오기까지 — 인프로세스 엔진의 속살.

zvec의 핵심 아이디어는 한 문장이다 — "풀 기능 벡터 DB를, 서버가 아니라 라이브러리 한 덩어리로 패키징한다." 외부에서 보면 Collection 객체 하나에 insert()/query()만 호출하면 되지만, 그 아래에는 스키마·세그먼트·인덱스·저장·질의 엔진이 층층이 쌓여 있다. 먼저 숲(전체 그림)을 보고, 그다음 검색 한 줄기를 따라가 보자.

먼저 전체 그림 한 장

┌────────────── 내 애플리케이션 프로세스 (Python / Node / Go ...) ──────────────┐ │ │ │ import zvec → collection = zvec.create_and_open(path, schema) │ │ │ │ │ ▼ (얇은 바인딩: pybind11 / SWIG / FFI / C API) │ │ ╔══════════════════ libzvec (C++ 코어, 같은 프로세스 안) ═══════════════╗ │ │ ║ ║ │ │ ║ [Collection] ── 스키마·필드·인덱스 정의를 묶는 최상위 핸들 ║ │ │ ║ │ ║ │ │ ║ ▼ ║ │ │ ║ [Segment Manager] 데이터를 '세그먼트' 단위로 쪼개 관리(LSM처럼) ║ │ │ ║ ├── Vector Index FLAT / HNSW / IVF / DiskANN / Vamana ║ │ │ ║ ├── Invert Index 스칼라 필터 · FTS(cppjieba 토큰) ║ │ │ ║ └── Forward Store 벡터 원본 · 메타데이터 (mmap / Arrow) ║ │ │ ║ │ ║ │ │ ║ [SQL Engine (ANTLR)] 필터 표현식 파싱 → 실행 계획 ║ │ │ ║ [Reranker] 벡터+FTS+필터 결과 융합·재정렬(하이브리드) ║ │ │ ║ [WAL] 모든 쓰기를 먼저 로그에 → 크래시 복구 ║ │ │ ╚══════════════════════════════════╤═══════════════════════════════════════╝ │ └──────────────────────────────────────┼─────────────────────────────────────────┘ ▼ 로컬 디스크 폴더 (./my_db/) ← 이게 곧 '데이터베이스 파일' WAL 로그 · 세그먼트 파일 · 인덱스 · Arrow/Parquet

흐름 한 줄기 따라가기 — collection.query(VectorQuery(...), topk=10)

실제 코드 호출 하나가 내부에서 어떤 순서로 도는지, 핵심 5%(해피패스)만 따라간다.

① 바인딩 경유 — Python에서 C++로. collection.query(...)는 순수 Python 래퍼를 거쳐 네이티브 _zvec 모듈로 내려간다. 이때 네트워크 직렬화·소켓 왕복이 전혀 없다 — 같은 프로세스 메모리를 그대로 넘긴다. 이게 인프로세스의 속도 비밀이다.

② 필터 파싱 (있다면). "price < 10000 AND tag = 'waterproof'" 같은 스칼라 필터가 붙어 있으면, ANTLR SQL 엔진이 이를 파싱해 실행 계획으로 바꾼다. 역색인(invert index)으로 조건에 맞는 후보 ID를 먼저 좁힌다.

③ 세그먼트별 벡터 검색. 데이터는 여러 세그먼트로 나뉘어 있다. 각 세그먼트의 벡터 인덱스(예: HNSW 그래프)를 타고 질의 벡터와 가까운 Top-k 후보를 모은다. 거리 계산은 SIMD로 가속된다.

# C++ 코어가 내부에서 하는 일 (개념 요약)
filter_ids = sql_engine.eval(filter_expr)        # 필터로 후보 좁히기
for seg in segments:                              # 세그먼트마다
    cand = seg.vector_index.search(q, topk, filter_ids)  # HNSW/IVF 탐색
    heap.merge(cand)                              # 부분결과 합치기
results = reranker.fuse(heap)                     # (하이브리드면) 융합·재정렬
return results.topk(10)                           # 최종 Top-10

④ 결과 병합 & 재정렬. 세그먼트별 부분 결과를 하나의 힙(heap)으로 합친다. 하이브리드 검색(벡터+FTS)이라면 reranker가 서로 다른 점수 체계를 RRF 같은 방식으로 융합해 최종 순위를 매긴다.

⑤ 결과 반환 — 다시 Python으로. 최종 Top-k가 {'id', 'score', ...} 리스트로 바인딩을 거쳐 돌아온다. 점수 순으로 정렬돼 있고, 필요하면 원본 벡터·메타데이터까지 함께 실어 준다.

핵심 설계 패턴 ① — 인프로세스 + 단일 라이터(single-writer)

가장 중요한 결정. zvec은 서버를 두지 않는다. 대신 데이터 폴더를 파일 락으로 보호해, 한 프로세스만 쓰고(write) 여러 프로세스가 동시에 읽도록(read) 한다. src/db/collection.ccfile_lock.h·shared_mutex를 쓰는 게 그 증거다. SQLite의 동시성 모델과 같은 철학 — 단순함과 속도를 위해 분산 쓰기를 포기한 트레이드오프다.

핵심 설계 패턴 ② — 세그먼트 + 다중 인덱스 분리

데이터를 세그먼트로 쪼개 관리한다(LSM 트리와 유사). 새 데이터는 새 세그먼트로 쌓이고, 검색은 여러 세그먼트를 병렬로 훑어 합친다. 또 벡터 인덱스 / 역색인(필터·FTS) / 포워드 스토어(원본)를 명확히 분리해, 같은 데이터에 의미 검색·키워드 검색·필터를 각각 최적 자료구조로 건다. 이 분리가 하이브리드 검색을 가능케 한다.

핵심 설계 패턴 ③ — 플러그형 인덱스 (IndexFactory)

인덱스 알고리즘을 IndexParams로 추상화하고 IndexFactory::CreateAndInitIndex()로 찍어낸다(examples/c++ 참고). 덕분에 같은 데이터에 FLAT→HNSW→DiskANN을 코드 거의 그대로 갈아 끼운다. DiskANN은 별도 플러그인(.so)으로 분리돼, 처음 쓸 때 동적 로드(load_diskann_plugin)되고 libaio가 없으면 친절히 에러를 낸다.

용어
HNSW (Hierarchical Navigable Small World)
벡터들을 '여러 층의 친구 그래프'로 엮어, 비슷한 벡터로 빠르게 점프하며 찾아가는 인덱스. 가장 널리 쓰이는 ANN 알고리즘. m(이웃 수)·ef(탐색 폭)로 속도와 정확도를 조절한다. 메모리에 그래프를 올려 두므로 빠르다.
용어
DiskANN (Disk-based ANN)
인덱스 그래프 대부분을 디스크(SSD)에 두고 일부만 메모리에 캐시하는 방식. 메모리에 다 못 올리는 초대규모(수억~수십억) 벡터를 적은 RAM으로 검색하게 해 준다. SSD 무작위 읽기를 빠르게 하려고 libaio(비동기 IO)를 쓴다.
용어
WAL (Write-Ahead Logging)
데이터를 실제 자료구조에 반영하기 '전에' 변경 내용을 로그 파일에 먼저 적는 기법. 도중에 프로세스가 죽어도, 재시작 때 로그를 다시 재생(replay)해 데이터를 복구한다. DB가 '내구성(durability)'을 보장하는 표준 방법.

5디렉토리 구조 해부

저장소를 열었을 때 어디부터 봐야 하는가 — 3층 구조(코어 / DB / 바인딩).

처음 저장소를 열면 디렉토리가 많아 막막하다. 핵심만 잡으면 된다 — src/core/는 '인덱스 알고리즘', src/db/는 '데이터베이스 기능', src/binding/·python/은 '언어 껍데기'다. 공부는 examples/src/db/collection.ccsrc/core/algorithm/ 순서가 좋다.

zvec/ ├── src/ ← ★ C++ 코어 (전체의 79%) │ ├── include/zvec/ 공개 헤더 — 여기가 'API 설계도' │ │ ├── c_api.h C API (다른 언어 바인딩의 토대) │ │ ├── db/ collection.h · schema.h · query.h · index_params.h │ │ └── core/ 인덱스·메트릭 인터페이스 │ │ │ ├── core/ ← 벡터 인덱싱 엔진 (DB와 무관한 순수 알고리즘) │ │ ├── algorithm/ ★ flat · hnsw · hnsw_rabitq · ivf · diskann · vamana │ │ ├── quantizer/ 양자화: int8 · half_float · binary · cosine · mips │ │ ├── metric/ 거리 함수 L2 · IP · Cosine · MIPS │ │ └── framework/ 인덱스 팩토리·플러그인 골격 │ │ │ ├── db/ ← ★ '데이터베이스' 계층 (인덱스를 DB로 포장) │ │ ├── collection.cc ★ 최상위 핸들 — insert/query/open 진입점 │ │ ├── index/segment/ 세그먼트 관리(LSM식 데이터 분할) │ │ ├── index/storage/ mmap·Arrow·Parquet·WAL 저장 계층 │ │ ├── sqlengine/ ANTLR 기반 필터 SQL 파서·플래너 │ │ └── reranker/ 하이브리드 결과 융합(RRF 등) │ │ │ ├── ailego/ 자체 기반 라이브러리(수학·해시·IO·병렬) │ ├── binding/{c,python}/ C / Python 바인딩 구현 │ └── turbo/ AVX512-VNNI 등 초가속 커널 │ ├── python/zvec/ ← ★ pip 패키지 본체(순수 Python 래퍼) │ ├── zvec.py create_and_open · open · init 공개 함수 │ ├── model/ Collection · Doc · param · schema 파이썬 모델 │ ├── extension/ ★ 임베딩·리랭커: OpenAI · Qwen · SentenceTransformer · BM25 │ └── executor/ query_executor (질의 조립) │ ├── examples/{c,c++}/ ← ★ 가장 빠른 입문: basic_example · index_example ├── tests/{core,db,c,ailego}/ 단위 테스트 ├── thirdparty/ 18개 서드파티(RocksDB·Arrow·ANTLR·cppjieba·RaBitQ ...) ├── CMakeLists.txt 빌드 정의(옵션·SIMD 감지) └── pyproject.toml scikit-build-core로 C++ 빌드를 pip에 연결
위치역할
src/include/zvec/db/API의 '설계도'. collection.h·schema.h·query.h만 읽어도 전체 그림이 잡힌다.
src/db/collection.cc모든 길이 통하는 심장. insert·query·open·세그먼트 오케스트레이션.
src/core/algorithm/인덱스 알고리즘의 실제 구현. HNSW·DiskANN 내부가 궁금하면 여기.
python/zvec/extension/임베딩 함수(OpenAI·Qwen·ST)·리랭커. "텍스트→벡터"를 자동화하는 편의층.
examples/코드로 손에 익히는 가장 빠른 길. C/C++ 기본 예제부터.

6학습 포인트 (기술별)

이 레포에서 실제로 무엇을 배울 수 있는가 — 기술별 + 실습 아이디어.

학습 포인트 ①

"인프로세스 DB" 설계 — SQLite의 철학을 벡터로

서버 없이 라이브러리로 도는 DB는 어떻게 동시성·영속성을 보장할까? src/db/collection.cc파일 락 + shared_mutex + WAL 조합을 읽으면, "단일 라이터·다중 리더" 모델이 어떻게 구현되는지 몸으로 이해된다. SQLite·DuckDB를 이해하는 발판이기도 하다.

실습 아이디어: 두 개의 파이썬 프로세스로 같은 컬렉션을 동시에 open해 읽기는 되는지, 두 곳에서 쓰기를 시도하면 어떻게 막히는지 확인해 본다.

학습 포인트 ②

ANN 인덱스 알고리즘 비교 — FLAT vs HNSW vs DiskANN

src/core/algorithm/에 여섯 가지 인덱스가 나란히 있어, 알고리즘 비교 학습의 보고다. 그래프 기반(HNSW)·클러스터 기반(IVF)·디스크 기반(DiskANN)이 어떤 자료구조로 "근사 최근접"을 구현하는지 코드로 대조할 수 있다.

실습 아이디어: 같은 데이터에 FLAT·HNSW·IVF 인덱스를 각각 걸어, 재현율(recall)과 검색 속도(QPS)가 어떻게 트레이드오프되는지 측정해 본다.

학습 포인트 ③

네이티브 코어 + 다국어 바인딩 패턴

C++ 코어 하나를 Python(pybind11/SWIG)·Node·Go·Dart로 노출하는 구조는 고성능 라이브러리의 표준 배포 전략이다. c_api.h(안정적 C ABI)를 토대로 각 언어 래퍼를 올리는 방식을 배우면, 내 C++ 코드를 다른 언어에 파는 법을 알게 된다.

실습 아이디어: c_api.h의 함수 목록과 python/zvec/model/의 파이썬 클래스를 짝지어, "C 함수 ↔ 파이썬 메서드" 대응표를 직접 그려 본다.

학습 포인트 ④

SIMD·양자화로 보는 '극한 최적화'

src/core/quantizer/(int8·half_float·binary)와 src/turbo/avx512_vnni/"벡터 거리 계산을 어디까지 빠르게 만들 수 있나"의 교본이다. RaBitQ 비트 압축, AVX-512 커널을 보며 메모리-속도-정확도 삼각 트레이드오프를 배운다.

실습 아이디어: 같은 벡터를 FP32 vs INT8(SQ8) 양자화로 저장해, 메모리 사용량과 검색 정확도가 어떻게 달라지는지 비교한다.

학습 포인트 ⑤

하이브리드 검색 — 벡터 + 키워드 + 필터의 융합

"의미 검색"만으론 부족할 때가 많다. zvec의 MultiQuery + reranker + ANTLR SQL 필터를 보면, 밀집·희소 벡터·전문 검색·스칼라 필터를 한 질의로 섞고 RRF로 재정렬하는 현대 검색 파이프라인을 통째로 익힌다. RAG 품질을 올리는 실전 기술이다.

실습 아이디어: 같은 질문을 (1) 벡터만, (2) 키워드(FTS)만, (3) 둘을 하이브리드로 검색해 결과 차이를 눈으로 비교해 본다.

7하드웨어/시스템 요구사항

내 컴퓨터로 돌릴 수 있나? — 인프로세스라 의외로 가볍다.

좋은 소식 — zvec은 GPU가 전혀 필요 없다. 벡터 '검색' 엔진이지 '학습' 엔진이 아니므로, CPU만으로 돈다(임베딩을 만드는 단계는 별개). 별도 서버·도커도 없어, 노트북 한 대면 시작한다. 실제 요구사항은 데이터 규모와 고른 인덱스에 좌우된다.

항목요구사항 / 권장
OSLinux(x86_64·ARM64) · macOS(ARM64) · Windows(x86_64). 모바일은 Android·iOS(Dart SDK).
Python3.10 ~ 3.14 (pip install zvec). Node.js·Go·Rust·Dart도 가능.
CPUAVX2 지원 x86이면 SIMD 가속 최대. ARM64·RISC-V도 지원(없어도 동작, 느릴 뿐).
GPU불필요. 검색은 전부 CPU.
디스크데이터 폴더 하나. DiskANN 쓰면 SSD 권장(무작위 읽기 성능).

메모리는 '어떤 인덱스를 고르느냐'가 전부다. 대략의 그림:

인덱스메모리 특성적정 규모(대략)
FLAT벡터 원본 전체를 메모리에~수만 벡터(정확도 100% 필요할 때)
HNSW그래프+벡터를 메모리에(가장 메모리 큼)~수백만~수천만(RAM 여유 시)
HNSW+RaBitQ / INT8양자화로 메모리 대폭 절감수천만~억대(메모리 빠듯할 때)
DiskANN대부분 디스크, 일부만 메모리억~수십억(RAM 한 줌으로)

실행 전 알아둘 것 — zvec은 cgroup의 CPU·메모리 한도를 자동 감지해 기본값을 잡는다(컨테이너 친화적). zvec.init(memory_limit_mb=..., query_threads=...)로 직접 조절도 가능하다. FTS를 쓰면 jieba 사전(data/jieba_dict)이 휠에 동봉돼 별도 설치가 필요 없다.

실무 팁
"작게 시작해 인덱스만 갈아 끼워 키운다"

프로토타입은 FLAT이나 HNSW로 단순하게 시작하라(설정 신경 0). 데이터가 수백만을 넘어 메모리가 빠듯해지면 코드 거의 그대로 INT8 양자화나 DiskANN으로 인덱스만 교체하면 된다. "서버 이전 없이 같은 라이브러리 안에서 스케일업"이 zvec의 가장 큰 실무 이점이다.

8직접 해볼 수 있는 실습 과제

난이도별로 — 손으로 돌려봐야 진짜 내 것이 된다.

먼저 '복사만 하면 OK'인 기본 호출부터. 아래가 zvec 사용의 전부다 — 서버도 도커도 없다.

import zvec

# ① 스키마 정의: 'embedding'이라는 4차원 FP32 벡터 필드
schema = zvec.CollectionSchema(
    name="example",
    vectors=zvec.VectorSchema("embedding", zvec.DataType.VECTOR_FP32, 4),
)
# ② 컬렉션 생성 + 열기(로컬 폴더 하나가 곧 DB)
collection = zvec.create_and_open(path="./zvec_example", schema=schema)
# ③ 문서(벡터) 삽입
collection.insert([
    zvec.Doc(id="doc_1", vectors={"embedding": [0.1, 0.2, 0.3, 0.4]}),
    zvec.Doc(id="doc_2", vectors={"embedding": [0.2, 0.3, 0.4, 0.1]}),
])
# ④ 유사도 검색 — 질의 벡터와 가까운 Top-k
results = collection.query(zvec.VectorQuery("embedding", vector=[0.4, 0.3, 0.3, 0.1]), topk=10)
print(results)   # [{'id': 'doc_2', 'score': ...}, ...]  점수순 정렬
실습 1

1분 예제 그대로 돌려보기난이도 ★☆☆ 입문

pip install zvec 후 위 코드를 그대로 실행해 본다. 그다음 ./zvec_example 폴더를 열어 어떤 파일들이 생겼는지(WAL·세그먼트·인덱스) 직접 살펴본다. "DB가 폴더 하나"라는 감을 잡는다.

실습 2

진짜 텍스트로 RAG 미니 검색난이도 ★☆☆ 입문

zvec.extension의 임베딩 함수(예: SentenceTransformer 또는 OpenAI/Qwen)로 문장 5~10개를 벡터로 바꿔 넣고, 자연어 질문으로 가장 비슷한 문장을 찾아 본다. "텍스트→벡터→검색"의 RAG 핵심 루프를 손에 익힌다.

실습 3

인덱스 바꿔가며 속도·정확도 비교난이도 ★★☆ 중급

1만~10만 개의 랜덤 벡터를 만들어, 같은 데이터에 FlatIndexParam vs HnswIndexParam(m·ef 조절)을 각각 걸고 검색 시간과 재현율(FLAT을 정답으로)을 측정한다. ANN의 핵심 트레이드오프를 숫자로 본다.

실습 4

하이브리드 검색 — 벡터 + 필터 + FTS난이도 ★★☆ 중급

제품 데이터에 벡터(이미지/설명) + 스칼라 필드(가격·카테고리) + 문자열(이름)을 넣고, "가격 < 10000" 필터 + 키워드 FTS + 벡터 유사도를 MultiQuery로 한 번에 검색한다. 셋을 섞은 결과가 벡터 단독보다 얼마나 정밀해지는지 본다.

실습 5

대용량 + DiskANN으로 메모리 절약난이도 ★★★ 고급

100만~500만 벡터를 만들어 HNSW(메모리) vs DiskANN(디스크) 인덱스의 RAM 사용량을 측정·비교한다. DiskANN 플러그인 로드(load_diskann_plugin)와 libaio 요구사항도 직접 확인한다. "메모리 한 줌으로 초대규모"를 체감한다.

9관련 기술 심화 학습 로드맵

zvec을 발판으로 벡터 검색+임베디드 DB를 제대로 — 6주 계획.

주차주제학습 자료 / 할 일
1주차임베딩 & 벡터 검색 기초임베딩이란 무엇인가, 코사인/L2/내적 거리의 차이. zvec 1분 예제로 첫 검색.
2주차ANN 알고리즘HNSW·IVF·PQ 논문 개념. src/core/algorithm/hnsw/를 읽으며 그래프 탐색 이해.
3주차인프로세스 DB 설계SQLite·DuckDB 구조와 비교. collection.cc의 락·WAL·세그먼트 읽기.
4주차저장·영속성 계층WAL·mmap·Apache Arrow/Parquet·LZ4. "디스크에 어떻게 안전하게 쓰나".
5주차하이브리드 검색 & RAG밀집/희소 벡터·BM25·RRF 재정렬. MultiQuery·reranker로 실전 파이프라인.
6주차최적화 & 양자화SIMD(AVX2/512)·INT8/RaBitQ 양자화·DiskANN. 메모리-속도-정확도 튜닝 실험.

10핵심 키워드 사전

문서·코드에 자주 나오는 용어 — 한 줄 정의.

용어의미
In-process / Embedded별도 서버가 아니라 내 앱과 같은 프로세스에서 라이브러리로 도는 DB(SQLite식).
Vector / Embedding글·이미지를 AI가 바꾼 숫자 배열. 의미가 비슷하면 벡터도 가깝다.
Dense / Sparse Vector밀집=모든 차원에 값(일반 임베딩), 희소=대부분 0(BM25식 키워드 벡터).
ANN / Top-k근사 최근접 이웃 탐색. 질의와 가장 가까운 k개를 빠르게 찾기.
HNSW층층 친구 그래프로 빠르게 탐색하는 메모리 ANN 인덱스(가장 일반적).
IVF벡터를 클러스터로 나눠 후보를 좁히는 인덱스.
DiskANN / Vamana인덱스를 디스크에 두는 그래프 인덱스. 적은 RAM으로 초대규모 검색.
FLAT전수 비교(brute force). 100% 정확, 작은 데이터용.
Quantization (RaBitQ/SQ8)벡터를 적은 비트로 압축해 메모리 절감. 정확도 ↔ 용량 트레이드오프.
Metric (L2/IP/Cosine)벡터 거리 측정법. L2=유클리드, IP=내적, Cosine=코사인 유사도.
WAL쓰기를 먼저 로그에 → 크래시·정전에도 복구(내구성 보장).
Segment데이터를 쪼개 담는 단위(LSM식). 검색은 여러 세그먼트를 병렬로 합침.
FTS (Full-Text Search)문자열 필드 키워드 검색. zvec은 cppjieba 토크나이저로 내장.
Hybrid Search / MultiQuery벡터+희소+필터+키워드를 한 질의로 섞고 RRF로 재정렬.
SIMD (AVX2/512)한 명령으로 여러 숫자 동시 계산. 거리 계산 가속의 핵심.
Collection / DocCollection=DB의 테이블 격, Doc=한 건의 벡터+메타데이터 레코드.

11참고 링크

원문으로 더 깊이 — 공식 소스 위주.