如何构建LLM申请(三): 用于生成文本的各种嵌入模型

2024年03月11日 由 alex 发表 304 0

在上一篇文章中,我们学习了 RAG 的数据准备工作,其中包括数据导入、数据准备和分块。


由于我们需要在 RAG 中搜索相关的上下文块,因此我们必须将数据从文本格式转换为向量嵌入。


因此,我们将探索通过句子转换器转换文本的最有效方法。


1


嵌入模型

嵌入是一种单词表示法(使用数字向量),可以让含义相似的单词具有相似的表示法。


这些向量可以通过各种机器学习算法和大型文本数据集来学习。词嵌入的主要作用之一是为文本分类和信息检索等下游任务提供输入特征。


2


在过去的十年中,人们提出了几种单词嵌入方法,以下是其中的几种。


3


独立于上下文的嵌入

独立于上下文的嵌入重新定义了单词表示法,无论上下文如何变化,都能分配唯一的向量。本文将重点探讨其对同义词消歧的影响。


  • 独立于上下文的模型为每个单词分配不同的向量,与上下文无关。
  • 像 "duck "这样的同音词会获得一个单一向量,在没有上下文提示的情况下融合多种含义。
  • 这种方法产生了一个全面的单词向量图,以固定的表征方式捕捉多种含义。


4


与上下文无关的嵌入式技术提供了高效率,但对细微的语言理解,尤其是同音异义词的理解提出了挑战。这种模式的转变促使我们更仔细地研究自然语言处理中的权衡问题。


一些常见的基于频率的上下文无关嵌入:


  • 词袋

词袋会将所有句子中最常见的词编成词典,然后对句子进行编码,如下图所示。


5


  • TF-IDF

TF-IDF 是一种从句子中查找特征的简单技术。在计数特征中,我们对文档中的所有单词/词组进行计数,而在 TFIDF 中,我们只对重要的单词进行计数。我们如何做到这一点呢?如果你想到语料库中的一篇文档,我们将考虑该文档中任何单词的两个方面:


  • 词频: 该词在文档中的重要程度如何?


6


  • 反向文档频率: 术语在整个语料库中的重要程度?


7


8


一些常见的基于预测的上下文无关嵌入:


  • Word2Vec

Word2Vec 中的单词嵌入是通过双层神经网络学习的,在训练过程中会不经意地捕捉语言上下文。嵌入是算法主要目标的副产品,展示了这种方法的效率。Word2Vec 通过两种不同的模型架构提供灵活性: CBOW 和连续跳格。


连续词袋(CBOW):


  • 从周围上下文单词的窗口预测当前单词。
  • 强调上下文单词在预测目标单词时的协同影响。


连续跳格:

  • 使用当前单词预测周围的上下文单词。
  • 重点在于目标词在生成上下文词时的预测能力。


9


Word2Vec 的双模型架构在捕捉语言细微差别方面具有多功能性,允许从业人员根据自然语言处理任务的具体要求在 CBOW 和连续跳格之间做出选择。了解这些架构之间的相互作用,可以增强 Word2Vec 在不同语境中的应用。


10


  • GloVe(全球词表向量): GloVe 的优势在于它在训练过程中利用了来自语料库的全局词-词共现统计数据。由此产生的表征不仅囊括了语义关系,还揭示了词向量空间中有趣的线性子结构,从而增加了对词嵌入的理解深度。
  • FastText:与 GloVe 不同,FastText 采用了一种新颖的方法,将每个单词视为由字符 n-grams 组成。这一与众不同的特点使 FastText 不仅能学习罕见的单词,还能巧妙地处理词汇表之外的单词。对字符级嵌入的重视使 FastText 能够捕捉形态上的细微差别,从而提供更全面的词汇表示。


上下文相关的嵌入

上下文相关方法可根据上下文为同一个词学习不同的嵌入。


11


基于 RNN

  • ELMO(语言模型嵌入): 基于神经语言模型学习上下文化的单词表征,该模型具有一个基于字符的编码层和两个 BiLSTM 层。
  • CoVe(语境化单词向量): 使用为机器翻译而训练的注意序列到序列模型中的深度 LSTM 编码器,对单词向量进行上下文化处理。


