Embedding模型部署及效果评测

最近大模型发展迅速,与之对应的向量化需求也被带动起来了,由此社区也衍生出很多模型,本文选几款,简单做下评测。

前置概念

为方便读者,先简单介绍几个概念。

概念1:Vector Embedding

也即向量化嵌入,举个例子:

想象一下,你是一位市场研究员,职责是分析消费者的购买行为,并为你的客户提供针对性的营销策略。在你的数据库中,有成千上万的消费者交易记录,每条记录都包含了消费者的个人信息、购买的商品、购买的时间和地点等信息。

在没有Vector Embedding的情况下,如果你想找出哪些消费者可能对新产品感兴趣,你可能需要手动查看每条交易记录,然后根据消费者的购买历史和商品的特点来进行判断。然而,这种方法可能忽略了消费者的其他重要特征,如他们的收入水平、兴趣爱好、生活方式等,导致分析的结果不够准确。

现在引入Vector Embedding,此时你就可以将每位消费者的个人信息和购买历史转化为一个多维的“消费者画像向量”。这个向量不仅包括了消费者的基本信息和购买历史,还包含了他们的收入水平、兴趣爱好、生活方式等各个方面的元素。换句话说,这些信息能反映出消费者的复杂特征。例如,一位经常购买高端护肤品的消费者画像向量,大概率与追求高品质生活的向量相近,而一位经常购买户外运动装备的消费者画像向量,大概率与追求健康生活方式和热爱自然的向量相近。此时,若想找出哪些消费者可能对新产品感兴趣,只需要计算出新产品的向量,并与大量消费者画像的向量进行对比,即可快速筛选出潜在的目标客户(目标客户的向量相似度高)。这个过程不再需要逐个查看消费者的个人信息和交易记录,大大简化了数据的处理过程。

更深入的概念可阅读附录[1]进行学习。

概念2:文档切分中的Chunk和Overlap

在处理较长文档或文本时,将其分割成若干小块,每块称为一个Chunk。在这个特定的切分策略中,每个Chunk由最多N个Token组成。Token通常指文本中的单词或符号,取决于具体语境。而Overlap是相邻Chunk之间共有的Token数。举个例子:

每Chunk 200 Token,Overlap 20在这个例子中,每个Chunk由最多200个Token组成。Overlap为20,意味着相邻的Chunks会有20个Token是重复的,从而确保文本的连贯性。例如,如果某个文本段落共有230个Token,它将被分成两个Chunks:第一个Chunk将有200个Token,第二个Chunk将有30个Token(因为230-200=30),并且这两个Chunks之间将有20个Token重叠。

这种切分方式有助于确保在将长文档送入诸如大型语言模型进行Embedding或处理时,能够保持文本的语义连贯性,同时又能满足模型处理长度有限的输入的要求。切分文档时考虑Chunk的大小和Overlap的数量,对于提高模型处理效率和文本的语义理解都是十分重要的。

模型调研

与大模型类似,Embedding也是使用模型来实现的,只不过Embedding模型更为轻量。一般都在2G以内。经调研(附录[6~10]),发现以下模型对中文的支持效果较好,且已经开源方便本地私有化部署:图片

可以看得出m3模型的优势是支持多语言,并且字符数扩展到了8192,这意味着BGE-M3能够高效地处理长篇幅的文档,满足对于长文档检索的需求。

以上几类模型的链接请参考附录[2~5],下文针对这几种模型进行效果评测。

模型部署

