使用 QLoRA 微调 Llama 2,并在 Amazon SageMaker 上通过 AWS In
  • 12

使用 QLoRA 对 Llama 2 进行微调并在 AWS Inferentia2 上部署到 Amazon SageMaker

关键要点

在本文中,我们展示了如何使用参数高效微调PEFT方法对 Llama 2 模型进行微调,并将微调后的模型部署到 AWS Inferentia2。本教程还将介绍如何利用 AWS Neuron 软件开发工具包SDK来实现高效的模型推理。

简介

在本篇文章中,我们将讲述如何使用 PEFT 方法微调 Llama 2 模型,并将其部署到 AWS Inferentia2 上。我们采用 AWS Neuron SDK 以便于访问 Inferentia2 设备,充分利用其高性能。接下来,我们将通过支持 Deep Java LibraryDJL的大型模型推理容器来实现模型服务。

解决方案概述

使用 QLoRa 高效微调 Llama 2

Llama 2 系列大型语言模型LLMs是一个包含从 70 亿到 700 亿参数的生成文本模型集合。Llama 2 基于来自公共来源的 2 万亿标记的数据进行了预训练。AWS 客户一般会对 Llama 2 模型进行微调,以实现更好的后续任务性能。然而,由于 Llama 2 模型参数数量庞大,完整的微调过程既昂贵又耗时。PEFT 方法可以通过仅微调少量额外的模型参数,同时将大多数预训练模型参数保持不变,从而解决这一问题。有关 PEFT 的更多信息,请参考这篇 博文。在本篇文章中,我们使用 QLoRa 对 Llama 2 7B 模型进行微调。

在 Amazon SageMaker 上使用 Inf2 部署微调模型

AWS Inferentia2 是专为推理工作负载设计的 ML 加速器,能够以最高 40 的成本节省实现高性能,适用于生成 AI 和 LLM 工作负载。在本文中,我们使用支持 AWS Inferentia2 的 Amazon Elastic Compute CloudAmazon EC2Inf2 实例,其中包含第二代 Inferentia2 加速器。每个加速器包括两个 NeuronCoresv2,每个 NeuronCorev2 是一个独立的异构计算单元,包含四个主要引擎:张量引擎、向量引擎、标量引擎和 GPSIMD 引擎。它还包含片上软件管理的 SRAM 内存,以最大限度地提高数据本地性。

为在 Inf2 上部署模型,我们需要 AWS Neuron SDK 作为在 Inf2 硬件上运行的软件层。AWS Neuron 是用于在 AWS Inferentia 和 AWS Trainium 基础实例上运行深度学习工作负载的 SDK。它支持端到端的 ML 开发生命周期,包括构建新模型、训练和优化这些模型,以及将其部署到生产环境。AWS Neuron 包含深度学习 编译器、运行时 和 工具,与 TensorFlow 和 PyTorch 等流行框架原生集成。在本博客中,我们将使用 transformersneuronx,这是 AWS Neuron SDK 中用于 transformer 解码器推理工作流的一部分。

准备工作

以下是部署本博文中模型所需的准备事项。您可以通过 AWS 管理控制台 或使用最新版本的 AWS 命令行界面AWS CLI进行操作。

Amazon SageMakerAmazon SageMaker 域Amazon SageMaker Python SDK

步骤讲解

接下来,我们将分为两个部分讲解代码:

微调 Llama27b 模型,并将模型工件上传到指定的 Amazon S3 存储桶位置。使用托管在 Amazon SageMaker 中的 DJL 提供的容器,将模型部署到 Inferentia2。

完整的代码示例和说明可以在这个 GitHub 存储库中找到。

第 1 部分:使用 PEFT 微调 Llama27b 模型

我们将使用 Tim Dettmers 等人撰写的论文中的新方法 QLoRA:量化感知低秩适配器调优用于语言生成。QLoRA 是一种新技术,它在不牺牲性能的情况下,减少了大型语言模型在微调期间的内存占用。

注意: 以下展示的 Llama 27b 模型的微调是在具有 mlg52xlarge 实例类型的 Amazon SageMaker Studio Notebook 上进行测试的。作为最佳实践,我们建议在自有 Amazon 虚拟专用云由 Amazon VPC 提供中启动 Amazon SageMaker Studio 集成开发环境。这让您能够控制、监视和检查 VPC 内外的网络流量,并使用标准的 AWS 网络和安全功能。有关更多信息,请参阅 使用私有 VPC 保护 Amazon SageMaker Studio 连接。

