关于 ml-fine-tuning
用于将预训练模型适配到新任务、领域和行为的技能。帮助从业者比较微调与其他方案、准备数据集,并应用 LoRA、QLoRA 和偏好调优等方法。
主要功能
- 01比较模型适配方法
- 02准备并划分训练数据
- 03QLoRA 与 PEFT 指导
- 04SFT 与 DPO 训练模式
- 05微调嵌入模型
- 06监控稳定性与遗忘
适用场景
- 01选择提示词、RAG 或训练方案
- 02准备指令微调数据
- 03使用适配器微调 LLM
- 04为检索任务适配嵌入模型
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill ml-fine-tuning安装后在 Claude Code 中输入/ml-fine-tuning确认已加载。
详细介绍
ML 微调
概述
使用此技能将预训练模型适配到新任务、领域、风格、指令、模态或约束。微调并不总是首选方案:在训练大型基础模型之前,应先比较提示词、检索增强生成、特征提取、经典任务头以及更小的特定任务模型。
选择适配方法
| 方法 | 适用情况 | 权衡 |
|---|---|---|
| 提示词/系统指令 | 行为变化简单,且上下文长度足够 | 无训练成本;持久性和可控性有限 |
| RAG | 需要会变化或必须引用的事实性/领域知识 | 需要评估检索质量、分块和依据性 |
| 特征提取 + 任务头 | 标注数据集较小,且预训练嵌入效果出色 | 效率高;深度适配能力有限 |
| 部分微调 | 需要以有限算力进行领域适配 | 必须谨慎选择层 |
| 全量微调 | 数据集较大、任务特异性强且算力充足 | 成本最高,遗忘风险也最高 |
| LoRA/适配器/PEFT | 需要高效适配并构建多个变体 | 容量略受限制;目标模块很重要 |
| QLoRA | 需要在受限的 GPU 上微调大型 LLM | 量化和优化器选择会影响稳定性 |
| 偏好微调/RLHF/DPO | 需要让行为与偏好对齐 | 奖励/偏好数据质量起主导作用 |
| 蒸馏 | 需要更小、更快且可部署的模型 | 依赖教师模型质量和有代表性的数据 |
数据集准备
微调质量通常取决于数据质量。应去重、移除损坏样本、过滤不安全或无关内容、平衡任务、统一标签,并保留评估留出集。对于指令微调,应使用一致的模式和与基础模型匹配的聊天模板。对于分类任务,应检查标签定义和标注者间一致性。对于检索/嵌入微调,应挖掘困难负例并避免假负例。
当样本之间存在关联时,应按实体、时间、来源或文档划分数据。绝不能让近似重复样本、提示词变体、同一文档中的分块或生成的释义跨越训练集/验证集/测试集边界。对于生成任务,应保留一个便于人工审核且包含有代表性困难案例的验证集。
QLoRA 和 PEFT(Hugging Face 蓝图)
QLoRA 在以 4 位精度冻结基础模型的同时训练小型低秩适配器,从而大幅节省 GPU 显存。
1. 初始化 4 位基础模型(BitsAndBytesConfig)
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
model_id = "meta-llama/Meta-Llama-3-8B-Instruct"
# Configure 4-bit quantization details
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4", # Normalized Float 4 (optimal for zero-mean normal weights)
bnb_4bit_compute_dtype=torch.bfloat16 # Compute in BF16 for training stability
)
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=bnb_config,
device_map="auto"
)
2. 配置 LoRA 参数并准备模型
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
# Prepare frozen model for quantized adapter training
model = prepare_model_for_kbit_training(model)
# Define Low-Rank Adaptation (LoRA) Config
peft_config = LoraConfig(
r=16, # Rank dimension (typically 8, 16, 32, or 64)
lora_alpha=32, # Scaling factor (usually 2 * rank)
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# Wrap base model with LoRA adapters
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()
TRL(Transformer 强化学习)训练设置
TRL 提供了 SFTTrainer(用于监督微调)和 DPOTrainer(用于直接偏好优化)等封装器。
1. 监督微调(SFTTrainer)
from trl import SFTTrainer
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir="./results",
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
logging_steps=10,
max_steps=500,
fp16=False,
bf16=True, # Optimal on Ampere/Hopper architecture GPUs
optim="paged_adamw_8bit" # Page state out to host memory to prevent OOMs
)
trainer = SFTTrainer(
model=model,
train_dataset=dataset,
peft_config=peft_config,
dataset_text_field="text",
max_seq_length=512,
tokenizer=tokenizer,
args=training_args
)
# trainer.train()
2. 直接偏好优化(DPOTrainer)
DPO 直接使用偏好/不偏好输出对训练模型,无需单独的奖励模型。
from trl import DPOTrainer
dpo_trainer = DPOTrainer(
model=model,
ref_model=None, # TRL will implicitly handle ref_model under PEFT by disabling adapters
args=training_args,
beta=0.1, # Temperature parameter for DPO loss (scales difference from reference policy)
train_dataset=preference_dataset,
tokenizer=tokenizer,
max_length=512,
max_prompt_length=256
)
# dpo_trainer.train()
SentenceTransformers 自定义嵌入模型微调
嵌入微调可为以检索为主的(RAG)应用创建自定义向量空间。
from sentence_transformers import SentenceTransformer, InputExample, losses
from torch.utils.data import DataLoader
model = SentenceTransformer("all-MiniLM-L6-v2")
# Create positive pairs (e.g., query and matching document)
train_examples = [
InputExample(texts=["How to initialize FSDP in PyTorch?", "Use FullyShardedDataParallel wrapper..."]),
InputExample(texts=["What is QLoRA?", "QLoRA trains adapters over a frozen 4-bit base model..."])
]
train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=16)
# MultipleNegativesRankingLoss treats other pairs in the batch as implicit negative examples
train_loss = losses.MultipleNegativesRankingLoss(model=model)
# model.fit(
# train_objectives=[(train_dataloader, train_loss)],
# epochs=3,
# warmup_steps=100
# )
训练稳定性
微调时应使用较保守的学习率。预热通常会有所帮助。监控训练损失和验证损失、任务指标、生成质量以及过拟合情况。对于 LLM,应留意格式偏移、冗长度变化、拒答能力退化、幻觉、工具使用能力退化和安全问题。出现不稳定时,应使用梯度裁剪,并验证指令微调的标签是否正确屏蔽。
灾难性遗忘是指模型在新数据上有所提升,却丧失了通用能力。可通过降低学习率、减少训练轮数、混合多领域数据、回放样本、使用适配器而非全量微调、正则化或平衡多任务来缓解。
来源
- Hugging Face Transformers 文档:https://huggingface.co/docs/transformers
- Hugging Face PEFT 文档:https://huggingface.co/docs/peft
- Hugging Face TRL 文档:https://huggingface.co/docs/trl
- Hugging Face Diffusers 训练文档:https://huggingface.co/docs/diffusers/training/overview
- Sentence Transformers 文档:https://www.sbert.net/
- Ray 和 Accelerate 分布式训练文档:https://docs.ray.io/ and https://huggingface.co/docs/accelerate