为了部署Embedding模型,我们需要引入对应的工具库,目前主要有几类:

  1. Sentence-Transformers: Sentence-Transformers库是基于HuggingFace的Transformers库构建的,它专门设计用于生成句子级别的嵌入。它引入了一些特定的模型和池化技术,使得生成的嵌入能够更好地捕捉句子的语义信息。Sentence-Transformers库特别适合于需要计算句子相似度、进行语义搜索和挖掘同义词等任务。
  2. HuggingFace Transformers: HuggingFace的Transformers库是一个广泛使用的NLP库,它提供了多种预训练模型,如BERT、GPT-2、RoBERTa等。这些模型可以应用于各种NLP任务,如文本分类、命名实体识别、问答系统等。Transformers库支持多种编程语言,并且支持模型的微调和自定义模型的创建。虽然Transformers库的功能强大,但它主要关注于模型的使用,而不是直接提供句子级别的嵌入。
  3. Langchain集成的HuggingFaceBgeEmbeddings。与3一样。
  4. FlagEmbedding: 这是一个相对较新的库,其核心在于能够将任意文本映射到低维稠密向量空间,以便于后续的检索、分类、聚类或语义匹配等任务。FlagEmbedding的一大特色是它可以支持为大模型调用外部知识,这意味着它不仅可以处理纯文本数据,还能整合其他类型的信息源,如知识图谱等,以提供更丰富的语义表示。

总的来说,FlagEmbedding强调的是稠密向量的生成和外部知识的融合;HuggingFace Transformers提供了一个广泛的预训练模型集合,适用于多种NLP任务;而Sentence-Transformers则专注于生成高质量的句子嵌入,适合那些需要深入理解句子语义的应用场景。

结合上述说明,以及翻阅网上各类文章,发现使用 Sentence-Transformers 居多,因此本文选用它。

安装 sentence-transformers(在Linux机器安装吧,Windows机器各种报错):

pip install -U sentence-transformers

基于Sentence-Transformers的向量化方法:
在这里插入图片描述

上面的例子演示了句子的向量化过程。额外解释一下倒数第二行:

embeddings_1 @ embeddings_2.T 是 Python 中的一种矩阵乘法运算。这里使用了 @ 符号来表示矩阵的点积(dot product)操作。具体来说:

  • embeddings_1 是一个二维数组(或称为矩阵),其中每一行代表一个句子在向量空间中的嵌入表示。
  • embeddings_2 也是一个二维数组,其结构与 embeddings_1 相同,但包含不同的句子的嵌入表示。
  • embeddings_2.Tembeddings_2 的转置,这意味着将它的行列互换。这样,原来的每行变成了每列,原来的每列变成了每行。

当执行 embeddings_1 @ embeddings_2.T 时,Python 会计算两个矩阵的点积。结果是一个新的二维数组,其中的每个元素是 embeddings_1 中的一行和 embeddings_2.T 中对应列的乘积之和。在这个上下文中,它实际上是在计算两组句子嵌入之间的相似度矩阵。

例如,如果 embeddings_1embeddings_2.T 分别是以下的矩阵:

在这里插入图片描述

那么点积的结果将是:

在这里插入图片描述

这个结果矩阵中的每个元素代表了原始句子对之间的某种形式的相似度分数。

有了工具集后,把模型文件下载到本地并加载即可。

评测方法

到网上随便找一篇文章:

据传,菜煎饼起源于13世纪中期,当时明军与元军在峄州展开激战,当地人民死伤惨重。后来,从山西洪洞一带移民至此的民众,仅靠官府发放的半斤粮食无法充饥,便将五谷掺水,用石磨研磨成浆糊,放在铁板上,用竹片摊成“薄纸”,并大量包装蔬菜、野菜、草根和树叶,以此充饥。

菜煎饼是山东鲁南地区的一种大众食品,制作原料主要有面粉、杂粮、鸡蛋等,老少兼宜,俗称“中国热狗”,流行于枣庄、济宁、临沂、徐州等鲁南地,后传布周围省市。上个世纪七十年代,枣庄农村的生活还是很匮乏的,老百姓的主食以煎饼为主,煎饼的主要原料是地瓜干,条件好一点的可稍放点小麦,刚烙煎饼时鏊子凉,需把鏊子烧热擦些油才容易把煎饼从鏊子上揭下来,这样烙出的煎饼就很厚,稍等一会儿,煎饼凉了又板又硬,很难下咽。因此我们枣庄人把烙煎饼时前几张和后几张煎饼称为滑鏊子煎饼或滑塌子。这样的煎饼很难下咽,但丢了又可惜,精明的母亲们就将大白菜,土豆丝,粉条,豆腐切碎加点猪油,放上辣椒面,花椒面和盐,做成了所谓的菜煎饼,这样一来不但滑鏊子煎饼解决了,并且做出的煎饼还特别好吃,这样一传十、十传百,于是菜煎饼就在农村各家各户传开了!

