文件名 BGE的FlagEmbedding库——使用嵌入模型提取稀疏向量.md

BGE的FlagEmbedding库——使用嵌入模型提取稀疏向量

本文目录

正文

学习背景:

在调研向量化方法时,学习到可以将chunk进行稀疏向量和稠密向量(Dense vec)提取。

其中,稠密向量就是常规的embedding方法。稀疏向量则一般采用TFIDF、bm25等词袋模型,对出现过的词语进行统计分析。

但是,在了解bge-m3模型后,了解到BGE推出过专门用于BGE模型的embedding库——FlagEmbedding,这个库可以使用bge系列模型进行稀疏向量的提取。 这基本是 FlagEmbedding 独有的功能之一。

代码

from FlagEmbedding import BGEM3FlagModel
import json

# 模型的加载和定义可以放在外面
model = BGEM3FlagModel('/home/worker/models/bge-m3', device=1)
string = "What is BGE M3?"
sentences_1 = [string]

# 关键修复:将运行逻辑放入 if __name__ == '__main__':
if __name__ == '__main__':
    output_1 = model.encode(sentences_1, return_dense=True, return_sparse=True, return_colbert_vecs=False)
    
    # 后续的数据处理逻辑
    dense_vecs = output_1['dense_vecs'].tolist()
    lexical_weights = output_1['lexical_weights'][0]
    
    # 处理稀疏向量的权重,确保可以被 JSON 序列化
    regular_dict = {}
    for key, value in lexical_weights.items():
        regular_dict[key] = float(value)
    
    # 构建最终的响应字典
    response_dict = {}
    response_dict['dense_vecs'] = dense_vecs
    response_dict['lexical_weights'] = regular_dict
    
    # 打印 JSON 字符串
    print(json.dumps(response_dict))

运行结果:

与传统稀疏向量提取方法对比(BM25)

于中文而言,基于bge的tokenizer会将词切的更细。例如:

example: 已经腊月二十九了,嘉靖三十九年入冬以来京师地面和邻近数省便没有下过一场雪

result : ‘已经’ ‘腊’ ‘月’ **‘二十’ ‘九’ ‘了’ ‘,’ ‘嘉’ ‘靖’ ‘三’ ‘十九’ ‘年’ ‘入’ ‘冬’ ‘以来’ ‘京’ ‘师’ ‘地面’ ‘和’ ‘邻’ ‘近’ **‘数’ ‘省’ ‘便’ ‘没有’ ‘下’ ‘过’ ‘一场’ ‘雪’

可以明显看出,很多词语在中文语境中并不该拆分,例如”腊月“、”邻近“…

结论:这种切词方法在稠密向量提取中,能带来较好的效果,但不适用基于词频统计的稀疏向量中。这种操作可能造成语义的丢失