量化基本模型

我们首先使用 Huggingface transformers 库加载一个带有 4 位量化的模型:

python

基础微调模型

modelname = NousResearch/Llama27bchathf

使用的数据集

datasetname = mlabonne/guanacollama21k

激活 4 位精度基础模型加载

use4bit = Truebnb4bitcomputedtype = float16bnb4bitquanttype = nf4usenestedquant = False

computedtype = getattr(torch bnb4bitcomputedtype)

bnbconfig = BitsAndBytesConfig( loadin4bit=use4bit bnb4bitquanttype=bnb4bitquanttype bnb4bitcomputedtype=computedtype bnb4bitusedoublequant=usenestedquant)

使用 QLoRA 微调 Llama 2,并在 Amazon SageMaker 上通过 AWS In

加载基础模型和分词器

model = AutoModelForCausalLMfrompretrained( modelname quantizationconfig=bnbconfig devicemap=devicemap)modelconfigpretrainingtp = 1

tokenizer = AutoTokenizerfrompretrained(modelname trustremotecode=True)

加载训练数据集

接着,我们加载用于微调的训练数据集,如下所示:

python

加载数据集您可以在此处处理它

dataset = loaddataset(datasetname split=train)

附加适配器层

在这里,我们附加一个小型的可训练适配器层,该层在 Hugging Face 的 peft 库中配置为 LoraConfig。

python

包含应用 LoRA 的线性层

modules = findalllinearnames(model)

设置 LoRA 配置

lorar = 64

LoRA 缩放的 alpha 参数

loraalpha = 16

LoRA 层的丢弃概率

loradropout = 01

peftconfig = LoraConfig( loraalpha=loraalpha loradropout=loradropout r=lorar bias=none tasktype=CAUSALLM targetmodules=modules)

训练模型

使用上述 LoRA 配置,我们将微调 Llama2 模型以配合超参数。以下是训练模型的代码片段:

python

设置训练参数

trainingarguments = TrainingArguments()

