这个坑值得记一笔。把 1536 维向量列从 vector 换成 halfvec,索引体积减半,检索 top10 命中率从 0.93 掉到 0.90,业务侧的答案准确率跟着降了 2 个点。

刚开始盯着「距离计算仍按 float 口径比较阈值」,折腾了半个多小时,排掉了。

这类报错背后常见的原因有几处,逐个排除就行。半精度浮点在长向量上累积误差;归一化在半精度下做,范数偏差被放大;部分向量本身取值极端,半精度溢出。

量出两种类型的向量体积与索引体积

python -c "import psycopg;print(psycopg.connect('dbname=rag').execute(\"select pg_size_pretty(pg_relation_size('chunks_vec_idx'))\").fetchone())"

建一张 halfvec 影子表并复制数据

python -c "import psycopg;psycopg.connect('dbname=rag').execute('create table chunks_h as select id, embedding::halfvec(1536) as embedding from chunks')"

接着在同一批问题上对比两侧召回

python eval_recall.py --db rag --table chunks_h --k 10 --n 500

等前面都确认过,再按业务可接受损失决定是否保留半精度

python compare_recall.py --a chunks --b chunks_h

别只看报错消失,验证要多做一步。两侧召回差控制在 0.5 个点以内则保留 halfvec,否则回退,体积与精度都有数据支撑。

省空间省的是内存和 IO,代价体现在召回上,切类型前一定要用同一批问题跑对照,别只看体积。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189