Chapter 03

快速上手:Colab 跑通 Llama-3 8B QLoRA

📌 commit 1cf145c070ea 30 行代码训出 chat 模型

Unsloth 之所以在 Reddit 和 HF 论坛火,关键就是"在免费 Colab T4 上 30 行代码训 Llama-3 8B"这种体验。 这一章带你跑通官方 Llama3_(8B)-Alpaca.ipynb 的完整流程:从加载模型到训练再到推理。

3.130 行训练脚本骨架

这是 Unsloth SFT 训练的标准模板。看着像 TRL SFTTrainer,但 model 是用 FastLanguageModel 起来的:

from unsloth import FastLanguageModel
import torch
from trl import SFTTrainer
from transformers import TrainingArguments
from datasets import load_dataset

# 1. 加载模型(自动 patch、注入 Triton kernel)
max_seq_length = 2048
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/llama-3-8b-bnb-4bit",   # 预量化模型
    max_seq_length = max_seq_length,
    dtype = None,                                  # 自动 bf16
    load_in_4bit = True,                           # QLoRA
)

# 2. 加 LoRA adapter
model = FastLanguageModel.get_peft_model(
    model,
    r = 16,
    target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
                      "gate_proj", "up_proj", "down_proj"],
    lora_alpha = 16,
    lora_dropout = 0,
    bias = "none",
    use_gradient_checkpointing = "unsloth",        # ★ Unsloth 增强版
    random_state = 3407,
    use_rslora = False,
    loftq_config = None,
)

# 3. 准备数据
dataset = load_dataset("yahma/alpaca-cleaned", split="train")
def formatting_func(examples):
    return [
        f"### Instruction:\n{i}\n### Response:\n{o}"
        for i, o in zip(examples["instruction"], examples["output"])
    ]

# 4. 训练(用 TRL SFTTrainer)
trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    dataset_text_field = "text",
    max_seq_length = max_seq_length,
    formatting_func = formatting_func,
    args = TrainingArguments(
        per_device_train_batch_size = 2,
        gradient_accumulation_steps = 4,
        warmup_steps = 5,
        max_steps = 60,
        learning_rate = 2e-4,
        bf16 = True,
        logging_steps = 1,
        optim = "adamw_8bit",                       # ★ 8bit Adam 省显存
        weight_decay = 0.01,
        lr_scheduler_type = "linear",
        seed = 3407,
        output_dir = "outputs",
    ),
)
trainer.train()

# 5. 保存
model.save_pretrained("lora_model")
tokenizer.save_pretrained("lora_model")

30 行内完成。这就是 Unsloth 的全部公共 API,剩下的"魔法"都在 FastLanguageModel 里。

3.2对照普通 HF + PEFT 写法

同一件事用 HF + PEFT 大致这样:

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model
import torch

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B")
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Meta-Llama-3-8B",
    quantization_config=bnb_config,
    torch_dtype=torch.bfloat16,
    attn_implementation="flash_attention_2",
)

lora_config = LoraConfig(
    r=16,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj"],
    lora_alpha=16, lora_dropout=0, bias="none",
    task_type="CAUSAL_LM",
)
model = get_peft_model(model, lora_config)

# ... 后面同 TRL SFTTrainer ...

HF + PEFT 路径多了几个 import + 一个 BitsAndBytesConfig 对象,但代码量差距不大。真正差距在底层

