
微调并评估LLaMA 3的终极指南
LLaMA-3是Meta的第二代开源LLM系列,采用了优化的Transformer架构,提供8B和70B两种大小的模型,适用于各种NLP任务。虽然预训练的自回归模型如LLaMA-3在预测序列中的下一个token方面表现良好,但微调对于使模型响应符合人类预期是必要的。机器学习中的微调涉及到在新数据上调整预训练模型的权重,通过在特定任务数据集上训练模型,以适应新输入,增强特定任务的性能。在微调LLaM
导读
不超过100行代码微调并评估LLM。
微调大型语言模型(LLM)相比于依赖如OpenAI的GPT模型等专有基础模型,带来了诸多益处。想一想,你可以获得低至十分之一的推理成本,每秒处理的token数量提高十倍,而且无需担心OpenAI在其API背后可能进行的任何隐晦操作。我们应该这样思考微调:不是考虑如何超越OpenAI或取代RAG,而是如何在特定应用场景下保持相同性能的同时,减少推理时间和成本。
但让我们面对现实吧,构建RAG应用程序的普通开发者对自己的能力缺乏信心,不知道如何微调LLM——收集训练数据很难,理解方法论也很困难,而评估微调模型更是不易。因此,微调成为了LLM实践者的最佳补剂。你会经常听到诸如“现在微调不是优先事项”,“我们会先尝试RAG,如果必要再转向微调”,以及经典的“已在规划路线图中”。但如果我告诉你,任何人都能在不到两小时内免费开始微调LLM,代码行数不超过100行呢?为什么不是两者兼得,而非要二选一?
在本文中,我将展示如何使用Hugging Face的transformers库微调LLaMA-3 8B模型,以及如何使用DeepEval评估你的微调模型,所有操作都在Google Colab中完成。
让我们直接进入正题。
什么是LLaMA-3以及微调?
LLaMA-3是Meta的第二代开源LLM系列,采用了优化的Transformer架构,提供8B和70B两种大小的模型,适用于各种NLP任务。虽然预训练的自回归模型如LLaMA-3在预测序列中的下一个token方面表现良好,但微调对于使模型响应符合人类预期是必要的。
机器学习中的微调涉及到在新数据上调整预训练模型的权重,通过在特定任务数据集上训练模型,以适应新输入,增强特定任务的性能。在微调LLaMA-3的情况下,这意味着给模型一组指令和响应,以使用指令微调,使其作为助手时更有用。微调之所以优秀,是因为你知道吗?仅训练LLaMA-3 8B模型,Meta就花费了130万GPU小时。
微调有两种不同的形式:
-
SFT(监督微调):LLMs在一组指令和响应上进行微调。模型的权重将被更新,以最小化生成输出与标记响应之间的差异。
-
RLHF(基于人类反馈的强化学习):LLMs被训练以最大化奖励函数(使用近端策略优化算法或直接偏好优化(DPO)算法)。该技术使用人类对生成输出的评价反馈,进而捕捉更复杂的人类偏好,但容易受到不一致的人类反馈的影响。
正如你可能已经猜到的,本文中我们将使用SFT来指令微调LLaMA-3 8B模型。
微调中的常见陷阱
劣质训练数据
前面对RLHF的陈述突显了一个非常重要的一点:**当涉及到微调时,训练数据集的质量是最关键的因素。**实际上,LIMA论文显示,在65B LLaMA(1)上使用1000个高质量样本进行微调可以胜过OpenAI的DaVinci003。
再考虑另一个例子,这是一个在14万条Slack消息上微调的gpt-3.5-turbo:
这确实挺搞笑的,但可能只是因为我没有从自己的LLM中得到这样的回应。
使用错误的提示模板
这实际上只在你使用了特定模型的情况下才重要,这些模型是在特定的提示模板上训练的,比如LLaMA-2的聊天模型。简而言之,Meta在训练LLaMA-2聊天模型时使用了以下模板,理想情况下,你需要将训练数据格式化为此格式。
[s][INST] [[SYS]] System prompt [[/SYS]] User prompt [/INST] Model answer [/s]
基于以上原因,我们将使用mlabonne/guanaco-llama2–1k数据集进行微调。这是一个高质量的1000个指令-响应数据集(源自timdettmers/openassistant-guanaco
数据集),已经按照LLaMA-2的提示模板重新格式化。
微调LLaMA-3的逐步指南
第一步 安装
首先,创建一个新的Google Colab笔记本。
然后,安装并导入所需的库:
!pip install transformers peft bitsandbytes trl deepeval import os import torch from datasets import load_dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, pipeline, ) from peft import LoraConfig from trl import SFTTrainer
在这里,我们使用来自Hugging Face和Confident AI生态系统的库:
-
transformers
:用于加载模型、分词器等。 -
peft
:执行参数高效微调。 -
bitsandbytes
:设置4位量化。 -
trl
:进行监督微调。 -
deepeval
:评估微调后的LLaMA
第二步 量化设置
为了在LLaMA-3 8B微调期间优化Colab RAM使用,我们采用QLoRA(量化低秩近似)。以下是其关键原则的分解:
-
4位量化:QLoRA通过仅用4位(而非标准的32位浮点数)表示权重来压缩预训练的LLaMA-3 8B模型,这大大减少了模型的内存占用。
-
冻结预训练模型:量化后,LLaMA-3的绝大多数参数被冻结。这阻止了在微调过程中对核心模型的直接更新。
-
低秩适配器:QLoRA在模型架构中引入轻量级、可训练的适配器层。这些适配器在不显著增加参数数量的情况下捕获任务特定知识。
-
基于梯度的微调:在微调过程中,梯度流经冻结的4位量化模型,但仅用于更新低秩适配器中的参数。这种隔离优化极大地减少了计算开销。
下图是原始论文中QLoRA的可视化表示。
我们可以利用bitsandbytes
来实现:
... ################################# ### Setup Quantization Config ### ################################# compute_dtype = getattr(torch, "float16") quant_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=compute_dtype, bnb_4bit_use_double_quant=False, )
第三步 使用QLoRA配置加载LLaMA-3
这一步相当直接。我们将直接从Hugging Face加载LLaMA-3 8B模型。
请注意,尽管LLaMA-3是开源的,并且可以在Hugging Face上获取,但你需要向Meta发送请求以获得访问权限,这个过程通常需要长达一周的时间。
... ####################### ### Load Base Model ### ####################### base_model_name = "meta-llama/Meta-Llama-3-8B" llama_3 = AutoModelForCausalLM.from_pretrained( base_model_name, quantization_config=quant_config, device_map={"": 0} )
第四步 - 加载分词器
当一个大型语言模型读取文本时,它首先必须将文本转换为可读的格式。这一过程被称为分词,由分词器执行。
分词器通常是为其对应的模型设计的。复制以下代码来加载LLaMA-3的分词器:
... ###################### ### Load Tokenizer ### ###################### tokenizer = AutoTokenizer.from_pretrained( base_model_name, trust_remote_code=True ) tokenizer.pad_token = tokenizer.eos_token tokenizer.padding_side = "right"
步骤5 加载数据集
正如前一节所述,我们将使用mlabonne/guanaco-llama2–1k数据集进行微调,因为它的数据标签质量高,并且与LLaMA-3的提示模板兼容。
... #################### ### Load Dataset ### #################### train_dataset_name = "mlabonne/guanaco-llama2-1k" train_dataset = load_dataset(train_dataset_name, split="train")
步骤6 为PEFT加载LoRA配置
我不会深入探讨QLoRA和LoRA之间的详细差异,但LoRA本质上是QLoRA的内存效率较低的版本,因为它不使用量化,但可能会产生略微更高的准确性。(你可以在这里阅读更多关于LoRA的信息。)
在这个步骤中,我们为参数高效微调(PEFT)配置LoRA,与常规微调所有模型参数不同,PEFT只更新一小部分参数。
... ######################################### ### Load LoRA Configurations for PEFT ### ######################################### peft_config = LoraConfig( lora_alpha = 16 lora_dropout=0.1, r=64, bias="none", task_type="CAUSAL_LM", )
步骤7 设置训练参数和SFT微调参数
我们即将完成,剩下的是设置训练所需的参数以及训练器的监督微调(SFT)参数:
... ############################## ### Set Training Arguments ### ############################## training_arguments = TrainingArguments( output_dir="./tuning_results", num_train_epochs=1, per_device_train_batch_size=4, gradient_accumulation_steps=1, optim="paged_adamw_32bit", save_steps=25, logging_steps=25, learning_rate=2e-4, weight_decay=0.001, fp16=False, bf16=False, max_grad_norm=0.3, max_steps=-1, warmup_ratio=0.03, group_by_length=True, lr_scheduler_type="constant" ) ########################## ### Set SFT Parameters ### ########################## trainer = SFTTrainer( model=llama_3, train_dataset=train_dataset, peft_config=peft_config, dataset_text_field="text", max_seq_length=None, tokenizer=tokenizer, args=training_arguments, packing=False, )
我将不解释这些参数的具体含义,但如果感兴趣,你可以查阅Hugging Face的文档:
-
TrainerArguments API参考
-
SFTTrainer API参考
步骤8—开始微调并保存模型
运行以下代码开始微调:
... ####################### ### Fine-Tune Model ### ####################### trainer.train()
你应该预计训练将持续长达一个小时。在此期间,这里有一张野生骆马派对的图片来为你解闷 😃
一旦微调完成,保存你的模型和分词器,你就可以立即开始测试微调后模型的效果!
... ################## ### Save Model ### ################## new_model = "tuned-llama-3-8b" trainer.model.save_pretrained(new_model) trainer.tokenizer.save_pretrained(new_model) ################# ### Try Model ### ################# prompt = "What is a large language model?" pipe = pipeline( task="text-generation", model=llama_3, tokenizer=tokenizer, max_length=200 ) result = pipe(f"[s][INST] {prompt} [/INST]") print(result[0]['generated_text'])
使用DeepEval评估微调后的LLM
我知道你在想什么(或者至少我希望我知道)。你可能期待着在类似tensorboard的工具上看到微调过程中的损失曲线图,但幸运的是,我不会用这种“评估”方式来让你感到枯燥。相反,我们将使用DeepEval,一个针对LLM的开源评估框架。
既然我们微调LLaMA-3 8B是为了使其作为助手更加有用,我们将根据三个指标来评估我们的模型:偏见、毒性以及帮助性。在DeepEval中,这些指标是通过精心设计的提示工程和诸如QAG和G-Eval等框架结合使用LLM来评估的。
对于感兴趣的人,这里有一篇很好的文章,讲述了为什么我们使用LLM作为评估者的理论依据。首先,设置你的OpenAI API密钥,并定义LLM评估指标:
%env OPENAI_API_KEY=your-openai-api-key from deepeval.metrics import GEval, BiasMetric, ToxicityMetric from deepeval.test_case import LLMTestCaseParams helpfulness_metric = GEval( name="Helpfulness", criteria="Helpfulness - determine if how helpful the actual output is in response with the input.", evaluation_params=[LLMTestCaseParams.INPUT, LLMTestCaseParams.ACTUAL_OUTPUT], threshold=0.5 ) bias_metric = BiasMetric(threshold=0.5) toxicity_metric = ToxicityMetric(threshold=0.5)
DeepEval的指标返回一个分数(0-1),并提供评分的理由。只有当计算出的分数超过阈值(根据不同的指标,这可能是最大或最小阈值)时,指标才被认为是成功的。
最后,通过使用DeepEval的合成数据生成器创建测试案例,来创建一个你想要评估模型输出的输入列表:
from deepeval.synthesizer import Synthesizer from deepeval.test_case import LLMTestCase ... synthesizer = Synthesizer() synthesizer.generate_goldens_from_docs( # Generate queries from your documents document_paths=['example_1.txt', 'example_2.docx', 'example_3.pdf'], max_goldens_per_document=2 ) pipe = pipeline( task="text-generation", model=llama_3, tokenizer=tokenizer, max_length=200 ) test_cases = [] for golden in synthesizer.synthetic_goldens: actual_output = pipe(f"[s][INST] {input} [/INST]")[0]['generated_text'] test_case = LLMTestCase(input=golden.input, acutal_output=actual_output) test_cases.append(test_case)
我们为了简单起见硬编码了输入,但你已经明白了要点。最后,使用你之前定义的LLM评估指标来创建并评估你的数据集:
from deepeval.dataset import EvaluationDataset ... evaluation_dataset = EvaluationDataset(test_cases=test_cases) evaluation_dataset.evaluate([bias_metric, helpfulness_metric, toxicity_metric])
就这样完成了!恭喜你坚持到了本教程的结尾,但有了这样的设置,你将能够添加更多的指标和测试案例,进一步评估和迭代你的微调过的LLaMA-3。
附言。 DeepEval还与Hugging Face集成,允许在微调期间进行实时评估。
结论
在这篇文章中,我们探讨了LLaMA-3是什么,为什么你应该进行微调及其所涉及的内容,以及在微调时需要注意的事项,包括使用正确的数据集,以及将其格式化以适应基础模型训练时使用的提示模板。
我们也看到了如何利用Hugging Face生态系统,在Google Colab笔记本中无缝执行微调,使用如QLoRA等量化技术。最后,我们了解到如何使用DeepEval来评估微调后的模型。我们已经为你完成了所有艰难的工作,并提供了一个完整的生态系统,用于LLM的微调评估。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】
更多推荐
所有评论(0)