FastEmbed稀疏嵌入深度解析:SPLADE++与BM42算法详解
FastEmbed是一个快速、准确、轻量级的Python库,旨在提供最先进的嵌入技术。在信息检索领域,稀疏嵌入技术因其高效的存储和检索性能而备受关注。本文将深入解析FastEmbed中的两种核心稀疏嵌入算法——SPLADE++与BM42,帮助读者理解它们的工作原理、优势及应用场景。
什么是稀疏嵌入?
稀疏嵌入是一种将文本转换为高维向量的技术,其特点是向量中大部分元素为零,只有少数非零元素。这种特性使得稀疏嵌入在存储和计算效率上具有显著优势,特别适合大规模文本检索任务。FastEmbed作为一款优秀的嵌入工具,提供了多种稀疏嵌入算法,其中SPLADE++和BM42是最具代表性的两种。
图:FastEmbed稀疏嵌入算法在不同采样率下的准确率对比,展示了SPLADE++与BM42算法的性能表现
SPLADE++算法详解
SPLADE++的核心原理
SPLADE++(Sparse Lexical and Expansion Model)是一种基于Transformer的稀疏嵌入模型,它通过以下步骤生成稀疏向量:
-
ReLU激活与对数变换:对模型输出应用ReLU激活函数,然后进行对数变换(log(1 + max(output, 0))),增强重要特征的表达。
-
注意力掩码加权:将变换后的特征与注意力掩码相乘,过滤掉填充部分的影响。
-
最大值池化:对每个词表维度取最大值,生成最终的稀疏向量。
SPLADE++的实现细节
在FastEmbed中,SPLADE++的实现位于fastembed/sparse/splade_pp.py文件中。核心代码如下:
def _post_process_onnx_output(self, output: OnnxOutputContext, **kwargs: Any) -> Iterable[SparseEmbedding]:
if output.attention_mask is None:
raise ValueError("attention_mask must be provided for document post-processing")
relu_log = np.log(1 + np.maximum(output.model_output, 0))
weighted_log = relu_log * np.expand_dims(output.attention_mask, axis=-1)
scores = np.max(weighted_log, axis=1)
for row_scores in scores:
indices = row_scores.nonzero()[0]
scores = row_scores[indices]
yield SparseEmbedding(values=scores, indices=indices)
这段代码实现了SPLADE++的核心后处理流程,将模型输出转换为稀疏嵌入向量。
SPLADE++的优势与应用场景
SPLADE++的主要优势在于:
- 高表达能力:通过Transformer模型捕捉文本深层语义信息。
- 动态特征扩展:能够自动扩展重要词汇的表示,提高检索准确性。
- 良好的稀疏性:生成的向量稀疏度高,有利于存储和计算。
SPLADE++适用于需要高精度文本检索的场景,如学术论文检索、专利检索等。
BM42算法详解
BM42的核心原理
BM42是对经典BM25算法的改进,它解决了BM25在短文本处理上的不足。BM42的核心创新在于:
-
注意力权重替代词频:使用Transformer模型的注意力权重替代传统的词频统计,更好地捕捉词语重要性。
-
词干提取与停用词过滤:结合NLP技术,对词语进行词干提取和停用词过滤,减少噪声。
-
分数重计算:基于词语重要性排序,重新计算分数,增强相对重要性的影响。
BM42的实现细节
BM42的实现位于fastembed/sparse/bm42.py文件中。其核心处理流程包括:
def _post_process_onnx_output(self, output: OnnxOutputContext, **kwargs: Any) -> Iterable[SparseEmbedding]:
# 从模型输出中提取注意力权重
pooled_attention = np.mean(output.model_output[:, :, 0], axis=1) * output.attention_mask
for document_token_ids, attention_value in zip(token_ids_batch, pooled_attention):
# 重构BPE token
reconstructed = self._reconstruct_bpe(document_tokens_with_ids)
# 过滤停用词和标点
filtered = self._filter_pair_tokens(reconstructed)
# 词干提取
stemmed = self._stem_pair_tokens(filtered)
# 聚合权重
weighted = self._aggregate_weights(stemmed, attention_value)
# 重计算分数
rescored = self._rescore_vector(max_token_weight)
yield SparseEmbedding.from_dict(rescored)
BM42的优势与应用场景
BM42的主要优势包括:
- 短文本处理能力:对短文本和文本片段有更好的处理效果。
- 传统NLP技术结合:融合词干提取和停用词过滤,提高检索质量。
- 高效的查询处理:查询嵌入无需运行模型,速度更快。
BM42特别适合聊天记录检索、短文本问答系统等场景。
SPLADE++与BM42的对比分析
技术特点对比
| 特性 | SPLADE++ | BM42 |
|---|---|---|
| 核心思想 | 基于Transformer的动态特征扩展 | 注意力权重替代词频的BM25改进 |
| 模型大小 | 较大(约0.532GB) | 较小(约0.09GB) |
| 处理速度 | 较慢 | 较快 |
| 稀疏性 | 高 | 高 |
| 适用场景 | 长文本、高精度需求 | 短文本、实时性需求 |
性能表现
从实验数据来看(如图1所示),在不同采样率下,SPLADE++和BM42都表现出良好的准确率。SPLADE++在高采样率下略占优势,而BM42在低采样率下表现更稳定。这意味着在资源有限的情况下,BM42可能是更好的选择。
如何选择?
- 当处理长文本且对检索精度要求极高时,优先选择SPLADE++。
- 当处理短文本或需要快速响应时,BM42是更好的选择。
- 资源有限时,BM42的轻量级特性更具优势。
FastEmbed稀疏嵌入的使用方法
安装FastEmbed
要使用FastEmbed中的稀疏嵌入功能,首先需要安装FastEmbed库。可以通过以下命令克隆仓库并安装:
git clone https://gitcode.com/gh_mirrors/fa/fastembed
cd fastembed
pip install .
使用SPLADE++进行嵌入
from fastembed.sparse import SpladePP
# 初始化SPLADE++模型
model = SpladePP(model_name="prithivida/Splade_PP_en_v1")
# 嵌入文档
documents = ["FastEmbed is a fast embedding library.", "SPLADE++ is a powerful sparse embedding model."]
embeddings = list(model.embed(documents))
# 打印嵌入结果
for doc, embedding in zip(documents, embeddings):
print(f"Document: {doc}")
print(f"Sparse embedding size: {len(embedding.values)}")
使用BM42进行嵌入
from fastembed.sparse import Bm42
# 初始化BM42模型
model = Bm42(model_name="Qdrant/bm42-all-minilm-l6-v2-attentions")
# 嵌入文档
documents = ["FastEmbed supports BM42 algorithm.", "BM42 is an improved version of BM25."]
embeddings = list(model.embed(documents))
# 嵌入查询
queries = ["What is BM42?", "How to use FastEmbed?"]
query_embeddings = list(model.query_embed(queries))
总结与展望
FastEmbed提供的SPLADE++和BM42两种稀疏嵌入算法,为不同场景下的文本检索需求提供了强大支持。SPLADE++凭借其深度语义理解能力,在需要高精度的场景中表现出色;而BM42则以其高效性和对短文本的良好处理能力,在实时应用中具有优势。
随着技术的不断发展,稀疏嵌入算法将在信息检索、自然语言处理等领域发挥越来越重要的作用。FastEmbed作为一个开源项目,为开发者提供了便捷、高效的嵌入工具,值得广大开发者关注和使用。
通过本文的介绍,相信读者对FastEmbed中的SPLADE++和BM42算法有了更深入的了解。希望这篇文章能帮助你在实际应用中更好地选择和使用稀疏嵌入技术。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




