知行札记
专题技术实践AI 工程实践

模型适配实验

从数据和基线出发组织 SFT、LoRA、QLoRA 与偏好学习,保存可复核的训练产物。

先写出需要改善的输出行为

适配目标可以是稳定输出某个格式、遵循领域术语、完成特定推理任务或增加某类知识的可用性。每个目标需要对应独立测试。外部知识更新快、需要逐条引用时,知识库通常便于维护;模型适配可用于改变输出分布与任务能力,两者可以组合。

开始训练前保存三个基线:原模型,原模型加改进提示,原模型加允许资料。若问题由解析错误或证据缺失造成,训练无法直接修复该数据链路。对可验证的任务保存验算器;对主观输出写出评分规则和人工样例。

数据、模板与标签共同决定目标

SFT 样例通常包含消息序列或 prompt/completion。保存角色、轮次、工具调用和工具回执的边界。训练所用 chat template、特殊 token、EOS 与推理端一致;assistant-only loss 是否覆盖中间工具调用、最终回答及多个 assistant 轮次,检查 token 与标签实际内容。

训练/验证/测试按文档、用户、时间或任务族划分,减少同一对象的改写版本泄漏到多个集合。数据授权、个人信息与合成数据来源随数据卡保存。固定测试集后,不把它反复加入训练来抬分;迭代用验证集,阶段结论用保留测试。

下面演示 PEFT 的 LoRA 配置边界,适用于具有相应模块名称的 causal LM。base_model 由调用方加载并核实配置;数值是示例参数,未通过训练证明为最佳。

from peft import LoraConfig, TaskType, get_peft_model

config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    target_modules=["q_proj", "v_proj"],
    r=8,
    lora_alpha=16,
    lora_dropout=0.05,
    bias="none",
)
peft_model = get_peft_model(base_model, config)
peft_model.print_trainable_parameters()

target_modules 需要与实际结构匹配;有些模型合并 QKV,不能照抄名字。PEFT 会将目标层替换为包含适配参数的层,原基座与新参数的训练状态需要检查。r 控制更新的秩,lora_alpha 控制缩放,dropout 改变训练时正则化;学习率和数据量另行决定优化行为。PEFT Quicktour 给出配置与保存接口,main 文档需要与所锁定稳定版本对照。

数据先通过模板和泄漏检查

SFT 会话记录按实际 chat template 转换。下面是两条教学数据,不构成有效训练集;字段形状、模板和损失范围需与 trainer 对齐。

{"messages":[{"role":"user","content":"将 2 米换成厘米。"},{"role":"assistant","content":"2 米等于 200 厘米。"}]}
{"messages":[{"role":"user","content":"将 0.5 米换成厘米。"},{"role":"assistant","content":"0.5 米等于 50 厘米。"}]}

在 tokenization 后打印样本、special tokens 和 label mask,确认学习的是目标回答;检查样本尾部是否截断、EOS 是否正确、packing 是否跨样本混淆。按来源、时间或实体划分评测集,并去除训练与评测之间的近重复。工具轨迹数据还需保留参数、观察与最终状态,删除凭据并核对真实成功记录。

TRL 的 assistant_only_loss=True 可用于对话数据,但依赖支持助手 mask 的模板。prompt-completion 数据也可按 completion 区域计算 loss,不能只设一个选项便假定所有格式都已正确遮罩。TRL SFT Trainer。

配置 PEFT 与训练循环

以下演示 SFTTrainer 与 LoRA 的连接位置,模型和数据来自环境配置。它省略量化、分布式和最终评测,未执行训练;采用版本必须支持这些参数及相应数据格式。

import os
from datasets import load_dataset
from peft import LoraConfig
from trl import SFTConfig, SFTTrainer

train = load_dataset('json', data_files='train.jsonl', split='train')
valid = load_dataset('json', data_files='valid.jsonl', split='train')
config = SFTConfig(
    output_dir='outputs/adapter',
    per_device_train_batch_size=1,
    gradient_accumulation_steps=8,
    learning_rate=1e-4,
    num_train_epochs=1,
    logging_steps=10,
)
trainer = SFTTrainer(
    model=os.environ['BASE_MODEL'],
    args=config,
    train_dataset=train,
    eval_dataset=valid,
    peft_config=LoraConfig(
        r=16, lora_alpha=32, target_modules='all-linear',
        task_type='CAUSAL_LM',
    ),
)
trainer.train()
trainer.save_model('outputs/adapter')

这些数值用于表达配置位置,不是通用最优值。all-linear 的实际模块范围、输出层排除及架构支持随 PEFT 实现确定。QLoRA 还需配置冻结量化基座、计算精度、训练准备和适配器;减小 batch 或采用梯度检查点只能减少对应部分显存。继续预训练、DPO 和 GRPO 的数据、损失与采样循环各不相同,不能仅切换 trainer 名便完成任务转换。PEFT LoRA 指南。

QLoRA 与显存预算逐项计算

QLoRA 保留量化基座,在计算时解量化并训练 adapter。量化权重节省存储,激活、KV、optimizer 和临时缓冲仍占用显存。显存需求随序列长度、微批次、目标模块和内核变化;“某个 7B 模型最低 6 GB”不能成为所有任务的硬件保证。

先记录模型参数量与 dtype,再记录序列长度分布、微批次、梯度累积、checkpointing 与注意力实现。全局 batch 通常是微批次 × 梯度累积 × 数据并行度,流水线阶段数量不会自动增加独立样本数。两张 16 GB 卡是否可承载一个大于单卡显存的模型,取决于切分或 offload,不能直接相加视为一张 32 GB 卡。

OOM 时先定位权重、激活或临时峰值来源。减 batch 可能无助于权重放不下;减序列可能影响任务;offload 降显存同时增加传输和运行时间。每次改变记录质量与时间,而非只保留“训练成功”。

偏好与强化学习增加新的数据契约

DPO 需要同一提示下的 chosen/rejected 对;偏好规则、长度差与标注一致性会影响目标。GRPO 等在线生成方法还需要生成器、奖励函数、rollout 数量与拒绝或无效结果处理。规则奖励也可能被投机,验算器需要独立测试和边界用例。TRL 文档 提供对应训练器与数据格式入口。

对学习者或小团队,SFT、DPO 与 RL 是按数据和目标选择的路线,逐步升级需有证据支持。每阶段比较同一用例、相同模板和解码设置,并报告通用回归、任务提升与失败。

保存和部署时保持基座身份

adapter 通常依赖确切基座、tokenizer 和模板。保存 adapter 配置、权重、基座 revision、训练依赖锁文件、数据摘要和评测输出。合并 adapter、转换 GGUF 或重新量化会形成新的部署产物,再做同一测试集的质量回归。

可复核的实验报告至少说明:目标、数据来源与切分、基线、训练配置、实际环境、时间与费用、测量结果和失败边界。此处示例未训练或导出模型,具体显存、提速与质量结论需要运行证据。

最后更新于

本页目录