trainer = SFTTrainer( model=model traindataset=dataset peftconfig=peftconfig # LoRA 配置 datasettextfield=text maxseqlength=maxseqlength tokenizer=tokenizer args=trainingarguments packing=packing)

训练模型

trainertrain()

保存训练后的模型

trainermodelsavepretrained(newmodel)

合并模型权重

经过微调的模型将创建一个新的模型,其中包含训练后的 LoRA 适配器权重。以下代码片段将展示如何将适配器与基础模型合并,以便我们能够使用微调后的模型进行推理。

python

以 FP16 的格式重新加载模型并与 LoRA 权重合并

basemodel = AutoModelForCausalLMfrompretrained( modelname lowcpumemusage=True returndict=True torchdtype=torchfloat16 devicemap=devicemap)model = PeftModelfrompretrained(basemodel newmodel)model = modelmergeandunload()

savedir = mergedmodelmodelsavepretrained(savedir safeserialization=True maxshardsize=2GB)

重新加载分词器以保存

tokenizer = AutoTokenizerfrompretrained(modelname trustremotecode=True)tokenizerpadtoken = tokenizereostokentokenizerpaddingside = righttokenizersavepretrained(savedir)

将模型权重上传到 Amazon S3

在第一部分的最后一步中,我们将合并后的模型权重保存到指定的 Amazon S3 位置。该模型权重将被 Amazon SageMaker 中的模型服务容器用来通过 Inferentia2 实例托管模型。

pythonmodeldatas3location = s3//ltbucketnamegt/ltprefixgt/!cd {savedir} ampamp aws s3 cp recursive {modeldatas3location}

第 2 部分:使用 AWS Inferentia2 和 SageMaker LMI 容器托管 QLoRA 模型进行推理

在本节中,我们将逐步说明如何在 Amazon SageMaker 托管环境中部署 QLoRA 微调的模型。我们将使用来自 SageMaker DLC 的 DJL 提供 的容器,该容器与 transformersneuronx 库集成,用于托管此模型。该设置可以将模型加载到 AWS Inferentia2 加速器上,跨多个 NeuronCore 并启用通过 HTTP 端点进行服务。

准备模型工件

DJL 支持许多深度学习优化库,包括 DeepSpeed、FasterTransformer 等。对于模型特定的配置,我们提供了一个包含关键参数的 servingproperties 文件,例如 tensorparalleldegree 和 modelid 来定义模型加载选项。modelid 可以是 Hugging Face 模型 ID 或存储模型权重的 Amazon S3 路径。在我们的示例中,我们提供了微调模型的 Amazon S3 位置。以下代码片段显示了用于模型服务的属性:

surfshark加速器

pythonwritefile servingpropertiesengine=PythonoptionentryPoint=djlpythontransformersneuronxoptionmodelid=ltmodel data s3 locationgtoptionbatchsize=4optionneuronoptimizelevel=2optiontensorparalleldegree=8optionnpositions=512optionrollingbatch=autooptiondtype=fp16optionmodelloadingtimeout=1500

有关通过 servingproperties 文件可用的可配置选项的更多信息,请参阅此 文档。请注意,在本博客中,我们使用了 optionnposition=512 以加快 AWS Neuron 编译。如果您希望尝试更大的输入令牌长度,建议您提前预编译模型请参阅 在 EC2 上进行 AOT 预编译模型。否则,如果编译时间过长,您可能会遇到超时错误。

在定义 servingproperties 文件后,我们将文件打包为 targz 格式,如下所示:

pythonshmkdir mymodelmv servingproperties mymodel/tar czvf mymodeltargz mymodel/rm rf mymodel

然后,我们将 targz 文件上传到 Amazon S3 存储桶位置:

pythons3codeprefix = largemodellmi/codebucket = sessdefaultbucket() # 用于存储工件的存储桶codeartifact = sessuploaddata(mymodeltargz bucket s3codeprefix)print(fS3 Code or Model tar ball uploaded to gt {codeartifact})

创建 Amazon SageMaker 模型端点

要使用 Inf2 实例进行服务,我们使用支持 DJL neuronX 的 Amazon SageMaker LMI 容器。有关如何使用 DJL NeuronX 容器进行推理的更多信息,请参阅此 博文。以下代码展示了如何使用 Amazon SageMaker Python SDK 部署模型:

python

检索 DJLneuronx Docker 镜像 URI

imageuri = imageurisretrieve( framework=djlneuronx region=sessbotosessionregionname version=0240)

定义用于服务的 inf2 实例类型

instancetype = mlinf248xlarge

endpointname = sagemakerutilsnamefrombase(lmimodel)

部署模型进行推理

modeldeploy(initialinstancecount=1 instancetype=instancetype containerstartuphealthchecktimeout=1500 volumesize=256 endpointname=endpointname)

我们的请求和响应将采用 JSON 格式,因此我们指定序列化程序和反序列化程序

predictor = sagemakerPredictor( endpointname=endpointname sagemakersession=sess serializer=serializersJSONSerializer())

测试模型端点

模型成功部署后,我们可以通过向预测器发送样本请求来验证端点:

pythonprompt=什么是机器学习?inputdata = f[INST] ltgtn作为数据科学家nltgtn{prompt} [/INST]

response = predictorpredict( {inputs inputdata parameters {maxnewtokens300 dosampleTrue}})

print(jsonloads(response)[generatedtext])

示例输出如下:

在数据分析的背景下,机器学习 (ML) 是一种统计技术,能够从数据集中提取预测能力,并随着复杂性和准确性的增加,通过迭代缩小统计的范围。

机器学习不是一种新的统计技术,而是多种现有技术的结合。此外,它并未被设计用于特定数据集或生成特定结果。相反,它被设计得足够灵活,以适应任何数据集并对任何结果做出预测。

清理

如果您决定不再需要 SageMaker 端点运行,可以使用 AWS SDK for Python (boto3) AWS CLI 或 Amazon SageMaker 控制台 将其删除。此外,您还可以 关闭不再需要的 Amazon SageMaker Studio 资源。

结论

在本文中,我们展示了如何使用带有 4 位量化的 LoRA 适配器对 Llama27b 模型进行微调,并使用 DJL 提供的容器将其部署到 AWS Inferentia2 实例上。最后,我们通过 SageMaker Python SDK 验证了 Amazon SageMaker 模型端点的文本生成预测。请随时尝试,我们期待您的反馈。请继续关注 AWS Inferentia 的更多功能和新创新。

有关 AWS Neuron 的更多示例,请参见 [awsneuronsamples](https//githubcom/awsneuron/awsneurons