0

静态嵌入:你应该关注吗?

Kacper Łukawski

·

2025年1月17日

Static Embeddings: should you pay attention?

在资源受限的计算世界中,一场静悄悄的革命正在发生。虽然 Transformer 以其强大的能力主导着排行榜,但静态嵌入正在意外地卷土重来,以令人惊讶的微小质量权衡提供了显著的速度提升。我们评估了 Qdrant 用户如何从这场复兴中受益,结果令人鼓舞

静态嵌入有何不同?

在处理嵌入时,Transformer 通常被视为唯一选择。注意力机制有助于捕捉输入 token 之间的关系,因此每个 token 都能获得一个上下文感知的向量表示,其定义不仅取决于 token 本身,还取决于周围的 token。基于 Transformer 的模型轻松超越了 word2vec 或 GloVe 等旧方法的质量,这些方法只能为每个词创建一个单一的向量嵌入。因此,“bank”这个词在“河岸”(river bank)和“金融机构”(financial institution)这两种语境下会具有相同的表示。

Static embeddings

基于 Transformer 的模型会在不同的语境中对“bank”这个词进行不同的表示。然而,Transformer 也伴随着成本。它们计算开销大,通常需要大量内存,尽管嵌入模型通常比大型语言模型参数少。即便如此,仍然优先使用 GPU,即使是在推理阶段。

静态嵌入依然存在!MinishLab 在 2024 年 10 月引入了他们的 model2vec 技术,实现了模型尺寸缩小 15 倍、速度提升高达 500 倍的惊人成果,同时保持了令人印象深刻的性能水平。他们的想法是从基于 Transformer 的句子 Transformer 中提取知识,创建一个速度更快、内存消耗更少的静态嵌入模型。这次引入似乎是静态嵌入复兴的催化剂,因为我们看到静态嵌入甚至被集成到了流行的 Sentence Transformers 库中。Tom AarsenHugging Face 博客上发表的最新博文揭示了如何使用 Sentence Transformers 训练一个静态嵌入模型,并且以一小部分的计算成本获得高达 85% 的 Transformer 级别质量。该博文还介绍了一个用于英文文本检索的嵌入模型,名为 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("http://localhost: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 倍。

我们没有对编码速度进行任何正式的基准测试,但在使用 BeIRTREC-COVID 数据集进行的一项实验表明,我们可以在 Qdrant 中在大约 7.5 分钟内编码并完全索引 17.1 万份文档。这一切都是在消费级笔记本电脑上完成的,没有使用 GPU 加速。

静态嵌入的量化

实际可以加快检索速度的是使用 Matryoshka 嵌入,因为 static-retrieval-mrl-en-v1 模型在训练时考虑到了这种技术。然而,这并非加速搜索的唯一方法。量化方法在我们的用户中非常流行,我们很想知道它们是否也能成功应用于静态嵌入。

我们使用了 static-retrieval-mrl-en-v1 模型,并在使用和不使用二值量化的情况下,在 BeIR 的各种子集上进行了测试,以了解它对检索质量有多大影响。结果非常有前景,如我们的 NDCG@10 测量值所示(一个评估搜索结果排序质量的指标,分数越高表示性能越好)。

NDCG@10
数据集原始向量二值量化,无重评分
SciFact0.593480.54195
TREC-COVID0.44280.44185
ArguAna0.443930.42164
NFCorpus0.300450.28027

二值量化无疑加快了检索速度,降低了成本,但在某些情况下似乎对检索质量影响不大。然而,这是你需要仔细地在你自己的数据上验证的事情。如果你是 Qdrant 用户,你可以在现有集合上启用量化并衡量其对检索质量的影响

我们进行的所有测试均使用 beir-qdrant 完成,可以通过运行项目仓库中提供的脚本进行复现。

谁应该使用静态嵌入?

静态嵌入似乎是那些希望在其应用中使用语义搜索,但无法负担托管标准表示模型,或由于硬件限制而无法实现的用户来说,是一种经济实惠的选择。一些用例可能包括

  • 移动应用 - 尽管许多智能手机拥有强大的 CPU 甚至 GPU,但电池续航仍然是一个问题,静态嵌入可能是在质量和功耗之间取得平衡的良好选择。此外,静态嵌入可用于需要离线模式的应用。
  • 网页浏览器扩展 - 在网页浏览器中运行基于 Transformer 的模型通常不是一个可行的选择,但静态嵌入可能是一个不错的选择,因为它们参数更少且编码速度更快。
  • 嵌入式系统 - 对于计算能力有限的设备,如物联网设备或微控制器,静态嵌入可能是一个不错的选择。

如果你是上述情况之一,那么你绝对应该尝试一下静态嵌入。然而,如果搜索质量不是你的首要任务,那么即使在高性能环境中,你也可能考虑使用静态嵌入。编码过程中的速度提升可能会为你带来巨大的改变。

静态嵌入的定制

最后但同样重要的是,由 Tom Aarsen 发布的训练流程可以帮助你训练自己的静态嵌入模型,因此你可以轻松地根据数据的特点进行调整。这个训练过程也会比基于 Transformer 的模型快得多,所以你甚至可以更频繁地重新训练。重新计算嵌入是语义搜索系统的瓶颈,而静态嵌入可能是解决这个问题的好办法。自定义静态嵌入模型是否能胜过通用的预训练模型仍是一个悬而未决的问题,但这绝对值得一试。

免费开始使用 Qdrant

开始使用