半精度与降维是什么
两个省空间的工程手段:半精度把每维从 4 字节降到 2 字节(pgvector 里对应 halfvec 类型),精度损失通常很小;Matryoshka 类模型支持截断维度,例如把 1024 维截到 512 维,用少量召回损失换存储与计算下降。两者都会改变相似度的数值分布,因此依赖分数绝对值的阈值与重排门限必须重新校准,并重跑同一评测集确认召回可接受。
基本信息
| 半精度 | float16,pgvector 提供 halfvec 类型,每维 2 字节 |
|---|---|
| 维度截断 | Matryoshka 表示学习,取前 n 维后重新归一化 |
| 收益 | 存储与内存下降,检索与加载更快 |
| 代价 | 精度与召回可能小幅下降 |
| 校验要求 | 必须重跑同一评测集 |
| 连带影响 | 阈值与重排门限需要重新校准 |
典型使用场景
- 存储成本敏感的大集合,希望整体占用减半
- 内存受限的单机部署,放不下全精度向量
- 需要更快冷启动加载的场景,减少读取体积
- pgvector 中把 vector 列换成 halfvec 以省一半空间
- Matryoshka 模型做多档维度:粗筛用短维度、精排用长维度
pgvector 半精度示例
pgvector 半精度示例
CREATE TABLE kb16 (id bigserial PRIMARY KEY, embedding halfvec(1024)); -- 每维 2 字节
CREATE INDEX ON kb16 USING hnsw (embedding halfvec_cosine_ops); -- 配套算子类
-- 查询时同样用 halfvec 表达,否则维度与类型不匹配
SELECT id FROM kb16 ORDER BY embedding <=> $1::halfvec LIMIT 10;截断维度示例
截断维度示例
full = model.encode(text) # 1024 维
short = full[:512] # 截断到 512 维
short = short / np.linalg.norm(short) # 截断后必须重新归一化
# 入库与查询必须使用同一档维度,混用会直接报维度不匹配手段对照
| 手段 | 收益 | 注意 |
|---|---|---|
| 半精度 | 每维 4 字节降到 2 字节 | 索引要配套专用算子类,类型不匹配会报错 |
| 维度截断 | 维度减半,存储与计算同步下降 | 必须重新归一化后再入库 |
| 量化 | 压缩比更高 | 可与半精度叠加,需评测确认 |
| 全精度 | 精确保留模型输出 | 内存占用最大 |
降维与截断都会改变相似度分布:阈值与重排门限要重新校准,并重新跑评测集,否则会出现「召回范围突变」的怪现象。
维度一旦写入库就不能混用:库中存全精度向量而查询用截断维度,会直接抛出维度不匹配错误,迁移时尤其容易踩到。