当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > Sentence Transformers 怎样用二进制量化保存嵌入向量

Sentence Transformers 怎样用二进制量化保存嵌入向量

来源:17golang原创 2026-10-29 16:43:28 0浏览 收藏

Sentence Transformers 可以在生成嵌入时直接使用二进制量化,也可以先生成 float32 向量,再调用 quantize_embeddings 转换。二进制量化把每个维度压成 1 bit,官方实现会把这些 bit 打包进字节,因此 1024 维向量通常变成形状为 (1024 / 8) = 128 的 int8 或 uint8 数组。

官方地址:https://www.sbert.net/

如果目标是降低向量索引的内存和磁盘占用,最小做法是让 encode 使用 precision="binary",保存返回数组及其模型、维度和 dtype 元数据;如果还要保证召回质量,则把二进制结果用于初筛,再保留较高精度的重排数据。

先确定二进制量化放在哪一层

最直接的入口是 SentenceTransformer.encode 的 precision 参数。它适合从文本开始就按二进制格式生成结果;如果程序已经缓存了默认的浮点嵌入,则可以在后面调用 quantize_embeddings,避免改动前面的编码流程。

from sentence_transformers import SentenceTransformer
from sentence_transformers.quantization import quantize_embeddings

# 加载同一个模型,文档向量和查询向量必须保持模型一致
model = SentenceTransformer("mixedbread-ai/mxbai-embed-large-v1")
texts = ["如何降低向量索引的存储占用", "二进制向量怎样参与召回"]

# 方案一:编码阶段直接得到二进制数组
binary_embeddings = model.encode(texts, precision="binary")

# 方案二:已有 float32 结果时再量化,便于保留原始向量做重排
float_embeddings = model.encode(texts)
binary_from_float = quantize_embeddings(float_embeddings, precision="binary")

print(binary_embeddings.shape, binary_embeddings.dtype)
print(binary_from_float.shape, binary_from_float.dtype)

两种入口的量化目标相同,但数据生命周期不同:直接量化可以少保留一份中间结果;后置量化则适合已经有浮点缓存、还需要用原始向量做重排的检索系统。不要只保存一个没有元数据的二进制文件,否则后续很难判断它对应哪个模型和维度。

Sentence Transformers 从文本到 float32 嵌入、二进制量化和字节数组保存的静态关系说明图
图1:结构说明图,展示编码结果、二进制量化、bit 打包和数组保存之间的关系,不是运行截图。

保存时重点记录 shape 和 dtype

二进制量化不是把数组简单改成更小的浮点类型。官方说明是先按零阈值把归一化嵌入映射为 0/1,再用 np.packbits 把 8 个 bit 收进一个字节。因此一个 1024 维的 float32 向量原本需要 4096 字节,打包后的二进制数组通常只有 128 字节,形状也从 (1024,) 变成 (128,)。

import json
import numpy as np

# 保存数组与描述文件,恢复时必须按同一 dtype 读取
np.save("doc_embeddings.binary.npy", binary_embeddings)
metadata = {
    "model": "mixedbread-ai/mxbai-embed-large-v1",
    "precision": "binary",
    "shape": list(binary_embeddings.shape),
    "dtype": str(binary_embeddings.dtype),
    "metric": "hamming"
}
with open("doc_embeddings.binary.json", "w", encoding="utf-8") as fp:
    # ensure_ascii=False 让中文元数据保持可读
    json.dump(metadata, fp, ensure_ascii=False, indent=2)

# 恢复时先读元数据,再检查数组的形状和类型
restored = np.load("doc_embeddings.binary.npy")
assert tuple(metadata["shape"]) == restored.shape
assert metadata["dtype"] == str(restored.dtype)

如果向量库需要无符号字节格式,可以把精度指定为 "ubinary";二者不要在没有转换规则的情况下混用。实际项目还应把模型名、量化精度、维度、dtype 和相似度度量一起写进索引元数据,避免查询向量和文档向量使用了不同的编码协议。

二进制适合召回,重排负责精度

二进制向量的优势是占用小、Hamming 距离计算快,但压缩后不应被当作完整的浮点相似度替代品。一个稳妥的链路是:先把查询向量也量化为 binary,在二进制索引中取出较大的候选集,再用 float32 查询向量和更高精度的文档向量进行重排,最后返回较小的 top-k。

例如目标结果是 10 条,可以先召回 rescore_multiplier * 10 条候选,再对候选做 dot-product 重排。这样二进制索引负责缩小搜索范围,重排索引负责恢复排序质量;两者的模型、向量维度和文档 ID 必须一一对应。

二进制索引召回与高精度向量重排以及模型元数据关联的静态结构说明图
图2:关系说明图,展示二进制索引、候选文档、高精度重排和元数据之间的静态边界,不是检索结果截图。

几个容易混淆的边界

  • 不要把 128 当成模型输出维度。它是 1024 个 bit 打包成字节后的数组长度,原始语义维度仍是 1024。
  • 不要只保存二进制文件。模型标识、precision、shape、dtype 和度量方式缺一项,都可能导致恢复或查询不匹配。
  • 不要用很小的样本估计 int8 标定范围。本文讨论的是 binary;如果改用 int8,官方建议使用更大的校准嵌入集合或明确的 min/max 范围。
  • 不要把二进制召回误写成质量不变。最终效果取决于模型、数据分布、召回倍率和重排策略,应按自己的检索集评估。

常见问题

二进制量化后为什么 dtype 还是 int8?因为实现把 bit 打包进字节,数组元素承载的是字节,不是 Python 层面的单 bit 类型;需要无符号格式时使用 ubinary。

可以只用二进制向量做最终排序吗?可以,但要接受排序精度和模型数据相关的取舍。对质量敏感的检索,通常使用二进制初筛加高精度重排更稳妥。

总结:从 encode(precision="binary") 开始,保存数组和完整元数据;用 Hamming 距离做快速候选召回,再根据需求保留 float32 或 int8 数据做重排。这样才能同时得到较低的存储成本和可控的检索质量。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
ONNX Runtime 怎样为指定会话选择图优化等级ONNX Runtime 怎样为指定会话选择图优化等级
上一篇
ONNX Runtime 怎样为指定会话选择图优化等级
Sentence Transformers 怎样用 CrossEncoder 对候选文档重排
下一篇
Sentence Transformers 怎样用 CrossEncoder 对候选文档重排
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    775次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    771次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    856次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    821次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    652次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码