LangChain+LLM实战---Embedding、从入门到生产使用

news2024/11/27 0:38:51

搜索功能已经深入到我们的日常生活中,我们常说“Google一下就知道了”,用户已经开始期望几乎每个应用程序和网站都提供某种类型的搜索功能。随着有效搜索变得越来越相关(双关语),寻找新的方法和体系结构来改进搜索结果对于架构师和开发人员来说至关重要。从基础开始,这篇博文将描述Redis中利用深度学习模型创建的向量Embeddings的人工智能搜索功能。

向量Embedding

什么是向量Embedding?简单地说,向量Embedding是可以表示许多类型数据的数字列表。

向量Embedding非常灵活。音频、视频、文本和图像都可以表示为矢量Embedding。这种特性使得向量Embedding成为数据科学家工具箱中的瑞士军刀。

Embedding creation process

从不同类型的数据创建向量Embedding的过程:音频,文本,视频。

为了解释为什么Embedding提供了这样的实用程序,让我们看一下以前处理文本数据(如表格数据中的分类值)的方法。数据科学家有时会使用one-hot编码等方法将分类特征转换为数值。这些编码将为每种类型的类别创建一个列。值为1表示项目属于该列指定的类别。相反,值为0表示项目不属于该类别。

例如,考虑书籍类型:“小说”、“非小说”和“传记”。每一种体裁都可以编码成一个热向量,然而,这样的向量会非常稀疏,因为书籍通常只属于两个体裁。下图显示了这种编码是如何工作的。注意这里0的数量是1的两倍。对于像图书类型这样的类别,随着更多的类型被添加到数据集中,这种稀疏性将会呈指数级恶化。

稀疏性会给ML模型带来挑战。对于每一种新的类型,编码表示的大小都会增长,因此数据集的计算成本会变得很高。

One-hot encoding example

One-hot(独热)编码示例

对于图书类型,或者任何具有相对较少类别的分类数据,我们可以使用简单的one-hot编码,但是,对于整个英语语言呢?对于这种规模的语料库,这种编码方法将变得不切实际。

进入向量Embedding

向量Embedding呈现固定大小的表示,不随数据中观测值的数量而增长。由模型创建的结果向量,通常是384个浮点值,比其他编码方法(如one-hot编码)的表示密度要高得多。这意味着在更少的字节中存在更多的信息,因此在计算上的利用成本更低。正如您稍后将读到的,这些密集表示可以用于多种目的,例如反向图像搜索、聊天机器人、问答和推荐系统。

创建向量Embedding

为了理解向量Embedding是如何创建的,对现代深度学习模型的简要介绍是有帮助的。

机器学习模型不使用非结构化数据。为了使模型能够理解文本或图像,我们必须将它们转换为数字表示。在机器学习之前,这样的表示通常是通过Feature Engineering“手工”创建的。

随着深度学习的出现,复杂数据中的非线性特征交互是由模型学习而不是人工设计的。当一个输入遍历深度学习模型时,该输入数据的新表示将以不同的形状和大小创建。每一层通常关注输入的不同方面。深度学习的这一方面,从输入中“自动”生成特征表示,构成了如何创建向量Embedding的基础。

例如,考虑在ImageNet数据集上训练的著名的ResNet模型。ResNet是一种卷积神经网络(CNN),通常用于与图像相关的任务。在这种情况下,ResNet被训练来预测图像中的对象属于1000个类中的哪一个。

在训练过程中,ResNet将捕获图像中存在的特征信息,通过将图像传递给多个卷积层、池化层和完全连接层。这些图层将捕获边缘、线条和角等特征,并将它们分组到传递给下一个图层的“桶”中。由于CNN的空间不变特性,无论边缘或直线出现在图像的哪个位置,这些特征都将始终映射到相同的桶。这些层将通过模型的层变得越来越小,直到一个由1000个浮点值组成的完全连接的层作为输出。每个值代表1000个类中的1个。该值越高,图像中的对象属于该类的概率就越大。

Diagram of a simple Convolutional Neural Network (CNN)

