12 对话模型微调2

news/2024/9/18 20:55:19/ 标签: 深度学习, 人工智能

1 P-Tuning

        P-Tuning 是在 Prompt-Tuning的基础上,通过新增 LSTM 或 MLP 编码模块来加速模型的收敛;

之前的实验也看到了使用prompt训练速度很慢,那么P-Tuning呢

参数占比:

trainable params: 5,267,456 || all params: 1,308,379,136 || trainable%: 0.4026

1.1 代码部分

PromptEncoderConfig: 

PromptEncoderConfig 类通常包含了以下配置项:

  1. Prompt Length:提示向量的长度,即提示向量中包含的token数量。
  2. Embedding Dimension:提示向量的嵌入维度,通常与预训练模型的隐藏层维度相同。
  3. Initialization Method:提示向量的初始化方法,可以是随机初始化或其他预定义的方式。
  4. Trainable Parameters:哪些参数是可训练的,例如提示向量本身是否可训练。
  5. Additional Layers:是否添加额外的层来进一步处理提示向量,例如线性层、LSTM层等。

示例代码

from datasets import Dataset
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForSeq2Seq, TrainingArguments, Trainerds = Dataset.load_from_disk("../data/")
tokenizer = AutoTokenizer.from_pretrained("../bloom-model/")
def process_func(example):MAX_LENGTH = 256input_ids, attention_mask, labels = [], [], []instruction = tokenizer("\n".join(["Human: " + example["instruction"], example["input"]]).strip() + "\n\nAssistant: ")response = tokenizer(example["output"] + tokenizer.eos_token)input_ids = instruction["input_ids"] + response["input_ids"]attention_mask = instruction["attention_mask"] + response["attention_mask"]labels = [-100] * len(instruction["input_ids"]) + response["input_ids"]if len(input_ids) > MAX_LENGTH:input_ids = input_ids[:MAX_LENGTH]attention_mask = attention_mask[:MAX_LENGTH]labels = labels[:MAX_LENGTH]return {"input_ids": input_ids,"attention_mask": attention_mask,"labels": labels}tokenized_ds = ds.map(process_func, remove_columns=ds.column_names)from transformers import DataCollatorWithPadding
from transformers.trainer_callback import TrainerCallback
import matplotlib.pyplot as pltfrom peft import PromptEncoderConfig, TaskType, get_peft_model, PromptEncoderReparameterizationTypeconfig = PromptEncoderConfig(task_type=TaskType.CAUSAL_LM, num_virtual_tokens=10,encoder_reparameterization_type=PromptEncoderReparameterizationType.MLP,encoder_dropout=0.1, encoder_num_layers=5, encoder_hidden_size=1024)
config# 自定义回调类,用于在训练过程中打印损失
model = AutoModelForCausalLM.from_pretrained("../bloom-model/")
model = get_peft_model(model, config)
print(model.print_trainable_parameters())class PrintLossCallback(TrainerCallback):def __init__(self):self.losses = []self.steps = []def on_log(self, args, state, control, logs=None, **kwargs):# 打印训练过程中的日志信息try:if logs is not None:print(f"Step {state.global_step}: Loss={logs['loss']:.4f}, Learning Rate={logs['learning_rate']:.6f}")self.losses.append(logs['loss'])self.steps.append(state.global_step)except Exception as e :print(f'on_log error {e}')def plot_losses(self):plt.figure(figsize=(10, 5))plt.plot(self.steps, self.losses, label='Training Loss')plt.xlabel('Steps')plt.ylabel('Loss')plt.title('Training Loss Over Time')plt.legend()plt.show()args = TrainingArguments(output_dir="./chatbot_ptune",per_device_train_batch_size=8,gradient_accumulation_steps=8,logging_steps=10,num_train_epochs=1,save_steps=100,
)
plot_losses_callback = PrintLossCallback()
trainer = Trainer(model=model,args=args,tokenizer=tokenizer,train_dataset=tokenized_ds,data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),callbacks=[plot_losses_callback]  # 注册自定义回调
)if torch.cuda.is_available():trainer.model = trainer.model.to("cuda")
# 训练模型
trainer.train()

推理: 

from peft import PeftModel
# 在一个jupyter文件中,如果前面已经加载了模型,并对模型做了一定修改,则需要重新加载原始模型
model = AutoModelForCausalLM.from_pretrained("../bloom-model/")
peft_model = PeftModel.from_pretrained(model=model, model_id="./chatbot_ptune/")peft_model = peft_model.cuda()
ipt = tokenizer("Human: {}\n{}".format("考试有哪些技巧?", "").strip() + "\n\nAssistant: ", return_tensors="pt").to(peft_model.device)
print(tokenizer.decode(peft_model.generate(**ipt, max_length=128,do_sample=True)[0], skip_special_tokens=True))

