静态嵌入:你应该关注吗?
在资源受限的计算世界中,一场悄无声息的革命正在发生。尽管 Transformer 以其令人印象深刻的能力在排行榜上占据主导地位,但静态嵌入正在意外地卷土重来,以惊人的速度提升和微小的质量权衡提供显著的改进。我们评估了 Qdrant 用户如何从这场复兴中受益,结果令人鼓舞。
静态嵌入有何不同?
在嵌入方面,Transformer 通常被认为是唯一的选择。注意力机制的使用有助于捕获输入词元之间的关系,因此每个词元都获得一个上下文感知的向量表示,其定义不仅取决于词元本身,还取决于周围的词元。基于 Transformer 的模型轻松超越了 word2vec 或 GloVe 等旧方法的质量,这些方法只能为每个单词创建一个单独的向量嵌入。结果,单词“bank”在“river bank”(河岸)和“financial institution”(金融机构)的上下文中具有相同的表示。

基于 Transformer 的模型在每个上下文中都会以不同的方式表示单词“bank”。然而,Transformer 也伴随着成本。它们计算成本高昂,通常需要大量内存,尽管嵌入模型的参数通常比大型语言模型少。尽管如此,即使是推理,也更倾向于使用 GPU。
然而,静态嵌入仍然存在!MinishLab 在 2024 年 10 月推出了他们的 model2vec 技术,实现了模型尺寸减少 15 倍,速度提升高达 500 倍,同时保持了令人印象深刻的性能水平。他们的想法是从基于 Transformer 的句子 Transformer 中提取知识,并创建一个更快、内存消耗更少的静态嵌入模型。这一引入似乎是静态嵌入复兴的催化剂,因为我们甚至可以看到静态嵌入被整合到流行的 Sentence Transformers 库中。Tom Aarsen 在 Hugging Face 博客上最近发表的博文揭示了如何使用 Sentence Transformers 训练静态嵌入模型,并以一小部分计算成本获得高达 Transformer 级别 85% 的质量。该博文还介绍了一个用于英语文本检索的嵌入模型,名为 static-retrieval-mrl-en-v1。
Qdrant 中的静态嵌入
从向量数据库的角度来看,静态嵌入与任何其他嵌入模型没有区别。它们毕竟是密集向量,您可以简单地将它们存储在 Qdrant 集合中。以下是使用 sentence-transformers/static-retrieval-mrl-en-v1 模型的方法
import uuid
from sentence_transformers import SentenceTransformer
from qdrant_client import QdrantClient, models
# The model produces vectors of size 1024
model = SentenceTransformer(
"sentence-transformers/static-retrieval-mrl-en-v1"
)
# Let's assume we have a collection "my_collection"
# with a single vector called "static"
client = QdrantClient("https://:6333")
# Calling the sentence transformer model to encode
# the text is not different compared to any other model
client.upsert(
"my_collection",
points=[
models.PointStruct(
id=uuid.uuid4().hex,
vector=model.encode("Hello, world!"),
payload={"static": "Hello, world!"},
)
]
)
检索不会因为您使用静态嵌入而变得更快。然而,您将体验到从数据创建向量的巨大加速,这通常是一个瓶颈。Hugging Face 博客文章提到,该模型在 CPU 上可能比最先进的嵌入模型快 400 倍。
我们没有对编码速度进行任何适当的基准测试,但对来自 BeIR 的 TREC-COVID 数据集进行的一项实验表明,我们可以在大约 7.5 分钟内在 Qdrant 中编码和完全索引 171K 份文档。所有这些都在消费级笔记本电脑上完成,没有 GPU 加速。
静态嵌入的量化
真正能让检索更快的是使用 Matryoshka 嵌入,因为 static-retrieval-mrl-en-v1 模型是在考虑该技术的情况下训练的。然而,这并不是加快搜索速度的唯一方法。量化方法在我们的用户中非常流行,我们很好奇它们是否可以同样成功地应用于静态嵌入。
我们采用了 static-retrieval-mrl-en-v1 模型,并在 BeIR 的各种子集上测试了它,有和没有二进制量化,以查看它对检索质量的影响程度。结果非常有希望,如我们的 NDCG@10 测量所示(一个评估搜索结果排名质量的指标,分数越高表示性能越好)
| NDCG@10 | ||
|---|---|---|
| 数据集 | 原始向量 | 二进制量化,不重排序 |
| SciFact | 0.59348 | 0.54195 |
| TREC-COVID | 0.4428 | 0.44185 |
| ArguAna | 0.44393 | 0.42164 |
| NFCorpus | 0.30045 | 0.28027 |
二进制量化无疑加快了检索速度并降低了成本,但在某些情况下似乎对检索质量没有太大影响。然而,这是您应该在自己的数据上仔细验证的事情。如果您是 Qdrant 用户,那么您只需在现有集合上启用量化并测量对检索质量的影响。
我们所做的所有测试都是使用 beir-qdrant 执行的,可以通过运行项目仓库中提供的脚本进行复现。
谁应该使用静态嵌入?
静态嵌入似乎是那些希望在其应用程序中使用语义搜索但无法负担托管标准表示模型,或者由于硬件限制无法这样做的人的经济实惠的选择。一些用例可能包括
- 移动应用程序 - 尽管许多智能手机拥有强大的 CPU 甚至 GPU,但电池寿命仍然是一个问题,静态嵌入可能是质量和功耗之间的良好折衷。此外,静态嵌入可用于需要离线模式的应用程序。
- 网络浏览器扩展 - 在网络浏览器中运行基于 Transformer 的模型通常不是一个好选择,但静态嵌入可能是一个不错的选择,因为它们参数较少,编码速度更快。
- 嵌入式系统 - 静态嵌入可能是计算能力有限的设备(例如 IoT 设备或微控制器)的良好选择。
如果您是上述情况之一,那么您绝对应该尝试静态嵌入。但是,如果搜索质量不是您的首要任务,那么即使在高性能环境中,您也可以考虑使用静态嵌入。编码过程的加速可能会为您带来巨大的改变。
静态嵌入的定制
最后但同样重要的是。Tom Aarsen 发布 的训练管道可以帮助您训练自己的静态嵌入模型,因此您可以轻松地将其调整到您的数据特性。这个训练过程也将比基于 Transformer 的模型快得多,因此您可以更频繁地重新训练它。重新计算嵌入是语义搜索系统的瓶颈,静态嵌入可能是解决此问题的好方法。自定义静态嵌入模型是否能胜过通用预训练模型仍然是一个悬而未决的问题,但绝对值得一试。