AI 大模型微调实践

背景

前一阵子部署了利用 AI 进行 code review 的功能,实际体验下来,发现效果并不十分稳定,想着有没有什么方法能够让 AI 大模型在 code review 这个方向上能力增强,于是在网上搜索资料,发现在现有的大模型上,我们还能够进行微调,让大模型更加符合我们的需求,这正是我所需要的。

我看到了这个网站:
https://github.com/KMnO4-zx/huanhuan-chat
他们把甄嬛传的剧本提取出来,丢给大模型进行训练,最后能够得到一个可以模仿甄嬛的聊天语言模型。也可以在线体验:
https://openxlab.org.cn/apps/detail/BYCJS/Chat_huanhuan
这个还听有意思的,于是也想自己训练试一试。但是可能由于本地的 GPU 配置不行,按照网站给出的方法没有跑起来,最后用 unsloth:https://github.com/unslothai/unsloth 这个库提供的方法跑起来了,按照 unsloth 官网上的说法,它可以缩短训练的时间,并且所需要的显存更少。

训练之后将模型保存到本地,然后使用 LM Studio 加载,就可以与它进行对话了。
在这里插入图片描述

环境配置

真的想吐槽一下,AI 训练的环境配置对新手真的太不友好了,安装各种各样的包,而且搞不好还有兼容问题,真的很烦人。这里我使用了 google 的 colab 在线环境和本地环境配置两种方式。

colab

colab 是 google 提供的一个在线大模型训练的环境,用起来就和 jupyter 一样的,而且它的网络环境超级好,不论是下载模型还是将训练好的大模型上传到 hugging face ,速度都非常快。下图是我训练完了之后将模型 push 到 hugging face上,上传速度可以达到 95MB/s 。
在这里插入图片描述而且 AI 训练常用的一些库以及驱动之类的,完全不需要我们自己操心,非常省事。唯一的缺点就是免费的额度有限,调着调着额度用完了就需要花钱买,9.9美元一个月也不算贵,但支付起来比较麻烦,需要绑定国外的银行卡,也不支持微信支付或者支付宝。所以我还是决定在本地配置一下环境。
在这里插入图片描述

本地环境配置

我本地最开始用的是 windows 系统,是平时工作用的,在windows 系统上折腾了几天,发现实在搞不定了,也不敢在这个系统上胡乱折腾,毕竟还要办公。在网上看了其他人在ubuntu上配置成功过,于是一咬牙一跺脚,装了个 ubuntu 系统。
按照这位大神的配置视频:https://www.youtube.com/watch?v=ZQIPnSiiwKw,一步一步的配置,最终就能在本地跑起来。
但中间还是会遇到一些各种各样其他的问题,比如我想将大模型保存为 gguf 格式的时候就报错了,
在这里插入图片描述
这个问题需要装一下缺失的库

sudo apt install curl libcurl4-openssl-dev

还有提示找不到 nvidia-smi 指令,需要安装

sudo apt install nvidia-utils-470

在这里插入图片描述另外如果本地使用 jupyter 调试的话,还需要安装下面的库,否则可能会报进度条缺失的错误

pip install ipywidgets widgetsnbextension pandas-profiling

训练和保存

模型训练的代码主要还是参考 unsloth 官方提供的示例,
https://colab.research.google.com/drive/1XamvWYinY6FOSX9GLvnqSjjsNflxdhNc?usp=sharing#scrollTo=6bZsfBuZDeCL
不过,由于我想要训练的数据是甄嬛传,因此在这个例子上作了一些修改,具体如下:

模型加载

from unsloth import FastLanguageModel
import torch
from datasets import Dataset
import pandas as pd
max_seq_length = 2048 # Choose any! We auto support RoPE Scaling internally!
dtype = None # None for auto detection. Float16 for Tesla T4, V100, Bfloat16 for Ampere+
load_in_4bit = True # Use 4bit quantization to reduce memory usage. Can be False.

# 1.加载模型
fourbit_models = [
    "unsloth/Meta-Llama-3.1-8B-bnb-4bit",      # Llama-3.1 15 trillion tokens model 2x faster!
    "unsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bit",
    "unsloth/Meta-Llama-3.1-70B-bnb-4bit",
    "unsloth/Meta-Llama-3.1-405B-bnb-4bit",    # We also uploaded 4bit for 405b!
    "unsloth/Mistral-Nemo-Base-2407-bnb-4bit", # New Mistral 12b 2x faster!
    "unsloth/Mistral-Nemo-Instruct-2407-bnb-4bit",
    "unsloth/mistral-7b-v0.3-bnb-4bit",        # Mistral v3 2x faster!
    "unsloth/mistral-7b-instruct-v0.3-bnb-4bit",
    "unsloth/Phi-3.5-mini-instruct",           # Phi-3.5 2x faster!
    "unsloth/Phi-3-medium-4k-instruct",
    "unsloth/gemma-2-9b-bnb-4bit",
    "unsloth/gemma-2-27b-bnb-4bit",            # Gemma 2x faster!
] # More models at https://huggingface.co/unsloth

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/Meta-Llama-3.1-8B",
    max_seq_length = max_seq_length,
    dtype = dtype,
    load_in_4bit = load_in_4bit,
    # token = "hf_...", # use one if using gated models like meta-llama/Llama-2-7b-hf
)

