为了账号安全,请及时绑定邮箱和手机立即绑定

Qwen2大模型微调入门实战(附完整代码)(非常详细)零基础入门到精通,收藏这一篇就够了

标签:
杂七杂八
概述

大模型微调项目实战是一系列实践指南,旨在引导读者从零基础入门到精通大语言模型的微调技术。本文以阿里云通义千问团队开放的大型语言模型Qwen2为核心,通过指令微调任务——文本分类,详细介绍微调过程的各个方面。从环境准备、数据集处理、模型加载,到微调可视化和训练、推理,本教程覆盖了完整的大模型微调流程。

实践过程中,首先确保Python环境配置完备,并使用pip安装所需的库,包括swanlabmodelscopetransformersdatasetspeft等。接下来,下载并准备用于文本分类任务的数据集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,您能直观监控训练过程并分析模型表现。实验中提及的代码提供了完整的示例,包括数据处理、微调、可视化和推理环节,使入门至精通成为可能。随着对大语言模型微调技术的深入理解,您可以尝试调整各种超参数、探索不同的数据集、尝试不同的指令策略等,以优化模型性能,拓展应用领域。

通过本教程,您将掌握大模型微调的核心技能,根据实践与理论相结合的指导,您可在多种场景下灵活应用这些知识,推动个性化探索和应用的边界。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消