别急着上向量数据库,暴力搜索就够了
Just brute force your embeddings

我在 2000 年代写嵌入式 C 代码时就发现,O(n) 算法有时能碾压 O(log n) 算法。如今做向量搜索也是同理,很多人误以为必须上向量数据库,但如果你只有 100 万文档且查询量不大,用 Numpy 暴力计算点积反而更快更简单。在我的 M4 MBP 上,处理 100 万条 384 维 embedding 仅需 0.012 秒。对于许多团队而言,无需花费数百万美元购买数据库或花半年学习运维,直接暴力搜索直到无法忍受性能瓶颈才是务实之选。正如 Jo Kristian Bergum 所言,穷举搜索可能正是你所需的全部。
我的 O(n) 算法能轻松碾压你的 O(log n) 算法;你在学校学到的很多东西其实并不重要。
- emschwartz
如果你的嵌入模型是专门针对量化嵌入进行训练的,那这个方法效果尤其出色。二进制 + 汉明距离 = 快得离谱。
这篇帖子是 2024 年的,但我之前写过关于使用这种技术的文章:https://emschwartz.me/binary-vector-embeddings-are-so-cool/
- Ellis_dev
100 万文档的数据量是个很好的现实检验。我会很乐意先从 NumPy 版本开始,只有当它真的开始拖后腿时,再考虑上向量数据库。
- firasd
没错!我正在开发一个叫 Liveclip 的 MCP 服务器(尚未发布),我们直接把嵌入向量存为 SQLite 里的文本……它在约 40MB 文本、1450 条最高法院(SCOTUS)判例上运行良好。
start=$(date +%s); curl -s -X POST "https://[urlredacted].workers.dev/mcp" -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"table_search_similar","arguments":{"key":"scotus_2010s","col":"M","query":"endangered fish"}}}'
2>&1 | grep '^data:' | sed 's/^data: //' | jq; end=$(date +%s); echo "elapsed: $((end-start))s"
{
"result": {
"content": [],
"structuredContent": {
"has_more": true,
"headers": {
"A": "author_name",
"B": "category",
"C": "per_curiam",
"D": "case_name",
"E": "date_filed",
"F": "federal_cite_one",
"G": "absolute_url",
"H": "year_filed",
"I": "scdb_id",
"J": "scdb_decision_direction",
"K": "scdb_votes_majority",
"L": "scdb_votes_minority",
"M": "text"
},
"offset": 0,
"ok": true,
"rows": [
{
"A": "Justice Thomas",
"B": "dissenting",
"C": "False",
"D": "Florida v. Georgia",
"E": "2018-06-27",
"F": "",
"G": "https://www.courtlistener.com/opinion/4511641/florida-v-geor...",
"H": "2018",
"I": "",
"J": "",
"K": "",
"L": "", […]
}
]
}
}
}