问题出现得很突然,日志倒是留得挺全。训练好的索引写入文件后,服务重启加载报读取失败,文件大小看起来正常,重新训练又能用。

刚开始盯着「容器里的挂载目录只读,写入静默失败」,折腾了半个多小时,排掉了。

真正麻烦的地方在于,几个原因的现象几乎一样。写入时进程没有 flush 完就被杀掉。另一种情况是路径用了相对目录,工作目录变化后找不到。

另外,索引与向量数据分开保存,版本对不上。

保存后立刻校验文件大小

python -c "import os;print(os.path.getsize('faiss.index'))"

随后用绝对路径读写并确认目录可写

faiss.write_index(index, '/data/index/faiss.index')

然后加载前先做一次存在性检查

python -c "import os;print(os.path.exists('/data/index/faiss.index'))"

等前面都确认过,再把索引与 id 映射一起打包保存

python -c "import pickle;pickle.dump(ids, open('/data/index/ids.pkl','wb'))"

改完先别撤,确认这几项。加载索引成功且向量数量与保存时一致,检索可用,id 映射也能正确对上原始文档。

这里还有个坑。索引里只存向量不存原始 id,重建时顺序一旦变化就会全部错位,id 映射表必须和索引同版本保存。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189