大模型微调项目实战是一系列实践指南,旨在引导读者从零基础入门到精通大语言模型的微调技术。本文以阿里云通义千问团队开放的大型语言模型Qwen2为核心,通过指令微调任务——文本分类,详细介绍微调过程的各个方面。从环境准备、数据集处理、模型加载,到微调可视化和训练、推理,本教程覆盖了完整的大模型微调流程。
实践过程中,首先确保Python环境配置完备,并使用pip
安装所需的库,包括swanlab
、modelscope
、transformers
、datasets
和peft
等。接下来,下载并准备用于文本分类任务的数据集zh_cls_fudan-news
,通过简单的脚本处理数据,使其适配于训练模型。
使用modelscope
下载Qwen2-1.5B-Instruct模型,并结合transformers
进行模型加载。配置SwanLab监控训练过程,以便实时评估模型效果。通过定义数据转换和预处理函数,将原始数据转换为模型训练所需的格式。设置训练参数和流程,利用Trainer
对模型进行微调,并通过SwanLab展示训练过程的可视化。
最后,展示如何使用微调后的模型进行推理和结果展示。本教程不仅提供了完整的代码示例,还指导读者理解微调过程背后的原理,以及如何优化模型性能。通过实际操作,读者将能够掌握从理论到实践的大模型微调技能,并在此基础上进行个性化探索和应用。
必要库安装确保Python环境配置已完成,以下是用于安装所需库的命令:
pip install swanlab modelscope transformers datasets peft accelerate pandas
数据集准备
已下载并准备数据集 zh_cls_fudan-news
用于文本分类任务。以下为下载训练和测试文件的命令:
# 直接通过链接下载数据集训练和测试文件
wget https://modelscope.cn/datasets/huangjintao/zh_cls_fudan-news/files/train.jsonl -O train.jsonl
wget https://modelscope.cn/datasets/huangjintao/zh_cls_fudan-news/files/test.jsonl -O test.jsonl
模型加载
以下代码展示了如何下载Qwen2-1.5B-Instruct模型并使用transformers
加载相应的权重:
from modelscope import snapshot_download
from transformers import AutoTokenizer, AutoModelForCausalLM
model_dir = snapshot_download("qwen/Qwen2-1.5B-Instruct", cache_dir="./", revision="master")
tokenizer = AutoTokenizer.from_pretrained(model_dir, use_fast=False, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="auto", torch_dtype=torch.bfloat16)
训练可视化工具配置
使用SwanLab监控训练过程,评估模型效果:
from swanlab.integration.huggingface import SwanLabCallback
swanlab_callback = SwanLabCallback(project="Qwen2-fintune", experiment_name="Qwen2-1.5B-Instruct")
代码示例与完整训练流程
数据转换函数定义
def dataset_jsonl_transfer(origin_path, new_path):
with open(origin_path, "r") as file:
messages = [{"instruction": "你是一个文本分类领域的专家,你会接收到一段文本和几个潜在的分类选项,请输出文本内容的正确类型", "input": f"文本:{line['text']},类型选型:{line['category']}", "output": line['output']} for line in json.load(file)]
with open(new_path, "w", encoding="utf-8") as file:
json.dump(messages, file, ensure_ascii=False)
数据集预处理函数
def process_func(example):
MAX_LENGTH = 384
input_ids, attention_mask, labels = [], [],
instruction = tokenizer(f"系统\n你是一个文本分类领域的专家,你会接收到一段文本和几个潜在的分类选项,请输出文本内容的正确类型\n用户\n{example['input']}\n助手\n", add_special_tokens=False)
response = tokenizer(f"{example['output']}", add_special_tokens=False)
input_ids += instruction["input_ids"] + response["input_ids"] + [tokenizer.pad_token_id]
attention_mask += instruction["attention_mask"] + response["attention_mask"] + [1]
labels += [-100] * len(instruction["input_ids"]) + response["input_ids"] + [tokenizer.pad_token_id]
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}
训练参数与流程
from datasets import Dataset
train_df = pd.read_json("new_train.jsonl", lines=True)
train_ds = Dataset.from_pandas(train_df)
train_dataset = train_ds.map(process_func, remove_columns=train_df.column_names)
config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
inference_mode=False,
r=8,
lora_alpha=32,
lora_dropout=0.1,
)
model = get_peft_model(model, config)
args = TrainingArguments(
output_dir="./output/Qwen2",
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
logging_steps=10,
num_train_epochs=2,
save_steps=100,
learning_rate=1e-4,
save_on_each_node=True,
gradient_checkpointing=True,
report_to="none",
)
trainer = Trainer(
model=model,
args=args,
train_dataset=train_dataset,
data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),
callbacks=[swanlab_callback],
)
trainer.train()
推理与结果展示
训练完成后,使用模型进行推理:
# 加载测试集
test_df = pd.read_json("new_test.jsonl", lines=True)
# 推理函数
def predict(messages, model, tokenizer):
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to("cuda")
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=512
)
generated_ids = [
output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
return response
# 使用训练好的模型进行预测
predictions = []
for index, row in test_df.iterrows():
messages = [
{"role": "system", "content": row['instruction']},
{"role": "user", "content": row['input']}
]
response = predict(messages, model, tokenizer)
predictions.append(response)
# 显示预测结果
for pred in predictions:
print(pred)
结论与后续探索
完成上述步骤后,您将掌握从环境准备到模型微调的全过程。Qwen2指令微调任务的成功不仅体现在模型性能的提升,还在于对文本分类任务的准确理解与执行。通过SwanLab,您能直观监控训练过程并分析模型表现。实验中提及的代码提供了完整的示例,包括数据处理、微调、可视化和推理环节,使入门至精通成为可能。随着对大语言模型微调技术的深入理解,您可以尝试调整各种超参数、探索不同的数据集、尝试不同的指令策略等,以优化模型性能,拓展应用领域。
通过本教程,您将掌握大模型微调的核心技能,根据实践与理论相结合的指导,您可在多种场景下灵活应用这些知识,推动个性化探索和应用的边界。
共同学习,写下你的评论
评论加载中...
作者其他优质文章