八十年代末期,农村土地实行了联产承包责任制已有多年,农民在农忙季节忙耕种,农闲时便有了剩余时间,有的农村妇女就到街上摆地摊卖菜煎饼挣点零花钱。一辆三轮车,一盘小饼鍪,一个蜂窝炉,一个切菜板,几样时令蔬菜,食客现场点菜,业主现场烙制,简简单单的营生,成为枣庄街头一道风景。许许多多的农村人多了一个贴补家用的挣钱机会,人们生活也多了一道风味小吃。到了九十年代末期,就连一些男人也走上了街头卖起了菜煎饼。

1993年5月,山东省劳动厅在枣庄举办特级厨师培训班,聘请江苏省淮安商业技工学校一行6人赴枣庄讲学,这六人当中有校领导、高级讲师、特级厨师,途中经台儿庄区招待所午餐,席上菜肴丰盛,但惟有“菜煎饼”被其六人齐呼:“天下第一美食”。

山东菜煎饼如何做呢?首先要热锅,放油(油要多),下豆腐中火翻炒至金黄,放入之前切好的粉条,继续翻炒几分钟,加入适量的盐。再放入切好的韭菜,翻炒几下搅匀即可(千万不可炒过了,韭菜要生生的),撒味精出锅。将煎饼摊开,用勺子舀上适量的韭菜馅儿,用勺背整匀。好了之后,可以将两边向中间折叠形成长方形,一张煎饼就做好了。

按照前文的样例,写一段脚本进行评测(为方便演示,简单地根据段落进行拆分):

