记录一下那天晚上的排查过程。为了省存储把 1024 维的向量手动截断到 512 维入库,检索时同一批 query 的 top10 命中率从 88% 掉到 46%,相似度分布整体向 0.6 附近挤压。
刚开始盯着「没有做重新归一化,余弦相似度被缩放」,折腾了半个多小时,排掉了。
排查方向其实有限,先把可能性排一排。直接截断破坏了各维度共同表达的语义。也可能是查询向量仍是 1024 维,与库里维度不一致。
还有一种情况,索引用内积,截断后向量模长发生变化。
上来先确认入库与查询的维度是否一致
python -c "import numpy as np;v=np.load('vec.npy');print(v.shape)"
再往下改用官方支持的降维方式而不是硬截断
python -c "from sklearn.decomposition import PCA;import numpy as np;X=np.random.rand(1000,1024);print(PCA(n_components=512).fit_transform(X).shape)"
降维后统一做 L2 归一化
python -c "import numpy as np;v=np.random.rand(1,512);print((v/np.linalg.norm(v)).shape)"
末了用固定 query 集对比降维前后召回
python recall_eval.py --queries q.jsonl --before idx1024 --after idx512
改完先别撤,确认这几项。按 PCA 降维并归一化后 top10 命中率回到 84%,存储下降一半,相似度分布形态与 1024 维基本一致。
这里还有个坑。向量维度不是可以随意裁剪的字段,硬截断等于丢掉一半语义空间,要降维就用降维方法并重新建索引。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
