在 Amazon SageMaker 上使用微调嵌入模型提高 RAG 准确性 机器学习博客

项目展示

利用微调嵌入模型提升 RAG 准确性

主要要点

RAG 概述:检索增强生成RAG能从外部数据源提供额外知识,提升大型语言模型LLM的性能。挑战:预训练嵌入模型通常在一般数据集上训练,无法有效捕捉特定领域的细微差异。解决方案:透过在领域特定数据上微调嵌入模型来提高 RAG 系统的准确性。实作示例:介绍如何使用 Amazon SageMaker 微调 Sentence Transformer 嵌入模型。

检索增强生成RAG是一种流行的框架,可以从在训练语料库中不存在的外部数据源提供额外知识给大型语言模型LLMs。透过 RAG,模型能够利用额外的上下文来生成更准确的响应。

RAG 的架构通常由以下几个组成部分构成:

索引:准备非结构化文本语料,进行解析和切分,然后将每个片段嵌入并存储在向量数据库中。

检索:透过向量相似度从向量数据库中检索与问题相关的上下文。使用提示工程提供额外的上下文给 LLM,然后生成基于原始问题和上下文的答案。

RAG 准确性面临的挑战

预训练嵌入模型通常在大型通用数据集如维基百科或网络抓取数据上进行训练。尽管这些模型能捕捉广泛的语义关系并适用于多种任务,但在表达特定领域的概念和细微差异时可能会出现困难。这种限制会导致在需要专业任务如法律、医疗或技术领域时的性能不如预期。此外,预训练的嵌入可能未能有效捕捉特定任务或行业的上下文关系和细微之处。

为了克服这些挑战,必须对嵌入模型进行微调,使用与目标领域或任务相符的数据进行训练。透过微调,模型可以学习捕捉特定于该领域的语意、行话和上下文关系。

领域特定的嵌入能显著提高向量表征的质量,从而实现更准确的检索和更相关的响应。

这篇文章将展示如何使用 Amazon SageMaker 微调一个 Sentence Transformer 嵌入模型并部署到 Amazon SageMaker 端点。该文章的代码和更多示例可在 GitHub 仓库 中获得。关于微调 Sentence Transformer 的更多信息,请参阅 Sentence Transformer 训练概述。

使用 SageMaker 微调嵌入模型

SageMaker是一个完全管理的机器学习服务,简化了从数据准备、模型训练到部署和监控的整个机器学习工作流程。它提供了一个无缝和集成的环境,让开发人员和数据科学家能专注于构建和迭代机器学习模型,而不必担心基础设施管理的复杂性。

SageMaker 的一大优势是对流行开源框架如 TensorFlow、PyTorch 和 Hugging Face 变压器的原生支持,这使得使用这些框架进行模型训练和部署变得流畅。

前提条件

在本次带领中,您需要具备以下前提条件:

一个已设置的 AWS 账号。

配置了 python3 内核的 Amazon SageMaker JupyterLab 若要快速设置 SageMaker Studio,可以 为单一用户创建一个域 并启动 您的 JupyterLab。

拥有亚马逊简单存储服务 (Amazon S3) 桶中写入权限的 AWS 身份和访问管理 (IAM) 角色,并具备创建 Sagemaker 端点的权限。如果您拥有账户的管理员访问权限,则不需要额外行动。

微调嵌入模型的步骤

接下来,我们将使用 SageMaker JupyterLab 来逐步介绍数据准备、创建训练脚本、训练模型及部署为 SageMaker 端点的过程。

我们将微调嵌入模型 sentencetransformers/allMiniLML6v2,这是一个在 10 亿句子对数据集上进行微调的开源 Sentence Transformers 模型。它能将句子和段落映射到一个 384 维的稠密向量空间,并可用于聚类或语义搜索等任务。为了进行微调,我们将使用 Amazon Bedrock FAQ 的数据集,该数据集包含问题和答案对,并使用 MultipleNegativesRankingLoss 函数 进行训练。

