Generated by Answer me with HTML 0.5.7 · 2026-10-23 09:35 · ★ Star on GitHub
运行内存视角:HNSW vs IVF-PQ
常驻 RSS 谁更低,交叉点在哪,训练峰值在哪
结论
- 稳态常驻:IVF-PQ 每条约 64 B,HNSW 每条约 4.2 KB,差 64 倍。
- 交叉点约 991 条。你 1912 条只省 3.8 MB。
- 真正的坑是建库训练峰值,不是查询常驻。
两者常驻内存怎么算
| 项目 | HNSW | IVF-PQ |
|---|---|---|
| 向量本体 | 4 KB 每条,原样常驻 | 64 B 每条,压缩常驻 |
| 结构开销 | 邻接表约 128 B 每条 | 倒排表约 8 B 每条 |
| 固定开销 | 无 | 码本 nlist 乘维乘 4B |
| 是否可 mmap | 否,整块读进堆 | 是,可留磁盘 |
| 训练需求 | 无 | 需 k-means 全量或抽样 |
| 内存随 N | 线性,斜率 4.2 KB | 线性,斜率 72 B |
按规模看常驻占用
数据
| HNSW 1912 条 | 8.09 |
|---|---|
| IVF-PQ 1912 条 | 4.32 |
| HNSW 10 万条 | 423 |
| IVF-PQ 10 万条 | 10.59 |
- 单条 1024 维 float32 等于 4096 字节。
- HNSW 加邻接表和 id,单条约 4.2 KB。
- IVF-PQ 取 nlist 1024、m 64,单条 64 B。
- 码本是固定 4.19 MB,与条数无关。
- 交叉点算得 991 条,低于它 HNSW 更省。
- 到百万条,HNSW 要 4.2 GB,直接压爆 cgroup。
建库那一刻才是风险点
训练峰值
IVF-PQ 稳态省内存,但 k-means 训练要把原始 float32 读进内存。
- 百万条全量训练峰值 4.1 GB,你的 900 MB cgroup 撑不住。
- 常规做法是抽样 39 乘 nlist 条约 4 万条,峰值约 164 MB。
- HNSW 无需训练,插入即建,不存在这个峰值。
你现在这 331 MB 花在哪
- RSS 总计
- 331 MB
- 匿名堆
- 293 MB
- 文件映射
- 38 MB
- HNSW 索引
- 8.09 MB
- 索引占比
- 2.4 %
- 看门狗阈值
- 350 MB
- 索引只占 2.4 %,压缩它省不到 4 MB。
- 大盘是 Python 运行时、numpy、sqlite 页缓存。
- 换 IVF-PQ 对 RSS 曲线形状无实质改变。