可能没有有关作弊的语料。 

整体上效果也不咋滴!

2 Lora

2.1  算法思想

LoRA 的思想很简单:

  • 在原始 PLM (Pre-trained Language Model) 旁边增加一个旁路,做一个降维再升维的操作,来模拟所谓的intrinsic rank
  • 训练的时候固定 PLM 的参数,只训练降维矩阵 A 与升维矩阵 B 。而模型的输入输出维度不变,输出时将 BA 与 PLM 的参数叠加。
  • 用随机高斯分布初始化 A ,用 0 矩阵初始化 B ,保证训练的开始此旁路矩阵依然是 0 矩阵。

在LoRA中,降维矩阵A和升维矩阵B的初始化方式是有特定原因的。降维矩阵A使用随机高斯分布初始化,是为了保持模型的表达能力。高斯分布的随机初始化可以帮助模型在训练初期快速学习到有效的特征表示,从而提高模型的性能。而升维矩阵B使用0矩阵初始化,是为了减少对原始模型参数的影响。将B初始化为0矩阵,使得在训练初期,模型仍然保持原始预训练参数的输出,从而保证了模型在微调初期的稳定性。如果将A和B都用0矩阵初始化,那么在训练初期,模型将无法学习到有效的特征表示,导致微调效果不佳。如果A用0矩阵初始化,B用随机高斯分布初始化,那么在训练初期,模型可能会受到B矩阵的干扰,导致训练过程不稳定,甚至可能损害模型的性能。总之,LoRA中降维矩阵A和升维矩阵B的初始化方式是为了保持模型的表达能力,同时减少对原始模型参数的影响,从而提高微调的效率和稳定性。在实际应用中,可以根据具体任务和模型需求,对初始化方式进行适当调整。

2.2 参数

peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1
)

参数说明:

  • task_type:指定任务类型。如:条件生成任务(SEQ_2_SEQ_LM),因果语言建模(CAUSAL_LM)等。
  • inference_mode:是否在推理模式下使用Peft模型。
  • r: LoRA低秩矩阵的维数。关于秩的选择,通常,使用4,8,16即可。
  • lora_alpha: LoRA低秩矩阵的缩放系数,为一个常数超参,调整alpha与调整学习率类似。缩放系数(通常标记为α,alpha)就是用来控制LoRA层输出的缩放程度,从而影响最终叠加到原有模型权重上的更新量。可以把 α 值设置成 rank 值的两倍;
  • lora_dropout:LoRA 层的丢弃(dropout)率,取值范围为[0, 1)
  • target_modules:要替换为 LoRA 的模块名称列表或模块名称的正则表达式。针对不同类型的模型,模块名称不一样,因此,我们需要根据具体的模型进行设置,比如,LLaMa的默认模块名为[q_proj, v_proj],我们也可以自行指定为:[q_proj,k_proj,v_proj,o_proj]。 在 PEFT 中支持的模型默认的模块名如下所示:
  • TRANSFORMERS_MODELS_TO_LORA_TARGET_MODULES_MAPPING = {"t5": ["q", "v"],"mt5": ["q", "v"],"bart": ["q_proj", "v_proj"],"gpt2": ["c_attn"],"bloom": ["query_key_value"],"blip-2": ["q", "v", "q_proj", "v_proj"],"opt": ["q_proj", "v_proj"],"gptj": ["q_proj", "v_proj"],"gpt_neox": ["query_key_value"],"gpt_neo": ["q_proj", "v_proj"],"bert": ["query", "value"],"roberta": ["query", "value"],"xlm-roberta": ["query", "value"],"electra": ["query", "value"],"deberta-v2": ["query_proj", "value_proj"],"deberta": ["in_proj"],"layoutlm": ["query", "value"],"llama": ["q_proj", "v_proj"],"chatglm": ["query_key_value"],"gpt_bigcode": ["c_attn"],"mpt": ["Wqkv"],
    }
