概览
-
系统阐述了大模型训练的微调方法,涵盖prompt tuning、prefix tuning、LoRA、p-tuning及AdaLoRA等技术方案。
-
详细解析了基于deepspeed框架结合LoRA技术的大模型训练实现代码。
-
介绍了petals分布式训练框架,其通过将模型划分为多个模块,由不同用户设备分别负责计算,有效实现了计算压力的分布式处理。
理解篇
prompt tuning
20210302
采用固定预训练参数的方法,为每个任务单独引入一个或多个可训练的embedding向量。这些embedding与query进行拼接后,作为常规输入传递给大语言模型(LLM),且仅对这些embedding进行训练。图中左侧展示了单任务全参数微调的方法,右侧则呈现了prompt tuning的实现方式。
-
标准的T5模型(橙色线)多任务微调实现了强大的性能,但需要为每个任务存储单独的模型副本。
-
prompt tuning也会随着参数量增大而效果变好,同时使得单个冻结模型可重复使用于所有任务。
-
显著优于使用GPT-3进行fewshot prompt设计。
-
当参数达到100亿规模与全参数微调方式效果无异。
代码样例:
from peft import PromptTuningConfig, get_peft_model
peft_config = PromptTuningConfig(task_type="SEQ_CLS", num_virtual_tokens=10)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)
prefix tuning
20210801
Prefix tuning 在保持预训练模型参数固定的基础上,通过为每个任务引入额外的 embedding 来实现任务适配。与 prompt tuning 不同,它采用多层感知机(MLP)作为 prefix 的编码器,而非将 prefix 直接输入到大型语言模型(LLM)中。
embedding = torch.nn.Embedding(num_virtual_tokens, token_dim)
transform = torch.nn.Sequential(
torch.nn.Linear(token_dim, encoder_hidden_size),
torch.nn.Tanh(),
torch.nn.Linear(encoder_hidden_size, num_layers * 2 * token_dim),
)
在三个数据集中prefix和全参数微调的表现对比:
代码样例:
peft_config = PrefixTuningConfig(task_type="CAUSAL_LM", num_virtual_tokens=20)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)
LoRA
20210816
LoRA冻结了预训练模型的参数,并在每一层decoder中加入dropout+Linear+Conv1d额外的参数
那么,LoRA是否能达到全参数微调的性能呢?
根据实验可知,全参数微调要比LoRA方式好的多,但在低资源的情况下也不失为一种选择
细致到每个任务中的差距如下图:
代码样例:
peft_config = LoraConfig(task_type="SEQ_CLS", inference_mode=False, r=8, lora_alpha=16, lora_dropout=0.1)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)
p-tuning
20211102
手动尝试最优的提示无异于大海捞针,于是便有了自动离散提示搜索的方法(作图),但提示是离散的,神经网络是连续的,所以寻找的最优提示可能是次优的。p-tuning依然是固定LLM参数,利用多层感知机和LSTM对prompt进行编码,编码之后与其他向量进行拼接之后正常输入LLM。注意,训练之后只保留prompt编码之后的向量即可,无需保留编码器。
self.lstm_head = torch.nn.LSTM(
input_size=self.input_size,
hidden_size=self.hidden_size,
num_layers=num_layers,
dropout=lstm_dropout,
bidirectional=True,
batch_first=True,
)
self.mlp_head = torch.nn.Sequential(
torch.nn.Linear(self.hidden_size * 2, self.hidden_size * 2),
torch.nn.ReLU(),
torch.nn.Linear(self.hidden_size * 2, self.output_size),
)
self.mlp_head(self.lstm_head(input_embeds)[0])
以上代码可清晰展示出prompt编码器的结构。
如上图所示,GPT在P-tuning的加持下可达到甚至超过BERT在NLU领域的性能。下图是细致的对比:
MP: Manual prompt
FT: Fine-tuning
MP+FT: Manual prompt augmented fine-tuning
PT: P-tuning
代码样例:
peft_config = PromptEncoderConfig(task_type="CAUSAL_LM", num_virtual_tokens=20, encoder_hidden_size=128)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)
p-tuning v2
20220320
p-tuning 在小参数量模型上的表现欠佳(如图所示),这促使了 V2 版本的诞生。该版本借鉴了 LoRA 的思路,在每层网络中嵌入新的参数(称为 Deep FT)。从图中可以明显看出,p-tuning v2 整合了多种微调方法。它在多个任务上进行微调后,针对不同任务(如 token classification 和 sentence classification)采用了随机初始化的任务头(AutoModelForTokenClassification、AutoModelForSequenceClassification),而非依赖自然语言方式。可以说,V2 版本是集多种优势于一体的解决方案。
KP: Knowledge Probe,知识探针,用于检测LLM的世界知识掌握能力:
SeqTag: Sequence Tagging,如抽取式问答、命名实体识别
Re-param.:Reparameterization,对提示词做单独的编码器
No verb.: No verbalizer,不直接使用LLM head而接一个随机初始化的linear head
以下表格对比了[CLS] label linear head 和 verbalizer with LM head,[CLS] label linear head的方式药略好。
v1到v2的可视化:蓝色部分为参数冻结,橙色部分为可训练部分
下图中对比了FT、PT、PT-2三种方法,粗体为性能最好的,下划线为性能次好的。
代码样例:
peft_config = PrefixTuningConfig(task_type="SEQ_CLS", num_virtual_tokens=20)
model = AutoModelForSequenceClassification.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)
AdaLoRA
20230318
预训练语言模型中,各权重参数对下游任务的影响程度存在显著差异。为提升微调效率,需要采用智能化的参数预算分配策略,优先更新对模型性能提升贡献更大的关键参数。
具体而言,我们采用奇异值分解技术将权重矩阵分解为增量矩阵,并基于新定义的重要性度量指标动态调节各增量矩阵中的奇异值。这种机制确保在模型微调过程中,仅对性能提升显著或关键性参数进行更新,从而在提升模型性能的同时,显著提高了参数使用效率。
详细的算法如下:
对比不同方法的性能:
代码样例:
peft_config = AdaLoraConfig(peft_type="ADALORA", task_type="SEQ_2_SEQ_LM", r=8, lora_alpha=32, target_modules=["q", "v"],lora_dropout=0.01)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)
代码篇
注:以下代码在pytorch 1.12.1版本下运行,其他包都是最新版本
deepspeed
官方的demo所需要的配置如下:
GPU SKUs | OPT-1.3B | OPT-6.7B | OPT-13.2B | OPT-30B | OPT-66B | Bloom-175B |
---|---|---|---|---|---|---|
1x V100 32G | 1.8 days | |||||
1x A6000 48G | 1.1 days | 5.6 days | ||||
1x A100 40G | 15.4 hrs | 3.4 days | ||||
1x A100 80G | 11.7 hrs | 1.7 days | 4.9 days | |||
8x A100 40G | 2 hrs | 5.7 hrs | 10.8 hrs | 1.85 days | ||
8x A100 80G | 1.4 hrs($45) | 4.1 hrs ($132) | 9 hrs ($290) | 18 hrs ($580) | 2.1 days ($1620) | |
64x A100 80G | 31 minutes | 51 minutes | 1.25 hrs ($320) | 4 hrs ($1024) | 7.5 hrs ($1920) | 20 hrs ($5120) |
注意到官方给的样例单卡V100只能训练13亿规模的模型,如果换成67亿是否能跑起来呢?
按照官方文档搭建环境:
pip install deepspeed>=0.9.0
git clone <https://github.com/microsoft/DeepSpeedExamples.git>
cd DeepSpeedExamples/applications/DeepSpeed-Chat/
pip install -r requirements.txt
请注意如果你之前装了deepspeed,请更新至0.9.0
试试全参数微调,这毫无疑问OOM
deepspeed --num_gpus 1 main.py \\
--data_path Dahoas/rm-static \\
--data_split 2,4,4 \\
--model_name_or_path facebook/opt-6.5b \\
--gradient_accumulation_steps 2 \\
--lora_dim 128 \\
--zero_stage 0 \\
--deepspeed \\
--output_dir $OUTPUT \\
&> $OUTPUT/training.log
答案是:我们需要卸载,这次便能愉快的run起来了
deepspeed main.py \\
--data_path Dahoas/rm-static \\
--data_split 2,4,4 \\
--model_name_or_path facebook/opt-6.7b \\
--per_device_train_batch_size 4 \\
--per_device_eval_batch_size 4 \\
--max_seq_len 512 \\
--learning_rate 9.65e-6 \\
--weight_decay 0.1 \\
--num_train_epochs 2 \\
--gradient_accumulation_steps 1 \\
--lr_scheduler_type cosine \\
--num_warmup_steps 0 \\
--seed 1234 \\
--lora_dim 128 \\
--gradient_checkpointing \\
--zero_stage 3 \\
--deepspeed \\
--output_dir $OUTPUT_PATH \\
&> $OUTPUT_PATH/training.log
可以加上LoRA
deepspeed --num_gpus 1 main.py \\
--data_path Dahoas/rm-static \\
--data_split 2,4,4 \\
--model_name_or_path facebook/opt-6.7b \\
--per_device_train_batch_size 8 \\
--per_device_eval_batch_size 8 \\
--max_seq_len 512 \\
--learning_rate 1e-3 \\
--weight_decay 0.1 \\
--num_train_epochs 2 \\
--gradient_accumulation_steps 16 \\
--lr_scheduler_type cosine \\
--num_warmup_steps 0 \\
--seed 1234 \\
--gradient_checkpointing \\
--zero_stage 0 \\
--lora_dim 128 \\
--lora_module_name decoder.layers. \\
--deepspeed \\
--output_dir $OUTPUT_PATH \\
&> $OUTPUT_PATH/training.log
peft
以下代码省略了数据处理
初始化
from datasets import load_dataset,load_from_disk
import transformers
from transformers import AutoModelForCausalLM, AutoTokenizer,default_data_collator
from peft import prepare_model_for_int8_training, LoraConfig, get_peft_model
MICRO_BATCH_SIZE = 1
BATCH_SIZE = 1
GRADIENT_ACCUMULATION_STEPS = BATCH_SIZE // MICRO_BATCH_SIZE
EPOCHS = 3
LEARNING_RATE = 3e-6
CUTOFF_LEN = 256
LORA_R = 16
LORA_ALPHA = 32
LORA_DROPOUT = 0.05
模型加载,并使用int8进行训练
model_path = "facebook/opt-6.7b"
output_dir = "model"
model = AutoModelForCausalLM.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path, add_eos_token=True)
model = prepare_model_for_int8_training(model)
config = LoraConfig(
r=LORA_R,
lora_alpha=LORA_ALPHA,
target_modules=None,
lora_dropout=LORA_DROPOUT,
bias="none",
task_type="CAUSAL_LM",
)
model = get_peft_model(model, config)
tokenizer.pad_token_id = 0
data = load_from_disk("data")
训练与保存
trainer = transformers.Trainer(
model=model,
train_dataset=data["train"],
eval_dataset=data["validation"],
args=transformers.TrainingArguments(
per_device_train_batch_size=MICRO_BATCH_SIZE,
per_device_eval_batch_size=MICRO_BATCH_SIZE,
gradient_accumulation_steps=GRADIENT_ACCUMULATION_STEPS,
warmup_steps=1000,
num_train_epochs=EPOCHS,
learning_rate=LEARNING_RATE,
# bf16=True,
fp16=True,
logging_steps=1,
output_dir=output_dir,
save_total_limit=4,
),
data_collator=default_data_collator,
)
model.config.use_cache = False
trainer.train(resume_from_checkpoint=False)
model.save_pretrained(output_dir)
直接这么启动当然会OOM,依然需要卸载
编写accelerate配置文件accelerate.yaml
compute_environment: LOCAL_MACHINE
deepspeed_config:
gradient_accumulation_steps: 1
gradient_clipping: 1.0
offload_optimizer_device: none
offload_param_device: none
zero3_init_flag: true
zero3_save_16bit_model: true
zero_stage: 3
distributed_type: DEEPSPEED
downcast_bf16: 'yes'
dynamo_backend: 'yes'
fsdp_config: {}
machine_rank: 0
main_training_function: main
megatron_lm_config: {}
mixed_precision: fp16
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
use_cpu: true
deepspeed配置文件:ds.json
{
"fp16": {
"enabled": true,
"loss_scale": 0,
"loss_scale_window": 500,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"betas": "auto",
"eps": 1e-8,
"weight_decay": "auto"
}
},
"scheduler": {
"type": "WarmupLR",
"params": {
"warmup_min_lr": 0,
"warmup_max_lr": 2e-05,
"warmup_num_steps": 0
}
},
"zero_optimization": {
"stage": 2,
"offload_optimizer": {
"device": "cpu",
"pin_memory": false
},
"allgather_partitions": true,
"allgather_bucket_size": 2e8,
"overlap_comm": true,
"reduce_scatter": true,
"reduce_bucket_size": 2e8,
"contiguous_gradients": true
},
"gradient_accumulation_steps":2,
"gradient_clipping": "auto",
"steps_per_print": 2000,
"train_batch_size": 4,
"train_micro_batch_size_per_gpu": 1,
"wall_clock_breakdown": false
}
启动
accelerate launch --dynamo_backend=nvfuser --config_file accelearte.yaml finetune.py
注:其他方法与Lora使用方法差距不大,不再赘述,在peft项目中均有代码样例。
顺便提一嘴:petals
petals采用分布式架构,将模型划分为多个块并分配给不同用户的设备,有效分摊了计算负载。这一机制类似于磁力链接下载工具的分片原理,并借助hivemind库实现去中心化的训练与推理。此外,用户还可创建局域网群组,对私有模型进行分块处理等定制化操作。
import torch
import torch.nn.functional as F
import transformers
from petals import DistributedBloomForCausalLM
initial_peers = [TODO_put_one_or_more_server_addresses_here] # e.g. ["/ip4/127.0.0.1/tcp/more/stuff/here"]
tokenizer = transformers.BloomTokenizerFast.from_pretrained("bigscience/bloom-petals")
model = DistributedBloomForCausalLM.from_pretrained("bigscience/bloom-petals", initial_peers=initial_peers)
inputs = tokenizer("a cat sat", return_tensors="pt")["input_ids"]
remote_outputs = model.generate(inputs, max_length=10)
print(tokenizer.decode(remote_outputs[0]))
model.transformer.word_embeddings.weight.requires_grad = True
outputs = model.forward(input_ids=inputs)
loss = F.cross_entropy(outputs.logits.flatten(0, 1), inputs.flatten())
loss.backward()
print("Gradients (norm):", model.transformer.word_embeddings.weight.grad.norm())
一、大模型风口已至:月薪30K+的AI岗正在批量诞生
2025年大模型应用呈现爆发式增长,根据工信部最新数据:
国内大模型相关岗位缺口达47万
初级工程师平均薪资28K
70%企业存在"能用模型不会调优"的痛点
真实案例:某二本机械专业学员,通过4个月系统学习,成功拿到某AI医疗公司大模型优化岗offer,薪资直接翻3倍!
二、如何学习大模型 AI ?
🔥AI取代的不是人类,而是不会用AI的人!麦肯锡最新报告显示:掌握AI工具的从业者生产效率提升47%,薪资溢价达34%!🚀
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
1️⃣ 提示词工程:把ChatGPT从玩具变成生产工具
2️⃣ RAG系统:让大模型精准输出行业知识
3️⃣ 智能体开发:用AutoGPT打造24小时数字员工
📦熬了三个大夜整理的《AI进化工具包》送你:
✔️ 大厂内部LLM落地手册(含58个真实案例)
✔️ 提示词设计模板库(覆盖12大应用场景)
✔️ 私藏学习路径图(0基础到项目实战仅需90天)
第一阶段(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%免费】