基于变换器

  • BERT(来自变换器的双向编码器表征): 基于变换器的语言表征模型,在大型跨领域语料库中进行训练。该模型应用掩码语言模型来预测序列中随机掩码的单词,然后通过下一句预测任务来学习句子之间的关联。
  • XLM(跨语言语言模型): 它是一个使用下一个标记预测、类似 BERT 的屏蔽语言建模目标和翻译目标进行预训练的转换器。
  • RoBERTa(鲁棒性优化 BERT 预训练方法): 它以 BERT 为基础,修改了关键超参数,取消了下一句预训练目标,并使用更大的迷你批次和学习率进行训练。
  • ALBERT(用于语言表征自我监督学习的精简版 BERT): 它提出了减少参数的技术,以降低内存消耗并提高 BERT 的训练速度。


BERT

谷歌人工智能公司开发的自然语言处理利器 BERT(双向变换编码器表示法)重塑了语言模型的格局。将深入探讨预训练方法及其双向架构的复杂性。


  • 预训练: BERT 针对两项无监督任务进行了预训练--屏蔽语言建模(MLM)和下一句预测(NSP)。MLM 从输入中随机屏蔽部分(15%)词组,目标是仅根据上下文预测被屏蔽词的原始词汇 ID。
  • 除屏蔽语言模型外,BERT 还使用了 NSP 任务,对文本对表征进行联合预训练。许多重要的下游任务,如问题解答(QA)和自然语言推理(NLI),都是基于对两个句子之间关系的理解,而语言建模并不能直接捕捉到这种关系。
  • 预训练数据: 对于预训练语料库,我们使用书籍语料库(8 亿字)和英语维基百科(25 亿字)。
  • 双向性: 与从左到右的语言模型预训练不同,MLM 目标可使表征融合左右语境,从而使我们能够预训练一个深度双向转换器。


BERT 的架构由多个编码器层组成,每个编码器层对输入进行自我关注,并将其传递给下一层。即使是最小的变体 BERT BASE,也拥有 12 个编码器层、一个包含 768 个隐藏单元的前馈神经网络块和 12 个注意力头。


12


输入表示法

BERT 将由句子或句子对(如 < 问题,答案>)组成的序列作为输入序列,这些序列由一个标记序列组成,用于问题解答任务。


在将输入序列输入模型之前,先使用 WordPiece Tokenizer(词汇量为 30k 的标记化器)进行准备。它的工作原理是将一个词拆分成几个子词(标记)。


特殊标记包括:


  • [CLS] 用作每个序列的第一个标记。该标记对应的最终隐藏状态被用作分类任务的集合序列表示。
  • [SEP]句子对被打包成一个序列。我们用两种方法区分句子。首先,我们用一个特殊标记([SEP])将它们分开。其次,我们为每个标记添加一个学习嵌入,表明它属于句子 A 还是句子 B。
  • [PAD]用于表示输入句子中的填充(空标记)。该模型希望输入固定长度的句子。因此,根据数据集的不同,最大长度是固定的。较短的句子会被填充,而较长的句子则会被截断。为了明确区分真实标记和 [PAD] 标记,我们使用了注意力掩码。


我们引入了分段嵌入技术,以指示给定标记属于第一句还是第二句。位置嵌入则表示标记在句子中的位置。与最初的转换器相比,BERT 从绝对序数位置学习位置嵌入,而不是使用三角函数。


13


14


为了获得标记嵌入,嵌入层使用了一个嵌入查找表(如上图所示),其中行代表词汇表中所有可能的标记 ID(例如 30k 行),列代表标记嵌入的大小。


为什么是句子 BERT(S-BERT)而不是 BERT?

到目前为止,效果还不错,但这些转换器模型在构建句子向量时存在一个问题: 转换器使用单词或标记级嵌入,而不是句子级嵌入。


在使用句子转换器之前,使用 BERT 计算准确句子相似性的方法是使用交叉编码器结构。这意味着,我们会将两个句子传递给 BERT,在 BERT 的顶部添加一个分类头,并以此输出相似度得分。


BERT 交叉编码器结构由一个 BERT 模型组成,该模型处理句子 A 和 B。两者都以相同的顺序进行处理,并由[SEP]标记分隔。所有这些之后都是一个输出相似性分数的前馈神经网络分类器。


15


16


交叉编码器网络确实能产生非常准确的相似性得分(比 SBERT 更好),但它不具备可扩展性。如果我们想对一个 10 万个句子的小型数据集进行相似性搜索,就需要完成 10 万次交叉编码器推理计算。


为了对句子进行聚类,我们需要对 10 万个数据集中的所有句子进行比较,这样就需要进行近 5 亿次比较--这根本不现实。


