首页 > 其他分享 >利用大模型构造数据集,并微调大模型

利用大模型构造数据集,并微调大模型

时间:2024-11-12 22:14:52浏览次数:3  
标签:chain 模型 微调 构造 dataset import model

一、前言

目前大模型的微调方法有很多,而且大多可以在消费级显卡上进行,每个人都可以在自己的电脑上微调自己的大模型。

前排提示,文末有大模型AGI-CSDN独家资料包哦!

但是在微调时我们时常面对一个问题,就是数据集问题。网络上有许多开源数据集,但是很多时候我们并不想用这些数据集微调模型,我们更希望使用某本书、某个作者的作品、我们自己的聊天记录、某个角色的对话来微调模型。

用于微调的数据通常是成千上万的问答对,如果手工搜集,需要花费大量时间。

文本将介绍一种方式,利用大模型来构造自己的数据集,并使用我们构造的数据集来微调大模型。
在这里插入图片描述

二、构造数据集

2.1 目的

数据集通常是问答对形式,比如alpaca数据集的形式如下:

  {
    "instruction": "保持健康的三个提示。",
    "input": "",
    "output": "以下是保持健康的三个提示:\n\n1. 保持身体活动。每天做适当的身体运动,如散步、跑步或游泳,能促进心血管健康,增强肌肉力量,并有助于减少体重。\n\n2. 均衡饮食。每天食用新鲜的蔬菜、水果、全谷物和脂肪含量低的蛋白质食物,避免高糖、高脂肪和加工食品,以保持健康的饮食习惯。\n\n3. 睡眠充足。睡眠对人体健康至关重要,成年人每天应保证 7-8 小时的睡眠。良好的睡眠有助于减轻压力,促进身体恢复,并提高注意力和记忆力。"
  }


但是实际上我们能拿到的数据通常是一大段文本的形式,比如:

    小时候,那时我还只有6岁,看到一本描写原始森林壮观景象的书,名叫真实的故事。书里有一幅很精彩的插画,画的是一条大蟒蛇正在吞食一只动物,下面就是那幅插画的复制品。
    这本书上说:“大蟒蛇把它们的猎物不加咀嚼地整个吞下去,之后,就再也不动了,然后通过长达六个月的睡眠来消化掉这些食物。”
	...


现在我们要做的就是把大段文本形式的数据转换成alpaca的形式。

在以往我们只能通过人工的方式完成,而现在我们可以借助大模型的能力。大致思路就是让大模型根据文本,总结出对话、问答内容。这点可以通过Prompt工程实现。

2.2 Prompt设计

在系统Prompt中,我们需要强调根据上下文内容,让模型提取对话、问答等内容。比如:

QA_PAIRS_SYSTEM_PROMPT = """  
<Context></Context> 标记中是一段文本,学习和分析它,并整理学习成果:  
- 提出问题并给出每个问题的答案。  
- 答案需详细完整,尽可能保留原文描述。  
- 答案可以包含普通文字、链接、代码、表格、公示、媒体链接等 Markdown 元素。  
- 最多提出 30 个问题。  
"""


这样就可以让模型自己提问,自己回答。然后我们需要规定输出的格式,我们希望得到字典数组,所以用户Prompt可以设置成:

QA_PAIRS_HUMAN_PROMPT = """  
请按以下格式整理学习成果:  
<Context>  
文本  
</Context>  
[  
{{"question": "问题1","answer":"答案1"}},  
{{"question": "问题2","answer":"答案2"}},  
]  
------  
  
我们开始吧!  
  
<Context>  
{text}  
<Context/>  
"""


根据问题不同,可以对上面的内容进行一些调整。下面可以开始编写代码。

2.3 处理文档

首先导入需要用到的模块:

import json  
from typing import List  
  
from tqdm import tqdm  
from langchain_core.prompts import ChatPromptTemplate  
from langchain_core.pydantic_v1 import BaseModel, Field  
from langchain_core.output_parsers import JsonOutputParser  
from langchain_openai import AzureChatOpenAI  
from langchain_community.document_loaders import UnstructuredFileLoader  
from langchain_text_splitters import RecursiveCharacterTextSplitter


