学习记录:初次学习使用transformers进行大模型微调

server/2025/2/27 11:55:52/

初次使用transformers进行大模型微调

环境:

电脑配置:
笔记本电脑:I5(6核12线程) + 16G + RTX3070(8G显存)
需要自行解决科学上网

Python环境:
python版本:3.8.8
大模型:microsoft/DialoGPT-medium(微软的对话大模型,模型小,笔记本也能学习微调)
数据集:daily_dialog (日常对话数据集)

其他:
模型及数据集:使用来源于抱抱脸

微调大模型

准备工作:

下载模型:

找到自己想要的模型:

  1. 打开抱抱脸官网——点击Model:
    在这里插入图片描述

  2. 输入要搜索的模型(这里以DialoGPT-medium为例):
    在这里插入图片描述

  3. 复制名称到代码中替换要下载的模型名称:

在这里插入图片描述
模型下载:

import os
from transformers import AutoModel, AutoTokenizer# 因为使用了科学上网,需要进行处理
os.environ["HTTP_PROXY"] = "http://127.0.0.1:xxxx"
os.environ["HTTPS_PROXY"] = "http://127.0.0.1:xxxx"if __name__ == '__main__':# model_name = 'google-t5/t5-small'  # 要下载的模型名称model_name = 'microsoft/DialoGPT-medium'  # 要下载的模型名称 需要到抱抱脸进行复制cache_dir = r'xxxx'  # 模型保存位置# 加载模型时指定下载路径model = AutoModel.from_pretrained(model_name, cache_dir=cache_dir)
下载数据集:

找到自己想要的模型:

  1. 打开抱抱脸官网——点击Datasets:List item
  2. 输入要搜索的内容,点击对应数据集进入:
    在这里插入图片描述
  3. 找到适合用的模型后,点击复制
    在这里插入图片描述

开始微调训练

代码示例:

# 系统模块
import os# 第三方库
from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer
from datasets import load_dataset# 设置代理(注意:可能需要根据实际网络环境调整或移除)
os.environ["HTTP_PROXY"] = "http://127.0.0.1:xxxx"  # HTTP代理设置
os.environ["HTTPS_PROXY"] = "http://127.0.0.1:xxxx"  # HTTPS代理设置if __name__ == '__main__':# 数据准备阶段 --------------------------------------------------------------# 加载完整数据集(daily_dialog包含日常对话数据集)full_dataset = load_dataset("daily_dialog", trust_remote_code=True)# 创建子数据集(仅使用训练集前500条样本,用于快速实验)dataset = {"train": full_dataset["train"].select(range(500))  # select保持数据集结构}# 模型加载阶段 --------------------------------------------------------------# 模型配置参数model_name = "microsoft/DialoGPT-medium"  # 使用微软的对话生成预训练模型cache_dir = r'xxx'  # 本地模型缓存路径# 加载分词器(重要:设置填充token与EOS token一致)tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir=cache_dir)tokenizer.pad_token = tokenizer.eos_token  # 将填充token设置为与EOS相同# 加载预训练模型(使用因果语言模型结构)model = AutoModelForCausalLM.from_pretrained(model_name, cache_dir=cache_dir)# 数据预处理阶段 ------------------------------------------------------------def tokenize_function(examples):"""将对话数据转换为模型输入格式的预处理函数"""# 将多轮对话用EOS token连接,并在结尾添加EOSdialogues = [tokenizer.eos_token.join(dialog) + tokenizer.eos_tokenfor dialog in examples["dialog"]]# 对文本进行分词处理tokenized = tokenizer(dialogues,truncation=True,  # 启用截断max_length=512,  # 最大序列长度padding="max_length"  # 填充到最大长度(静态填充))# 创建标签(对于因果语言模型,标签与输入相同)tokenized["labels"] = tokenized["input_ids"].copy()return tokenized# 应用预处理(保留数据集结构)tokenized_dataset = {"train": dataset["train"].map(tokenize_function,batched=True,  # 批量处理提升效率batch_size=50,  # 每批处理50个样本remove_columns=["dialog", "act", "emotion"]  # 移除原始文本列)}# 数据验证(检查预处理结果)print("Sample keys:", tokenized_dataset["train"][0].keys())  # 应包含input_ids, attention_mask, labelsprint("Input IDs:", tokenized_dataset["train"][0]["input_ids"][:5])  # 检查前5个token# 训练配置阶段 --------------------------------------------------------------training_args = TrainingArguments(output_dir="./dialo_finetuned",  # 输出目录per_device_train_batch_size=2,  # 每个设备的批次大小(根据显存调整)gradient_accumulation_steps=8,  # 梯度累积步数(模拟更大batch size)learning_rate=1e-5,  # 初始学习率(可调超参数)num_train_epochs=3,  # 训练轮次(根据需求调整)fp16=True,  # 启用混合精度训练(需要GPU支持)logging_steps=10,  # 每10步记录日志# 可添加的优化参数:# evaluation_strategy="steps",    # 添加验证策略# save_strategy="epoch",          # 保存策略# warmup_steps=100,               # 学习率预热步数)# 创建训练器trainer = Trainer(model=model,args=training_args,train_dataset=tokenized_dataset["train"],  # 训练数据集# 可扩展功能:# eval_dataset=tokenized_dataset["validation"],  # 添加验证集# data_collator=...,             # 自定义数据整理器# compute_metrics=...,           # 添加评估指标)# 训练执行阶段 --------------------------------------------------------------trainer.train()  # 启动训练# 模型保存阶段 --------------------------------------------------------------model.save_pretrained("./dialo_finetuned")  # 保存模型权重tokenizer.save_pretrained("./dialo_finetuned")  # 保存分词器# 推荐使用以下方式统一保存:trainer.save_model("./dialo_finetuned")       # 官方推荐保存方式