model = FastLanguageModel.get_peft_model(
    model,
    r = 16, # Choose any number > 0 ! Suggested 8, 16, 32, 64, 128
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                      "gate_proj", "up_proj", "down_proj",],
    lora_alpha = 16,
    lora_dropout = 0, # Supports any, but = 0 is optimized
    bias = "none",    # Supports any, but = "none" is optimized
    # [NEW] "unsloth" uses 30% less VRAM, fits 2x larger batch sizes!
    use_gradient_checkpointing = "unsloth", # True or "unsloth" for very long context
    random_state = 3407,
    use_rslora = False,  # We support rank stabilized LoRA
    loftq_config = None, # And LoftQ
)

准备数据

# 2.准备训练数据
from datasets import load_dataset
EOS_TOKEN = tokenizer.eos_token # Must add EOS_TOKEN

alpaca_prompt = """现在你要扮演皇帝身边的女人--甄嬛.

### Instruction:
{}

### Input:
{}

### Response:
{}"""

def formatting_prompts_func(examples):
    instructions = examples["instruction"]
    inputs       = examples["input"]
    outputs      = examples["output"]
    texts = []
    for instruction, input, output in zip(instructions, inputs, outputs):
        # Must add EOS_TOKEN, otherwise your generation will go on forever!
        text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN
        texts.append(text)
    return { "text" : texts, }

# Get local dataset
dataset = load_dataset("json", data_files = {"train" : "huanhuan.jsonl"}, split = "train")
dataset = dataset.map(formatting_prompts_func, batched = True,)

数据长这个样子
在这里插入图片描述每条数据分为 instruction, input 和 output 。
在这里插入图片描述

训练数据

from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported

trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    dataset_text_field = "text",
    max_seq_length = max_seq_length,
    dataset_num_proc = 2,
    packing = False, # Can make training 5x faster for short sequences.
    args = TrainingArguments(
        per_device_train_batch_size = 2,
        gradient_accumulation_steps = 4,
        warmup_steps = 5,
        # num_train_epochs = 1, # Set this for 1 full training run.
        max_steps = 100,
        learning_rate = 2e-4,
        fp16 = not is_bfloat16_supported(),
        bf16 = is_bfloat16_supported(),
        logging_steps = 1,
        optim = "adamw_8bit",
        weight_decay = 0.01,
        lr_scheduler_type = "linear",
        seed = 3407,
        output_dir = "outputs_huanhuan1",
        report_to = "none", # Use this for WandB etc
    ),
)
trainer_stats = trainer.train()

本地训练花了十几分钟的样子。

保存模型

model.save_pretrained("huanhuan_model") # save
#将模型保存为 gguf 格式
model.save_pretrained_gguf("model_gguf", tokenizer, quantization_method = "q4_k_m")
#将模型 push 到 huggingface
model.push_to_hub_gguf("***/test_llm_local", tokenizer, quantization_method = "q4_k_m", token = "***")

push 到 huggingface 上的模型,其中 token 需要我们在 huggingface 的后台自己生成。
在这里插入图片描述

模型加载

模型保存好了之后,我们可以使用代码或者 LM Studio加载。
LM Studio
LM Studio:https://lmstudio.ai/
LM Studio 可以直接搜索 huggingface 上的大模型使用,也可以加载本地的大模型,
在这里插入图片描述代码加载

from unsloth import FastLanguageModel
from transformers import TextStreamer

max_seq_length = 2048 # Choose any! We auto support RoPE Scaling internally!
dtype = None # None for auto detection. Float16 for Tesla T4, V100, Bfloat16 for Ampere+
load_in_4bit = True # Use 4bit quantization to reduce memory usage. Can be False.

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "outputs_huanhuan1/checkpoint-100", # the model that you trained
    max_seq_length = max_seq_length,
    dtype = dtype,
    load_in_4bit = load_in_4bit,
)
FastLanguageModel.for_inference(model) # Enable native 2x faster inference

交互:

alpaca_prompt = """现在你要扮演皇帝身边的女人--甄嬛.

### Instruction:
{}

### Input:
{}

### Response:
{}"""

inputs = tokenizer(
[
    alpaca_prompt.format(
        "嬛嬛你怎么了,朕替你打抱不平!", # instruction
        "", # input
        "", # output - leave this blank for generation!
    )
], return_tensors = "pt").to("cuda")

text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128)

在这里插入图片描述

总结

这样我们就得到了微调之后的模型了,huggingface 上还有很多模型和数据,可以选择我们需要的数据进行微调就能得到我们所需要的模型了。
另外补充一下我本地 gpu 的配置
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值