在构建chain前,我们先完成文档处理的操作。我们希望传入的内容是文本数据,这里可以是txt等文件形式。我们这里以txt为例:

def split_document(filepath):  
	loader = UnstructuredFileLoader(filepath)  
	text_spliter = RecursiveCharacterTextSplitter(  
		chunk_size=2048,  
		chunk_overlap=128  
	)  
	documents = loader.load_and_split(text_spliter)  
	return documents


使用上面的函数,可以返回大段的文本片段。

2.4 构建chain

下面就是构建用于生成数据集的chain,包括Prompt、LLM、Outputparser三个部分内容分别如下:

2.4.1 Prompt

我们使用ChatPromptTemplate将上面的Prompt整合起来,代码如下:

QA_PAIRS_SYSTEM_PROMPT = "..."
QA_PAIRS_HUMAN_PROMPT = "..."
prompt = ChatPromptTemplate.from_messages([  
	("system", QA_PAIRS_SYSTEM_PROMPT),  
	("human", QA_PAIRS_HUMAN_PROMPT)  
])


在QA_PAIRS_HUMAN_PROMPT中我们添加了{text}占位,invoke时需要传入{“text”: “xxx”}。

2.4.2 LLM

大模型的选择非常多,一般的建议是选择长上下文、且能力比你要微调的模型强的模型。这里使用GPT-3.5-16k,代码如下:

llm = AzureChatOpenAI(  
	azure_endpoint=endpoint,  
	deployment_name=deployment_name,  
	openai_api_key=api_key,  
	openai_api_version="2024-02-01",  
)


2.4.3 OutputParser

最后是提取出结果,我们定义结果的Model:

class QaPair(BaseModel):  
	question: str = Field(description='问题内容')  
	answer: str = Field(description='问题的回答')  
	  
  
class QaPairs(BaseModel):  
	qas: List[QaPair] = Field(description='问答对列表')

parser = JsonOutputParser(pydantic_object=QaPairs)


最后将三者连接起来:

chain = prompt | llm | parser


我们把构建chain的操作写成create_chain函数:

def create_chain():  
	prompt = ChatPromptTemplate.from_messages([  
		("system", QA_PAIRS_SYSTEM_PROMPT),  
		("human", QA_PAIRS_HUMAN_PROMPT)  
	])  
	llm = AzureChatOpenAI(  
		azure_endpoint=endpoint,  
		deployment_name=deployment_name,  
		openai_api_key=api_key,  
		openai_api_version="2024-02-01",  
	)  
	parser = JsonOutputParser(pydantic_object=QaPairs)  
	chain = prompt | llm | parser  
	return chain


下面我们可以来试一试效果:

def main():  
	chain = create_chain()  
	documents = split_document('The.Little.Prince.txt')  
	with open(f'dataset.json', 'w', encoding='utf-8') as f:  
	datas = []  
	bar = tqdm(total=len(documents))  
	for idx, doc in enumerate(documents):  
		bar.update(idx + 1)  
		out = chain.invoke({'text': doc.page_content})  
		datas += out  
		f.write(json.dumps(datas, ensure_ascii=False))  
  
  
if __name__ == '__main__':  
	main()


我使用小王子的书作为测试,下面是生成的部分数据集:

[  	{  		"question": "作者小时候看了一本关于什么的书?",  		"answer": "描写原始森林壮观景象的书"  	},  	{  		"question": "这本书上说大蟒蛇通过什么方式来消化食物?",  		"answer": "通过长达六个月的睡眠来消化食物"  	}	...]


我们可以收集同一作者的大量书籍,使用上面的方式构建数据集。在构建过程中,每次执行后,结果可能不一样,因此可以通过多次构建的方式生成更多样本。

三、微调模型

在准备好数据集后,我们就可以进行微调了,我们可以使用已有的项目进行微调,比如LLaMA-Factory就是一个不错的选择。