微调后使用

代码:

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
from transformers import TextStreamer
from collections import deque
import torchdef optimized_generation(text, tokenizer, model):inputs = tokenizer(text, return_tensors="pt").to(model.device)outputs = model.generate(**inputs,max_new_tokens=150,temperature=0.9,  # 越高越有创意 (0-1)top_k=50,  # 限制候选词数量top_p=0.95,  # 核采样阈值repetition_penalty=1.2,  # 抑制重复num_beams=3,  # 束搜索宽度early_stopping=True,do_sample=True)return tokenizer.decode(outputs[0], skip_special_tokens=True)# 单轮对话
def simple_chat(model_path, text, max_length=100):"""单轮对话:param text::param max_length::return:"""# 加载模型和分词器tokenizer = AutoTokenizer.from_pretrained(model_path)model = AutoModelForCausalLM.from_pretrained(model_path)# 确保pad_token设置正确tokenizer.pad_token = tokenizer.eos_token# inputs = tokenizer(text + tokenizer.eos_token, return_tensors="pt")# outputs = model.generate(#     inputs.input_ids,#     max_length=max_length,#     pad_token_id=tokenizer.eos_token_id,#     temperature=0.7,#     do_sample=True# )# response = tokenizer.decode(outputs[0], skip_special_tokens=True)response = optimized_generation(text + tokenizer.eos_token, tokenizer, model)return response[len(text):]  # 去除输入文本# 多轮对话
class DialogueBot:def __init__(self, model_path, max_history=3):self.tokenizer = AutoTokenizer.from_pretrained(model_path)self.model = AutoModelForCausalLM.from_pretrained(model_path).to("cuda")self.max_history = max_historyself.history = deque(maxlen=max_history * 2)  # 每轮包含用户和机器人各一条# 确保pad_token设置if self.tokenizer.pad_token is None:self.tokenizer.pad_token = self.tokenizer.eos_tokendef generate_response(self, user_input):# 添加用户输入(带EOS)self.history.append(f"User: {user_input}{self.tokenizer.eos_token}")# 构建prompt并编码prompt = self._build_prompt()inputs = self.tokenizer(prompt,return_tensors="pt",max_length=512,truncation=True).to(self.model.device)# 流式输出# streamer = TextStreamer(self.tokenizer)# 生成回复outputs = self.model.generate(inputs.input_ids,attention_mask=inputs.attention_mask,max_new_tokens=150,temperature=0.85,top_p=0.95,eos_token_id=self.tokenizer.eos_token_id,pad_token_id=self.tokenizer.eos_token_id,do_sample=True,# streamer=streamer,early_stopping=True)# 解码并处理回复full_response = self.tokenizer.decode(outputs[0][inputs.input_ids.shape[-1]:],skip_special_tokens=True)# 清理无效内容(按第一个EOS截断)clean_response = full_response.split(self.tokenizer.eos_token)[0].strip()# 添加机器人回复到历史(带EOS)self.history.append(f"Bot: {clean_response}{self.tokenizer.eos_token}")return clean_responsedef _build_prompt(self):return "".join(self.history)if __name__ == '__main__':# 指定模型路径model_path = "./dialo_finetuned"# 测试单轮对话print(simple_chat(model_path, "Hello, how are you?"))# 使用示例 多轮对话# bot = DialogueBot(model_path)# while True:#     user_input = input("You: ")#     if user_input.lower() == "exit":#         break#     print("Bot:", bot.generate_response(user_input))

http://www.ppmy.cn/server/171027.html

相关文章

鸿蒙NEXT开发-视频播放绘图能力

注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识 目录 1. 视频播放 1.1 视频播放基本介绍 1.2…

html - 手工添加上次阅读的位置, 方便下次阅读

文章目录 html - 手工添加上次阅读的位置, 方便下次阅读概述笔记END html - 手工添加上次阅读的位置, 方便下次阅读 概述 在看一本电子书,有pdf格式的,但是比较喜欢看html格式的(复制比较方便)。 但是有个缺点,如果看到一半,关掉…

Megatron-LM:使用模型并行训练数十亿参数的语言模型

摘要 最近在语言建模方面的工作表明,训练大型Transformer模型能够推动自然语言处理应用的技术前沿。然而,由于内存限制,训练非常大的模型可能相当困难。在这项工作中,我们展示了训练极大Transformer模型的技术,并实现…

DeepSeek 与网络安全:AI 在网络安全领域的应用与挑战

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 1. 引言 在当今数字化时代,网络安全已成为国家、企业和个人面临的重要挑战。从传统的病毒、木马攻击,到高…

批量将手机照片修改为一寸白底证件照的方法

生活中经常需要用到一寸白底证件照,但每次去照相馆拍摄既费时又麻烦。其实,利用手机拍照和批量证件照生成工具,就能轻松批量修改手机照片为一寸白底证件照。 首先,在电脑浏览器中打开【报名电子照助手】,找到“批量证件…

神经网络参数量计算

算一个只有两层的神经网络的参数量,我们需要考虑两层之间的连接权重和偏置项。以下是详细的计算步骤: 网络结构 输入层(第一层): 有 2 个神经元。 输出层(第二层): 有 3 个神经元。…

使用消息队列怎样防止消息重复?

大家好,我是君哥。 使用消息队列时,我们经常会遇到一个可能对业务产生影响的问题,消息重复。在订单、扣款、对账等对幂等有要求的场景,消息重复的问题必须解决。 那怎样应对重复消息呢?今天来聊一聊这个话题。 1.三…

机器学习破局指南:零基础6个月系统训练计划

以下是为零基础学习者制定的「机器学习」系统学习计划(含学习路径资源推荐),分为6个阶段,建议学习周期4-6个月: 一、基础准备阶段(1-2周) 目标:掌握必要数学工具与编程基础 数学基础…