修改于2026-08-23 08:04:43修改于2026-08-23 08:04:431800举报文章被收录于专栏:AI开发相关AI开发相关
这篇把 TriviumDB 0.7.5 的 QuIVer ANN 索引和 hnswlib、FAISS HNSW、USearch、Chroma 放在同一台机器上,用同一批数据、同一批查询、同一套指标,实测 Recall@10 和 QPS 的权衡曲线。所有数字都是本机跑出来的,跑法、参数、环境都在文末,可以照着重跑。结论的边界先划清楚,再给数字。
测试环境
(本文所有跑分在同一台机器上完成,完整清单见 §2.3)
组件配置CPUIntel Core i5-13490F(6 P-core + 4 E-core,共 16 线程,AVX2,无 AVX-512)内存2 × 16 GB DDR5-6000(A-DATA XPG Lancer CL36,双通道)显卡NVIDIA GeForce RTX 4060 Ti 16 GB(CPU-only,未参与计算)存储C 盘:Crucial P3 Plus 1TB(CT1000P3PSSD8,NVMe),另有 SanDisk Ultra 3D NVMe;跑分数据/索引在 C 盘桌面系统Windows 11
ANN 跑分对内存带宽很敏感,DDR5-6000 双通道和 DDR4-3200 的 QPS 能差出百分之几十;SSD 影响构建和冷数据读取。显卡这轮不参与计算,列出来是免得有人以为开了 GPU。
省流速看
TriviumDB 的定位是 AI 嵌入式记忆引擎,服务 RAG、Agent 记忆、语义缓存这类用 LLM embedding 的应用。
所以主战场评测用这类数据的代表:Cohere-1M(768 维)、MiniLM-1M(384 维)、DBpedia-1M(1536 维),外加论文外补的 7 个 LLM embedding 数据集(详见 §3.2)。
同机、同数据、同查询、同指标的前提下(R@10≈90%,MT=16),实测结论:
- Cohere-1M(768 维)是强主场:TriviumDB MT-QPS 约 73,197,是 hnswlib 的 2.9×、FAISS HNSW 的 3.1×、USearch 的 3.6×。和论文声称的 2.5–5.5× 区间吻合。
- MiniLM-1M(384 维)是"可用但不占优":TriviumDB 约 45,697,略低于 hnswlib / FAISS HNSW(约 55k),但快于 USearch(34k)和 Chroma(1.8k)。绝对吞吐复现论文级(42,963 vs 论文 41,106),详见 §7.2。
- DBpedia-1M(1536 维)优势明显:TriviumDB 约 50,068,hnswlib / FAISS / USearch 只有 13–15k,是 HNSW 类的 3.3–3.8×。
- QuIVer 优势随向量维度增大而扩大:10 个 LLM embedding 数据集上,128 维 0.21× → 384 维 0.82× → 768 维 1.4–2.9× → 1024 维 3.4× → 1536 维 3.6–5.0×。BQ 位运算距离几乎不随维度涨,f32 点积成本线性涨,维度越高代差越大。低维小规模(128 维)是 HNSW 的天下,见 §5.3 和 §7.4。
- QuIVer 有明确的适用边界(论文叫"不可能三角":激进压缩 × 高吞吐 × 全数据兼容,三选二)。边界外的数据,比如 SIFT 非负直方图、GloVe 低维词向量,Recall 会明显塌。这条边界用实测数据画在 §7.1。
- Chroma / Zvec 是同生态位的生产级向量数据库,本机公平参数重建后,Chroma 的 Pareto 几乎是一条平线(QPS 0.9k–5.2k),Zvec 约 9.9k QPS(Cohere-1M),瓶颈都在 Python 客户端端到端开销,不是 HNSW 搜索本身,都打不过TDB数据库 见 §7.3。
一句话定位:TriviumDB 的向量检索在高维 LLM embedding(768/1024/1536 维)上是第一梯队,同召回下吞吐约为 HNSW 类的 1.4–5.0×;低维(128/384 维)与 HNSW 同级甚至落后。它的护城河在三位一体、零运维和高维性能,不在所有数据通吃。
一、为什么向量检索值得单独测
"能不能用"和"快不快"是两件事。RAG、Agent 记忆、语义缓存里,向量检索在主链路上:一次问答 LLM 生成要几百毫秒到几秒,召回这一步可能要并行打几万甚至上百万次相似度计算。基座慢,上层再花哨也救不回来。
TriviumDB 的卖点不是"又一个向量库",而是"一个嵌入式文件同时管向量+图+文档"。那它作为向量引擎本身到底硬不硬?如果向量检索被纯向量库甩开一个量级,三位一体的价值就站不住。所以这篇只把向量检索拎出来,和同生态位的方案对撞,用同一台机器、同一批数据、同一套指标,看清楚行在哪、不行在哪。
二、对比对象与方法论
2.1 选谁比
方案 | 形态 | 索引算法 | 版本 |
|---|---|---|---|
TriviumDB | 嵌入式数据库(Rust,napi/pyo3 绑定) | QuIVer :2-bit BQ 签名图导航 + Vamana 拓扑 + f32 精排 | 0.7.5 |
hnswlib | 纯向量库(C++,Python 绑定) | HNSW | 0.8.0 |
FAISS HNSW | 纯向量库(C++,Python 绑定) | HNSW Flat | 1.15.0 |
USearch | 纯向量库(C++,Python 绑定) | HNSW | 2.26.0 |
Chroma | 嵌入式向量数据库(Python 客户端) | HNSW(底层 hnswlib) | 1.5.9 |
Zvec | 嵌入式向量数据库(Python 客户端) | HNSW | 0.6.0 |
VSAG | 纯向量库(C++,Python 绑定) | HNSW / HGraph | 0.0.11(本机无法运行,见 §7.4) |
hnswlib / FAISS HNSW / USearch 是纯向量库,和 TriviumDB 比的是"检索引擎"这一层。Chroma 和 Zvec 是嵌入式向量数据库,和 TriviumDB 比的是"端到端"这一层(建库、查询、管理全包),它们的 QPS 是 Python 客户端批量查询口径,和底层库的 MT-QPS 不在同一层,后面会单独说明。
为什么没有 LevelDB / RocksDB / SQLite?它们是嵌入式方案,但定位是 KV / 关系型存储,原生不做 ANN 近邻搜索。拿它们比 Recall@10-QPS,得自己在外层接暴力扫描或向量索引,比的是"组装方案"而不是库本身的向量检索能力。本文只比开箱即用的向量检索方案,所以不纳入。
2.2 对比守则
- 只报同机对比:所有库同一台机器、同一轮会话跑完,不搬别处的数字。
- 同数据、同查询、同指标:每个数据集固定同一批训练向量、同一批查询、同一份 Ground Truth;统一 L2 归一化后按余弦度量;统一 Recall@10 和 QPS 口径。
- 放完整参数扫描:每条 Pareto 曲线都是
ef从松到紧扫出来的,不是挑单点。 - 单线程和多线程分开报:正文曲线用 MT,表格附 1T。MT=16,原因见下条。
- 线程数取本机实际可用数:CPU 是 6 P-core + 4 E-core 的 i5-13490F,16 线程。所有库统一 MT=16(baseline 显式设
TRIVIUM_MT_THREADS=16,TriviumDB 的 rayon 池默认就是 16)。 - 只测向量检索:图遍历、文档过滤、混合检索不在本文范围。
- 服务型库不硬比:Qdrant / Milvus / Weaviate 多一层独立进程和网络,硬比不公平也没信息量(笔记本端到端测试里 Qdrant 本地模式写入不达标,见 §7.3)。
2.3 测试环境
项目 | 配置 |
|---|---|
CPU | Intel Core i5-13490F(6 P-core + 4 E-core,共 16 线程,AVX2,无 AVX-512) |
内存 | 2 × 16 GB DDR5-6000(A-DATA XPG Lancer CL36,双通道) |
显卡 | NVIDIA GeForce RTX 4060 Ti 16 GB(本文 CPU-only,未参与计算) |
存储 | C 盘:Crucial P3 Plus 1TB(CT1000P3PSSD8,NVMe);另有 SanDisk Ultra 3D NVMe。跑分数据/索引在 C 盘桌面 |
系统 | Windows 11 |
跑分日期 | 2026-08-17 ~ 08-22(多轮实测) |
线程 | MT=16(本机可用逻辑处理器数,全库统一) |
Rust | rustc 1.97.1,release + LTO, RUSTFLAGS="-C target-cpu=native" |
Python | 3.13.14(managed venv) |
关键 Python 库 | numpy 2.5.2 · hnswlib 0.8.0 · faiss-cpu 1.15.0 · usearch 2.26.0 · chromadb 1.5.9 · pyvsag 0.0.11(无法加载) |
CPU-only:所有方案只在 CPU 跑(i5-13490F 无 AVX-512,AVX2 是共同起点),不用 GPU、不用量化推理加速。这也是嵌入式方案的真实使用场景。
三、数据集
3.1 主战场:LLM embedding 数据集
论文内的四个数据集:
数据集 | 规模 | 维度 | 分布 / 来源 | 在论文中的位置 |
|---|---|---|---|---|
Cohere-1M | 1,000,000 / 1,000 | 768 | Cohere embed-english-v2.0 的 Wikipedia embedding(HF) | Competitive 档(≥88%) |
MiniLM-1M | 1,000,000 / 1,000 | 384 | all-MiniLM-L6-v2 embedding | Competitive 档(≥88%) |
DBpedia-1M | 990,000 / 1,000 | 1536 | OpenAI text-embedding 的 DBpedia 条目 | Competitive 档(≥88%) |
ArXiv Abstracts-InstructorXL | 1,000,000 / 1,000 | 768 | Qdrant/arxiv-abstracts-instructorxl-embeddings | 论文外(后补入本表) |
前三个覆盖论文 Competitive 档里的三个数据集(论文该档还有 BGE-M3-1M 和 DBpedia-3072),ArXiv-Abstracts 是论文外补的第一个 768 维数据,用来验证"优势不是只对论文那几个数据集成立"。
论文外扩展的六个数据集(本轮新增):
数据集 | 规模 | 维度 | 分布 / 来源 | 说明 |
|---|---|---|---|---|
ArXiv Titles-InstructorXL | 1,000,000 / 1,000 | 768 | 同一模型,论文标题 embedding | 与 Abstracts 对照 |
DBpedia OpenAI-1024 | 999,000 / 1,000 | 1024 | OpenAI text-embedding-3-large(1024d) | 1024 维 |
DBpedia OpenAI-1536-100K | 99,000 / 1,000 | 1536 | OpenAI text-embedding-3-small(1536d) | 小规模 100K |
GTE Multilingual Ads | 1,000,000 / 1,000 | 768 | 阿里 GTE-multilingual 广告关键词 | 多语言 |
GTE Multilingual Product Ads | 999,000 / 1,000 | 768 | 阿里 GTE-multilingual 商品广告 | 多语言 |
ColBERT-TREC-COVID | 99,000 / 1,000 | 128 | ColBERT 多向量 mean-pool 单向量近似 | 低维小规模反例 |
统一 L2 归一化 + 余弦度量。这样一共覆盖 10 个 LLM embedding 数据集,维度从 128 到 1536,规模从 99K 到 1M,分布覆盖英文/多语言、抽象/标题、广告/商品。ColBERT 的说明:原始数据是多向量(每文档 180 token × 128 维),这里用 mean-pool 转成 128 维单向量近似,不代表真实 ColBERT late interaction 检索——它用来观察低维小规模下 QuIVer 的表现,是主动放进来的反例(见 §7.4)。
3.2 边界对照:SIFT-128 与 GloVe-100
为了不把主场优势包装成全面优势,额外跑了两个边界外的数据集作对照:
数据集 | 规模 | 维度 | 分布 | 预期 |
|---|---|---|---|---|
SIFT-128 | 1M / 10k 查询 | 128 | 非负直方图特征(欧氏原生) | 边界外 |
GloVe-100 | 1.18M / 10k 查询 | 100 | 低维词向量(高固有维度) | 边界外/边缘 |
预期依据:QuIVer 论文(arXiv:2605.02171)在多数据集评测里给了明确的适用边界,BQ 原生拓扑对 cosine-native 对比学习 embedding 高度有效(5 个数据集 ≥88% Recall@10 @ ef=64),对 CLIP 类多模态数据中等有效(71–78%),对欧氏原生或无结构分布实证不适合(<15%)。论文把这概括为"不可能三角"。§7.1 用本机实测验证这条边界。
3.3 数据准备(官方脚本)
代码语言:
bash
复制
# 官方脚本:prepare_all.py(数据集准备)、bench_baselines.py(外部库基线)、
# bench_cohere1m.rs(TriviumDB 本体基准)
python scripts/prepare_all.py cohere # Cohere-1M:HF Hub 直接下官方三件套
python scripts/prepare_all.py sift128 glove100 # SIFT/GloVe:ann-benchmarks HDF5 转换
# DBpedia / ArXiv:参考 prepare_all.py 的 hf_bin 流程按同格式准备脚本:
scripts/prepare_all.py。所有数据集统一 L2 归一化 + 余弦度量;SIFT 原始是欧氏,归一化后按余弦重算了精确 Top-10 GT。
说明:SIFT/GloVe 的查询集从 10,000 条抽样到 1,000 条。官方脚本的暴力基准在 10k 查询 × 1M 基座下要 ~40GB 相似度矩阵,超出 32GB 内存;用固定种子确定性抽样,同批查询用于所有库。其余数据集官方查询集本身就是 1,000 条。
3.4 论文的四档适用梯度:Competitive / High / Usable / Collapse
论文(arXiv:2605.02171)在第 5.6 节对 12 个百万级数据集给出四档适用性梯度(原文 Finding 3),每档按 ef=64 时的 Recall@10 划分:
论文档位 | 判定标准(ef=64 的 Recall@10) | 数据集 | 我们的实测覆盖 |
|---|---|---|---|
Competitive |
| MiniLM、BGE-M3、Cohere、DBpedia-1536、DBpedia-3072(单模态对比学习) | MiniLM ✅、Cohere ✅、DBpedia ✅ |
High | 71–78% | Wolt-CLIP、RedCaps(多模态 CLIP) | 未跑 |
Usable | 32–42% | GloVe-100、Synthetic-LR(低秩合成) | GloVe-100 ✅ |
Collapse | <15% | SIFT-128、GIST-960、Random-Sphere(欧氏原生 / 无结构) | SIFT-128 ✅ |
所以"数据集在不在论文列表里"不能直接回答"是不是 QuIVer 优势区"。论文的档位只看召回可达性:Competitive 档的五个数据集全部能到 ≥88% Recall@10(ef=64),High/Usable 逐档衰减,Collapse 档崩到 15% 以下。本轮实测覆盖:Competitive 档的 MiniLM / Cohere / DBpedia,加上论文外 7 个 LLM embedding 数据集,共 10 个,结果见 §5 和 §7。
四、参数怎么配的
所有 HNSW 类统一 M=32、ef_construction=128(TriviumDB 的 QuIVer 也是 m=32、ef_c=128、α=1.2,默认参数对齐),只扫查询参数
ef(9 档)。Chroma 按同样参数重建索引(M=32、ef_construction=128、16 线程、cosine),保证公平。
库 | 构图参数 | 扫描参数 | 度量 |
|---|---|---|---|
hnswlib | M=32, ef_c=128 | ef × 9 | cosine |
FAISS HNSW | M=32, ef_c=128 | ef × 9 | IP(归一化后等价 cosine) |
USearch | connectivity=32, expansion_add=128 | ef × 9 | cos |
Chroma | M=32, ef_construction=128 | ef × 9 | cosine(Python 客户端口径) |
TriviumDB | m=32, ef_c=128, α=1.2 | ef × 9 | cosine(BQ 粗筛 + f32 精排) |
五、主结果
5.1 Cohere-1M(768 维):强主场
图:Cohere-1M 上 TriviumDB(紫)整条曲线压在 HNSW 类上方;Chroma(灰)是单独一条平线,远在下方。
图里每条线都是各自
ef完整扫描扫出来的。三个点:
- 整条曲线上 TriviumDB 都在 HNSW 类上方,全程没有反超。R@10≈90% 时 TriviumDB MT-QPS 约 73,197,hnswlib 25,645、FAISS HNSW 23,832、USearch 20,561。这个倍数落在论文宣称的 2.5–5.5× 区间内。不是略快一点,是量级差。
- 往高 QPS、低 recall 的方向走,QuIVer 优势更大。ef=10 时 TriviumDB 是 55% recall @ 158,811 QPS,hnswlib 同档 79.9% @ 41,035 QPS,用更低的召回换到近 4× 的吞吐。语义缓存、粗召回去重、实时 Top-N 这类不要求极致召回但要求扛高 QPS 的场景,正好吃这套。
- Chroma 在同机公平参数下只有 ~1.2k QPS(R@10 97.7%),且曲线是平的(ef 怎么调都不变)。瓶颈在 Python 客户端端到端开销,不是 HNSW 搜索本身。详见 §7.3。
5.2 跨数据集截点:R@10≈90% 时的 MT-QPS
下表是 R@10=90% 处对
ef曲线线性插值得到的,和图表完全自洽。同机、同数据、同查询、MT=16 线程。Chroma 一列是 Python 客户端批量查询口径(曲线平,recall 固定在其上限附近,这里取该上限下的 QPS),与其它列不在同一层,仅作参考。按维度从低到高排。
数据集(维度 / 规模) | TriviumDB | hnswlib | FAISS HNSW | USearch | Chroma* |
|---|---|---|---|---|---|
ColBERT-TREC-COVID(128 / 99K) | 44,179 | 211,714 | 242,338 | 139,452 | ~5.2k |
MiniLM-1M(384 / 1M) | 45,697 | 55,447 | 55,949 | 34,334 | ~1.8k |
GTE Product Ads(768 / 999K) | 58,849 | 43,104 | 47,225 | 35,087 | ~1.8k |
ArXiv Abstracts(768 / 1M) | 46,802 | 23,852 | 22,026 | 20,611 | ~1.2k |
GTE Ads(768 / 1M) | 51,902 | 20,351 | 24,452 | 23,403 | ~1.7k |
Cohere-1M(768 / 1M) | 73,197 | 25,645 | 23,832 | 20,561 | ~1.2k |
ArXiv Titles(768 / 1M) | 56,954 | 19,724 | 20,947 | 15,488 | ~1.1k |
DBpedia OpenAI-1024(1024 / 999K) | 64,065 | 19,000 | 23,032 | 18,233 | ~1.0k |
DBpedia-1M(1536 / 990K) | 50,068 | 13,833 | 15,299 | 13,161 | ~0.75k |
DBpedia OpenAI-1536-100K(1536 / 99K) | 91,384 | 18,476 | 19,951 | 17,198 | ~0.9k |
* Chroma 列为 Python 客户端端到端 QPS,非底层库 MT-QPS。
图:Cohere-1M 在 R@10≈90% 处的吞吐对比,TriviumDB(紫)领先 HNSW 类 2.9–3.6×。
5.3 优势随维度增大:跨数据集规律
图:TriviumDB ÷ hnswlib 的 MT-QPS 比值(R@10≈90% 处)。128 维落后,384 维同级,768 维 1.4–2.9×,1024 维 3.4×,1536 维 3.6–5.0×。
规律很清楚:维度越高,QuIVer 的优势越大。原因在 QuIVer 的设计里:BQ 签名距离用 XOR + Popcount 位运算,成本几乎不随维度涨;而 HNSW 的 f32 点积成本随维度线性涨。1536 维时 HNSW 的点积是 384 维的 4 倍,BQ 几乎不变,代差自然拉开。
同一个维度(768)下比值也有差异:GTE Product Ads 1.37×、ArXiv Abstracts 1.96×、GTE Ads 2.55×、Cohere 2.85×、ArXiv Titles 2.89×,说明分布也起作用,但整体趋势一致。规模也参与:1536 维的 DBpedia 在 990K 规模是 3.62×,在 99K 规模是 4.95×——小规模下 BQ 热路径的优势反而更突出。唯一低于 1.0 的是 128 维的 ColBERT(0.21×,低维小规模是 HNSW 的天下,见 §7.4)——这条反例和论文"不可能三角"一致,QuIVer 的选择不是"所有 embedding 通吃"。
图:DBpedia-1M(1536 维)上优势最明显,TriviumDB 约 50,068 QPS @90% recall,HNSW 类只有 13–15k。
图:ArXiv Abstracts(768 维,论文外数据集),TriviumDB 约 46,802 QPS @90% recall,约为 hnswlib 的 2.0×。
图:MiniLM-1M(384 维)上 TriviumDB 与 HNSW 同级(0.82×),快于 USearch(1.33×)和 Chroma(~1.8k)。
六、构建时间与内存占用(Cohere-1M)
库 | 构建耗时 | 索引内存 / RSS | 备注 |
|---|---|---|---|
hnswlib | 166.2 s | 3,189 MB | HNSW,M=32 |
FAISS HNSW | 161.8 s | 3,189 MB | HNSW Flat,M=32 |
USearch | 186.3 s | 3,189 MB | HNSW,M=32 |
Chroma | 380.6 s | 4.73 GB(RSS) | 端到端,Python 客户端 + 索引 |
TriviumDB | 51.8 s | Hot 675 MB | 免训练量化;构建约为 HNSW 类的 1/3 |
内存口径:hnswlib / FAISS / USearch 是脚本估算值(向量 2,930 MB + 邻接 244 MB),TriviumDB 是
index.stats().hot_bytes实测值(675 MB),Chroma 是笔记本端到端实测 RSS(4.73 GB,1M 全量)。口径不完全一致,只看量级。1M×768 的 f32 原向量本身就要 ~3 GB,TriviumDB 的 hot 区(签名索引)只要 675 MB,全量 f32 精排按需从冷区读,这是"2-bit 签名 + 冷热分离"的收益。
构建速度上,TriviumDB 的 BQ 量化免训练,对归一化向量取符号位就行,构建时间和 HNSW 同类甚至更快。10 个数据集的 0.7.5 构建时间都在秒级到分钟级:Cohere 51.8s、MiniLM 41.7s、DBpedia 82.1s、ArXiv Abstracts 53.5s、ArXiv Titles 60.3s、DBpedia-1024 59.9s、DBpedia-1536-100K 4.2s、GTE Ads 43.3s、GTE Product Ads 37.8s、ColBERT 2.0s。
七、边界与端到端
7.1 适用边界实测(SIFT-128 / GloVe-100)
数据集 | TriviumDB QuIVer Recall@10 封顶(ef=800) | hnswlib 同口径 | 论文预期 |
|---|---|---|---|
SIFT-128(128 维,非负直方图 / 欧氏原生) | 43.4% | 99.9% | <15%(欧氏口径) |
GloVe-100(100 维,低维词向量 / 高固有维度) | 69.4% | 97.2% | 边界外 / 边缘 |
QuIVer 在 LLM embedding 之外的数据上不做任何承诺。如果你的数据不是 embedding 分布(图像直方图、低维词向量、高固有维度),请选 HNSW 类方案。这条边界是论文主动划的,本文用本机实测验证了它。
边界结论是结构性的:BQ 符号量化在非负直方图 / 低维数据上失效是数据分布问题,与 QuIVer 版本无关。
为什么?QuIVer 的签名是 2-bit 二进制量化(BQ),对归一化后的向量按每维符号位拼成二进制签名做粗筛。SIFT 是图像局部直方图特征,归一化后几乎每维都大于 0,所有向量的符号签名几乎全为 1,签名失去判别力,粗筛退化成近似随机。GloVe 只有 100 维,符号位本来就少,量化信息量不足,天花板压在 70% 上下。论文把这套规律概括为"不可能三角":激进压缩(2-bit BQ)、高吞吐、全数据兼容,三者只能取二。QuIVer 选了前两个,代价是放弃对 SIFT/GloVe 这类分布的通吃。
7.2 MiniLM-1M:低维下与 HNSW 同级,绝对性能复现论文
MiniLM-1M(384 维,论文 Competitive 档)上,TriviumDB 的召回能做到 90% 以上(ef=80 时 R@10=90.83%),不是边界数据那种崩塌。但吞吐比 Cohere 收敛很多:R@10≈90% 时约 45,697 QPS,比 hnswlib / FAISS HNSW(约 55k)低两成,快于 USearch(34k)1.3 倍,远快于 Chroma(1.8k)。一句话:
可用但不占优。对照论文:7840HS(Zen 4,8C/16T,AVX-512 + VPOPCNTDQ,DDR5-5600)ef=64 R@10=88.1% @ 41,106 QPS。我们用没有 AVX-512 的 i5-13490F 跑到 ef=80 R@10=90.83% @ 42,963,QPS 接近甚至略高,Recall 还更高。论文也专门测过关掉 AVX-512(回退 AVX2)多线程吞吐只降 5–10%,说明优势主要在算法设计而不是指令集——和我们的实测互相印证。
论文对 hnswlib 的多线程提速声称是 2.5–5.5×(Cohere-1M 表 6 为 3.6×–4.7×)。我们 Cohere 实测 2.85× 落在区间内;MiniLM 实测 0.82× 没复现这个倍数,如实报数,不做强结论。
正确跑法
:TriviumDB 本体基准用
cargo bench --bench bench_cohere1m(bench profile)跑,不要用
cargo build --release --bench,两者性能差 3–5 倍。
7.3 Chroma、Zvec 与端到端对比
Chroma 是本机用公平参数重建的(M=32、ef_construction=128、16 线程、cosine),但它扫出来的 Pareto 几乎是平的:Cohere 上 Recall 固定在 97.7%、QPS 固定在 ~1.2k,MiniLM 上 Recall 98.9%、QPS ~1.8k,DBpedia 上 Recall 98.4%、QPS ~0.75k,ArXiv 上 Recall 98.4%、QPS ~1.2k。
曲线为什么是平的?
Chroma 的查询走 Python 客户端 → FFI → hnswlib,ef 参数在查询时透传无效(建库时定死),而且单次查询的 Python 开销(序列化、锁、元数据)远大于 HNSW 搜索本身。所以扫 ef 几乎不改变 QPS,改变的是 ~0.8ms 的延迟里 Python 占大头。
注:Chroma 的 QPS 是 Python 客户端批量查询口径,和 hnswlib / FAISS / USearch / TriviumDB 的底层库 MT-QPS 不在同一层。Chroma 列的数值只说明"生产级嵌入式向量数据库端到端"的吞吐量级,不说明其 HNSW 后端本身慢。
Zvec 0.6.0(同机 Cohere-1M):另一个嵌入式向量数据库(HNSW + Python 客户端),同机同数据跑了一轮,配置对齐(m=32、ef_construction=128、16 线程、cosine,构建前
flush() + optimize()):
指标 | TriviumDB 0.7.5 | Zvec 0.6.0 |
|---|---|---|
构建耗时(1M) | 51.8 s | 217.7 s(含 optimize 180.9 s) |
内存 | Hot 675 MB | RSS 6,336 MB |
MT-QPS @ R@10≈90% | ≈73,197 | ≈9,889(约 7×) |
图:Cohere-1M 上 TriviumDB(紫)在上方,Zvec(青)居中但显著低于 hnswlib(蓝)和 TriviumDB,Chroma(灰)在底部。Zvec 同召回下约 9,889 QPS,是 TriviumDB 的 1/7,是裸 hnswlib 的 1/2.6,但比 Chroma 快约 8 倍。
Zvec 的 Python 客户端路径仍有明显开销,但它的 Pareto 是正常随 ef 变化的(不像 Chroma 是平线),说明它把 ef 透传给了底层 HNSW。和 Chroma 放在一起看,结论是:
两个生产级嵌入式向量数据库都跑在"Python 客户端端到端"这个数量级上,远低于裸库和 TriviumDB——这是这类产品的共性,不是某一家的问题。
笔记本端到端独立复测(12700H 14核20线程 4800 DDR5 32G,其余配置近似):用同样的 Cohere-1M 数据,在另一台笔记本上做了端到端对比,结论一致且更狠:
指标 | TriviumDB 0.7.5 | ChromaDB 1.5.9 |
|---|---|---|
建库耗时(1M) | 33.8 s | 538.3 s(快 15.9×) |
多线程 QPS(8 线程) | 3,067 | 832(快 3.7×) |
Recall@10 | 98.98% | 94.83%(+4.2pt) |
预热后内存 RSS | 1.27 GB | 4.73 GB(省 3.7×) |
同一个测试里:usearch 同召回(98.7%)下 TDB 快 11.3 倍;FAISS 在 768 维召回封顶 84.46%,够不到 TDB 的下限 92.58%(
recall_k=1时 f32 精排兜底);LanceDB(IVF_PQ)召回崩到 54.91%;Qdrant 本地模式 5000 条 × 768 维 upsert 就要 5 分钟以上,直接退出测试。
7.4 低维边界:ColBERT mean-pool 是反例
图:128 维小规模(99K)下 HNSW 类全面碾压 TriviumDB,这是 10 个 LLM embedding 数据集里唯一的反例。
ColBERT-TREC-COVID(99K × 128 维,mean-pool 单向量近似)上,R@10≈90% 时 hnswlib 211,714 QPS、FAISS HNSW 242,338 QPS、USearch 139,452 QPS,TriviumDB 只有 44,179,约为 HNSW 类的 1/5。
低维小规模是 HNSW 的天下。为什么?128 维时 f32 点积本身就便宜,HNSW 的图导航开销小,而 BQ 粗筛 + f32 精排的两段式在这么低维的数据上省不了多少;小规模(99K)又让图遍历的绝对成本很低。这个场景不是 QuIVer 的设计目标——它主打的位运算优势要在高维(≥768)才拉开。选这个数据集进来,就是要让"优势区间"的边界有个明确的低端。
说明:ColBERT 原始数据是多向量(每文档 180 token × 128 维),这里是 mean-pool 成 128 维单向量的近似测试,不代表真实 ColBERT late interaction 检索。
7.5 没测的项
- VSAG 缺测:pyvsag 0.0.11 的 Windows wheel 只打包了 Linux 原生库,Windows 无法 import。同机原则下不拿别机数字顶替。
- 只测了向量检索:图遍历、文档过滤、混合检索不在本文。
- RedCaps(CLIP)未跑:论文 High 档,需要手动 Zenodo 数据,后续可补。
- ef 语义不完全等价:各库 ef 是各自实现的搜索波束,数值相同不代表路径相同,曲线本身诚实。
- 内存口径:baseline 是估算值,TriviumDB 是
index.stats().hot_bytes实测值,Chroma 是端到端 RSS,口径不完全一致,只看量级。 - 归一化口径:SIFT/GloVe 转余弦后与 ann-benchmarks 官网欧氏口径不可直接对比。
- ColBERT 是 mean-pool 近似:不代表真实 late interaction 检索,仅用于观察低维小规模行为。
这些没跑的项不影响核心结论:论文 Competitive 档三个数据集 + 论文外七个数据集全部实测,10 个数据集里 9 个 TriviumDB 领先或同级(768 维以上 1.4–5.0×),唯一反例是低维小规模的 ColBERT;SIFT/GloVe 边界崩塌。这条结论链是完整的。
八、复现方式
下面是可以直接照抄的命令。先按 §2.3 准备好官方脚本和数据集,再依次跑外部库基线、TriviumDB 本体、Chroma,最后解析汇总画图。
8.1 官方脚本(均来自上游仓库YoKONCy/TriviumDB)
8.2 本次实测命令
代码语言:
bash
复制
# —— 0) 数据集(已就绪,重跑需先删根目录 *_train.f32 等)——
python scripts/prepare_all.py cohere # Cohere-1M:HF Hub 直接下官方三件套
python scripts/prepare_all.py sift128 glove100 # 需先把 ann-benchmarks 的 HDF5 放根目录
# 其余 7 个论文外数据集(ArXiv×2 / DBpedia-OpenAI×2 / GTE×2 / ColBERT):
# 按 prepare_all.py 的 hf_bin 流程准备同格式 f32 / i32 文件(colbert 需先 mean-pool 到 128 维单向量)
# —— 1) 外部库基线(hnswlib / FAISS HNSW / USearch)——
TRIVIUM_ANN_DIM=768 TRIVIUM_ANN_TRAIN=cohere_train.f32 TRIVIUM_ANN_TEST=cohere_test.f32 \
TRIVIUM_ANN_GT=cohere_groundtruth.i32 TRIVIUM_MT_THREADS=16 TRIVIUM_BL_M=32 TRIVIUM_BL_EFC=128 \
BASELINES=hnswlib,faiss_hnsw,usearch \
python benches/bench_baselines.py
# MiniLM / DBpedia / ArXiv:改 TRIVIUM_ANN_DIM 与对应文件名重复跑
# (MiniLM=384,DBpedia=1536,ArXiv=768)
# —— 2) TriviumDB 本体(必须用 cargo bench 的 bench profile!见 §7.2)——
TRIVIUM_ANN_NAME=cohere-1m TRIVIUM_ANN_M=32 TRIVIUM_ANN_EF_CONSTRUCTION=128 \
TRIVIUM_ANN_EF=10,20,40,80,120,200,400,600,800 RAYON_NUM_THREADS=16 \
TRIVIUM_RESULT_PATH=articles/bench2/cohere1m_075_benchprofile_triviumdb.json \
cargo bench --bench bench_cohere1m
# —— 3) Chroma / Zvec(同机公平参数,Python 客户端口径)——
TRIVIUM_ANN_DIM=768 TRIVIUM_ANN_TRAIN=cohere_train.f32 TRIVIUM_ANN_TEST=cohere_test.f32 \
TRIVIUM_ANN_GT=cohere_groundtruth.i32 TRIVIUM_MT_THREADS=16 TRIVIUM_BL_M=32 TRIVIUM_BL_EFC=128 \
python articles/bench2/bench_chroma_pareto.py
python articles/bench2/bench_zvec_cohere.py # Zvec:构建前需 flush() + optimize()
# —— 4) 解析 / 汇总 / 画图(本文全部 0.7.5 图由此生成)——
python articles/bench2/assemble_results_075.py
python articles/bench2/make_charts_075.py8.3 重跑要注意的两件事
- TriviumDB 必须用cargo bench --bench bench_cohere1m,不要用
cargo build --release --bench。错误 profile 下性能差 3–5 倍(MiniLM 实测 42,963 vs 9,612)。 - 线程数取本机实际可用数:本文 CPU 是 i5-13490F 的 16 线程,所有库统一 MT=16 才公平。重跑前先
python -c "import os; print(os.cpu_count())"确认你的可用核数,统一口径。
所有 QPS 是 1,000 条查询 × 1M 基座下的实测吞吐均值;Recall@10 以精确暴力 Top-10 为 ground truth。Chroma 列是 Python 客户端批量查询口径,与底层库 MT-QPS 不同层。换机器、换版本、换数据分布,数字都会变。本文结论只在上述环境和 LLM embedding(Cohere / MiniLM / DBpedia / ArXiv)场景下成立。
注:本文代码与数字基于 2026-08-17 ~ 08-22 本机多轮实测(环境见 §2.3),以 0.7.5 数据为准;不构成任何性能担保;换机器、换版本、换数据分布结果都会变。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系
cloudcommunity@tencent.com删除。