
turbovec이 임베딩을 작게 만들었다면, turbo-graph는 제약 많은 검색을 운영 가능하게 만듭니다.
RAG 쿼리가 더 이상 top_k 하나가 아니라:
tenant ∩ graph ∩ tag ∩ source ∩ time ∩ BM25 candidates ∩ vector search
라면, 이 view를 요청마다 Python에서 다시 만들 필요가 없습니다.
turbo-graph는 turbovec/TurboQuant 코어를 유지하면서 다음을 더합니다.
SlotMask compilationGraphMemoryIndexturbovec를 쓰면 좋은 경우:
turbo-graph를 쓰면 좋은 경우:
목차: 언제 써야 하나요? · turbovec과의 관계 · 상세 비교 · 벤치마크 · 설치 · 빠른 시작 · 문서
이 저장소는 turbovec 코드베이스의 포크입니다. TurboQuant 인코딩·검색, .tv / .tvim, Python 코어 API는 upstream과 같은 계열입니다.
주황 블록 = 그래프 레이어(이 포크). 공유 코어 = turbovec TurboQuant 계열.
기능 비교 표 전체 보기
| 기능 | turbovec | turbo-graph |
|---|---|---|
| TurboQuant encode / search | ✅ | ✅ 동일 코어 |
TurboQuantIndex / IdMapIndex |
✅ | ✅ 호환 API |
커널 allowlist / mask |
✅ v0.3~ | ✅ + SlotMask 캐시 |
| 그래프 이웃 확장 | — | ✅ |
| tag / source / time | SQL 직접 | ✅ 인덱스 + 캐시 |
| rerank + BM25 hybrid | — | ✅ |
| explain / telemetry | 일부 | ✅ |
Python GraphMemoryIndex |
— | ✅ 핵심 운영 API |
| 프레임워크 통합 | ✅ | ✅ |
upstream turbovec은 “벡터 검색 후 Python에서 필터” 같은 단순 구조가 아닙니다.
IdMapIndex.search(..., allowlist=ids): id 제한을 SIMD 커널 안에서 적용합니다. 빈 32-vector block은 LUT 전에 건너뜁니다 (#30).TurboQuantIndex.search(..., mask=...): slot 마스크도 같은 방식입니다.(nq, min(k, n_allowed))입니다. tight filter에서 recall을 살리려고 padding이나 global over-fetch에 기대지 않습니다.turbo-graph는 커널 필터를 대체하지 않습니다. turbovec이 앱에 남기던 그래프·메타데이터 조합·캐시·rerank를 crate 안으로 옮깁니다.
주황 = turbovec에서 앱이 맡는 조립. turbo-graph 경로는 제약 뷰를 한 번 컴파일해 재사용합니다.
요약: allowlist를 싸게 만들 수 있으면 turbovec. graph ∩ tag ∩ source ∩ time ∩ candidates 재조립이 병목이고 cache hit/trace/rerank 제어가 필요하면 turbo-graph.
아래 3개 이상 yes:
allowlist=는 충분한데 allowlist 구성이 병목이다.3개 미만이면 turbovec을 유지하고, 필터가 무거운 경로부터 turbo-graph로 옮기면 됩니다.
from turbovec import IdMapIndex # upstream
from turbo_graph import IdMapIndex # 이 repo — 코어 API 동일
전체 표·PR 체크리스트: docs/benchmark_turbo_graph_vs_turbo_vec.md
수치 출처는 benchmarks/results/*.json입니다. 차트는 python3 benchmarks/create_diagrams.py로 다시 만들 수 있습니다.
공통 설정 (코어): DB 100K, query 1K, k=64, seed 42, L2 정규화.
GloVe 2-bit만 FAISS가 0.06pp 앞섭니다. 나머지는 TurboQuant가 앞서거나 k≈16부터 수렴합니다. 원본: benchmarks/results/recall_*.json.
ARM은 8개 설정 모두 우위입니다. x86 2-bit MT만 열세입니다.
16개 speed 수치 전체 (ms/query)
| Dim | Bit | Arch | Thr | TQ | FAISS | Gain |
|---|---|---|---|---|---|---|
| 1536 | 2 | ARM | ST | 1.083 | 1.235 | +12.3% |
| 1536 | 2 | ARM | MT | 0.103 | 0.115 | +10.4% |
| 1536 | 2 | x86 | ST | 1.271 | 1.172 | −8.4% |
| 1536 | 2 | x86 | MT | 0.304 | 0.295 | −3.1% |
| 1536 | 4 | ARM | ST | 1.992 | 2.450 | +18.7% |
| 1536 | 4 | ARM | MT | 0.185 | 0.220 | +15.9% |
| 1536 | 4 | x86 | ST | 2.439 | 2.560 | +4.7% |
| 1536 | 4 | x86 | MT | 0.576 | 0.590 | +2.4% |
| 3072 | 2 | ARM | ST | 2.124 | 2.439 | +12.9% |
| 3072 | 2 | ARM | MT | 0.201 | 0.224 | +10.3% |
| 3072 | 2 | x86 | ST | 2.657 | 2.582 | −2.9% |
| 3072 | 2 | x86 | MT | 0.626 | 0.590 | −6.1% |
| 3072 | 4 | ARM | ST | 3.968 | 4.925 | +19.4% |
| 3072 | 4 | ARM | MT | 0.375 | 0.448 | +16.3% |
| 3072 | 4 | x86 | ST | 5.342 | 5.474 | +2.4% |
| 3072 | 4 | x86 | MT | 1.177 | 1.177 | 0.0% |
1536d × 1000만 × 2-bit ≈ 4 GB (float32 ~31 GB).
선택도가 낮으면 kernel SlotMask만으로도 빠릅니다. turbo-graph의 핵심 이득은 graph ∩ metadata ∩ candidates 컴파일과 재사용입니다.
공통 한계: brute-force O(n)입니다(HNSW/IVF 아님). 2-4bit 근사 검색이고, TQ+는 첫 add에 1000개 이상 vector가 필요합니다. 0.1.x는 Alpha 공개 라인이므로 production에서는 버전을 고정하세요.
pip install turbo-graph # 또는 turbo-graph-python/에서 maturin build
cargo add turbo-graph
Rust ≥ 1.70, dim % 8 == 0, bit_width ∈ {2, 3, 4}. x86_64는 AVX2 필요.
import numpy as np
from turbo_graph import IdMapIndex
idx = IdMapIndex(dim=1536, bit_width=4)
idx.add_with_ids(vectors.astype(np.float32), ids.astype(np.uint64))
allowed = np.array([1003, 1010, 1042], dtype=np.uint64)
scores, hit_ids = idx.search(query.astype(np.float32), k=10, allowlist=allowed)
import numpy as np
from turbo_graph import GraphMemoryIndex
memory = GraphMemoryIndex(dim=1536, bit_width=4)
memory.add_records(
vectors.astype(np.float32),
[
{
"id": 1001,
"title": "Architecture note",
"tags": ["architecture"],
"source": "docs.example",
"timestamp_ms": 1_700_000_000_000,
},
{
"id": 1002,
"title": "Retrieval cache note",
"tags": ["architecture", "cache"],
"source": "docs.example",
"timestamp_ms": 1_700_000_010_000,
}
],
)
memory.link_bidirectional(1001, 1002, 0.8)
hits = memory.search(
query.astype(np.float32),
k=10,
seeds=[1001],
required_tags=["architecture"],
allowed_sources=["docs.example"],
candidate_ids=[1001, 1002], # 선택: BM25/SQL/ACL에서 온 후보 id.
)
batch_hits = memory.search_batch(
batch_queries.astype(np.float32),
k=10,
seeds=[1001],
required_tags=["architecture"],
candidate_ids=[1001, 1002],
)
report = memory.explain(
query.astype(np.float32),
k=10,
seeds=[1001],
candidate_ids=[1001, 1002, 999],
)
실행 가능한 전체 Python workflow는
turbo-graph-python/examples/graph_memory_rag.py를 참고하세요.
use turbo_graph::{GraphMemoryIndex, GraphSearchPreset, MemoryRecord, TurboQuantIndex};
let mut index = TurboQuantIndex::new(1536, 4)?;
index.add(&vectors);
index.prepare();
let mut memory = GraphMemoryIndex::new(1536, 4)?;
memory.add_records(
&flat_vectors,
vec![MemoryRecord::new(1001, "Architecture note", ["architecture"])
.with_source("docs.example")
.with_timestamp_ms(1_700_000_000_000)],
)?;
let report = memory.explain_graph_search_with_preset(
&query, 10, &[1001], GraphSearchPreset::balanced(),
&["architecture"], &["docs.example"],
Some(1_700_000_000_000), None,
);
Graph API는 Rust가 가장 깊고, Python에서는 add/link/search/explain/cache/persist 중심의 핵심 운영 표면을 제공합니다.
python3 benchmarks/download_data.py all
python3 benchmarks/suite/recall_d1536_2bit.py
python3 benchmarks/suite/speed_d1536_2bit_arm_mt.py
cargo run -p turbo-graph --release --example graph_view_bench -- --iters 3 --csv /tmp/graph-view-bench.csv
cargo run -p turbo-graph --release --example graph_view_bench_summary -- /tmp/graph-view-bench.csv
docs/
├── README.ko.md ............ 문서 목록 (한국어)
├── api.md .................. API 레퍼런스
├── graph_memory_layer.md ... GraphMemory · SlotMask · preset
├── benchmark_turbo_graph_vs_turbo_vec.md
└── integrations/ ........... LangChain · LlamaIndex · Haystack · Agno
→ 문서 목록 · API · Graph layer · vs turbovec
0.1.0 릴리스 노트와 pre-0.1 개발 히스토리.MIT — LICENSE. 코어는 turbovec 계보, 그래프 레이어는 이 포크의 추가 작업.
$ claude mcp add turbo-graph \
-- python -m otcore.mcp_server <graph>