from datasets import Dataset
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForSeq2Seq, TrainingArguments, Trainerds = Dataset.load_from_disk("../data/")
tokenizer = AutoTokenizer.from_pretrained("../bloom-model/")
def process_func(example):MAX_LENGTH = 256input_ids, attention_mask, labels = [], [], []instruction = tokenizer("\n".join(["Human: " + example["instruction"], example["input"]]).strip() + "\n\nAssistant: ")response = tokenizer(example["output"] + tokenizer.eos_token)input_ids = instruction["input_ids"] + response["input_ids"]attention_mask = instruction["attention_mask"] + response["attention_mask"]labels = [-100] * len(instruction["input_ids"]) + response["input_ids"]if len(input_ids) > MAX_LENGTH:input_ids = input_ids[:MAX_LENGTH]attention_mask = attention_mask[:MAX_LENGTH]labels = labels[:MAX_LENGTH]return {"input_ids": input_ids,"attention_mask": attention_mask,"labels": labels}tokenized_ds = ds.map(process_func, remove_columns=ds.column_names)from transformers import DataCollatorWithPadding
from transformers.trainer_callback import TrainerCallback
import matplotlib.pyplot as pltfrom peft import LoraConfig, TaskType, get_peft_modelconfig = LoraConfig(task_type=TaskType.CAUSAL_LM, target_modules=".*\.1.*query_key_value", modules_to_save=["word_embeddings"])
config# 自定义回调类,用于在训练过程中打印损失
model = AutoModelForCausalLM.from_pretrained("../bloom-model/")
model = get_peft_model(model, config)
print(model.print_trainable_parameters())class PrintLossCallback(TrainerCallback):def __init__(self):self.losses = []self.steps = []def on_log(self, args, state, control, logs=None, **kwargs):# 打印训练过程中的日志信息try:if logs is not None:print(f"Step {state.global_step}: Loss={logs['loss']:.4f}, Learning Rate={logs['learning_rate']:.6f}")self.losses.append(logs['loss'])self.steps.append(state.global_step)except Exception as e :print(f'on_log error {e}')def plot_losses(self):plt.figure(figsize=(10, 5))plt.plot(self.steps, self.losses, label='Training Loss')plt.xlabel('Steps')plt.ylabel('Loss')plt.title('Training Loss Over Time')plt.legend()plt.show()args = TrainingArguments(output_dir="./chatbot_ptune",per_device_train_batch_size=8,gradient_accumulation_steps=8,logging_steps=10,num_train_epochs=1,save_steps=1000,
)
plot_losses_callback = PrintLossCallback()
trainer = Trainer(model=model,args=args,tokenizer=tokenizer,train_dataset=tokenized_ds,data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),callbacks=[plot_losses_callback]  # 注册自定义回调
)if torch.cuda.is_available():trainer.model = trainer.model.to("cuda")
# 训练模型
trainer.train()

效果还一般般!但是从损失曲线图来看要稳定一些。


http://www.ppmy.cn/news/1518746.html

相关文章

Windows服务器应急响应(下)

目录 介绍步骤 介绍 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体&#x…

sql 优化,提高查询速度

文章目录 一、前言二、建议2.1 使用索引2.2 避免使用select *2.3. 使用表连接代替子查询2.4. 优化WHERE子句,减少返回结果集的大小2.5 用union all代替union2.6 使用合适的聚合策略2.7 避免在WHERE子句中使用函数2.8 使用EXPLAIN分析查询2.9 小表驱动大表2.10 使用窗…

PHP程序设计教案

文章目录: 一:前言 1.什么是PHP 2.环境安装 3. 语法规范 3.1 注释 3.2 分隔符 3.3 其他规范 二:基础语法 1.输出 1.1 echo 1.2 print 1.3 var_dump类型和值 1.4 print_r()易读 2.常量变量 2.1 常量 2.1.1 define()/const…

vue前端实现登录页面的验证码(新手版)

一、搭建vue前端登录页面 <template><div style"width: 800px; margin: 5px auto; background-color: #17ecf3"><div align"center"><h2>用户登录</h2></div><div style"width: 60%; margin: 1px auto"…

如何解决`.gitignore`规则不生效或已提交相关文件的问题

前言 在使用Git进行版本控制时&#xff0c;.gitignore文件是一个非常有用的工具&#xff0c;它可以帮助我们排除不需要跟踪的文件或目录。然而&#xff0c;在实际开发过程中&#xff0c;有时我们会遇到.gitignore规则不生效的情况&#xff0c;或者是不小心将不应提交的文件提交…

RabbitMQ 入门教程

RabbitMQ 入门教程 1. 引言 RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;实现高级消息队列协议 (AMQP)。它能帮助开发者实现应用程序间的解耦、异步处理、流量削峰等需求。 2. 安装与配置 2.1 安装RabbitMQ 2.1.1 Ubuntu bash sudo apt-get update sudo apt…

动态IP池在数据抓取中的应用与优势

随着互联网技术的快速发展&#xff0c;数据抓取&#xff08;Web Scraping&#xff09;已经成为获取互联网信息的重要手段。然而&#xff0c;在进行大规模数据抓取时&#xff0c;往往会遇到反爬虫机制、IP封禁等问题。动态IP池作为一种解决方案&#xff0c;可以有效地绕过这些障…

告别手动记录,音频转文字软件助力会议记录新高度

