目录

引言

1. 环境准备

2. 加载模型和分词器

2.1 选择模型

2.2 加载模型和分词器

3. 加载训练数据

4. 数据预处理

4.1 提取问题和答案

4.2 分词和标签处理

5. 训练超参数配置

6. 训练模型

总结


github代码仓库https://github.com/huangxiaoye6/LLM-tuning

引言

在自然语言处理领域,大模型的微调是提升模型性能、使其适应特定任务的重要手段。本文将详细介绍如何对 Qwen3 - 0.6B 模型进行全量微调,包括模型和数据的加载、数据预处理、训练超参数配置以及模型训练等关键步骤。

1. 环境准备

首先,我们需要导入必要的库,这些库将帮助我们完成模型加载、数据处理和训练等任务。

from transformers import AutoModel,AutoTokenizer,pipeline,Trainer,TrainingArguments,AutoModelForCausalLM,default_data_collator
from datasets import Dataset, load_dataset
import numpy as np
import evaluate

这些库涵盖了从模型加载到数据处理,再到训练过程的各个方面。transformers库提供了预训练模型和相关工具,datasets库用于加载和处理数据集,numpy用于数值计算,evaluate用于评估模型性能。

2. 加载模型和分词器

2.1 选择模型

我们选择Qwen/Qwen3-0.6B作为基础模型。

model_name="Qwen/Qwen3-0.6B"

2.2 加载模型和分词器

使用AutoModelForCausalLM.from_pretrained方法加载模型,并设置一些参数,如device_map='auto'让模型自动分配到可用的设备上,torch_dtype="auto"自动选择合适的数据类型。同时,使用AutoTokenizer.from_pretrained方法加载对应的分词器,并将填充标记设置为结束标记。

model=AutoModelForCausalLM.from_pretrained(
    model_name,
    # trust_remote_code=True,
    device_map='auto',
    torch_dtype="auto",
)
tokenizer=AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token=tokenizer.eos_token

3. 加载训练数据

使用load_dataset方法从 JSON 文件中加载训练数据和验证数据。

dataset = load_dataset('json', data_files={
    'train': '../数据集/data/train.json',
    'validation': '../数据集/data/eval.json'
})

加载完成后,我们可以打印数据集的信息,包括数据集的组成部分和每个部分的样本数量。

print(f"数据集加载成功,包含以下部分: {list(dataset.keys())}")
print(f"训练数据集加载成功,包含 {len(dataset['train'])} 个样本")
print(f"验证数据集加载成功,包含 {len(dataset['validation'])} 个样本")

同时,我们还可以打印训练数据集和验证数据集的示例,以便了解数据的结构。

print(f"训练数据集示例: {dataset['train'][0]}")
print(f"验证数据集示例: {dataset['validation'][0]}")

4. 数据预处理

4.1 提取问题和答案

定义process_fun函数,用于从数据集中提取问题和答案。

def process_fun(example):
    question=[]
    answer=[]
    for i in example['conversations']:
        for j in i:
            if j['from']=='human':
                question.append(j['value'])
            elif j['from']=='gpt':
                answer.append(j['value'])
    return {'question':question,'answer':answer}

使用map方法应用该函数,对数据集进行处理。

process_data=dataset.map(process_fun,batched=True,remove_columns=dataset['train'].column_names)

4.2 分词和标签处理

定义tokenizer_fun函数,将问题和答案构建成完整的指令格式,并进行分词处理。同时,标记需要预测的部分,将不需要计算损失的部分标记为 -100。

def tokenizer_fun(examples):
    # 构建完整的指令格式(问:{问题}\n答:{答案})
    instructions = []
    for q, a in zip(examples['question'], examples['answer']):
        instruction = f"问:{q}\n答:{a}"
        instructions.append(instruction)
    
    encoded = tokenizer(
        instructions,
        max_length=512,
        truncation=True,
        padding="max_length",
        return_tensors="pt"
    )
    
    labels = encoded["input_ids"].clone()
    
    # 定位"答:"的位置,标记需要预测的部分
    answer_start_token = tokenizer.encode("答:", add_special_tokens=False)[0]
    
    # 遍历批次中的每个样本
    for i in range(len(labels)):
        # 找到每个样本中"答:"的第一个token位置
        answer_positions = (labels[i] == answer_start_token).nonzero(as_tuple=True)[0]
        if len(answer_positions) > 0:
            # 只取第一个"答:"的位置
            first_answer_pos = answer_positions[0]
            # 将"答:"之前的token标记为-100(忽略计算损失)
            labels[i, :first_answer_pos] = -100
    
    return {
        "input_ids": encoded["input_ids"],
        "attention_mask": encoded["attention_mask"],
        "labels": labels
    }

使用map方法应用该函数,对处理后的数据进行分词和标签处理。

tokenized_dataset = process_data.map(
    tokenizer_fun,
    batched=True,
    remove_columns=process_data['train'].column_names
)

5. 训练超参数配置

定义TrainingArguments类的实例,设置训练的各种参数。

# 定义训练参数
training_args = TrainingArguments(
    output_dir="./train_qwen_0.6B_model",  # 训练结果保存的目录
    logging_steps=100,  # 每100步记录一次日志
    logging_dir='./runs',  # 日志保存的目录
    eval_strategy='epoch',  # 每一轮结束后进行评估
    num_train_epochs=3,  # 训练的轮数
    per_device_train_batch_size=4,  # 每个设备上的训练批次大小
    per_device_eval_batch_size=4,  # 每个设备上的评估批次大小
    learning_rate=2e-5,  # 学习率
    weight_decay=0.01,  # 权重衰减
    save_strategy='epoch',  # 每一轮结束后保存模型
    load_best_model_at_end=True,  # 训练结束后加载最优模型
    metric_for_best_model='eval_loss',  # 用于选择最优模型的指标
    gradient_accumulation_steps=4,  # 如果GPU内存有限,进行梯度累积
)

6. 训练模型

创建Trainer类的实例,传入模型、训练参数、评估数据集、训练数据集和数据收集器。

trainer=Trainer(
    model=model,
    args=training_args,
    eval_dataset=tokenized_dataset["validation"],
    train_dataset=tokenized_dataset["train"],
    data_collator=default_data_collator,
)

调用train方法开始训练。

trainer.train()

训练完成后,手动保存模型和训练状态。

# 手动保存模型
trainer.save_model('./train_qwen')
trainer.save_state()

总结

通过以上步骤,我们完成了对 Qwen3 - 0.6B 模型的全量微调。从模型和数据的加载,到数据预处理,再到训练超参数的配置和模型训练,每个步骤都有其重要性。合理调整超参数和优化数据处理过程,可以进一步提升模型的性能。希望本文能为你在大模型微调方面提供有价值的参考。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