在 Losses 中,您可以找到可用于微调嵌入模型的不同损失函数。选择损失函数在微调模型时至关重要,因为它决定了我们的嵌入模型在特定下游任务中的表现。

当训练数据中只有正样本对时,建议使用 MultipleNegativesRankingLoss。例如,只有相似文本的对如同义改写的对、重复问题的对、查询和响应的对或 (sourcelanguage 和 targetlanguage 的对都适合使用这种损失函数。

在本示例中,考虑到我们以 Amazon Bedrock FAQ 作为训练数据,该数据包含问题和答案的对,因此 MultipleNegativesRankingLoss 函数可能会非常适合。

以下代码示例展示了如何从 JSON 文件加载训练数据集,并为训练准备数据,随后对预训练模型进行微调。微调完成后,将更新的模型保存下来。

pythonfrom sentencetransformers import SentenceTransformer InputExample losses evaluationfrom torchutilsdata import DataLoaderfrom sentencetransformersevaluation import InformationRetrievalEvaluatorimport json

def loaddata(path) 从 JSON 文件加载数据集。 with open(path r encoding=utf8) as f data = jsonload(f) return data

dataset = loaddata(trainingjson)

加载预训练模型

model = SentenceTransformer(sentencetransformers/allMiniLML6v2)

将数据集转换为所需格式

trainexamples = [InputExample(texts=[data[sentence1] data[sentence2]]) for data in dataset]

创建 DataLoader 对象

traindataloader = DataLoader(trainexamples shuffle=True batchsize=8)

定义损失函数

trainloss = lossesMultipleNegativesRankingLoss(model)

安卓加速器下载

EPOCHS = 100

modelfit( trainobjectives=[(traindataloader trainloss)] epochs=EPOCHS showprogressbar=True)

保存微调后的模型

modelsave(opt/ml/model/ safeserialization=False)

为了部署和提供微调的嵌入模型进行推理,我们创建一个名为 inferencepy 的 Python 脚本作为入口点。这个脚本实现了两个基本函数:modelfn 和 predictfn,这是 SageMaker 部署和使用机器学习模型所需的。

modelfn 函数负责加载微调的嵌入模型及对应的分词器。predictfn 函数接受输入句子,使用加载的分词器对它们进行分词,并使用微调模型计算其句子嵌入。若要获得每个句子的单一向量表示,它会对标记嵌入进行平均池化,然后对生成的嵌入进行标准化。最后,predictfn 返回经过标准化的嵌入作为列表,可以根据需要进行进一步处理或存储。

pythonwritefile opt/ml/model/inferencepy

from transformers import AutoTokenizer AutoModelimport torchimport torchnnfunctional as Fimport os

def meanpooling(modeloutput attentionmask) tokenembeddings = modeloutput[0] # modeloutput 的第一个元素包含所有的标记嵌入 inputmaskexpanded = attentionmaskunsqueeze(1)expand(tokenembeddingssize())float() return torchsum(tokenembeddings inputmaskexpanded 1) / torchclamp(inputmaskexpandedsum(1) min=1e9)

def modelfn(modeldir context=None) # 从 HuggingFace Hub 加载模型 tokenizer = AutoTokenizerfrompretrained(f{modeldir}/model) model = AutoModelfrompretrained(f{modeldir}/model) return model tokenizer

def predictfn(data modelandtokenizer context=None) # 拆解模型和分词器 model tokenizer = modelandtokenizer

在 Amazon SageMaker 上使用微调嵌入模型提高 RAG 准确性 机器学习博客

# 对句子进行分词sentences = datapop(inputs data)encodedinput = tokenizer(sentences padding=True truncation=True returntensors=pt)# 计算标记嵌入with torchnograd()    modeloutput = model(encodedinput)# 进行池化sentenceembeddings = meanpooling(modeloutput encodedinput[attentionmask])# 标准化嵌入sentenceembeddings = Fnormalize(sentenceembeddings p=2 dim=1)# 返回可 JSON 序列化的字典return {vectors sentenceembeddings[0]tolist()}

创建完 inferencepy 脚本后,我们将其与微调的嵌入模型打包成单个 modeltargz 文件。这个压缩文件可以上传到 S3 桶中,以便于部署为 SageMaker 端点。

pythonimport boto3import tarfileimport os

modeldir = opt/ml/modelmodeltarpath = modeltargz

with tarfileopen(modeltarpath wgz) as tar taradd(modeldir arcname=ospathbasename(modeldir))

s3 = boto3client(s3)

获取区域名称

session = boto3Session()regionname = sessionregionname

从 STS安全令牌服务获取帐户 ID

stsclient = sessionclient(sts)accountid = stsclientgetcalleridentity()[Account]

modelpath = fs3//sagemaker{regionname}{accountid}/modeltrainedembedding/modeltargz

bucketname = fsagemaker{regionname}{accountid}s3key = modeltrainedembedding/modeltargz

with open(modeltarpath rb) as f s3uploadfileobj(f bucketname s3key)

最后,我们可以将微调的模型部署到 SageMaker 端点。

pythonfrom sagemakerhuggingfacemodel import HuggingFaceModelimport sagemaker

创建 Hugging Face 模型类

huggingfacemodel = HuggingFaceModel( modeldata=modelpath # 您的训练 SageMaker 模型的路径 role=sagemakergetexecutionrole() # 拥有创建端点权限的 IAM 角色 transformersversion=426 # 使用的 Transformers 版本 pytorchversion=113 # 使用的 PyTorch 版本 pyversion=py39 # 使用的 Python 版本 entrypoint=opt/ml/model/inferencepy)

部署模型到 SageMaker 推理

predictor = huggingfacemodeldeploy( initialinstancecount=1 instancetype=mlm5xlarge)

完成部署后,您可以在 AWS 管理控制台的 SageMaker 中找到已部署的端点,选择推理并选择端点。

您有多种选择来 调用您的端点。例如,在 SageMaker JupyterLab 中,您可以使用以下代码片段进行调用:

python

示例请求:您始终需要定义 inputs

data = { inputs 代理是完全管理的吗?}

请求

predictorpredict(data)

它返回的向量包含 inputs 键的嵌入:

json{vectors [004694557189941406 007266131788492203 0058242443948984146 ]}

为了说明微调的影响,我们可以比较使用原始预训练模型和微调模型之间的两个语义相关句子的余弦相似度分数。更高的余弦相似度分数表明这两个句子在语义上更加相似,因为它们的嵌入在向量空间中更接近。

让我们考虑以下句子对:

代理是什么,如何使用它们?Amazon Bedrock 代理是完全管理的功能,自动分解任务,创建编排计划,安全地通过 API 连接公司数据,并为复杂任务例如自动化库存管理或处理保险索赔生成准确的响应。

这些句子与 Amazon Bedrock 中 IP 代理的概念相关,但详细程度不同。通过生成这些句子的嵌入并计算其余弦相似度,我们可以评估每个模型捕捉它们之间语义关系的能力。

原始预训练模型的相似度分数仅为 054。

微调模型的相似度分数则为 087。

我们可以观察到微调模型在识别 代理 和 Amazon Bedrock 代理 之间的语义相似性上明显高于预训

使用 Amazon SageMaker Canvas 和 Amazon Bedrock 微调和部署语言模型关键要点在这篇文章中,我们会探讨如何利用 Amazon Bedrock 及 Amazon SageMaker Canvas 来微调和部署大型语言模型 (LLM)。这些工具为企业用户提供了无需深厚...

通过新作业可观测性指标增强 AWS Glue 作业监控与调试第二部分关键点总结了解如何利用 Grafana 实现 AWS Glue 作业的实时监控。本文介绍了 AWS Glue 作业可观测性指标的整合,帮助用户可视化各类性能指标,从而提升数据管道的可靠性和效率。实时监控数据管道对于及时发现问题和减少...