大模型微调

文章目录

  • 前言
  • 一、使用的库
  • 二、数据预处理
    • 1.引入库
    • 2.读入数据
    • 3.对数据进行预处理
    • 4.转换为json格式文件
  • 三,使用算子分析数据并进行数据处理
  • 四,划分训练集和测试集
  • 五,编写训练脚本开始训练
  • 六,进行模型推理人工评估
  • 总结


前言

这是使用知乎评论进行模型微调,让模型输出更加通畅接近人的使用语言


一、使用的库

modelscope:提供模型、数据集下载能力
data-juicer:提供数据集处理能力
ms-swift:提供模型训练、推理能力
evalscope:提供模型评测能力

二、数据预处理

1.引入库

首先下载大模型调参所需要的库,前提我们需要创建一个虚拟环境防止模型间相互冲突

%pip install modelscope[framework]  
%pip install py-data-juicer[sci]    
%pip install ms-swift[llm]          
%pip install ms-swift[eval]     

2.读入数据

代码如下:

from modelscope import MsDataset
from pprint import pprint

ds =  MsDataset.load('OmniData/Zhihu-KOL', cache_dir="data", split='train')
print(ds)
pprint(ds[0])

大模型微调_第1张图片

3.对数据进行预处理

import json
# load json
metadata = list(map(lambda x: json.loads(x), ds['METADATA']))

# 处理 upvotes 
vote_list = []
for item in metadata:
    try:
        upvotes = item['upvotes'][3:]
        if not upvotes:
            votes = 0
            
        elif '万' in upvotes:
            votes = int(float(upvotes[:-2]) * 10000)
        else:
            votes = int(upvotes)
    except Exception as e:
        print(upvotes)
        votes = 0
    vote_list.append(votes)
print("Done")

对文件内容进行预处理,选出不同意的票数,然后进行数据的归一化

4.转换为json格式文件

import pandas as pd

df = pd.DataFrame.from_dict({
    'query': ds['INSTRUCTION'],
    'response': ds['RESPONSE'],
    'upvotes': vote_list
})

print(len(df))

df.to_json("data/zhihu.jsonl", orient="records", lines=True, force_ascii=False)
df.head()

三,使用算子分析数据并进行数据处理

Data-Juicer 是一个一站式多模态数据处理系统,旨在为大语言模型 (LLM) 提供更高质量、更丰富、更易“消化”的数据。设计简单易用,提供全面的文档、简易入门指南和演示配置,并且可以轻松地添加/删除现有配置中的算子。
GitHub代码地址在此
对设置完成的yaml的程序进行运行

!dj-analyze --config zhihu-bot.yaml 

大模型微调_第2张图片

!dj-process --config zhihu-bot.yaml 

四,划分训练集和测试集

import pandas as pd

data = pd.read_json("data/zhihu_refine.jsonl", lines=True)

def split_data(data, save=False, suffix=''):
    # split data into train and test, 9: 1
    train_data = data.sample(frac=0.9, random_state=42)
    test_data = data.drop(train_data.index)

    if suffix:
        suffix = '_' + suffix
    if save:
        train_data.to_json(f"data/zhihu_train{suffix}.jsonl", orient='records', lines=True, force_ascii=False)
        test_data.to_json(f"data/zhihu_test{suffix}.jsonl", orient='records', lines=True,  force_ascii=False)
    return train_data, test_data

train_data, test_data = split_data(data, save=True)

print(len(train_data))
print(len(test_data))

五,编写训练脚本开始训练

!CUDA_VISIBLE_DEVICES=0 swift sft \
    --sft_type lora \
    --model_type qwen2-7b-instruct \
    --model_id_or_path qwen/Qwen2-7B-Instruct \
    --dataset data/zhihu_train.jsonl#4000 alpaca-zh#2000 \
    --system "你是一个真实的人类。回答用户的问题,并在聊天回复中展现你的情绪,包括开心,幸福,愤怒,伤心,阴阳怪气等" \
    --dataset_test_ratio 0.01 \
    --output_dir output \
    --lora_target_modules ALL \
    --lora_rank 8 \
    --dtype bf16 \
    --seed 42 \
    --learning_rate 1e-4 \
    --warmup_ratio 0.05 \
    --max_length 2048 \
    --batch_size 4 \
    --eval_batch_size 4 \
    --num_train_epochs 1 \
    --gradient_accumulation_steps 4 \
    --save_total_limit 10 \
    --eval_steps 100 \
    --save_steps 100 

六,进行模型推理人工评估

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import pandas as pd

from swift.llm import (
    get_model_tokenizer, get_template, inference, ModelType, get_default_template_type,
)
from swift.utils import seed_everything
from swift.tuners import Swift
import torch

seed_everything(42)

def infer_querys(model, template, querys):
    if type(querys) == str:
        querys = [querys]
        
    responses = []
    for query in querys:
        response, history = inference(model, template, query)
        response = response.replace("\n", "\t")
        responses.append(response)
        print(f'response: {response}')
    
    return responses

def load_model(ckpt_dir):
    model_type = ModelType.qwen2_7b_instruct
    template_type = get_default_template_type(model_type)

    model, tokenizer = get_model_tokenizer(model_type, model_kwargs={'device_map': 'auto'})
    model.generation_config.max_new_tokens = 500
    model.generation_config.temperature = 0.8
    model.generation_config.top_p = 0.9
    model.generation_config.top_k = 10
    if ckpt_dir:
        model = Swift.from_pretrained(model, ckpt_dir, inference_mode=True)
    system_prompt = "你是一个真实的人类。回答用户的问题,并在聊天回复中展现你的情绪,包括开心,幸福,愤怒,伤心,阴阳怪气等"
    template = get_template(template_type, tokenizer, default_system=system_prompt)
    return model, template

querys = pd.read_json("data/zhihu_test.jsonl", lines=True)["query"].sample(10, random_state=42).tolist()
querys = ["你是谁?"] + querys

print(querys)

ckpt_dict = {
'origin': None,
'lora': 'output/qwen2-7b-instruct/v1-20240819-150005/checkpoint-371',
}
model = None
model_responses = {}
for ckpt_name, ckpt_dir in ckpt_dict.items():
    if model:
        del model
        torch.cuda.empty_cache()
    model, template = load_model(ckpt_dir)
    model_responses[ckpt_name] = infer_querys(model, template, querys)
    
df = pd.DataFrame.from_dict(model_responses)
df.index = querys
df.to_markdown("output.md")

总结

这次根据魔塔官方提供的框架学习到开源大模型训练微调全栈,后续我会继续完善模型

你可能感兴趣的:(人工智能)