import sys
import torch
from sentence_transformers import SentenceTransformer# 加载预训练的句子嵌入模型
model = SentenceTransformer(sys.argv[1])
# 定义句子列表
sentences_1 = ["据传,菜煎饼起源于13世纪中期,当时明军与元军在峄州展开激战,当地人民死伤惨重。后来,从山西洪洞一带移民至此的民众,仅靠官府发放的半斤粮食无法充饥,便将五谷掺水,用石磨研磨成浆糊,放在铁板上,用竹片摊成“薄纸”,并大量包装蔬菜、野菜、草根和树叶,以此充饥。"]
sentences_2 = ["菜煎饼是山东鲁南地区的一种大众食品,制作原料主要有面粉、杂粮、鸡蛋等,老少兼宜,俗称“中国热狗”,流行于枣庄、济宁、临沂、徐州等鲁南地,后传布周围省市。上个世纪七十年代,枣庄农村的生活还是很匮乏的,老百姓的主食以煎饼为主,煎饼的主要原料是地瓜干,条件好一点的可稍放点小麦,刚烙煎饼时鏊子凉,需把鏊子烧热擦些油才容易把煎饼从鏊子上揭下来,这样烙出的煎饼就很厚,稍等一会儿,煎饼凉了又板又硬,很难下咽。因此我们枣庄人把烙煎饼时前几张和后几张煎饼称为滑鏊子煎饼或滑塌子。这样的煎饼很难下咽,但丢了又可惜,精明的母亲们就将大白菜,土豆丝,粉条,豆腐切碎加点猪油,放上辣椒面,花椒面和盐,做成了所谓的菜煎饼,这样一来不但滑鏊子煎饼解决了,并且做出的煎饼还特别好吃,这样一传十、十传百,于是菜煎饼就在农村各家各户传开了!"]
sentences_3 = ["八十年代末期,农村土地实行了联产承包责任制已有多年,农民在农忙季节忙耕种,农闲时便有了剩余时间,有的农村妇女就到街上摆地摊卖菜煎饼挣点零花钱。一辆三轮车,一盘小饼鍪,一个蜂窝炉,一个切菜板,几样时令蔬菜,食客现场点菜,业主现场烙制,简简单单的营生,成为枣庄街头一道风景。许许多多的农村人多了一个贴补家用的挣钱机会,人们生活也多了一道风味小吃。到了九十年代末期,就连一些男人也走上了街头卖起了菜煎饼。"]
sentences_4 = ["1993年5月,山东省劳动厅在枣庄举办特级厨师培训班,聘请江苏省淮安商业技工学校一行6人赴枣庄讲学,这六人当中有校领导、高级讲师、特级厨师,途中经台儿庄区招待所午餐,席上菜肴丰盛,但惟有“菜煎饼”被其六人齐呼:“天下第一美食”。"]
sentences_5 = ["山东菜煎饼如何做呢?首先要热锅,放油(油要多),下豆腐中火翻炒至金黄,放入之前切好的粉条,继续翻炒几分钟,加入适量的盐。再放入切好的韭菜,翻炒几下搅匀即可(千万不可炒过了,韭菜要生生的),撒味精出锅。将煎饼摊开,用勺子舀上适量的韭菜馅儿,用勺背整匀。好了之后,可以将两边向中间折叠形成长方形,一张煎饼就做好了。"]
# 获取句子的嵌入向量表示、
sentences_embeddings_1 = torch.from_numpy(model.encode(sentences_1, normalize_embeddings=True))
sentences_embeddings_2 = torch.from_numpy(model.encode(sentences_2, normalize_embeddings=True))
sentences_embeddings_3 = torch.from_numpy(model.encode(sentences_3, normalize_embeddings=True))
sentences_embeddings_4 = torch.from_numpy(model.encode(sentences_4, normalize_embeddings=True))
sentences_embeddings_5 = torch.from_numpy(model.encode(sentences_5, normalize_embeddings=True))
# 合并所有的句子嵌入表示
all_sentences_embeddings = torch.cat([sentences_embeddings_1, sentences_embeddings_2, sentences_embeddings_3, sentences_embeddings_4, sentences_embeddings_5], dim=0)# 定义查询句子
queries_1 = ["菜煎饼的制作原料有哪些?"]
queries_2 = ["菜煎饼的组成是什么?"]
queries_3 = ["做菜煎饼需要什么?"]
# 获取查询句子的嵌入向量表示
queries_embeddings_1 = torch.from_numpy(model.encode(queries_1, normalize_embeddings=True))
queries_embeddings_2 = torch.from_numpy(model.encode(queries_2, normalize_embeddings=True))
queries_embeddings_3 = torch.from_numpy(model.encode(queries_3, normalize_embeddings=True))# 计算查询句子与所有句子的相似度
similarity_queries_1_sentences = queries_embeddings_1 @ all_sentences_embeddings.T
similarity_queries_2_sentences = queries_embeddings_2 @ all_sentences_embeddings.T
similarity_queries_3_sentences = queries_embeddings_3 @ all_sentences_embeddings.T# 打印numpy size
print("sentences_vector dimension:", sentences_embeddings_1.size())
print("sentences_vector dimension:", queries_embeddings_1.size())
# 打印相似度结果(几个问题都是在问制作原料,从字面来看,我们预期三个查询与sentences_2 和 sentences_5 的相似度较高)
print("Query 1 Similarity:", similarity_queries_1_sentences)
print("Query 2 Similarity:", similarity_queries_2_sentences)
print("Query 3 Similarity:", similarity_queries_3_sentences)

在这里插入图片描述

其中的time是为了测试程序运行耗时。

评测结果

作者在本机CPU执行,机器配置为:4核CPU(i7)、16GB内存。

评测结果如下:

图片