具体的微调方式可以参考项目文档。

本文选择使用peft模块实现微调操作,其实其它项目也是使用这个项目来完成。先导入必要的模块:

from peft import LoraConfig, TaskType  
from transformers import Trainer  
from datasets import load_dataset  
from transformers import AutoModelForCausalLM, TrainingArguments, AutoTokenizer  
from peft import get_peft_model


3.1 加载模型和配置LoRA

首先需要加载模型以及配置微调模型,我们选择使用LoRA进行微调:

# 配置参数  
peft_config = LoraConfig(task_type=TaskType.SEQ_2_SEQ_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1)  
# 加载模型  
model = AutoModelForCausalLM.from_pretrained(  
	"microsoft/Phi-3-mini-4k-instruct",  
	trust_remote_code=True  
)  
tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3-mini-4k-instruct")  
model = get_peft_model(model, peft_config)  
model.print_trainable_parameters()


3.2 加载数据集

接下来加载我们创建的数据集:

def tokenize_function(example):  
	encoded = tokenizer(
		example['question'], 
		truncation=True, 
		padding='max_length', 
		max_length=128
	)  
	encoded["labels"] = tokenizer(
		example["answer"], 
		truncation=True, 
		padding="max_length", 
		max_length=128
	)["input_ids"]  
	return encoded

# 加载数据集  
data_files = {"train": "train.json", "validation": "train.json"}  
dataset = load_dataset('./dataset', data_files=data_files)  
tokenized_dataset = dataset.map(tokenize_function, batched=True)


3.3 配置训练参数并训练

接下来配置训练参数开始训练:

training_args = TrainingArguments(  
	output_dir="outputs",  
	learning_rate=1e-3,  
	per_device_train_batch_size=4,  
	per_device_eval_batch_size=4,  
	num_train_epochs=2,  
	weight_decay=0.01,  
	evaluation_strategy="epoch",  
	save_strategy="epoch",  
	load_best_model_at_end=True,  
)  
trainer = Trainer(  
	model=model,  
	args=training_args,  
	train_dataset=tokenized_dataset["train"],  
	eval_dataset=tokenized_dataset["validation"],  
	tokenizer=tokenizer,  
)  
  
trainer.train()  
model.save_pretrained("outputs")


我们可以根据硬件情况调整per_device_train_batch_size和per_device_eval_batch_size。现在只需要运行代码,等待片刻即可训练完成。

四、推理

接下来我们要做的就是推理了。LoRA是一个旁支网络,我们需要在原有的模型上,添加LoRA,添加方式如下:

model.load_adapter('outputs', adapter_name='lora01')  
model.set_adapter("lora01")


调用上面代码后,model的推理操作就是添加LoRA后的推理。推理的完整代码如下:

from transformers import AutoModelForCausalLM, AutoTokenizer  
  
model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-3-mini-4k-instruct")  
tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3-mini-4k-instruct")  
  
model = model.to("cuda")  
model.load_adapter('outputs', adapter_name='lora01')  
model.set_adapter("lora01")  
model.eval()  
inputs = tokenizer("作者小时候看了一本关于什么的书?", return_tensors="pt")  
  
outputs = model.generate(input_ids=inputs["input_ids"].to("cuda"), max_new_tokens=50)  
print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0])


最后我们可以和使用正常的AutoModelForCausalLM模型一样使用微调后的模型。

读者福利:如果大家对大模型感兴趣,这套大模型学习资料一定对你有用

对于0基础小白入门:

如果你是零基础小白,想快速入门大模型是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。

包括:大模型学习线路汇总、学习阶段,大模型实战案例,大模型学习视频,人工智能、机器学习、大模型书籍PDF。带你从零基础系统性的学好大模型!

标签:chain,模型,微调,构造,dataset,import,model
From: https://blog.csdn.net/xzp740813/article/details/143725649