简单卷积神经网络(CNN)示意图

ResNet和其他类似的图像分类模型回答了这个问题:“这个图像中是什么类型的对象?”然而,这些分类在回答诸如“哪些图像与此图像相似?”之类的prompts时用处不大。对于这个问题,我们需要一起比较图像。尽管没有专门针对这项任务进行训练,ResNet仍然很有用,因为它可以捕获图像的密集表示。

简单地说,CNN和其他类似的模型学习有用的数据表示,以执行图像分类等任务。当输入通过模型的各个层时,可以提取这些表示。被提取的层,也称为潜在空间,通常是靠近模型输出的层。在上图中,这可能是包含768或500个隐藏单位的图层。提取的层或潜在空间提供了一个密集的表示,其中包含有关当前特征的信息,这对于视觉相似性搜索等任务在计算上是可行的。

这是向量Embedding。

存在大量的预训练模型,可以很容易地用于创建向量Embedding。Huggingface Model Hub (https://huggingface.co/models)包含许多模型,可以为不同类型的数据创建Embedding。例如,[all-MiniLM-L6-v2模型](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)是在线托管和运行的,不需要专业知识或安装。

sentence_transformers这样的包,也来自HuggingFace,为语义相似度搜索、视觉搜索等任务提供了易于使用的模型。要使用这些模型创建Embeddings,只需要几行Python代码:

1
2
3
4
5
6
7
8
9
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

sentences = [
  "That is a very happy Person",
  "That is a Happy Dog",
  "Today is a sunny day"
]
embeddings = model.encode(sentences)

语义相似度搜索的向量Embedding

语义相似搜索是将文本片段进行比较,以找出包含最相似含义的文本的过程。虽然这对普通人来说似乎很容易,但语言是相当复杂的。将非结构化文本数据提炼成机器学习模型可以理解的格式一直是许多自然语言处理研究人员的研究主题。

向量Embeddings为任何人提供了一种执行语义相似搜索的方法,而不仅仅是NLP研究人员或数据科学家。它们提供了一种有意义的、计算效率高的数字表示,可以通过预先训练的模型“开箱即用”来创建。下面是一个语义相似度的例子,它概述了用上面所示的sentence_transformers库创建的向量Embedding。

让我们看看下面的句子:

  • “That is a happy dog(那是一只快乐的狗)”
  • “That is a very happy person(那是一个非常幸福的人)”
  • “Today is a sunny day(今天是个晴天)”

这些句子中的每一个都可以转换成向量Embedding。下面是一个简化的表示,突出显示了这些示例句子在二维向量空间中相对于彼此的位置。这对于从视觉上衡量我们的Embedding如何有效地表示文本的语义意义非常有用。下文将详细介绍。

A simplified plot of vector embeddings projected into 2 dimensions.

向量Embeddings投影到二维的简化图

假设我们要将这些句子与“那是一个快乐的人”进行比较。首先,我们为查询语句创建向量Embedding。

1
2
3
4
5
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

# create the vector embedding for the query
query_embedding = model.encode("That is a happy person")

接下来,我们需要比较查询向量Embedding和数据集中的向量Embedding之间的距离。

有很多方法可以计算向量之间的距离。当涉及到语义搜索时,每种方法都有自己的优点和缺点,但我们将在另一篇文章中讨论。下面显示了一些常见的距离度量。

5-1

用于计算向量相似度的距离度量。

在这个例子中,我们将使用余弦相似度来度量两个向量的内积空间之间的距离。

Formula for Cosine Similarity

余弦相似度公式

在Python中,这看起来像

1
2
def cosine_similarity(a, b):
    return np.dot(a, b)/(norm(a)*norm(b))

在我们的查询向量和上图中的其他三个向量之间运行这个计算,我们可以确定句子之间的相似程度。

2D plot showing the cosine similarity between the vector embeddings created from our sentences earlier

2D图显示了之前从我们的句子中创建的向量Embeddings之间的余弦相似性

你可能已经猜到,“That is a very happy person(那是一个非常幸福的人)”和“That is a happy person(那是一个幸福的人)”是最相似的句子。这个例子只捕获了向量Embeddings的许多可能用例中的一个:语义相似搜索

下面列出了运行整个示例的Python代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import numpy as np

from numpy.linalg import norm
from sentence_transformers import SentenceTransformer

# Define the model we want to use (it'll download itself)
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

sentences = [
  "That is a very happy person",
  "That is a happy dog",
  "Today is a sunny day"
]

# vector embeddings created from dataset
embeddings = model.encode(sentences)

# query vector embedding
query_embedding = model.encode("That is a happy person")

# define our distance metric
def cosine_similarity(a, b):
    return np.dot(a, b)/(norm(a)*norm(b))

# run semantic similarity search
print("Query: That is a happy person")
for e, s in zip(embeddings, sentences):
    print(s, " -> similarity score = ",
         cosine_similarity(e, query_embedding))

在安装NumPysentence_transformers之后,运行这个脚本应该会得到以下计算结果

1
2
3
4
5
>>> Query: That is a happy person

>>> That is a very happy person -> similarity score = 0.94291496
>>> That is a happy dog -> similarity score = 0.69457746
>>> Today is a sunny day -> similarity score = 0.25687605

该脚本的结果应该与所选模型在HuggingFace inference API上看到的结果一致。

HuggingFace inference API similarity results

HuggingFace推理API相似度结果

向量Embedding搜索在生产环境中的使用

开发和生产是两个不同的东西,在学习了更多之后,你可能会开始问这样的问题:

  • 我把这些向量存储在哪里?
  • API应该是什么样子?
  • 如何将其与过滤等传统搜索功能结合起来?

幸运的是,开发Redis的好人们决定为你找出这些问题,并将向量相似搜索(VSS)功能构建到现有的reresearch模块中。这基本上把Redis变成了一个低延迟的向量数据库。

Redis as a vector database

Redis是一个矢量数据库

VSS功能是作为reresearch模块的新功能而构建的。它允许开发人员像在Redis散列中存储任何其他字段一样轻松地存储向量。它提供了在大型向量空间中执行低延迟搜索所需的高级索引和搜索功能,通常分布在许多机器上的向量从数万到数亿不等。

Redis现在支持两种类型的向量索引:

  1. Flat
  2. 分级可导航小世界(HNSW)

以及3个距离度量:

  1. LP —— 欧几里得距离
  2. IP —— 内积
  3. cos —— 余弦相似度(如上图所示)

下面是一个使用redis -py在向量被加载到Redis后创建索引的例子。

1
2
3
4
5
6
7
8
9
10
11
12
from redis import Redis
from redis.commands.search.field import VectorField, TagField

def create_flat_index(redis_conn: Redis, number_of_vectors: int, distance_metric: str='COSINE'):

	image_field = VectorField("img_vector","FLAT", {
        "TYPE": "FLOAT32",
        "DIM": 512,
        "DISTANCE_METRIC": distance_metric,
        "INITIAL_CAP": number_of_vectors,
        "BLOCK_SIZE": number_of_vectors})
	redis_conn.ft().create_index([image_field])

索引只需要创建一次,当新的哈希值存储在Redis中时,索引会自动重新索引。在将向量加载到Redis中并创建索引之后,就可以为各种基于相似性的搜索任务形成和执行查询。

索引只需要创建一次,当新的哈希值存储在Redis中时,索引会自动重新索引。在将向量加载到Redis中并创建索引之后,就可以为各种基于相似性的搜索任务形成和执行查询。

更好的是,所有现有的reresearch功能,如文本、标签和基于地理的搜索,都可以与VSS功能协同工作。这被称为“混合查询”。对于混合查询,传统的搜索功能可以用作矢量搜索的预过滤器,这可以帮助限制搜索空间。

上面的索引创建函数(create_flat_index)可以很容易地通过添加新字段(如redis-py中的TagFieldTextField)来支持混合查询。

Redis VSS演示

最近,我构建了一个web应用程序来探索这些功能。Fashion Product Finder利用了Redis中新的VSS功能,以及我最喜欢的Redis生态系统的其他部分,如redis-om-python。您可以访问应用程序在这里。

注册使用该应用程序后,您将看到如下所示的页面。

Fashion Product Finder application

时尚产品查找应用程序,使用由Redis提供的向量相似度搜索

要通过文本表示查询类似的产品,请找到您喜欢的产品并单击by text。同样,要通过视觉向量搜索查询,请单击产品上的by Image按钮。

可以为产品的性别和类别设置混合搜索属性,以便在执行矢量搜索时,返回的项目将通过这些标记进行过滤。下面是选择右下角黑色手表时的视觉向量搜索示例。

Fashion Product Finder search results

通过图片查询类似手表后的搜索结果为黑色G-Shock手表。

这个演示是一种探索Redis VSS功能的有趣方式,然而,这并不是应用程序中使用的Redis生态系统的唯一组件。事实上,Redis是这个应用程序使用的唯一数据库,用RedisJSON存储产品元数据,用RediSearch存储矢量数据。

您可以查看整个代码库在这里。如果你觉得有用,请点赞和分享!

有关Redis和reresearch模块中VSS的更多信息,您可以查看以下资源:

参考文档

  • VSS Documentation
  • [Redis Stack Documentation](https://partee.io/2022/08/11/vector-embeddings/Redis Stack docuemntation)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue-SplitPane可拖拽分隔面板(随意拖动div)

npm install vue-splitpane一、使用 (1)局部使用: 在vue文件中 import splitPane from vue-splitpane export default {componnets: { splitPane } }(2)全局使用: 在main.js文件注册 import splitPane…

openGauss学习笔记-116 openGauss 数据库管理-设置数据库审计-审计概述

文章目录 openGauss学习笔记-116 openGauss 数据库管理-设置数据库审计-审计概述116.1 背景信息116.2 操作步骤 openGauss学习笔记-116 openGauss 数据库管理-设置数据库审计-审计概述 116.1 背景信息 数据库安全对数据库系统来说至关重要。openGauss将用户对数据库的所有操作…

放卷开环张力控制(伺服转矩模式应用)

收放卷张力开环闭环控制算法,请参考下面文章链接: PLC张力控制(开环闭环算法分析)_RXXW_Dor的博客-CSDN博客文章浏览阅读4k次,点赞3次,收藏3次。里工业控制张力控制无处不在,也衍生出很多张力控制专用控制器,磁粉制动器等,本篇博客主要讨论PLC的张力控制相关应用和算…

leetcode:2926. 平衡子序列的最大和 【树状数组维护最大前缀和】

题目链接 lc2926 题目描述 题目思路 定义b[i] nums[i] - i 目标是从b中找到一个非降子序列使得元素和最大 # b[i] nums[i] - i # 找到b的一个非降子序列使得元素和最大 # f[i]: 子序列最后一个数下标是i,对应的最大子序列 # f[i] max (max f[j], 0) nums[i] …

【2023Q3_技术考核经验】

单选题: 1.下列有关影刀全局变量的概念说法错误的是:© B.和流程参数一样,只有事先给全局变量赋值,全局变量才可以用到其他流程当中去 C.全局变量适合用在变量值频繁更换的场景 解释:在右下角设置全局变量&#x…

本地电脑监控软件

本地电脑监控软件是一种用于监控计算机使用行为的软件,它可以帮助企业管理者了解员工的工作状态和行为,保护企业的计算机资源。 本地电脑监控软件可以监控员工的计算机使用行为,包括屏幕监控、键盘记录、文件操作等。这些功能可以帮助企业管理…

ansible安装和常见模块

文章目录 ansible的安装1.1 yum install epel-release.noarch1.2配置epel源的baseurl1.3安装ansible1.4安装ansible报错问题1.5 yum卸载 ansible的安装 ansible是由epel源提供的,所以需要配置epel源。要么通过配置好的baseos源直接执行“yum install epel-release.…

LabelImg使用笔记

LabelImg使用笔记 文章目录 LabelImg使用笔记一、LabelImg简介1.1、特性1.2、LabelImg的热键 二、LabelImg安装三、3种格式的使用3.1、VOC格式标注3.2、yolo格式标注3.3、json格式 四、LabelMe 和 LabelImg适用场景 一、LabelImg简介 LabelImg 是一个用于图像标注的开源工具&a…

vuepress 打包后左侧菜单链接 404 问题解决办法

背景 上周看到一本开源书 《深入架构原理与实践》,是基于 vuepress 搭建的,下载了源码,本地部署了一下,本文记录如何打包该源码遇到的路径问题及思考。 结论: vuepress 插件的 sideBar 的菜单路径默认是相对 / 的&am…

Python学习笔记--类的继承

七、类的继承 1、定义类的继承 说到继承,你一定会联想到继承你老爸的家产之类的。 类的继承也是一样。 比如有一个旧类,是可以算平均数的。然后这时候有一个新类,也要用到算平均数,那么这时候我们就可以使用继承的方式。新类继…

牛客出bug(华为机试HJ71)

Hj71:字符串通配符 描述 问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。 要求: 实现如下2个通配符: *:匹配0个…

318. 最大单词长度乘积

318. 最大单词长度乘积 难度: 中等 来源: 每日一题 2023.11.06 给你一个字符串数组 words ,找出并返回 length(words[i]) * length(words[j]) 的最大值,并且这两个单词不含有公共字母。如果不存在这样的两个单词,返回 0 。 示例 1&…

新版Helix QAC 100%覆盖MISRA C++:2023

Helix QAC 2023.3预期将100%覆盖在2023年第四季度发布的新的MISRA C:2023规则。 此外,该版本支持更多的C20语言特性,并改进了Perforce Validate平台和Helix QAC与Validate的集成,以及其他质量改进。 编码标准覆盖率(MISRA C:202…

JDK设置编码格式UTF-8

Windows中安装的JDK默认编码格式是GBK 需要修改为UTF-8.在系统中添加系统变量 环境变量 变量名:JAVA_TOOL_OPTIONS 变量值:-Dfile.encodingUTF-8

UE问题盘点

打包后运行时应用程序崩溃 GPU崩溃(Timed out waiting for RenderTread after 120.00 secs) 分析&解决: 像素流送模式,部署机无显示器无分辨率所致(接显示器或显卡欺骗器)项目设置Targeted RHIs为Di…

七种事务传播行为,核心只有Required默认和required_new

事务的概念:当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。 结论:一般情况下,你就用默认的把两个事务合并成一个事务,只有当写日志(事物之间不互相影响)的时候用req…

部署kubevirt教程

前提条件 已安装:kubernetes集群、kubectl、docker apt install -y qemu-kvm libvirt virt-install bridge-utils 【所有节点全部安装】 virt-host-validate qemu部署kubevirt 下载kubevirt-cr.yaml和kubevirt-operator.yaml 先执行: Kubectl apply …

大型企业效率革命:从数字化应用提升到信息化管理平台升级-亿发

数字化转型本质上是一场企业效率的革命,它以连接效率、数据效率和决策效率为核心。所有的转型活动都与人的参与和贡献紧密相关。因此,如何利用数字化手段提升全体员工的数字化应用能力,从而加速商业创新和实现高质量发展,成为管理…

Python武器库开发-常用模块之re模块(十八)

常用模块之re模块(十八) 在Python中需要通过正则表达式对字符串进⾏匹配的时候,可以使⽤⼀个python自带的模块,名字为re模块 我们可以在Python中使用以下的语句,导入re模块: import re正则表达式的大致匹配过程是: …

mybatis在springboot当中的使用

1.当使用Mybatis实现数据访问时,主要: - 编写数据访问的抽象方法 - 配置抽象方法对应的SQL语句 关于抽象方法: - 必须定义在某个接口中,这样的接口通常使用Mapper作为名称的后缀,例如AdminMapper - Mybatis框架底…