使用LLaMA-Factory的数据集制作流程与训练微调Qwen3及评估

发布于:2025-08-20 ⋅ 阅读:(14) ⋅ 点赞:(0)

AutoDL中的LLaMA-Factory 使用 训练微调 llame3数据集 cmmlu

使用LLaMA-Factory微调训练Qwen2-VL-7B/Qwen2.5-VL-7B与视觉大模型数据集制作流程与训练评估

b站:https://www.bilibili.com/video/BV1KceNzoE87/

本文介绍了使用LLaMA-Factory框架微调Qwen3-4B-Instruct-2507模型的完整流程。内容包括:1) 环境安装与WebUI配置;2) 数据集制作与格式要求;3) 通过ModelScope下载Qwen3模型;4) 使用命令行进行LoRA微调训练,展示了训练参数与GPU使用情况;5) 模型导出方法;6) 最后对微调后的模型进行评估。整个过程在6块GPU上约15分钟完成训练,并提供了训练损失曲线等可视化结果。

在这里插入图片描述

1 LLaMA-Factory环境安装

LLaMA-Factory 安装

git clone https://github.com/hiyouga/LLaMA-Factory.git

cd LLaMA-Factory

pip install -e ".[torch,metrics]"

# 检查环境是否安装成功。

llamafactory-cli version

在这里插入图片描述

启动WebUI界面,我修改端口号为6006,因为AutoDL用的这个端口号

GRADIO_SERVER_PORT=6006  llamafactory-cli webui

在这里插入图片描述

2 数据集制作

https://github.com/hiyouga/LLaMA-Factory/tree/main/data

需要的数据集格式参考如下:
https://github.com/hiyouga/LLaMA-Factory/blob/main/data/alpaca_en_demo.json

在这里插入图片描述

https://github.com/hiyouga/LLaMA-Factory/blob/main/data/alpaca_zh_demo.json
在这里插入图片描述

根据官方给的例子,本文所做的数据(文件名:hamful_jugement_train.json)如下:
在这里插入图片描述
将hamful_jugement_train.json放在/home/winstonYF/LLaMA-Factory/data中

准备好数据后,在dataset_info.json中添加内容

  "hamful_jugement_train": {
    "file_name": "hamful_jugement_train.json"
  },

在这里插入图片描述

3 模型下载

这次微调的模型采用Qwen3-4B-Instruct-2507

模型地址
https://www.modelscope.cn/models/Qwen/Qwen3-4B-Instruct-2507

确保安装了modelscope

pip install modelscope

采用SDK方式下载

from modelscope import snapshot_download

# 指定模型的下载路径
cache_dir = '/home/winstonYF/LLaMA-Factory/model'
# 调用 snapshot_download 函数下载模型
model_dir = snapshot_download('Qwen/Qwen3-4B-Instruct-2507', cache_dir=cache_dir)

print(f"模型已下载到: {model_dir}")

在这里插入图片描述

4 使用命令进行训练 而非webui

由于采用的是服务器训练,所以不采用webui进行训练

训练命令

下面的命令是通过webui的Preview command自动生成的,只需要改改路径:
在这里插入图片描述
最后命令如下:

llamafactory-cli train \
    --stage sft \
    --do_train True \
    --model_name_or_path /home/winstonYF/LLaMA-Factory/model/Qwen/Qwen3-4B-Instruct-2507 \
    --preprocessing_num_workers 16 \
    --finetuning_type lora \
    --template qwen3_nothink \
    --flash_attn auto \
    --dataset_dir data \
    --dataset hamful_jugement_train \
    --cutoff_len 2048 \
    --learning_rate 5e-05 \
    --num_train_epochs 3.0 \
    --max_samples 100000 \
    --per_device_train_batch_size 2 \
    --gradient_accumulation_steps 8 \
    --lr_scheduler_type cosine \
    --max_grad_norm 1.0 \
    --logging_steps 5 \
    --save_steps 100 \
    --warmup_steps 0 \
    --packing False \
    --enable_thinking True \
    --report_to none \
    --output_dir saves/Qwen3-4B-Instruct-2507/lora/train_2025-08-18-17-28-44 \
    --bf16 True \
    --plot_loss True \
    --trust_remote_code True \
    --ddp_timeout 180000000 \
    --include_num_input_tokens_seen True \
    --optim adamw_torch \
    --lora_rank 8 \
    --lora_alpha 16 \
    --lora_dropout 0 \
    --lora_target all

在这里插入图片描述

在这里插入图片描述
看看6块GPU的占有情况(占满了):
在这里插入图片描述

看运行时间,显示的15分钟运行完毕,这个速度还是挺快的。
训练完成,还是很快的
在这里插入图片描述
训练时的损失值变化
在这里插入图片描述

导出模型命令

训练后导出模型

llamafactory-cli export \
    --model_name_or_path /home/winstonYF/LLaMA-Factory/model/Qwen/Qwen3-4B-Instruct-2507\
    --adapter_name_or_path /home/winstonYF/LLaMA-Factory/saves/Qwen3-4B-Instruct-2507/lora/train_2025-08-18-17-28-44 \
    --template qwen3_nothink \
    --trust_remote_code True \
    --export_dir /home/winstonYF/LLaMA-Factory/model/Qwen/Qwen3-4B-Instruct-2507-F \
    --export_size 3 \
    --export_device cpu \
    --export_legacy_format false

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5 训练后的Qwen3模型评估

