在这一小时结束时,你将拥有一个以你的格式作答的小型语言模型,在本地的 Ollama 中运行——总成本:0 美元。无需博士学位。你只需要以下之一:一块显存 6GB 以上的 NVIDIA GPU,或一台内存 16GB 以上的 Apple Silicon Mac。我们将挑选一个入门数据集,用不会翻车的保守设置训练一个 QLoRA 适配器,导出为 GGUF,然后与你自己的模型对话。这是"食谱卡";指南 13:在本地微调 LLM 是完整的"菜谱大全"——当你想了解某一步背后的原理时就去看它。
第 0 步 —— 你到底该不该微调?(5 分钟)
在你花掉一小时之前,先诚实地把把关:微调是你该拿起的第三件工具,而不是第一件。
先用提示。 一个好的系统提示加上两三个示例输出,能在五分钟内解决大多数"让它像 X 那样作答"的问题。其次用 RAG。 如果问题在于知识——你的文档、你的产品、当前事实——那么检索胜出,因为微调无法可靠地添加事实。当以下情况时才微调: 你需要每次回复都保持一致的风格或格式、领域特定的措辞、必须始终能解析的结构化输出,或出于延迟考虑而使用简短提示。这是一段话的版本——带示例的完整决策清单在指南 13 的"何时应该微调?"一节。
还在看?很好——风格、格式和语气正是一小时微调所擅长的。
第 1 步 —— 选择你的路径(2 分钟)
| 路径 A:NVIDIA | 路径 B:Apple Silicon | |
|---|---|---|
| 硬件 | 显存 6GB 以上的 GeForce GPU(RTX 3060/4060 或更好) | 拥有16GB 以上统一内存的 M1–M4 Mac |
| 工具 | Unsloth(在 4-bit 基座上做 QLoRA) | MLX-LM(在 4-bit 模型上做 LoRA) |
| 基座模型 | unsloth/Llama-3.2-3B-Instruct | mlx-community/Mistral-7B-Instruct-v0.3-4bit |
| 约 1k 样本用时 | ~20–60 分钟 | ~20–40 分钟 |
QLoRA 是让这一切在消费级硬件上成为可能的诀窍:基座模型以 4-bit 加载,你只训练小的适配器矩阵,因此一个 7B 微调只需约 6GB 显存——而 Mac 上 4-bit 的 7B 微调约占用 8GB 工作内存,在 16GB 机器上仍有余量。在路径 B 上请注意,在一个已经是 4-bit 的模型上训练 LoRA 适配器就是 QLoRA——MLX 会处理好,无需额外设置。
不确定你的显卡是否合格?在硬件分析器中检查你的 GPU。完全没有兼容硬件?以约 0.35 美元/小时租一块 RTX 4090——见云 GPU 租用指南;下面的一切在租用的机器上运行方式完全相同。
如果你在为第一块微调显卡选购,16GB 的 RTX 4060 Ti 是甜蜜点——足够的显存可支撑 13B 的 QLoRA 训练:
第 2 步 —— 挑选一个入门数据集(5 分钟)
三个不错的选择,按优先顺序:
- No Robots —— 1 万条完全由人工标注者撰写的示例。小巧、干净、多样。是学习工作流的最佳首选数据集,也是下面脚本所使用的。
- Databricks Dolly 15k —— 1.5 万条人工撰写的问答对,采用 CC BY-SA 3.0 许可。如果你的微调有可能用于产品,就选这个。
- 你自己的 200–500 条示例 —— 当你想让模型听起来像你的那一刻,没有什么比得上你自己的数据。使用 Alpaca JSONL 格式(与指南 13 相同):
{"instruction": "Summarize this support ticket in two sentences.", "input": "Customer reports login fails after password reset...", "output": "Customer cannot log in following a password reset. Issue traced to a stale session cookie; cleared and resolved."}⚠️ 训练前请检查许可证。 Alpaca 和 ShareGPT 是 CC BY-NC(非商用)——No Robots 也是,因此把它当作学习数据集。任何商用用途请使用 Dolly 15k(CC BY-SA)或其他宽松许可的数据集——在数据集中心按"宽松许可(Permissive)"筛选即可看到全部。
第 3A 步 —— 在 NVIDIA 上用 Unsloth 训练(25 分钟)
一个脚本,从头到尾。先安装(干净的虚拟环境能省去 CUDA 依赖的麻烦):
pip install unslothfrom unsloth import FastLanguageModel
from datasets import load_dataset
from trl import SFTTrainer
from transformers import TrainingArguments
# 1. Load a small 4-bit base — 3B keeps this comfortable even on 6GB cards
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/Llama-3.2-3B-Instruct",
max_seq_length=2048,
load_in_4bit=True,
)
# 2. Add LoRA adapters (r=16 is the standard starting point)
model = FastLanguageModel.get_peft_model(
model,
r=16,
lora_alpha=16,
lora_dropout=0,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
)
# 3. Load No Robots and render each conversation with the chat template.
# Columns on the HF card: prompt, prompt_id, messages, category —
# "messages" is the list of {role, content} turns we train on.
dataset = load_dataset("HuggingFaceH4/no_robots", split="train[:1000]")
def to_text(row):
return {"text": tokenizer.apply_chat_template(row["messages"], tokenize=False)}
dataset = dataset.map(to_text)
# 4. Train — conservative defaults, same as Guide 13
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=2048,
args=TrainingArguments(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
num_train_epochs=2,
learning_rate=2e-4,
logging_steps=10,
optim="adamw_8bit",
output_dir="./outputs",
save_strategy="epoch",
),
)
trainer.train()
# 5. Save the adapter
model.save_pretrained("my-first-lora")
tokenizer.save_pretrained("my-first-lora")在 RTX 3060/4060 级别的 GPU 上,1000 条示例的子集(2 个 epoch)大约需要 20–60 分钟——区间取决于示例长度;较老的 6GB 显卡会落在上限。损失(loss)应从约 2 开始并稳步下降;如果没有,请跳到第 5 步。
第 3B 步 —— 在 Mac 上用 MLX 训练(25 分钟)
pip install mlx-lmMLX 需要一个 data/ 文件夹,内含其聊天格式的 train.jsonl 和 valid.jsonl——每一行是 {"messages": [...]},最后一条消息就是模型要学着生成的内容。几行代码即可转换 No Robots:
import json
from datasets import load_dataset
ds = load_dataset("HuggingFaceH4/no_robots")
def dump(rows, path):
with open(path, "w") as f:
for row in rows:
f.write(json.dumps({"messages": row["messages"]}) + "\n")
dump(ds["train"].select(range(1000)), "data/train.jsonl")
dump(ds["test"].select(range(100)), "data/valid.jsonl")然后训练——一条命令:
mlx_lm.lora \
--model mlx-community/Mistral-7B-Instruct-v0.3-4bit \
--data ./data \
--train \
--batch-size 2 \
--iters 600由于基座模型已经是 4-bit,这个 LoRA 训练就是 QLoRA——无需任何标志。在 16GB 的 M2/M3/M4 上预计需要 20–40 分钟;验证损失会一路打印出来。立即测试适配器:
mlx_lm.generate \
--model mlx-community/Mistral-7B-Instruct-v0.3-4bit \
--adapter-path adapters \
--prompt "Summarize what QLoRA does in one sentence."第 4 步 —— 测试并导出到 Ollama(10 分钟)
路径 A(Unsloth): 直接导出为 GGUF——在你的脚本中加一行:
model.save_pretrained_gguf("my-first-model", tokenizer, quantization_method="q4_k_m")路径 B(MLX): 把适配器融合进权重并导出。GGUF 导出需要 fp16 权重,因此在融合时反量化:
mlx_lm.fuse \
--model mlx-community/Mistral-7B-Instruct-v0.3-4bit \
--adapter-path adapters \
--de-quantize \
--export-gguf现在用一个两行的 Modelfile 把它接入 Ollama(把 FROM 指向你刚生成的 .gguf 文件):
FROM ./my-first-model/unsloth.Q4_K_M.gguf
SYSTEM You are a concise assistant that answers in two sentences maximum.ollama create my-first-model -f Modelfile
ollama run my-first-model前后对比就是回报所在。同一个提示——"解释一下 VPN 的作用":
之前(基座模型): "好问题!VPN,即虚拟专用网络,是一种在不太安全的网络上建立安全加密连接的技术……[还有三段]"
之后(你的微调版): "VPN 会加密你的流量并通过远程服务器转发,从而对本地网络隐藏你的活动并掩盖你的 IP 地址。它能在公共 Wi-Fi 上保护隐私,但并不能让你完全匿名。"
这就是每一次成功的风格微调的样子:知识相同,格式是你的。
第 5 步 —— 哪里出错了?(5 分钟)
每个人都会遇到的四种失败,按出现频率排序:
- CUDA 显存不足(out of memory) —— 把
per_device_train_batch_size降到 1,把max_seq_length减到 1024,或(MLX)加上--grad-checkpoint。3B 基座上的 QLoRA 只需约 4GB;如果在那里就 OOM,说明有别的东西在占用显存——把它关掉。 - 模型逐字复述训练示例 —— 你过拟合了。降到 1 个 epoch,或增加更多样化的数据。
- 模型在其他所有方面都变笨了 —— 学习率过高或 epoch 过多抹掉了通用能力。回到
2e-4和 2 个 epoch;这正是它们作为默认值的原因。 - 损失从不下降 —— 几乎总是数据格式问题:文本字段没有经过聊天模板,或你的 JSONL 键不匹配。打印一条格式化后的样本并读一读。
遇到的是奇怪的驱动或安装错误?故障排查一节逐条讲解了 CUDA OOM 及其同类问题。
接下来做什么
- 用 DPO 打磨答案 —— 在 SFT 之后,一次偏好训练能让模型选择更好的答案,而不仅仅是排版。指南 13 有可用的 DPO 脚本。
- 升级你的数据 —— 浏览中心里的全部 47 个数据集,按许可证和类别筛选。
- 秀出来 —— 训练出了有趣的东西?我们会在本地 AI 摘要中展示读者的微调作品;回复任意一期,附上你的前后对比。
常见问答
微调一个 LLM 的最低 GPU 要求是什么?
一块 6GB 的 NVIDIA 显卡(RTX 3060/4060 级别)可从容地用 QLoRA 微调 7B 模型,而 3B 模型只需约 4GB。不使用 QLoRA 的完整微调需要多 10–20 倍的内存——这正是本指南每一步都使用 4-bit 基座配 LoRA 适配器的原因。
我能在 Mac 上微调 LLM 吗?
可以。苹果的 MLX 框架利用统一内存在 4-bit 模型上训练 LoRA 适配器——一台 16GB 的 M 系列 Mac 约用 8GB 工作内存就能处理一个 7B 的 QLoRA 微调。它比桌面 NVIDIA 显卡慢,但完全本地且静音。
我需要多少条示例来微调?
对于风格、语气和格式:200–1000 条好示例。LIMA 证明了 1000 条精挑细选的样本就能对齐一个 65B 模型。对于新的领域技能,目标是 1 万条以上。质量永远胜过数量——一条糟糕的示例就会教出一个坏习惯。
微调需要多长时间?
按本指南的设置,在 RTX 3060/4060 级别的 GPU 上,1000 条示例大约 20–60 分钟;在 16GB 的 Apple Silicon Mac 上为 20–40 分钟。更大的数据集呈线性增长:1 万条示例是一夜的训练,而不是一个周末。
微调会给模型添加新知识吗?
不可靠——微调改变的是模型如何作答,而不是它知道什么。要让模型基于你的文档或当前事实作答,请改用 RAG(检索增强生成),或两者结合:用 RAG 提供事实,用微调提供口吻。