织梦 网站标题,unity制作app教程,网络服务提供者知道或者应当知道网络用户,做网站网页维护手机App开发代码的摘要说明 一、整体功能概述 这段 Python 代码主要实现了基于 Hugging Face Transformers 库对预训练语言模型#xff08;具体为 TAIDE-LX-7B-Chat 模型#xff09;进行微调#xff08;Fine-tuning#xff09;的功能#xff0c;使其能更好地应用于生成唐诗相关内容的…代码的摘要说明 一、整体功能概述 这段 Python 代码主要实现了基于 Hugging Face Transformers 库对预训练语言模型具体为 TAIDE-LX-7B-Chat 模型进行微调Fine-tuning的功能使其能更好地应用于生成唐诗相关内容的任务。整个流程涵盖了数据加载与预处理、模型配置、模型训练以及训练后模型的测试与结果保存等环节。 二、代码各部分详细说明 导入模块部分 导入了多个常用的 Python 库如 os、sys、argparse 等基础库以及和深度学习、自然语言处理相关的库像 torch、transformers、peft 等还导入了用于忽略警告信息、文本颜色控制等功能的相关模块为后续代码实现做准备。 基础配置与参数设置部分 模型相关路径定义了模型名称、模型所在目录、工作目录、输出目录以及检查点目录等路径相关的变量确保后续文件操作如加载模型、保存训练结果等能找到正确的位置。 训练参数设置设定了训练的总轮数num_epoch、学习率LEARNING_RATE还包括一系列影响模型训练和推理的超参数例如用于训练的数据集数量num_train_data、文本截断长度CUTOFF_LEN、LORA 相关参数LORA_R、LORA_ALPHA、LORA_DROPOUT、验证集大小VAL_SET_SIZE、微批次大小MICRO_BATCH_SIZE、梯度累积步数GRADIENT_ACCUMULATION_STEPS等这些参数将用于控制模型训练过程和微调效果。 分布式训练配置根据环境变量 WORLD_SIZE 判断是否进行分布式训练若需要则配置相应的设备映射device_map。 数据加载与预处理部分 创建目录首先确保输出目录和检查点目录存在若不存在则创建它们用于后续保存训练结果和模型检查点。 加载数据集从指定的 json 文件路径dataset_dir读取原始数据集先将其加载为 Python 的字典数据结构通过 json.load然后从中截取指定数量由 num_train_data 决定的数据保存为临时数据集文件tmp_dataset_path再通过 load_dataset 函数以 json 格式重新加载这个临时数据集用于后续处理。 数据处理函数定义定义了 generate_training_data 函数用于将包含指令、输入和输出文本的数据点转换为适合模型训练的格式具体是通过 tokenizer 将文本转换为令牌token形式并处理好输入令牌、对应标签以及注意力掩码等信息构建训练样本。 划分数据集可选根据 VAL_SET_SIZE 参数的值决定是否划分训练集和验证集如果 VAL_SET_SIZE 大于 0则从原始训练集中划分出验证集对训练集和验证集的数据都应用 generate_training_data 函数进行预处理使其格式符合模型训练要求若 VAL_SET_SIZE 为 0则整个数据集都作为训练集进行处理。 模型相关配置部分 创建模型和令牌器从指定的模型路径model_path加载预训练的语言模型并根据相关配置如量化配置 BitsAndBytesConfig 用于以特定量化方式加载模型以节省内存等进行初始化同时加载对应的分词器tokenizer并设置其填充令牌pad_token与结束令牌eos_token相同方便后续文本处理。 模型准备与微调配置将加载的模型通过 prepare_model_for_int8_training 函数进行处理使其适合 INT8 训练方式接着使用 LoraConfig 配置 LORA低秩适配一种参数高效微调方法相关参数并通过 get_peft_model 函数应用 LORA 配置到模型上以便后续进行参数高效的微调训练。 生成配置定义定义了 GenerationConfig 对象用于指定模型在生成文本时的一些解码参数例如是否采样do_sample、温度参数temperature、束搜索的束数量num_beams等这些参数会影响模型生成唐诗内容时的质量和多样性等特性。 模型训练部分 使用 transformers.Trainer 类来实例化训练器对象trainer传入模型、训练数据集、验证数据集可为 None以及训练相关的各种参数如批次大小、学习率、训练轮数、梯度累积步数、日志记录和模型保存相关的配置等同时指定了数据整理器data_collator用于整理训练数据的格式。在训练前还禁用了模型的缓存功能model.config.use_cache False然后通过 try-except 语句块尝试执行模型训练过程若训练出现异常则打印出错误信息。 模型保存部分 同样使用 try-except 语句块尝试将训练后的模型保存到指定的检查点目录ckpt_dir中若保存过程出现异常则打印相应的错误提示。 模型测试与结果保存部分 从指定的测试数据文件test_data_path中加载测试数据集通过 json.load然后循环遍历每条测试数据调用 evaluate 函数该函数基于给定的指令、生成配置和输入等信息利用已训练好的模型生成相应回复内容获取模型针对测试数据的回复将测试数据的输入以及模型生成的回复拼接后写入到指定的结果文件output_path中保存起来同时也会打印出来方便查看用于评估模型在测试集上的表现。 原文链接https://blog.csdn.net/chenchihwen/article/details/144000079 整体代码参照这篇文章
《生成式 AI》课程 作业6 大语言模型LLM的训练微调 Fine Tuning -- part2-CSDN博客文章浏览阅读872次点赞26次收藏8次。代码围绕一个主工作目录展开在这个主工作目录下包含了多个子目录和相关文件用于存放不同阶段的数据、模型以及输出结果等内容各个部分分工明确以支持整个预训练语言模型微调及测试的流程。这段 Python 代码主要实现了基于 Hugging Face Transformers 库对预训练语言模型具体为模型进行微调Fine-tuning的功能使其能更好地应用于生成唐诗相关内容的任务。整个流程涵盖了数据加载与预处理、模型配置、模型训练以及训练后模型的测试与结果保存等环节。https://blog.csdn.net/chenchihwen/article/details/144000079?spm1001.2014.3001.5501拆解说明如下
导入必要的库 import os
import sys
import argparse
import json
import warnings
import logging导入了多个 Python 标准库os用于操作系统相关的操作如文件路径处理、目录创建等sys用于处理 Python 运行时环境相关的配置和参数argparse常用于命令行参数解析但此代码中未体现其使用json用于处理 JSON 格式的数据读写warnings用于控制警告信息的显示logging用于记录日志信息。 # 忽略警告信息
warnings.filterwarnings(ignore)配置warnings模块使其忽略所有警告信息避免在程序运行过程中输出大量警告干扰正常的输出和分析。 import torch
import torch.nn as nn
import bitsandbytes as bnb
from datasets import load_dataset, load_from_disk
import transformers
from peft import PeftModel
from colorama import Fore, Back, Style导入了torch深度学习常用的张量计算库及其nn模块用于构建神经网络bitsandbytes可能用于模型量化等相关功能load_dataset和load_from_disk函数用于加载数据集transformers库用于自然语言处理相关的预训练模型、工具等PeftModel可能是某种特定的模型扩展相关类colorama用于在终端输出添加颜色等样式不过此处代码后续未看到其使用。 # 以下是根据Hugging Face Transformers库的相关功能进行的设置
from transformers import AutoTokenizer, AutoConfig, AutoModelForCausalLM, BitsAndBytesConfig
from transformers import GenerationConfig
from peft import (prepare_model_for_int8_training,LoraConfig,get_peft_model,get_peft_model_state_dict,prepare_model_for_kbit_training
)从transformers库中导入了多个用于创建模型、配置模型以及处理特定训练相关设置的类和函数比如AutoTokenizer用于自动加载合适的文本令牌化器AutoConfig用于自动加载模型配置AutoModelForCausalLM用于加载适用于因果语言建模的预训练模型BitsAndBytesConfig用于配置模型量化相关的参数从peft模块导入的函数主要用于对模型进行特定的微调如int8训练准备、配置LORA相关参数、获取基于LORA配置后的模型等。
模型和路径相关的参数设置 # 模型名称
model_name TAIDE-LX-7B-Chat
# 模型所在目录
model_path os.path.join(os.path.dirname(os.path.abspath(__file__)), TAIDE-LX-7B-Chat)定义了模型的名称以及模型所在的本地文件系统路径通过os.path.join结合当前脚本文件所在目录os.path.dirname(os.path.abspath(__file__))获取来确定完整的模型路径。 # 设置工作目录
work_dir os.path.dirname(os.path.abspath(__file__))
# 输出目录
output_dir os.path.join(work_dir, output)
# 检查点目录
ckpt_dir os.path.join(work_dir, checkpoint)确定了工作目录即当前脚本所在目录并基于此设置了后续用于存储输出结果的目录和保存模型检查点的目录路径。 # 训练的总Epoch数
num_epoch 1
# 学习率
LEARNING_RATE 3e-4定义了模型训练的关键超参数总训练轮数为1轮学习率设置为3e-4学习率决定了模型在训练过程中参数更新的步长大小。 # 配置模型和训练参数
cache_dir os.path.join(work_dir, cache)
from_ckpt False
ckpt_name None设置了模型缓存目录路径以及两个与是否从检查点加载模型、具体检查点名称相关的变量这里表示不从检查点加载from_ckpt为False且没有指定具体检查点名称ckpt_name为None。 # 以下是补充的超参数设置
# 用于训练的数据集数量
num_train_data 1040 # 可设置的最大值为5000数据量越多模型性能可能越好但训练时间也会增加
# 以下参数影响模型的训练和推理
CUTOFF_LEN 256 # 文本截断的最大长度
LORA_R 8 # LORA的R值
LORA_ALPHA 16 # LORA的Alpha值
LORA_DROPOUT 0.05 # LORA的Dropout率
VAL_SET_SIZE 0 # 验证集的大小0表示不使用验证集
TARGET_MODULES [q_proj, up_proj, o_proj, k_proj, down_proj, gate_proj, v_proj] # 目标模块用于LORA训练
#
MICRO_BATCH_SIZE 4 # 微批次大小这里设置为和原示例类似的值你可根据实际情况调整
GRADIENT_ACCUMULATION_STEPS 4 # 计算每个微批次累积的梯度步数示例中为16//4这里假设为4可按需改
logging_steps 20 # 定義訓練過程中每隔多少步驟輸出一次訓練誌
save_steps 65 # 定義訓練過程中每隔多少步驟保存一次模型
save_total_limit 3 # 控制最多保留幾個模型checkpoint
report_to [tensorboard] # 設定上報實驗指標的目標預設為無 # 可以根据需求调整报告的对象比如添加其他日志记录工具等这些都是详细的模型训练相关超参数设置 num_train_data指定了用于训练模型的数据集样本数量这里限制为1040个更多数据理论上有助于提升模型性能但会增加训练时长。CUTOFF_LEN用于限制输入文本的最大长度超过这个长度会截断有助于控制输入规模。LORA_R、LORA_ALPHA、LORA_DROPOUT是LORA低秩适应方法相关的参数用于调整模型微调时的结构和特性。VAL_SET_SIZE决定是否划分出验证集以及验证集的大小这里设置为0表示不划分验证集用于评估训练过程中的模型性能。TARGET_MODULES明确了在LORA训练时针对模型的哪些模块进行操作。MICRO_BATCH_SIZE和GRADIENT_ACCUMULATION_STEPS一起用于控制每次训练时实际处理的数据量和梯度更新的频率。logging_steps规定了每隔多少训练步骤记录一次训练日志save_steps定义了每隔多少步骤保存一次模型检查点save_total_limit控制最多保留的检查点数量report_to指定了向哪些目标如tensorboard上报实验指标用于可视化等分析。
分布式训练相关配置 world_size int(os.environ.get(WORLD_SIZE, 1))
ddp world_size! 1
if ddp:device_map {: int(os.environ.get(LOCAL_RANK) or 0)}首先获取环境变量WORLD_SIZE通常用于分布式训练表示总的进程数如果获取不到则默认值为1。根据world_size是否等于1来判断是否是分布式训练ddp变量标记如果是分布式训练ddp为True则通过环境变量LOCAL_RANK通常表示当前进程在本地的序号来配置设备映射这里简单地将其映射到一个整数用于指定设备比如 GPU 设备编号等。
创建目录 # 创建输出目录和检查点目录如果不存在
os.makedirs(output_dir, exist_okTrue)
os.makedirs(ckpt_dir, exist_okTrue)使用os.makedirs函数创建输出目录和检查点目录如果目录已经存在exist_okTrue参数表示存在时不报错则不会重复创建确保后续保存输出结果和模型检查点时有对应的目录可用。
数据集加载与处理 # 加载数据集
dataset_dir os.path.join(work_dir, data, training_data, Tang_training_data.json)
with open(dataset_dir, r, encodingutf-8) as f:data_json json.load(f)构建数据集文件的完整路径假设数据集是 JSON 格式存储在特定目录下然后使用json.load函数从打开的文件中读取 JSON 数据并解析为 Python 对象这里是字典或列表等结构存储在data_json变量中。 # 保存处理后的数据集
tmp_dataset_path os.path.join(work_dir, tmp_dataset.json)
# 获取文件所在目录路径
dir_path os.path.dirname(tmp_dataset_path)
# 如果目录不存在则创建目录
if not os.path.exists(dir_path):os.makedirs(dir_path)# 明确使用 w 模式打开文件用于写入同时指定 encoding 为 utf-8
with open(tmp_dataset_path, w, encodingutf-8) as f:json.dump(data_json[:num_train_data], f, indent2, ensure_asciiFalse)先确定临时数据集文件的路径以及其所在目录路径若目录不存在就创建它。然后从原始读取的数据集数据data_json中选取前面num_train_data个样本使用json.dump将这部分数据以缩进为2、不强制转换 ASCII 编码ensure_asciiFalse便于处理中文等非 ASCII 字符的方式写入到临时数据集文件中。 data load_dataset(json, data_filestmp_dataset_path, download_modeforce_redownload)使用load_dataset函数以 JSON 格式加载刚刚处理并保存的临时数据集文件data_files参数指定并设置下载模式为强制重新下载不过对于本地文件这里可能没实际的下载行为只是按照对应的加载逻辑处理将加载好的数据集对象存储在data变量中。
创建模型和令牌器
model AutoModelForCausalLM.from_pretrained(model_path,cache_dircache_dir,quantization_configBitsAndBytesConfig(load_in_4bitTrue,bnb_4bit_quant_typenf4,bnb_4bit_use_double_quantTrue,bnb_4bit_compute_dtypetorch.bfloat16),low_cpu_mem_usageTrue
)通过AutoModelForCausalLM类从指定的model_path路径加载预训练的因果语言模型使用cache_dir指定缓存目录同时配置了模型量化相关参数通过BitsAndBytesConfig这里设置为以4位量化加载load_in_4bitTrue采用nf4量化类型、启用双重量化以及指定计算的数据类型为torch.bfloat16并且设置为低 CPU 内存使用模式以优化模型加载和运行时的内存占用情况。 tokenizer AutoTokenizer.from_pretrained(model_name,add_eos_tokenTrue,cache_dircache_dir,quantization_configBitsAndBytesConfig(load_in_4bitTrue,bnb_4bit_quant_typenf4,bnb_4bit_use_double_quantTrue,bnb_4bit_compute_dtypetorch.bfloat16)
)
tokenizer.pad_token tokenizer.eos_token类似地使用AutoTokenizer从指定的model_name加载对应的文本令牌化器添加结束符令牌add_eos_tokenTrue配置缓存目录和量化相关参数与模型配置的量化参数一致。最后将令牌化器的填充令牌pad_token设置为结束符令牌eos_token方便后续处理文本序列长度不一致等情况。
生成训练数据的函数
def generate_training_data(data_point):此函数用于将数据点包含指令、输入和输出文本转换为模型可读取的令牌形式参数:data_point (dict): 包含 instruction、input 和 output 字段的字典所有字段均为字符串返回:dict: 包含模型的输入令牌、注意力掩码和相应输出目标的字典# 构建完整的输入提示prompt f\
[INST] SYS
You are a helpful assistant and good at writing Tang poem. 你是一个乐于助人的助手且擅长写唐诗。
/SYS
{data_point[instruction]}
{data_point[input]}
[/INST]# 计算输入令牌的数量len_user_prompt_tokens (len(tokenizer(prompt,truncationTrue,max_lengthCUTOFF_LEN 1,paddingmax_length,)[input_ids]) - 1)# 将输入提示转换为令牌full_tokens tokenizer(prompt data_point[output] /s,truncationTrue,max_lengthCUTOFF_LEN 1,paddingmax_length,)[input_ids][:-1]return {input_ids: full_tokens,labels: [-100] * len_user_prompt_tokens full_tokens[len_user_prompt_tokens:],attention_mask: [1] * (len(full_tokens)),}这个函数用于将输入的包含指令、输入文本和输出文本的数据点转换为适合模型训练的格式 首先构建完整的输入提示文本按照特定的格式拼接指令、输入等内容形成prompt字符串。然后通过令牌化器对prompt进行处理截断到CUTOFF_LEN 1长度并进行填充等操作计算出用户提示部分的令牌数量减去1可能是去除某个特定的标记等原因。接着将包含输出文本的完整提示再进行令牌化处理并去掉最后一个令牌具体原因可能与模型训练时的输入输出格式要求有关得到full_tokens。最后构建并返回一个字典包含模型输入的令牌序列input_ids对应的标签序列labels用户提示部分设为-100表示不计算这部分的损失后面接上实际输出对应的令牌以及注意力掩码全1表示都参与注意力计算长度与令牌序列长度一致。
评估模型的函数
def evaluate(instruction, generation_config, max_len, input, verboseTrue):此函数用于根据输入的指令、生成配置和最大长度获取模型的输出参数:instruction (str): 描述模型要执行的操作的字符串generation_config (transformers.GenerationConfig): 用于指定与模型推理相关的解码参数的对象max_len (int): 模型输出的最大长度input (str, 可选): 模型需要解决指令的输入字符串默认值为 verbose (bool, 可选): 是否打印模型的输出默认值为True返回:str: 模型根据指令和输入生成的响应# 构建完整的输入提示prompt f\
[INST] SYS
You are a helpful assistant and good at writing Tang poem. 你是一个乐于助人的助手且擅长写唐诗。
/SYS
{instruction}
{input}
[/INST]# 将提示文本转换为模型所需的数字表示形式inputs tokenizer(prompt, return_tensorspt)input_ids inputs[input_ids].cuda() if torch.cuda.is_available() else inputs[input_ids]# 使用模型进行生成回复generation_output model.generate(input_idsinput_ids,generation_configgeneration_config,return_dict_in_generateTrue,output_scoresTrue,max_new_tokensmax_len,)# 将生成的回复解码并打印for s in generation_output.sequences:output tokenizer.decode(s)output output.split([/INST])[1].replace(/s, ).replace(s, ).replace(Assistant:, ).replace(Assistant, ).strip()if verbose:print(output)return output该函数用于对模型进行评估根据给定的指令、生成配置以及最大输出长度等参数获取模型的输出 先按照特定格式构建完整的输入提示文本prompt包含系统描述、指令和可选的输入内容。接着使用令牌化器将提示文本转换为张量形式return_tensorspt表示返回 PyTorch 张量如果 GPU 可用则将输入的令牌input_ids移到 GPU 上方便后续加速计算。
evaluate函数续 generation_configgeneration_config,return_dict_in_generateTrue,output_scoresTrue,max_new_tokensmax_len,
)调用模型的generate方法来生成回复内容传递了几个重要参数 generation_config这是一个之前定义好的配置对象类型为transformers.GenerationConfig里面包含了如采样策略do_sample等参数、温度参数temperature、束搜索相关参数num_beams等等诸多与生成文本过程相关的设置用于控制模型生成回复的方式。return_dict_in_generateTrue表示让generate方法以字典形式返回生成的结果方便后续提取和处理相关信息比如包含生成的序列、对应的分数等信息。output_scoresTrue指示模型在生成过程中同时输出每个生成步骤的分数信息例如概率得分等虽然代码后续没有明显体现对这些分数的进一步处理但在一些更详细的分析场景中可能会用到。max_new_tokensmax_len指定了模型最多生成的新令牌数量也就是限制了生成回复的最大长度避免生成过长的无意义文本。 for s in generation_output.sequences:output tokenizer.decode(s)output output.split([/INST])[1].replace(/s, ).replace(s, ).replace(Assistant:, ).replace(Assistant, ).strip()if verbose:print(output)这段代码对生成的结果进行处理和输出如果verbose为True 首先通过循环遍历generation_output.sequences生成结果中的序列可能存在多个候选序列等情况不过这里代码逻辑上似乎只处理了其中一个没有更复杂的选择逻辑体现。使用tokenizer.decode将生成的令牌序列s解码为文本形式得到原始的回复文本。接着对解码后的文本进行一系列字符串处理操作 split([/INST])[1]按照[/INST]这个特定标记进行分割并取分割后的第二部分内容可能是为了去除前面的一些指令相关的固定格式内容提取出真正的回复部分。然后通过replace方法依次去除一些多余的标记如/s结束符标记、s起始符标记、Assistant:可能是回复开头的特定前缀标记以及Assistant类似的前缀情况并通过strip方法去除文本两端的空白字符最终得到比较干净整洁的回复文本内容。如果verbose为True就将处理后的回复文本打印输出方便查看模型生成的结果情况如果verbose为False则只是进行上述处理不进行打印用于后续可能的静默式评估或者将结果进一步传递使用等场景。最后函数返回处理后的回复文本无论是否打印使得调用该函数的地方可以获取到模型生成的结果用于后续的操作比如和真实结果对比评估模型性能等。
划分训练集和验证集如果需要 if VAL_SET_SIZE 0:train_val data[train].train_test_split(test_sizeVAL_SET_SIZE, shuffleTrue, seed42)train_data train_val[train].shuffle().map(generate_training_data)val_data train_val[test].shuffle().map(generate_training_data)
else:train_data data[train].shuffle().map(generate_training_data)val_data None这部分代码根据之前定义的验证集大小VAL_SET_SIZE来决定是否划分训练集和验证集 如果VAL_SET_SIZE大于0表示需要划分出验证集用于在训练过程中评估模型在未见过的数据上的性能。通过调用数据集对象data[train]假设data数据集有train这个子集表示训练数据部分的train_test_split方法按照给定的测试集大小比例test_sizeVAL_SET_SIZE、进行随机打乱shuffleTrue并设置随机种子seed42保证每次划分结果可复现来划分出训练集和验证集两部分分别存储在train_val这个包含train和test两个子集的对象中。然后对划分后的训练集和验证集进一步处理通过调用shuffle方法再次打乱顺序进一步打乱确保数据随机性可能是为了后续训练更稳定等原因并使用map方法结合generate_training_data函数将数据集中的每个样本转换为适合模型训练的格式如前面generate_training_data函数中所做的将文本数据转换为包含输入令牌、标签、注意力掩码等的字典形式最终得到处理后的训练数据train_data和验证数据val_data。如果VAL_SET_SIZE等于0则表示不需要划分验证集直接将整个训练数据集data[train]进行打乱shuffle并通过map方法应用generate_training_data函数处理每个样本得到训练数据train_data同时将验证数据val_data设为None表明没有单独的验证集用于后续评估。
将模型准备好以使用 INT8 训练 model prepare_model_for_int8_training(model)调用prepare_model_for_int8_training函数对已加载的模型进行预处理使其能够适应以INT8量化精度进行训练的要求这个函数内部可能会对模型的一些层结构、参数初始化等方面进行调整以便在后续训练过程中能够基于INT8量化方式正确地更新参数、计算梯度等确保训练的顺利进行和模型性能的合理优化。
使用 LoraConfig 配置 LORA 模型 config LoraConfig(rLORA_R,lora_alphaLORA_ALPHA,target_modulesTARGET_MODULES,lora_dropoutLORA_DROPOUT,biasnone,task_typeCAUSAL_LM,
)
model get_peft_model(model, config)首先创建一个LoraConfig配置对象传入之前定义好的相关LORA超参数 rLORA_R设置LORA方法中的秩rank参数它决定了低秩矩阵分解的维度等特性影响模型微调的效果和参数量等。lora_alphaLORA_ALPHA与LORA的自适应调整等相关的参数配合r等参数一起控制模型训练过程中的权重更新等情况。target_modulesTARGET_MODULES指定了在模型中哪些模块上应用LORA技术进行微调即明确了操作的具体对象范围。lora_dropoutLORA_DROPOUT设置LORA中的丢弃率Dropout参数用于防止过拟合等情况。biasnone表示不处理偏置项可能是不针对偏置进行LORA相关的调整等情况。task_typeCAUSAL_LM表明任务类型是因果语言建模用于让LORA配置知晓模型的任务特性以便进行针对性的适配。接着调用get_peft_model函数传入原始模型和LoraConfig配置对象对模型进行基于LORA配置的转换和调整返回一个应用了LORA技术后的新模型替换原来的model变量使得后续训练能够基于LORA微调的方式进行在尽量少增加参数量的情况下提升模型在特定任务上的性能。
定义 nf4_config nf4_config BitsAndBytesConfig(load_in_4bitTrue,bnb_4bit_quant_typenf4,bnb_4bit_use_double_quantTrue,bnb_4bit_compute_dtypetorch.bfloat16
)创建一个BitsAndBytesConfig配置对象重新配置了模型量化相关的参数和之前模型加载时配置的量化参数类似但这里单独定义了一个配置对象可能后续有其他使用场景或者方便修改统一的量化设置等 load_in_4bitTrue明确表示以4位量化的方式加载模型减少模型的内存占用等。bnb_4bit_quant_typenf4指定量化类型为nf4这是一种特定的量化技术选择。bnb_4bit_use_double_quantTrue启用双重量化机制进一步优化量化效果和模型存储、计算效率等。bnb_4bit_compute_dtypetorch.bfloat16设定在量化计算过程中使用的数据类型为torch.bfloat16用于在量化情况下兼顾计算精度和速度等方面的平衡。
定义生成配置 generation_config GenerationConfig(do_sampleTrue,temperature0.1,num_beams1,top_p0.3,no_repeat_ngram_size3,pad_token_id2
)创建一个GenerationConfig对象用于配置模型生成文本时的各种参数 do_sampleTrue表示采用采样的方式生成文本而不是确定性的生成例如对比于基于束搜索等确定性的生成策略这样可以增加生成文本的多样性但也可能带来一定的不确定性和结果的波动性。temperature0.1温度参数用于控制采样的随机性程度较小的值如这里的0.1会让采样更偏向于概率高的词汇生成的文本相对更保守、更符合常规较大的值则会增加随机性使生成的文本更加多样化但可能质量参差不齐。num_beams1束搜索相关参数这里设置为1表示不使用束搜索束搜索通常会保留多个候选路径并综合评估选择最优路径当num_beams大于1时启用这里仅设为1相当于就是普通的逐个生成词汇的方式。top_p0.3一种概率截断采样的参数叫核采样nucleus sampling表示只从概率累计和达到0.3的那部分词汇中进行采样有助于避免生成一些概率极低但可能出现的不合理词汇同时保证一定的词汇选择范围和文本多样性。no_repeat_ngram_size3设置生成文本时避免重复出现的n元语法连续的n个词汇组成的单元的大小为3即尽量不让连续的3个词汇重复出现以提高生成文本的流畅性和多样性防止重复啰嗦的表述。pad_token_id2指定填充令牌对应的id为2用于在处理批次数据等场景下对长度不一致的文本序列进行填充对齐操作时的标识。
训练模型 trainer transformers.Trainer(modelmodel,train_datasettrain_data,eval_datasetval_data,argstransformers.TrainingArguments(per_device_train_batch_size4, # 微批次大小可根据需要调整gradient_accumulation_steps16 // 4, # 计算每个微批次累积的梯度步数warmup_steps50,num_train_epochsnum_epoch,learning_rateLEARNING_RATE,fp16True, # 使用混合精度训练logging_steps20,save_strategysteps,save_steps65,output_dirckpt_dir,save_total_limit3,ddp_find_unused_parametersFalse if ddp else None,),data_collatortransformers.DataCollatorForLanguageModeling(tokenizer, mlmFalse),
)创建一个transformers.Trainer对象用于训练模型传入了多个关键参数 modelmodel指定要训练的模型即前面经过INT8训练准备、LORA配置后的模型。train_datasettrain_data传入训练数据集是经过前面处理如转换为合适格式、划分等操作后的用于训练的样本数据集合。eval_datasetval_data传入验证数据集如果有即val_data不为None时用于在训练过程中定期评估模型性能若val_data为None则表示训练过程中不进行基于验证集的评估。argstransformers.TrainingArguments(...)创建一个TrainingArguments对象来配置训练相关的各种超参数 per_device_train_batch_size4设置每个设备如每个 GPU上每次训练的微批次大小为4即每次处理4个样本数据这个大小可以根据硬件资源、模型复杂度等情况进行调整影响训练时的内存占用和梯度更新频率等。gradient_accumulation_steps16 // 4计算每个微批次累积的梯度步数这里实际设置为4通过16 // 4计算得出意味着每处理4个微批次后才进行一次梯度更新用于在内存有限等情况下模拟更大的批次大小训练效果同时控制梯度更新的节奏。warmup_steps50在训练开始阶段设置的热身步数在这个阶段学习率会从初始值逐渐上升到设定的正常学习率有助于模型在训练初期更稳定地收敛避免一开始就使用较大学习率导致训练不稳定等情况。num_train_epochsnum_epoch指定训练的总轮数这里使用之前定义的num_epoch变量即训练1轮根据前面的定义。learning_rateLEARNING_RATE使用之前定义好的学习率3e-4来控制模型参数更新的步长大小。fp16True启用混合精度训练即使用半精度float16的数据类型来存储和计算部分张量减少内存占用同时在支持的硬件上可以加速计算又能在一定程度上保证计算精度不至于损失太多适合深度学习模型训练场景。logging_steps20按照每训练20步记录一次训练日志方便查看训练过程中的各项指标变化情况如损失值、学习率等。save_strategysteps表示按照训练步数来决定何时保存模型检查点与之对应的还有按训练轮数等保存策略这里选择基于步数保存。save_steps65结合save_strategysteps意味着每隔65个训练步骤就保存一次模型检查点用于后续可以恢复训练或者选择不同阶段的模型进行评估等。output_dirckpt_dir指定保存模型检查点的目录为之前定义的ckpt_dir确保模型文件保存到正确的位置。save_total_limit3控制最多保留3个模型检查点避免过多的检查点占用大量磁盘空间当保存的检查点数量超过这个限制时可能会自动删除较早的检查点。ddp_find_unused_parametersFalse if ddp else None在分布式训练ddp为True的场景下设置是否查找未使用的参数这里设置为False表示不进行查找具体是否查找可能根据实际训练需求和模型特点等决定不查找可以节省一定的计算资源和时间如果不是分布式训练ddp为False则设为None可能按照默认行为处理。data_collatortransformers.DataCollatorForLanguageModeling(tokenizer, mlmFalse)指定数据整理器Data Collator用于将训练数据整理成合适的批次格式这里使用的是适用于语言建模任务的整理器传入了令牌化器tokenizer并且设置mlmFalse表示不是做掩码语言建模而是因果语言建模任务对应的整理方式它会对批次内的文本序列进行填充、截断等操作使其符合模型输入的格式要求。
禁用模型的 cache 功能 model.config.use_cache False将模型配置中的use_cache属性设置为False禁用模型的缓存功能。在某些情况下禁用缓存可以避免一些潜在的内存问题或者不正确的结果尤其是在训练过程中或者模型结构、输入等有动态变化的场景下确保每次计算都是基于最新的输入和模型状态进行而不会依赖之前缓存的中间结果。
训练过程 try:trainer.train()
except Exception as e:print(fTraining failed: {e})使用try-except语句块来执行模型训练过程调用trainer.train()方法启动训练让模型根据前面配置的训练数据集、超参数等进行训练。如果在训练过程中出现任何异常比如梯度爆炸、内存不足、运行时错误等就会捕获该异常并打印出错误信息Training failed: {e}方便排查问题了解训练失败的原因。
保存训练后的模型 try:model.save_pretrained(ckpt_dir)
except Exception as e:print(fSaving model failed: {e} 整体代码与工作目录必要的 package
参照这篇文章
《生成式 AI》课程 作业6 大语言模型LLM的训练微调 Fine Tuning -- part2-CSDN博客文章浏览阅读872次点赞26次收藏8次。代码围绕一个主工作目录展开在这个主工作目录下包含了多个子目录和相关文件用于存放不同阶段的数据、模型以及输出结果等内容各个部分分工明确以支持整个预训练语言模型微调及测试的流程。这段 Python 代码主要实现了基于 Hugging Face Transformers 库对预训练语言模型具体为模型进行微调Fine-tuning的功能使其能更好地应用于生成唐诗相关内容的任务。整个流程涵盖了数据加载与预处理、模型配置、模型训练以及训练后模型的测试与结果保存等环节。https://blog.csdn.net/chenchihwen/article/details/144000079?spm1001.2014.3001.5501
训练json数据摘要如下
Training datasample 你可以试着补充Tang Poem datasethttps://github.com/chinese-poetry/chinese-poetry/tree/master/%E5%85%A8%E5%94%90%E8%AF%97?fbclidIwAR2bM14S42T-VtrvMi3wywCqKfYJraBtMl7QVTo0qyPMjX9jj9Vj3JepFBA Tang_training_data.json [ { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 秦川雄帝宅函谷壯皇居。, output: 綺殿千尋起離宮百雉餘。連甍遙接漢飛觀迥凌虛。雲日隱層闕風煙出綺疎。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 巖廊罷機務崇文聊駐輦。, output: 玉匣啓龍圖金繩披鳳篆。韋編斷仍續縹帙舒還卷。對此乃淹留欹案觀墳典。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 移步出詞林停輿欣武宴。, output: 琱弓寫明月駿馬疑流電。驚雁落虛弦啼猿悲急箭。閱賞誠多美於茲乃忘倦。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 鳴笳臨樂館眺聽歡芳節。, output: 急管韻朱絃清歌凝白雪。彩鳳肅來儀玄鶴紛成列。去茲鄭衛聲雅音方可悅。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 芳辰追逸趣禁苑信多奇。, output: 橋形通漢上峰勢接雲危。煙霞交隱映花鳥自參差。何如肆轍跡萬里賞瑤池。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 白日依山盡黃河入海流。, output: 欲窮千里目更上一層樓。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 落日雙闕昏回輿九重暮。, output: 長煙散初碧皎月澄輕素。搴幌翫琴書開軒引雲霧。斜漢耿層閣清風搖玉樹。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 歡樂難再逢芳辰良可惜。, output: 玉酒泛雲罍蘭殽陳綺席。千鍾合堯禹百獸諧金石。得志重寸陰忘懷輕尺璧。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 建章歡賞夕二八盡妖妍。, output: 羅綺昭陽殿芬芳玳瑁筵。珮移星正動扇掩月初圓。無勞上懸圃即此對神仙。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 新豐停翠輦譙邑駐鳴笳。, output: 園荒一徑斷苔古半階斜。前池消舊水昔樹發今花。一朝辭此地四海遂爲家。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 春蒐馳駿骨總轡俯長河。, output: 霞處流縈錦風前瀁卷羅。水花翻照樹堤蘭倒插波。豈必汾陰曲秋雲發棹歌。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 重巒俯渭水碧嶂插遙天。, output: 出紅扶嶺日入翠貯巖煙。疊松朝若夜複岫闕疑全。對此恬千慮無勞訪九仙。 }, testing data Tang_testing_data.json [ { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 雪霽銀妝素桔高映瓊枝。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 夫子何爲者栖栖一代中。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 飛蓋去芳園蘭橈遊翠渚。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 條風開獻節灰律動初陽。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 昨夜星辰昨夜風畫樓西畔桂堂東。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 三日入廚下洗手作羹湯。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 嵩雲秦樹久離居雙鯉迢迢一紙書。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 慨然撫長劒濟世豈邀名。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 乘興南遊不戒嚴九重誰省諫書函。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 猿鳥猶疑畏簡書風雲常爲護儲胥。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 君問歸期未有期巴山夜雨漲秋池。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 相見時難別亦難東風無力百花殘。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 雲母屏風燭影深長河漸落曉星沈。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 高閣客竟去小園花亂飛。 }, { instruction: 以下是一首唐詩的第一句話請用你的知識判斷並完成整首詩。, input: 瑤池阿母綺窗開黃竹歌聲動地哀。 } ]