Qwen3 github:https://github.com/QwenLM/Qwen3

我们使用LLaMA-Factory训练,但是评估不用LLaMA-Factory,使用Qwen3来进行评估,首先就是Qwen3的安装。

https://github.com/QwenLM/Qwen2-VL

import json
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from sklearn.metrics import accuracy_score, recall_score, f1_score

def load_json_data(file_path):
    """加载JSON数据文件"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except FileNotFoundError:
        print(f"错误:找不到文件 {file_path}")
        return None
    except json.JSONDecodeError:
        print(f"错误:文件 {file_path} 不是有效的JSON格式")
        return None

def main():
    # 模型名称
    model_name = "/home/winstonYF/LLaMA-Factory/model/Qwen/Qwen3-4B-Instruct-2507-F"
    
    # 加载分词器和模型
    print(f"正在加载模型 {model_name}...")
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        torch_dtype="auto",
        device_map="auto"
    )
    model.eval()  # 设置为评估模式
    
    # 读取JSON文件路径
    json_path = 'hamful_jugement_val.json'
    data = load_json_data(json_path)
    
    if not data:
        return
    
    # 初始化评估指标
    total = 0
    correct = 0
    TP = 0  # 实际有害,模型预测有害
    TN = 0  # 实际安全,模型预测安全
    FP = 0  # 实际安全,模型预测有害
    FN = 0  # 实际有害,模型预测安全
    
    true_labels = []
    pred_labels = []
    
    print(f"开始评估,共 {len(data)} 条数据...")
    
    # 处理每条数据
    for i, item in enumerate(data, 1):
        try:
            # 拼接prompt
            instruction = item.get("instruction", "")
            input_content = item.get("input", "")
            prompt = f"{instruction}{input_content}"
            true_label = item.get("output", "").strip()
            
            # 确保真实标签是有效的
            if true_label not in ["Harmful", "Safe"]:
                print(f"警告:第{i}条数据的output不是有效的标签,已跳过")
                continue
            
            # 准备模型输入
            messages = [{"role": "user", "content": prompt}]
            text = tokenizer.apply_chat_template(
                messages,
                tokenize=False,
                add_generation_prompt=True,
            )
            model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
            
            # 生成模型输出
            with torch.no_grad():  # 禁用梯度计算,节省内存
                generated_ids = model.generate(
                    **model_inputs,
                    max_new_tokens=10,  # 只需要简短输出
                    temperature=0.0,    # 确定性输出
                    do_sample=False     # 不采样,使用贪婪解码
                )
            
            # 解析模型输出
            output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist()
            content = tokenizer.decode(output_ids, skip_special_tokens=True).strip()
            
            # 标准化模型输出
            if "harmful" in content.lower():
                pred_label = "Harmful"
            elif "safe" in content.lower():
                pred_label = "Safe"
            else:
                # 如果模型输出不是明确的Harmful/Safe,视为错误预测
                pred_label = None
                print(f"第{i}条数据:模型输出 '{content}' 不是有效的标签")
            
            # 更新评估指标
            if pred_label is not None:
                total += 1
                true_labels.append(1 if true_label == "Harmful" else 0)
                pred_labels.append(1 if pred_label == "Harmful" else 0)
                
                if true_label == pred_label:
                    correct += 1
                    if true_label == "Harmful":
                        TP += 1
                    else:
                        TN += 1
                else:
                    if true_label == "Harmful":
                        FN += 1
                    else:
                        FP += 1
            
            # 打印进度
            if i % 10 == 0:
                print(f"已完成 {i}/{len(data)} 条数据")
                
        except Exception as e:
            print(f"处理第{i}条数据时出错: {str(e)}")
            continue
    
    # 计算评估指标
    if total == 0:
        print("没有有效的数据用于评估")
        return
    
    accuracy = correct / total
    # 使用sklearn计算召回率和F1分数(以Harmful为正类)
    recall = recall_score(true_labels, pred_labels)
    f1 = f1_score(true_labels, pred_labels)
    
    # 输出评估结果
    print("\n===== 评估结果 =====")
    print(f"总数据量: {len(data)}")
    print(f"有效评估数据量: {total}")
    print(f"正确预测: {correct}")
    print(f"准确率: {accuracy:.4f}")
    print(f"召回率: {recall:.4f}")
    print(f"F1分数: {f1:.4f}")
    print("\n混淆矩阵:")
    print(f"TP (真阳性): {TP}")
    print(f"TN (真阴性): {TN}")
    print(f"FP (假阳性): {FP}")
    print(f"FN (假阴性): {FN}")

if __name__ == "__main__":
    main()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总数据量: 250
有效评估数据量: 250
正确预测: 241
准确率: 0.9640
召回率: 0.9910
F1分数: 0.9607

混淆矩阵:
TP (真阳性): 110
TN (真阴性): 131
FP (假阳性): 8
FN (假阴性): 1


网站公告

今日签到

点亮在社区的每一天
去签到