看起来,bge-m3效果最好,tao-8k也不错。但需要注意的是,这两个模型执行耗时也最高。

总结

本文选用常见的几类中文友好的开源Embedding模型进行了简单效果评测,发现bge-m3和tao-8k的效果不错。有条件的读者可以将其部署在GPU上进行评测,应该会更快。另外,也可以使用更为全面的数据集进行评估,以得出更为权威的结论。

在实际的生产环境中,还要进行压力测试,以评估文档向量化的性能。

如何学习AI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/465237.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RDMA驱动学习(二)- command queue

为了实现用户对网卡硬件的配置,查询,或者执行比如create_cq等命令,mellanox网卡提供了command queue mailbox的机制,本节将以create_cq为例看下这个过程。 command queue(后续简称cmdq)是一个4K对齐的长度…

在docker里创建 bridge 网络联通不同容器

1.网络创建: docker network create --subnet192.168.1.0/24 --gateway192.168.1.1 uav_management 2.查看网络: docker network ls 3.给已经创建的容器分配ip: docker network connect --ip 192.168.1.10 uav_management 容器名/容器id 示例&#xf…

影响神经网络速度的因素- FLOPs、MAC、并行度以及计算平台

影响神经网络速度的四个主要因素分别是 FLOPs(浮点操作数)、MAC(内存访问成本)、并行度以及计算平台。这些因素共同作用,直接影响到神经网络的计算速度和资源需求。 1. FLOPs(Floating Point Operations&a…

基于STM32单片机太阳能充电循迹避障小车

本设计基于STM32单片机太阳能充电循迹避障小车,以STM32单片机为微控制器核心,在太阳能板对车载电池充电情况下配合传感器能够实现循迹避障行驶的小车的设计过程。小车采用3.7V锂电池作为电源,太阳能板接入TP4056充电模块,使用MT36…

高效集成金蝶云星空销售出库单的解决方案

审核销售出库单(金蝶->金蝶)集成方案 在企业日常运营中,销售出库单的审核是一个关键环节。为了确保数据的准确性和及时性,我们采用了轻易云数据集成平台,将金蝶云星空系统中的销售出库单数据无缝集成到另一个金蝶云星空系统中。本次案例将…

SpringBoot中使用RESTful风格

文章目录 SpringBoot中使用RESTful风格一、引言二、SpringBoot与RESTful风格1、RESTful风格简介2、SpringBoot中的RESTful注解2.1、代码示例 三、SpringBoot核心配置四、总结 SpringBoot中使用RESTful风格 一、引言 在现代Web开发中,RESTful架构风格因其简洁性和易…

DAY21|二叉树Part08|LeetCode: 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

目录 LeetCode: 669. 修剪二叉搜索树 基本思路 C代码 LeetCode: 108.将有序数组转换为二叉搜索树 基本思路 C代码 LeetCode: 538.把二叉搜索树转换为累加树 基本思路 C代码 LeetCode: 669. 修剪二叉搜索树 力扣代码链接 文字讲解:LeetCode: 669. 修剪二叉搜…

ubuntu20.04安装ros与rosdep

目录 前置配置 配置apt清华源 配置ros软件源 添加ros安装源(中科大软件源) 设置秘钥 更新源 ros安装 安装ros 初始化 rosdep 更新 rosdep 设置环境变量 安装 rosinstall 安装验证 启动海龟仿真器 操控海龟仿真器 rosdep安装更新 安装 使用…

高亚科技签约酸动力,助力研发管理数字化升级

近日,中国企业管理软件资深服务商高亚科技与广东酸动力生物科技有限公司(以下简称“酸动力”)正式签署合作协议。借助高亚科技的8Manage PM项目管理软件,酸动力将进一步优化项目过程跟踪与节点监控,提升研发成果的高效…

CSRF与SSRF

csrf(跨站请求伪造)的原理: csrf全称是跨站请求伪造(cross-site request forgery),也被称为one-click attack 或者 session riding scrf攻击利用网站对于用户网页浏览器的信任,劫持用户当前已登录的web应用程序,去执行分用户本意的操作。 利…

享元模式-实现大颗粒度对象缓存机制

详解 享元模式是一种结构型设计模式,其主要目的是通过共享尽可能多的相同部分来有效地支持大量细粒度的对象。它通过将对象的属性分为内在属性(可以共享、不随环境变化的部分)和外在属性(根据场景变化、不能共享的部分&#xff0…

HTML 基础标签——结构化标签<html>、<head>、<body>

文章目录 1. <html> 标签2. <head> 标签3. <body> 标签4. <div> 标签5. <span> 标签小结 在 HTML 文档中&#xff0c;使用特定的结构标签可以有效地组织和管理网页内容。这些标签不仅有助于浏览器正确解析和渲染页面&#xff0c;还能提高网页的可…

新华三H3CNE网络工程师认证—VLAN的配置

VLAN&#xff08;虚拟局域网&#xff09;是一种在逻辑上划分网络的技术&#xff0c;它可以将一个物理网络分割成多个虚拟网络&#xff0c;从而实现不同组的设备之间的隔离。在配置VLAN时&#xff0c;通常涉及到三种端口类型&#xff1a;Access、Trunk和Hybrid。Access端口用于连…

R语言*号标识显著性差异判断组间差异是否具有统计意义

前言 该R代码用于对Iris数据集进行多组比较分析&#xff0c;探讨不同鸢尾花品种在不同测量变量&#xff08;花萼和花瓣长度与宽度&#xff09;上的显著性差异。通过将数据转换为长格式&#xff0c;并利用ANOVA和Tukey检验&#xff0c;代码生成了不同品种间的显著性标记&#x…

手边酒店多商户版V2源码独立部署_博纳软云

新版采用laraveluniapp开发&#xff0c;为更多平台小程序开发提供坚实可靠的底层架构基础。后台UI全部重写&#xff0c;兼容手机端管理。 全新架构、会员卡、钟点房、商城、点餐、商户独立管理

Multi Agents协作机制设计及实践

01 多智能体协作机制的背景概述 在前述博客中&#xff0c;我们利用LangChain、AutoGen等开发框架构建了一个数据多智能体的平台&#xff0c;并使用了LangChain的Multi-Agents框架。然而&#xff0c;在实施过程中&#xff0c;我们发现现有的框架存在一些局限性&#xff0c;这些…

ReactPress—基于React的免费开源博客CMS内容管理系统

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress 欢迎提出宝贵的建议&#xff0c;感谢Star。 ![ReactPress](https://i-blog.csdnimg.cn/direct/0720f155edaa4eadba796f4d96d394d7.png#pic_center ReactPress 是使用React开发的开源发布平台&…

如何在一个 Docker 容器中运行多个进程 ?

在容器化的世界里&#xff0c;Docker 彻底改变了开发人员构建、发布和运行应用程序的方式。Docker 容器封装了运行应用程序所需的所有依赖项&#xff0c;使其易于跨不同环境一致地部署。然而&#xff0c;在单个 Docker 容器中管理多个进程可能具有挑战性&#xff0c;这就是 Sup…

【JavaEE初阶 — 多线程】线程安全问题 & synchronized

目录 1. 什么是线程安全问题 (1) 观察线程不安全 (2) 线程安全的概念 2. 造成线程安全的原因 (1)线程调度的随机性 问题描述 解决方案 (2)修改共享数据&#xff06;原子性问题 问题描述 解决方案 3.synchronized 关键字 1. synchronized 的特性 (1) …

产品经理的重要性

一直觉得产品经理很重要&#xff0c;这几年写了好几篇和产品经理相关的思考。2020年写过对产品经理的一些思考的文章&#xff0c;2021年&#xff0c;写了一篇对如何分析项目的思考&#xff0c;2024年写了如何与PM探讨项目。 今天还想再写一篇&#xff0c;主要是最近很有感慨。…