相关文章

  • 2024大模型典型示范应用案例集——附219页PDF
    2024年是大模型深入赋能千行百业,融入实体经济,助力科技创新的一年。截至今年5月,我国国产大模型的数量已经超过300个,预示着大模型在各行业场景的创新应用和深度拓展,对培育新质生产力、高水平赋能新型工业化、推动高质量发展发挥了重要作用。今年,国务院政府工作报告首次提出......
  • 上机实验:数据准备与模型评估
    1、实验目的熟悉Python的基本操作,掌握对数据集的读写实现、对模型性能的评估实现的能力;加深对训练集、测试集、N折交叉验证、模型评估标准的理解。2、实验内容(1)利用pandas库从本地读取iris数据集;(2)从scikit-learn库中直接加载iris数据集;(3)实现五折交叉验证进行模型......
  • 大模型为什么是深度学习的未来?
    当今社会是科技的社会,是算力快速发展的时代。随着数据中心、东数西算、高性能计算、数据分析、数据挖掘的快速发展,大模型得到了快速地发展。大模型是“大算力+强算法”相结合的产物,是人工智能的发展趋势和未来。目前,大规模的生态已初具规模。其可以实现从“手工作坊”到“工......
  • 大模型可以在哪些场景应用落地?
    大模型是什么?大模型是指模型具有庞大的参数规模和复杂程度的机器学习模型。在深度学习领域,大模型通常是指具有数百万到数十亿参数的神经网络模型。前排提示,文末有大模型AGI-CSDN独家资料包哦!大模型是指模型具有庞大的参数规模和复杂程度的机器学习模型。在深度学习领域,大......
  • 本地部署大模型的几种方式
    现在大模型可谓是满天飞,只要你稍微关注时下的AI资讯,几乎每天都有新的AI大模型出现.这之中当然有诸如GhatGPT,Gemini这样的私有化大模型,更吸引人关注的可能是开源的可私有化部署的一些大模型.比如Meta前两天开放的Lamma3,Google的Gemma开源模型,国内也有Qwen以及......
  • 一口气了解大模型相关通识,基础笔记!
    一、大模型生态有哪些语言类大模型:GPT-3、GPT-3.5、GPT-4系列模型。并且,OpenAl在训练GPT-3的同时训练了参数不同、复杂度各不相同的A、B、C、D四项大模型(基座模型),用于不同场景的应用;前排提示,文末有大模型AGI-CSDN独家资料包哦!其中,A、B、C、D模型的全称分别是ada、b......
  • 计算机网络基础:从IP地址到分层模型
    计算机网络1.计算机网络概述概述​计算机网络是指两台或更多的计算机组成的网络,在同一个网络中,任意两台计算机都可以直接通信。互联网是网络的网络(Internet),即把很多计算机网络连接起来,形成一个全球统一的互联网,互联网中的所有计算机都需要遵循同一种网络协议。网络协议......
  • 书生大模型实战营第四期 L1G6000 OpenCompass 评测书生大模型实践
    评测书生大模型实践文章目录评测书生大模型实践前言评测API模型前言OpenCompass提供了API模式评测和本地直接评测两种方式。其中API模式评测针对那些以API服务形式部署的模型,而本地直接评测则面向那些可以获取到模型权重文件的情况。参考:https://github.......
  • 在通讯领域,特别是在自由空间光通信(Free Space Optics, FSO)通道模拟中,选择合适的模型需
    在通讯领域,特别是在自由空间光通信(FreeSpaceOptics,FSO)通道模拟中,选择合适的模型需要考虑模型对动态变化的光信号传播环境的适应性和预测能力。根据搜索结果,以下是一些可能适合通讯领域FSO通道模拟的模型:TACTiS-2:这是一个灵活的多变量概率时间序列预测模型,它简化了attenti......
  • 基于yolov8、yolov5的番茄成熟度检测识别系统(含UI界面、训练好的模型、Python代码、数
    摘要:番茄成熟度检测在农业生产及质量控制中起着至关重要的作用,不仅能帮助农民及时采摘成熟的番茄,还为自动化农业监测提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的番茄成熟度检测模型,该模型使用了大量图片进行训练,能够准确识别不同成熟度阶段的......