如果你突然被领导指派去参与一场会议&#xff0c;身边没有纸笔要怎么记录转达会议内容呢&#xff1f;我往往会采用手机的录音功能来记录会议内容会后再进行整理。这次我们就来探索音频转文字工具怎么提升我们的工作效率。 1.365在线转文字 链接传送&#xff1a;https://www.p…

微服务优缺点以及如何拆分

微服务优点 1,降低代码逻辑复杂度。 单个微服务模块相当于一个项目&#xff0c;开发人员只用关心这个模块的逻辑即可。 2&#xff0c;技术栈更加灵活 不同的微服务可以使用合适的语言架构实现&#xff0c;然后把服务注册到一个注册中心即可相互调用。 3&#xff0c;按需伸缩 当…

人工智能工作级开发者认证 HCCDP – AI 真题2 答案

1.GBDT通过bagging的防范可以对样本和特征都进行采集。答案:FALSE 原因:GBDT可以对样本采集,不能对特征采集 2.深度学习是机器学习的一个分支。答案:true 3.softmax激活函数的作用是减少及时量和防止梯度消失。答案false 4.在建筑施工现场,基于定制化的图像识别目标检测系统,…

Node.js 安装与使用及连接 MongoDB 的详细教程

下面我将详细讲解如何安装 Node.js、介绍 Node.js 的脚手架工具、使用 Express 脚手架创建项目&#xff0c;以及如何安装和连接 MongoDB。 一、Node.js 安装 下载 Node.js&#xff1a; 访问 Node.js 官方网站。 根据你的操作系统选择最新的 LTS&#xff08;长期支持版&#x…

从自动驾驶看无人驾驶叉车的技术落地和应用

摘 要 &#xff5c; 介绍无人驾驶叉车在自动驾驶技术中的应用&#xff0c;分析其关键技术&#xff0c;如环境感知、定位、路径规划等&#xff0c;并讨论机器学习算法和强化学习算法的应用以提高无人叉车的运行效率和准确性。无人叉车在封闭结构化环境、机器学习、有效数据集等方…

参加 帆软 BI 上海城市 课堂(08-30培训)

参加 帆软 BI 城市 课堂&#xff08;0830&#xff09;&#xff1a; 由于目前是自由职业&#xff0c;也想学习一下新的知识 。所以参加本次的培训&#xff0c;总的来说还是比较专业。 培训在 上海 帆软的总部 环球港进行。时间是 13:30~17&#xff1a;00 老师很专业。学习中 课…

关于前端布局的基础知识

float 横向布局 float 实现横向布局&#xff0c;需要向横着布局的元素添加float 其值left right 存在问题 如果使用float 所在父级五高度&#xff0c;会导致下方的元素上移 top的高度被吞了 解决方法&#xff1a; 给父级元素设置高度&#xff1a;不推荐&#xff0c;需要给父级…

LeetCode第65题 有效数字 结合设计模式:状态模式

思路&#xff1a;有限状态机&#xff0c;结合Java的设计模式&#xff1a;状态模式。 单纯用状态机会有大量的if-else&#xff0c;非常不好看&#xff0c;思路不清晰 用设计模式则非常清楚。但是设计模式是为了给人理解的&#xff0c;对机器而言也可能稍微影响性能&#xff1b; …

IO练习--随机点名

随机点名器1 需求: 有一个文件里面存储了班级同学的信息&#xff0c;每一个信息占一行。 格式为:张三-男-23 要求通过程序实现随机点名器。 运行效果: 第一次运行程序:随机同学姓名1(只显示名字) 第二次运行程序:随机同学姓名2(只显示名字) 第三次运行程序:随机同学姓名3(只显…

【精选】基于Hadoop的用户网站浏览分析的设计与实现(全网最新定制,独一无二)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

2.10鼠标事件

目录 实验原理 实验代码 运行结果 文章参考 实验原理 在 OpenCV 中存在鼠标的操作&#xff0c;比如左键单击、双击等。对于 OpenCV 来讲&#xff0c;用户的鼠标操作被认为发生了一个鼠标事件&#xff0c;需要对这个鼠标事件进行处理&#xff0c;这就是事件的响应。下面我们…

软件设计原则之接口隔离原则

接口隔离原则&#xff08;Interface Segregation Principle, ISP&#xff09;是面向对象设计中的一个重要原则&#xff0c;它属于SOLID原则之一。这个原则强调客户端&#xff08;即接口的调用者&#xff09;不应该被迫依赖于它们不使用的方法。换句话说&#xff0c;一个类对另一…

centos安装docker并配置加速器

docker安装与卸载&#xff1a; 1、检查当前是否安装docker yum list installed | grep docker2、卸载docker 根据yum list installed | grep docker查询出来的内容&#xff0c;逐个进行删除 yum remove docker.x86 64 -y3、启动与关闭docker 4、删除/etc/docker文件夹 如果…