理想情况下,我们需要预先计算句子向量,然后将其存储起来,在需要时使用。如果这些向量表示良好,我们所需要做的就是计算每个向量之间的余弦相似度。利用原始的 BERT(和其他转换器),我们可以通过平均 BERT 输出的所有标记嵌入值来构建句子嵌入(如果输入 512 个标记,则输出 512 个嵌入)。


或者,我们可以使用第一个 [CLS] 标记(BERT 特有的标记,其输出嵌入用于分类任务)的输出。


使用这两种方法中的一种,我们可以更快地存储和比较句子嵌入,将搜索时间从 65 小时缩短到 5 秒左右。但是,准确率并不高,比使用平均 GloVe 嵌入(2014 年开发)的准确率还低。


17


因此,使用 BERT 从 10K 个句子中找出最相似的句子对需要 65 个小时。而使用 SBERT,只需 5 秒钟就能创建嵌入模型,用余弦相似度进行比较只需 0.01 秒钟。


自 SBERT 论文发表以来,已经有更多的句子转换器模型利用训练原始 SBERT 的类似概念建立起来。它们都是在许多相似和不相似的句子对上训练出来的。


这些模型使用损失函数(如 softmax 损失、多重否定排序损失或 MSE margin 损失)进行优化,为相似句子生成相似的嵌入,反之则生成不相似的嵌入。


得出独立的句子嵌入是 BERT 的主要问题之一。为了解决这个问题,我们开发了 SBERT。


句子变换器


18


我们解释了 BERT 的句子相似性交叉编码器架构。SBERT 与之类似,但去掉了最后的分类头,而是一次处理一个句子。然后,SBERT 在最终输出层上使用均值池生成句子嵌入。


与 BERT 不同,SBERT 采用连体结构对句子对进行微调。我们可以将其理解为并行运行两个完全相同的 BERT,它们共享完全相同的网络权重。


19


实际上,我们使用的是一个 BERT 模型。不过,由于我们在训练过程中将句子 A 和句子 B 作为成对处理,因此更容易将其视为权重相同的两个模型。


连体 BERT 预训练


20


句子变换器的训练方法多种多样。我们将介绍在最初的 SBERT 论文中最突出的原始过程,该过程在 softmax-loss 上进行了优化。


softmax-loss 方法使用的是在斯坦福自然语言推理(SNLI)和多流派 NLI(MNLI)语料库上进行微调的 "siamese "架构。


SNLI 包含 570K 个句子对,MNLI 包含 430K 个句子对。这两个语料库中的句对都包含前提和假设。每对句子都有三种标签:


  • 0 - 必然性,例如前提暗示假设。
  • 1 - 中性,前提和假设都可能是真的,但它们之间没有必然联系。
  • 2 - 矛盾,前提和假设相互矛盾。


根据这些数据,我们将句子 A(假设前提)输入siamese BERT A,将句子 B(假设)输入siamese BERT B。


siamese BERT 输出我们的集合句子嵌入。在 SBERT 论文中,有三种不同的集合方法。它们分别是均值池法、最大值池法和 [CLS] 池法。在 NLI 和 STSb 数据集上,均值池方法的性能最好。


现在有两种句子嵌入。我们将嵌入式 A 称为 u,将嵌入式 B 称为 v。下一步是连接 u 和 v:


21


|u-v| 计算出两个向量的元素差。除了原始的两个嵌入向量(u 和 v),这些向量都会被输入一个前馈神经网络(FFNN),该网络有三个输出。


这三个输出与我们的 NLI 相似性标签 0、1 和 2 一致。我们需要计算 FFNN 的 softmax,这是在交叉熵损失函数中完成的。softmax和标签用于优化 "softmax-loss"。


22


请注意,softmax-loss 指的是交叉熵损失(默认情况下包含 softmax 函数)。


这将导致相似句子(标签 0)的集合句子嵌入变得更加相似,而不相似句子(标签 2)的嵌入变得不那么相似。


请记住,我们使用的是连体 BERT,而不是双 BERT。也就是说,我们使用的不是两个独立的 BERT 模型,而是一个处理句子 A 和句子 B 的 BERT。


这就意味着,当我们优化模型权重时,权重会被推向一个方向,让模型输出更多相似向量,我们会看到一个包含标签,而输出更多不相似向量,我们会看到一个矛盾标签。


SBERT 目标函数

通过使用这两个向量 u 和 v,下面将讨论优化不同目标的三种方法。