3.3预量化模型仓库:unsloth/* on HF

Unsloth 维护了大量预量化模型,model_name 直接填这些 4bit 版本能省下载和量化时间:

原模型Unsloth 预量化版
Llama-3-8B unsloth/llama-3-8b-bnb-4bit
Llama-3-70B unsloth/llama-3-70b-bnb-4bit
Llama-3.2-1B/3B unsloth/Llama-3.2-1B / 3B
Qwen3-4B / 14B unsloth/Qwen3-4B-bnb-4bit / 14B
Mistral-7B-v0.3 unsloth/mistral-7b-v0.3-bnb-4bit
Gemma-3-9B unsloth/gemma-3-9b-bnb-4bit
Phi-4 unsloth/phi-4(dynamic quant)
DeepSeek-V3 distill unsloth/deepseek-r1-distill-llama-8b

完整列表见 unsloth/models/mapper.py第一次跑直接选 unsloth/*-bnb-4bit,省心。

3.4训练时盯什么

训练过程中 Unsloth 会在屏幕上输出额外信息:

==((====))==  Unsloth 2026.5.4: Fast Llama patching. Transformers: 4.46.2.
   \\   /|    GPU: NVIDIA GeForce RTX 4090. Max memory: 23.99 GB. Platform: Linux.
O^O/ \_/ \    Torch: 2.5.1+cu126. CUDA: 8.9. CUDA Toolkit: 12.6. Triton: 3.1.0
\        /    Bfloat16 = TRUE. FA [Xformers = 0.0.28.post3. FA2 = True]
 "-____-"     Free Apache license: http://github.com/unslothai/unsloth

GPU = NVIDIA GeForce RTX 4090. Max memory = 23.99 GB.
6.789 GB of memory reserved.

| Step | Training Loss |
|------|---------------|
|   1  |   1.762400    |
|   2  |   1.598100    |
|   3  |   1.523300    |
...

Total time: 12.34s
Peak GPU memory = 14.5 GB

三个关键数字:

  1. Peak GPU memory:显存峰值,对比 HF + PEFT 通常能省 30%-50%;
  2. Total time:训完时间,比对照组应快 2-5×;
  3. Training Loss:训练 loss,下降趋势和 HF 版一致(数学等价)。

3.5训完跑推理

# 切到推理模式
FastLanguageModel.for_inference(model)

# 单条生成
inputs = tokenizer(
    "### Instruction:\n用中文写一段关于春天的描写\n### Response:\n",
    return_tensors="pt",
).to("cuda")

outputs = model.generate(
    **inputs,
    max_new_tokens=256,
    temperature=0.8,
    top_p=0.9,
    do_sample=True,
    use_cache=True,            # 推理时一定开
)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

FastLanguageModel.for_inference(model) 是 Unsloth 的优化推理模式:禁掉 dropout、用更激进的 KV cache 实现,比直接调 model.generate 快 2 倍。

3.6训完保存 / 导出

方法用途
model.save_pretrained("lora_model") 只保存 LoRA adapter(几十 MB)
model.save_pretrained_merged("merged_16bit", tokenizer, save_method="merged_16bit") 合并 LoRA 到 base,保存完整 fp16 模型
model.save_pretrained_gguf("gguf_q4", tokenizer, quantization_method="q4_k_m") 合并 + 转 GGUF(llama.cpp / Ollama 用)
model.push_to_hub_merged("user/repo", tokenizer, save_method="merged_16bit") 推到 HF Hub

第 12 章会详细讲导出与量化部署。

3.7常用 SFT 配置组合

用途关键参数
聊天模型 SFT chat_template="llama-3" + train_on_responses_only(trainer, ...)
continue pre-training UnslothTrainer + embedding_learning_rate=1e-5
DPO PatchDPOTrainer() + DPOTrainer
ORPO ORPOTrainer
GRPO(v2026 新增) unsloth/models/rl.py
视觉微调(VLM) FastVisionModel.from_pretrained(...)
语音 / 嵌入 FastTextToSpeechModel / SentenceTransformerModel

3.8训完一个 chat 模型该用什么 template

Unsloth 维护了一份 unsloth/chat_templates.py,覆盖主流模型:

from unsloth.chat_templates import get_chat_template

tokenizer = get_chat_template(
    tokenizer,
    chat_template="llama-3",    # 或 chatml, gemma, mistral, phi-3, qwen-2.5, qwen-3, ...
)

训练数据用 tokenizer.apply_chat_template(messages, tokenize=False) 拼成正确格式后再喂 trainer。

"只对 response 计算 loss"用 train_on_responses_only

from unsloth.chat_templates import train_on_responses_only

trainer = train_on_responses_only(
    trainer,
    instruction_part="<|start_header_id|>user<|end_header_id|>\n\n",
    response_part="<|start_header_id|>assistant<|end_header_id|>\n\n",
)

3.9第一次跑完应该看到什么

Llama-3-8B + alpaca-cleaned + 60 step(demo 长度):

max_steps 改成 num_train_epochs=3 跑完整数据集需要约 5 小时(4090),就是真实训练量级。

3.10这章带走的