趋近智
大师班
大型语言模型在首次部署后保持其对齐性是一个持续过程,而非一次性任务。用户期望会改变,新的安全问题会出现,并且期望的模型行为可能会随时间推移而漂移,或需要为特定应用进行修正。持续微调,通过监督式方法(SFT)或强化学习(RLHF),提供逐步调整模型的机制。与初始微调不同,持续微调涉及将新数据或反馈整合到已运行的模型中,带来了效率、稳定性和知识保留方面的特别挑战。
持续SFT旨在根据新的监督式示例(例如,提示-完成对)更新模型遵循指令或执行特定任务的能力。这需要整合新数据的策略,同时不降低现有能力。
新的SFT数据可以来自多个地方:
简单地在新数据上进行微调可能导致灾难性遗忘,即模型失去其之前学习过的任务能力。常见的缓解策略包括:
这是一个使用LoRA的简化PyTorch示例(假设peft等PEFT库可用),用于持续SFT步骤:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel, LoraConfig, get_peft_model
# 加载基础模型和分词器
model_name = "meta-llama/Llama-2-7b-hf" # 示例基础模型
base_model = AutoModelForCausalLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
# 假设存在之前微调步骤的LoRA适配器权重
# 如果开始持续微调,直接加载基础模型
# 如果继续,加载之前已适配的模型
# 为演示目的,我们假设是首次添加LoRA层
lora_config = LoraConfig(
r=16, # 更新矩阵的秩
lora_alpha=32, # 缩放因子
target_modules=["q_proj", "v_proj"], # 定位特定模块
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(base_model, lora_config)
model.print_trainable_parameters()
# 显示可训练参数显著减少
# --- 持续SFT步骤 ---
# 加载新的SFT数据批次(格式化的指令-响应对)
# new_data = load_new_sft_batch(...)
# inputs = tokenizer(
# new_data['prompts'],
# return_tensors='pt',
# padding=True,
# truncation=True
# )
# labels = tokenizer(
# new_data['responses'],
# return_tensors='pt',
# padding=True,
# truncation=True
# ).input_ids
# 假设'inputs'和'labels'是已准备好的张量
optimizer = torch.optim.AdamW(model.parameters(), lr=5e-5)
# 仅优化LoRA权重
# 简化训练步骤
model.train()
# outputs = model(
# **inputs, labels=labels
# ) # 传入标签用于损失计算
# loss = outputs.loss
# loss.backward()
# optimizer.step()
# optimizer.zero_grad()
# --- 在新数据上训练后 ---
# 保存更新后的LoRA适配器权重,而非整个模型
# model.save_pretrained("./updated_lora_adapters")
# 使用更新后的模型:
# updated_model = PeftModel.from_pretrained(
# base_model, "./updated_lora_adapters"
# )
评估持续SFT涉及检查以下方面的性能:
RLHF使模型与复杂的人类偏好对齐,这些偏好通常与有用性、诚实性和无害性相关。持续RLHF涉及根据新的偏好数据更新奖励模型(RM)和/或策略模型。
RM预测人类会偏爱两个响应中的哪一个。它需要定期更新,原因如下:
数据来源: 新的偏好对(y1,y0∣x,其中给定提示x时y1优于y0) 的收集方式与初始RM训练类似,通常侧重于当前策略模型生成的输出。
训练: RM可以通过以下方式更新:
import torch
import torch.nn.functional as F
from transformers import AutoModelForSequenceClassification, AutoTokenizer
# 假设'rm_model'是已加载的奖励模型(例如,基于分类头)
# 假设'rm_tokenizer'是其分词器
# 加载新的偏好数据批次:(提示, 选定响应, 被拒绝响应)对
# new_prefs = load_new_preference_batch(...)
# 为奖励模型分词输入
# chosen_inputs = rm_tokenizer(new_prefs['prompt'], new_prefs['chosen'], ...)
# rejected_inputs = rm_tokenizer(new_prefs['prompt'], new_prefs['rejected'], ...)
# 假设分词后的输入是已准备好的张量
rm_optimizer = torch.optim.AdamW(
rm_model.parameters(), lr=1e-6
) # 使用小学习率
# 简化的RM更新步骤
rm_model.train()
# chosen_rewards = rm_model(**chosen_inputs).logits
# rejected_rewards = rm_model(**rejected_inputs).logits
# 成对铰链损失或类似损失
# loss = -F.logsigmoid(chosen_rewards - rejected_rewards).mean()
# loss.backward()
# rm_optimizer.step()
# rm_optimizer.zero_grad()
# 保存更新后的奖励模型状态
# torch.save(rm_model.state_dict(), "./updated_reward_model.pt")
策略模型(即LLM本身)通过RL(通常是PPO)进行微调,以最大化RM预测的奖励,同时保持与原始SFT模型的接近(由KL散度惩罚控制)。持续RLHF更新涉及:
使用trl等库的框架可能如下所示:
# 假设'ppo_trainer'已使用策略模型、
# 参考模型(SFT)、分词器和PPO配置进行初始化。
# 假设'updated_rm_model'是最新奖励模型。
# --- 持续RLHF步骤 ---
# 从数据集中采样提示
# prompts = sample_prompts(...)
# tokenized_prompts = tokenizer(prompts, ...)
# 使用当前策略模型生成响应
# responses_tensors = ppo_trainer.generate(tokenized_prompts, ...)
# responses_text = tokenizer.batch_decode(responses_tensors)
# 从更新后的奖励模型获取奖励
# rewards = get_rewards_from_rm(updated_rm_model, prompts, responses_text,
# tokenizer)
# 执行PPO优化步骤
# stats = ppo_trainer.step(tokenized_prompts, responses_tensors, rewards)
# 定期保存更新后的策略模型(如果使用PEFT,则保存其适配器)
# ppo_trainer.save_model("./updated_policy_model")
评估持续RLHF是复杂的。指标包括:
简化工作流程,展示持续SFT和RLHF的并行循环,更新已部署的模型状态。
实施持续微调需要成熟的MLOps基础设施,能够处理数据管道、频繁的再训练任务、可靠的版本控制、分阶段推出以及全面的监控,以确保更新能提高对齐性,同时不导致模型能力或安全性的有害退步。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造