🚀 超快!使用 Unsloth 轻量化微调 Llama 3.1 8B 实战指南

30 阅读3分钟

前言:在开源模型如火如荼发展的今天,我们该怎么高效微调大模型呢?今天分享一个“黑科技”工具——Unsloth

它通过自定义内核优化,能实现 2 倍的训练速度并减少 60% 的显存占用。本文将手把手教你如何使用 QLoRA 在 FineTome-100k 数据集上完成一次高质量的指令微调。


一、 环境准备:安装 Unsloth

Unsloth 对环境有特殊要求,建议在 Linux 或 WSL2 环境下运行。

Bash

# 安装 Unsloth 核心库及相关依赖
!pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
!pip install --no-deps "xformers<0.0.27" "trl<0.9.0" peft accelerate bitsandbytes

二、 模型加载:4-bit 量化引入

为了节省显存,我们选择预量化的版本。Llama 3.1 原版 16-bit 需 16GB,而 4-bit 版仅需 5.4GB

Python

import torch
from unsloth import FastLanguageModel

max_seq_length = 2048  # 限制上下文窗口以节省显存
dtype = None           # 自动检测(Ampere架构及以上支持BF16)
load_in_4bit = True    # 开启4-bit量化

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/llama-3.1-8b-bnb-4bit",
    max_seq_length = max_seq_length,
    dtype = dtype,
    load_in_4bit = load_in_4bit,
)

三、 配置 LoRA:只训练 0.5% 的参数

我们通过 LoRA(低秩自适应)进行微调。在本配置下,我们只训练 80 亿参数中的 4200 万个,极大降低了计算成本。

Python

model = FastLanguageModel.get_peft_model(
    model,
    r = 16,            # 等级(Rank),推荐 8, 16, 32, 64
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                      "gate_proj", "up_proj", "down_proj"],
    lora_alpha = 16,   # 缩放因子
    lora_dropout = 0,  # 设置为0以获得Unsloth优化加速
    bias = "none",    
    use_gradient_checkpointing = "unsloth", # 关键:大幅节省显存
    random_state = 3407,
)

四、 数据准备:ShareGPT 格式与 ChatML 模板

我们使用的是 FineTome-100k 数据集。它经过精细过滤,非常适合多轮对话。我们将使用 ChatML 格式进行标准化。

Python

from unsloth.chat_templates import get_chat_template

# 1. 设置聊天模板映射
tokenizer = get_chat_template(
    tokenizer,
    mapping={"role": "from", "content": "value", "user": "human", "assistant": "gpt"},
    chat_template="chatml",
)

# 2. 处理数据集
def apply_template(examples):
    messages = examples["conversations"]
    text = [tokenizer.apply_chat_template(message, tokenize=False, add_generation_prompt=False) for message in messages]
    return {"text": text}

from datasets import load_dataset
dataset = load_dataset("mlabonne/FineTome-100k", split="train")
# 小提示:算力有限可以先跑前10000条:split="train[:10000]"
dataset = dataset.map(apply_template, batched=True)

五、 训练配置:SFT 实战

使用 SFTTrainer 进行监督微调。注意这里使用了 adamw_8bit 优化器。

显卡类型100k 数据预估耗时
A800 (80GB)~2 小时 45 分钟
L4 (24GB)~19 小时 40 分钟
T4 (16GB)~47 小时

Python

from trl import SFTTrainer
from transformers import TrainingArguments

trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    dataset_text_field = "text",
    max_seq_length = max_seq_length,
    packing = True, # 将小样本打包以提升训练效率
    args = TrainingArguments(
        learning_rate = 3e-4,
        lr_scheduler_type = "linear",
        per_device_train_batch_size = 8,
        gradient_accumulation_steps = 2,
        num_train_epochs = 1,
        optim = "adamw_8bit",
        weight_decay = 0.01,
        warmup_steps = 10,
        output_dir = "output",
        fp16 = not torch.cuda.is_bf16_supported(),
        bf16 = torch.cuda.is_bf16_supported(),
        logging_steps = 1,
    ),
)

trainer.train()

六、 推理与保存:导出 GGUF 格式

微调完成后,我们最关心的就是如何使用。Unsloth 支持直接导出 GGUF 格式,方便在 Ollama 或 LM Studio 中直接运行。

1. 快速推理测试

Python

model = FastLanguageModel.for_inference(model)
messages = [{"from": "human", "value": "Is 9.11 larger than 9.9?"}]
inputs = tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=True, return_tensors="pt").to("cuda")

from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer)
_ = model.generate(input_ids=inputs, streamer=text_streamer, max_new_tokens=128)

2. 保存与导出

Python

# 保存本地适配器
model.save_pretrained("../Fine_tuneModel/")
tokenizer.save_pretrained("../Fine_tuneModel/")

# 导出为 GGUF 格式 (Q8_0量化)
model.save_pretrained_gguf("../Fine_tuneModel/gguf-model.q8_0.gguf", tokenizer, "q8_0")

结语

通过 Unsloth,我们不仅实现了极速微调,还直接打通了从训练到部署的最后一步。微调后的 Llama 3.1 在指令遵循和逻辑判断上会有质的飞跃。

接下来你可以尝试:

  1. Open LLM Leaderboard 上评估你的模型。
  2. 使用自己的私有数据集进行垂直领域增强。

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏,并在评论区分享你的微调心得!