分类

将三个向量 u、v 和 |u-v| 连接起来,乘以可训练的权重矩阵 W,然后将乘法结果输入 softmax 分类器,该分类器会输出不同类别句子的归一化概率。交叉熵损失函数用于更新模型的权重。


23


回归

在这种方法中,得到向量 u 和 v 后,直接通过选定的相似度量来计算它们之间的相似度得分。将预测的相似度得分与真实值进行比较,然后使用 MSE 损失函数更新模型。


24


三重损失

三元组目标引入了三元组损失,该损失是根据三个句子计算得出的,这三个句子通常被称为锚句子、正句子和负句子。假定锚句子和正句子非常接近,而锚句子和负句子非常不同。在训练过程中,模型会评估句子对(锚句、正句)与句子对(锚句、负句)的接近程度。


25


现在,让我们来看看如何初始化和使用这些句子转换器模型。


句子转换器实践

开始使用句子转换器的最快、最简单的方法是通过 SBERT 创建者创建的句子转换器库。我们可以用 pip 安装它。


!pip install sentence-transformers


我们将从最初的 SBERT 模型 bert-base-nli-mean-tokens 开始。首先,我们下载并初始化模型。


from sentence_transformers import SentenceTransformer
model = SentenceTransformer('bert-base-nli-mean-tokens')
model


输出:


SentenceTransformer(
  (0): Transformer({'max_seq_length': 128, 'do_lower_case': False}) with Transformer model: BertModel 
  (1): Pooling({'word_embedding_dimension': 768, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False})
)


我们在这里看到的输出是 SentenceTransformer 对象,它包含三个部分:


  • 转换器本身,在这里我们可以看到 128 个词组的最大序列长度,以及是否小写任何输入内容(在本例中,模型不小写)。我们还可以看到模型类 BertModel。
  • 池化操作,在这里我们可以看到我们正在生成一个 768 维的句子嵌入。我们使用的是均值池方法。


有了模型后,我们就可以使用编码方法快速构建句子嵌入。


sentences = [
    "the fifty mannequin heads floating in the pool kind of freaked them out",
    "she swore she just saw her sushi move",
    "he embraced his new life as an eggplant",
    "my dentist tells me that chewing bricks is very bad for your teeth",
    "the dental specialist recommended an immediate stop to flossing with construction materials"
]
embeddings = model.encode(sentences)
embeddings.shape


输出:


(5, 768)


选择哪种嵌入模型?

我们很快就会发现,目前使用的大多数嵌入模型都属于转换器类别。这些模型由不同的供应商提供,有些是开源的,有些是专有的,每种模型都是针对特定目标量身定制的:


  • 有些最适合编码任务。
  • 还有一些是专门为英语语言设计的。
  • 还有一些嵌入模型擅长处理多语言数据集。


最简单的方法是利用现有的学术基准。不过,需要注意的是,这些基准可能无法全面反映人工智能应用中检索系统的实际使用情况。


另外,你也可以使用各种嵌入模型进行测试,并编制最终评估表,以确定最适合你的特定用例的模型。我强烈建议在此过程中加入重新排序器,因为它可以显著提高检索器的性能,最终获得最佳结果。


为了简化你的决策过程,Hugging Face 提供了卓越的大容量文本嵌入基准(MTEB)排行榜。该资源提供了有关所有可用嵌入模型及其各自在各种指标上得分的全面信息:


26


如果你选择第二种方法,Medium 上有一篇出色的博文介绍了如何利用 LlamaIndex 的检索评估模块。该资源可帮助你从初始模型列表中有效评估并确定嵌入和重定位器的最佳组合。


27


我相信,你现在已经具备了更好的能力,可以在为你的 RAG 架构选择最合适的嵌入和重排模型时做出明智的决定!


总结

本文探讨了用于生成文本向量表示的各种嵌入模型,包括词袋、TF-IDF、Word2Vec、GloVe、FastText、ELMO、BERT 等。报告深入探讨了 BERT 的架构和预训练,介绍了用于高效句子嵌入的句子 BERT (SBERT),并提供了一个使用句子转换器库的实践示例。结论强调了选择正确的嵌入模型所面临的挑战,并建议利用 Hugging Face Massive Text Embedding Benchmark (MTEB) Leaderboard 等资源进行评估。

文章来源:https://medium.com/@vipra_singh/building-llm-applications-sentence-transformers-part-3-a9e2529f99c1
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消