本次实验使用swanlab作为训练过程跟踪的可视化工具,既可以在微信公众号Swanlab上查看,也可以在手机APP上随时跟踪,具体使用操作可以参考 手机上看SwanLab实验的两种方法。
什么是SwanLab?
SwanLab是一个深度学习实验管理与训练可视化工具,由西安电子科技大学创业团队打造,融合了Weights & Biases与Tensorboard的特点,可以记录整个实验的超参数、指标、训练环境、Python版本等,并可视化图表,帮助你分析训练的表现。
在训练过程中,你可能因为各种原因无法看到当前实验的最新情况,这个时候如果能够在手机、平板上看到实验的最新进展,及时发现训练的问题,能够节省很多的时间。
SwanLab也与绝大多数主流的训练框架进行了集成,包括PyTorch、HuggingFace Transformers、PyTorch Lightning、MMDetection、Ultralytics、fastai等等,可以开箱即用地与你的深度学习工作流轻松集成。
训练过程:Lllama3-8b-Swanlab
训练代码:Github
如果你是第一次使用SwanLab,那么还需要去https://swanlab.cn上注册一个账号,在用户设置页面复制你的API Key,然后在训练开始时粘贴进去即可:
注意,在刚注册好还没有使用的时候,你的主页是这个样子:
当你训练时,你的主页会变成这样:
左侧为project名,右侧就是你训练时生成的experiment_name,点击查看即可。
swanlab公众号可以随时查看你的训练进度。
前言
Llama 是由 Meta(FaceBook) AI 发布的一个开源项目,允许商用,影响力巨大,而最近Meta 发布了Llama 3 系列语言模型(LLM),具体包括一个 8B 模型和一个70 B模型,在各个测试基准中,Llama 3 模型的表现相当出色,在实用性和安全性评估中,与那些市面上流行的闭源模型不相上下,并且由于允许商用,llama3已经在多个行业标准测试中展现了其卓越的性能。
性能
相较于诸多拥有庞大参数量的竞争对手,Llama 3 脱颖而出,引领着同类模型的最前沿。它展现出卓越的能力,在解决问题、解析叙事、概括内容及对话交流等方面尤为出色。实验评估证实,Llama 3 在评估人工智能语言理解与运用智能的关键指标上,超越众多其他模型,成绩斐然。
根据 Meta 官方发布的数据,Llama 3 的 80 亿参数版本在多样化的基准测试中,包括 MMLU、GPQA 及 HumanEval,均力压同级别的 Gemma 7B 和 Mistral 7B Instruct 模型。而其 700 亿参数的版本更是取得了令人瞩目的成就,不仅超越了广受欢迎但封闭源代码的 Claude 3 Sonnet,还在效能上与 Google 强大的 Gemini Pro 1.5 并驾齐驱,彰显了其在语言模型领域中的顶尖地位。
模型架构
官网文章:Meet Your New Assistant: Meta AI, Built With Llama 3 | Meta (fb.com)
代码链接:meta-llama/llama3: The official Meta Llama 3 GitHub site
meta在Llama 3中选择了相对标准的decoder-only的transformer架构。与Llama 2相比做了一些关键的改进。Llama 3使用了一个拥有128K词汇量的tokenizer,更有效地编码语言,这导致模型性能大幅提升。为了提高Llama 3模型的推理效率,在8B和70B的模型中都采用了分组查询注意力(GQA),使用8192个token的序列训练模型,并使用mask来确保自注意力不会跨越文档边界。
设计理念
1.训练数据
为了训练最佳的语言模型,筛选大规模、高质量的训练数据至关重要。根据设计原则,Meta在预训练数据上进行了大量的投入。Llama 3在超过1500亿token的数据上进行了预训练,这些数据均来自公开可得的来源。Llama3的训练数据集比Llama 2使用的数据集大七倍,并且包含了四倍的代码。为了应对即将到来的多语言应用场景,Llama 3的预训练数据集中有超过5%的高质量非英语数据,涵盖了30多种语言。
为确保Llama 3的训练数据具有最高的质量,Meta开发了一系列的数据过滤流程,包括使用启发式过滤器、NSFW过滤器、语义去重方法和文本分类器来预测数据质量。Meta在博客中表示,之前的Llama版本在识别高质量数据方面表现出人意料的良好,因此他们使用Llama 2生成了训练数据,用于为驱动Llama 3的文本质量分类器提供支持。
此外,Meta还进行了大量实验使他们能够选择一种数据混合方式,以确保Llama 3在各种用例中都能表现出色,包括问答、科学技术工程数学(STEM)、编码、历史知识等。
2.扩大训练
为了充分利用Llama 3模型的预训练数据,Meta致力于扩展预训练过程,并采取了多项关键措施。首先,他们开发了详细的scaling laws,通过预测最大模型在关键任务上的性能,Meta能够在实际训练之前做出明智的决策。
其次,Meta在Llama 3的开发过程中观察到了有关模型训练规模的新行为。Meta发现,即使在训练了两个数量级更多的数据后,模型的性能仍然持续改善,使他们能够构建更强大、更高效的语言模型。
为了训练最大规模的Llama 3模型,Meta采用了数据并行化、模型并行化和管道并行化等并行化技术并设计了高效的训练系统,可以在16,000个GPU同时进行训练,并实现超过400 TFLOPS的计算利用率。此外,Meta还改进了硬件的可靠性和数据完整性检测机制,并引入了可扩展的存储系统,减少了检查点和回滚的开销。这些改进使得Llama 3的训练效率相较于之前的版本提高了约三倍,有效训练时间超过95%。
3.指令微调
为了充分释放预训练模型在聊天场景中的潜力,Meta在指令调优的方法上进行了创新,结合了监督微调(SFT)、拒绝抽样、近端策略优化(PPO)和直接策略优化(DPO)。在SFT中使用的提示质量以及在PPO和DPO中使用的偏好排序对齐模型的性能有着重大影响。通过精心策划这些数据和进行多轮质量保证为模型的质量带来了巨大提升。
通过PPO和DPO学习偏好排序,还极大地提高了Llama 3在推理和编码任务上的性能。Meta发现,如果向模型提出一个它难以回答的推理问题,有时模型会产生正确的推理过程:模型知道如何得出正确的答案,但不知道如何选择它。通过偏好排序的训练,模型能够学会如何进行选择。
在线体验
体验地址:Meta Llama 3
我们已经将我们最新的模型整合到Meta AI中,我们相信这是世界上领先的AI助手。它现在采用了Llama 3技术,并将在我们的应用程序中更多国家提供。
您可以在Facebook、Instagram、WhatsApp、Messenger和网站上使用Meta AI来完成任务、学习、创作和与您关心的事物建立联系。您可以在这里了解更多关于Meta AI体验的信息。
访问Llama 3网站下载模型并参考入门指南,了解所有可用平台的最新列表。
您很快将能够在我们的Ray-Ban Meta智能眼镜上测试多模态的Meta AI。
如往常一样,我们期待看到您将如何使用Meta Llama 3构建所有令人惊叹的产品和体验。
微调代码
1.环境安装
datasets
transformers
unsloth
torch
swanlab
trl
安装命令
pip install datasets transformers swanlab trl
pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
# windows安装pytorch
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
# linux安装pytorch
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
每一部分作用:
- datasets:HuggingFace出品的数据集工具,可以下载来自huggingface社区上的数据集。代码中用datasets主要用于下载、加载数据集。
- transformers:HuggingFace出品的深度学习框架,已经成为了NLP(自然语言处理)领域最流行的训练与推理框架。代码中用transformers主要用于加载模型、训练以及推理。
- swanlab:一个深度学习实验管理与训练可视化工具,由西安电子科技大学团队打造,官网, 融合了Weights & Biases与Tensorboard的特点,可以记录整个实验的超参数、指标、训练环境、Python版本等,并可视化图表,帮助你分析训练的表现。本项目用swanlab主要用于记录指标和可视化。
- trl:是一款基于强化学习的全栈库,主要用于训练Transformer语言模型和稳定扩散模型。这个库提供了一整套工具,从监督微调步骤(SFT)、奖励建模步骤(RM)到近端策略优化步骤(PPO),使得用户可以方便地通过强化学习训练语言模型。Py之trl建立在Hugging Face的transformers库之上,使得预训练的语言模型可以通过Py之trl进行微调和优化。
- unsloth:一个开源免费的微调库,使用unsloth微调大模型,8G显存即可微调大模型,推理速度提升四倍,内存减少80%,在经过llama.cpp可以量化为4bit,不仅GPU,CPU也可本地推理。
- PyTorch:是一个由Facebook的人工智能研究团队开发的开源深度学习框架。
本次实验测试于datasets==2.18.0、transformers==4.40.0、swanlab==0.3.0、trl==0.9.4、unsloth==2024.6、torch==2.3.0,更多环境请查看 环境设置
2.加载模型
from unsloth import FastLanguageModel
max_seq_length = 1024
dtype = None
load_in_4bit = True
# 加载模型和分词器
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/llama-3-8b",
max_seq_length=max_seq_length,
dtype=dtype,
load_in_4bit=load_in_4bit,
)
3.加载数据集
使用huggingface的aplace-zh数据集,该数据集是由GPT-4生成,总计52k条数据。
from datasets import load_dataset
dataset = load_dataset("silk-road/alpaca-data-gpt4-chinese", split="train")
处理数据集:
# 根据模型需求的数据格式准备微调数据集
EOS_TOKEN = tokenizer.eos_token # 必须添加 EOS_TOKEN
alpaca_prompt = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
Instruction:
{}
Input:
{}
Response:
{}"""
def formatting_prompts_func(examples):
instructions = examples["instruction"]
inputs = examples["input"]
outputs = examples["output"]
texts = []
for instruction, input, output in zip(instructions, inputs, outputs):
# 必须添加EOS_TOKEN,否则无限生成
text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN
texts.append(text)
return {"text": texts, }
dataset = load_dataset("silk-road/alpaca-data-gpt4-chinese", split="train")
tune_data = dataset.map(formatting_prompts_func, batched=True, )
4.集成Swanlab
将SwanLabCallback类传入到trainer的callbacks参数中即可实现实验跟踪和可视化:
# 设置swanlab回调函数
swanlab_callback = SwanLabCallback(
project="llama3-fintune",
experiment_name="llama3-8b",
description="使用llama3-8b在alpaca_data_zh_51k.json数据集上微调",
)
from trl import SFTTrainer
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=tune_data,
dataset_text_field="text",
max_seq_length=max_seq_length,
dataset_num_proc=2,
packing=False,
args=train_params,
callbacks=[swanlab_callback]
)
5.参数设置
# 微调参数
model = FastLanguageModel.get_peft_model(
model,
r=64,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj", ],
lora_alpha=16,
lora_dropout=0,
bias="none",
use_gradient_checkpointing="unsloth",
random_state=3407,
use_rslora=False,
loftq_config=None,
)
- model:传入模型对象。
- r:LoRA 的秩(rank),
r=64
表示这些矩阵的秩为 64,这会影响微调后的参数量和模型的性能。 - target_modules:包含了要应用 LoRA 微调的模块名称。
- lora_alpha:
lora_alpha
控制 LoRA 的调整力度。更大的lora_alpha
会放大 LoRA 的效果。 - lora_dropout:LoRA 的 dropout 概率。
lora_dropout=0
表示在 LoRA 模块中不使用 dropout。dropout 是一种正则化技术,可以帮助防止过拟合。 - bias:不调整偏置项。
- use_gradient_checkpointing:是否使用梯度检查点技术来节省显存。梯度检查点技术可以在反向传播时重新计算某些中间激活值,以减少显存占用。
- random_state:随机数种子,用于保证实验的可重复性。
- use_rslora:不使用 rSLORA。
- loftq_config:LoFTQ(Low-Frequency Transformation Quantization)的设置。
# 模型训练的参数
train_params = TrainingArguments(
optim="paged_adamw_32bit",
learning_rate=3e-4,
weight_decay=0.01,
lr_scheduler_type='cosine',
warmup_ratio=0.03,
gradient_accumulation_steps=4,
bf16=True,
gradient_checkpointing=True,
label_smoothing_factor=0.1,
neftune_noise_alpha=5,
per_device_train_batch_size=8,
per_device_eval_batch_size=8,
max_grad_norm=2,
group_by_length=True,
num_train_epochs=3,
output_dir='./output',
save_steps=500,
logging_steps=10
)
设置和启动模型的训练参数:
# 设置和启动模型的训练
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=tune_data,
dataset_text_field="text",
max_seq_length=max_seq_length,
dataset_num_proc=2,
packing=False,
args=train_params,
callbacks=[swanlab_callback]
)
开始训练
训练过程:Lllama3-8b-Swanlab
在首次使用SwanLab时,需要去官网注册一下账号,然后在用户设置复制一下你的API Key。
然后在终端输入swanlab login
:
swanlab login
把API Key粘贴进去即可完成登录,之后就不需要再次登录了。
完整的训练代码:
from datasets import load_dataset
from transformers import TrainingArguments
from unsloth import FastLanguageModel
import torch
from swanlab.integration.huggingface import SwanLabCallback
from trl import SFTTrainer
import os
swanlab_callback = SwanLabCallback(
project="llama3-fintune",
experiment_name="llama3-8b",
description="使用llama3-8b在alpaca_data_zh_51k.json数据集上微调",
)
train_params = TrainingArguments(
optim="paged_adamw_32bit",
learning_rate=3e-4,
weight_decay=0.01,
lr_scheduler_type='cosine',
warmup_ratio=0.03,
gradient_accumulation_steps=4,
bf16=True,
gradient_checkpointing=True,
label_smoothing_factor=0.1,
neftune_noise_alpha=5,
per_device_train_batch_size=8,
per_device_eval_batch_size=8,
max_grad_norm=2,
group_by_length=True,
num_train_epochs=3,
output_dir='./output',
save_steps=500,
logging_steps=10
)
max_seq_length = 1024
dtype = None
load_in_4bit = True
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/llama-3-8b",
max_seq_length=max_seq_length,
dtype=dtype,
load_in_4bit=load_in_4bit,
)
# 准备微调数据集
EOS_TOKEN = tokenizer.eos_token # 必须添加 EOS_TOKEN
alpaca_prompt = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
Instruction:
{}
Input:
{}
Response:
{}"""
def formatting_prompts_func(examples):
instructions = examples["instruction"]
inputs = examples["input"]
outputs = examples["output"]
texts = []
for instruction, input, output in zip(instructions, inputs, outputs):
# 必须添加EOS_TOKEN,否则无限生成
text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN
texts.append(text)
return {"text": texts, }
dataset = load_dataset("silk-road/alpaca-data-gpt4-chinese", split="train")
tune_data = dataset.map(formatting_prompts_func, batched=True, )
model = FastLanguageModel.get_peft_model(
model,
r=64,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj", ],
lora_alpha=16,
lora_dropout=0,
bias="none",
use_gradient_checkpointing="unsloth",
random_state=3407,
use_rslora=False,
loftq_config=None,
)
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=tune_data,
dataset_text_field="text",
max_seq_length=max_seq_length,
dataset_num_proc=2,
packing=False,
args=train_params,
callbacks=[swanlab_callback]
)
trainer.train()
model.save_pretrained("lora_model") # Local saving
model.save_pretrained_merged("outputs", tokenizer, save_method="merged_16bit", ) # 合并模型,保存为16位hf
# model.save_pretrained_gguf("model", tokenizer, quantization_method="q4_k_m") # 合并模型,保存为4位gguf
训练结果可视化:
结果测试
from unsloth import FastLanguageModel
from transformers import TextStreamer
# 微调前测试
max_seq_length = 1024
dtype = None
load_in_4bit = True
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="./outputs",
max_seq_length=max_seq_length,
dtype=dtype,
load_in_4bit=load_in_4bit,
)
alpaca_prompt = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
### Instruction:
{}
### Input:
{}
### Response:
{}"""
FastLanguageModel.for_inference(model)
inputs = tokenizer(
[
alpaca_prompt.format(
"请用中文回答", # instruction
"我们如何在日常生活中减少用水?", # input
"", # output
)
], return_tensors="pt").to("cuda")
text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer=text_streamer, max_new_tokens=128)
相关链接:
参考文章:
- https://segmentfault.com/a/1190000044827143
- https://blog.csdn.net/weixin_62403633/article/details/138621426
模型:unsloth/llama-3-8b · Hugging Face
数据集:silk-road/alpaca-data-gpt4-chinese · Datasets at Hugging Face
SwanLab:https://swanlab.cn
sunsloth:https://github.com/unslothai/un