周志洋

个人站

持续学习 才能不被淘汰


大模型预训练与微调

预训练概述

预训练是大模型训练的第一阶段,通过在大规模无标注数据上学习语言的通用表示。预训练后的模型具备强大的语言理解能力,可以迁移到各种下游任务。

预训练的作用

# 预训练的作用
pretraining_purpose = {
    "学习通用表示": "从大规模数据中学习语言通用模式",
    "知识获取": "模型学习大量知识",
    "迁移能力": "预训练模型可迁移到下游任务",
    "基础能力": "为后续微调提供良好基础"
}

预训练方法

1. 自回归语言模型 (Autoregressive LM)

自回归语言模型通过预测下一个词来学习语言模式,GPT系列模型使用这种方法。

# 自回归语言模型
训练目标:
  任务: "给定前文,预测下一个词"
  公式: "P(x_t | x_1, ..., x_{t-1})"
  
训练过程:
  1: "输入序列: [x_1, x_2, ..., x_{t-1}]"
  2: "模型预测: P(x_t | context)"
  3: "计算损失: -log P(x_t | context)"
  4: "反向传播更新参数"

特点:
  - 单向注意力(只能看到前面的词)
  - 适合生成任务
  - GPT系列使用

2. 掩码语言模型 (Masked LM)

掩码语言模型通过预测被掩码的词来学习双向表示,BERT使用这种方法。

# 掩码语言模型
训练目标:
  任务: "预测被掩码的词"
  方法: "随机掩码15%的词,预测这些词"
  
掩码策略:
  - 80%: 用[MASK]替换
  - 10%: 用随机词替换
  - 10%: 保持不变

特点:
  - 双向注意力(可以看到上下文)
  - 适合理解任务
  - BERT使用

3. 序列到序列预训练

序列到序列模型同时使用编码器和解码器,T5使用这种方法。

# 序列到序列预训练
训练目标:
  任务: "将输入序列转换为输出序列"
  格式: "所有任务都转换为文本到文本格式"
  
示例:
  输入: "translate English to German: The house is wonderful."
  输出: "Das Haus ist wunderbar."

特点:
  - 统一的任务格式
  - 适合多种任务
  - T5使用

预训练数据

1. 数据来源

# 预训练数据来源
数据来源:
  网页数据:
    - Common Crawl: "大规模网页爬取数据"
    - 质量: "需要清洗和过滤"
    - 规模: "TB级别"
  
  书籍数据:
    - 电子书库
    - 质量: "高质量文本"
    - 规模: "GB到TB级别"
  
  代码数据:
    - GitHub代码
    - 质量: "需要去重和过滤"
    - 规模: "GB级别"
  
  其他数据:
    - 新闻文章
    - 学术论文
    - 百科数据

2. 数据预处理

# 数据预处理步骤
预处理步骤:
  1: "数据收集: 从多个来源收集数据"
  2: "数据清洗: 去除噪声和低质量内容"
  3: "去重: 去除重复内容"
  4: "过滤: 过滤不当内容"
  5: "分词: 将文本转换为token"
  6: "构建数据集: 组织成训练格式"

微调技术

1. 全量微调 (Full Fine-tuning)

全量微调更新模型的所有参数。

# 全量微调
特点:
  - 更新所有参数
  - 效果最好
  - 需要大量计算资源
  - 成本高

适用场景:
  - 有充足计算资源
  - 需要最佳性能
  - 大规模数据集

2. 参数高效微调 (PEFT)

参数高效微调只更新少量参数,大幅降低计算成本。

# 参数高效微调方法
方法类型:
  LoRA (Low-Rank Adaptation):
    - 低秩矩阵分解
    - 只训练少量参数
    - 效果接近全量微调
  
  QLoRA:
    - 量化 + LoRA
    - 进一步降低资源需求
    - 在量化模型上微调
  
  Adapter:
    - 插入适配器层
    - 只训练适配器参数
    - 保持原模型不变
  
  Prompt Tuning:
    - 只训练提示词
    - 参数最少
    - 效果相对较低

LoRA详解

1. LoRA原理

LoRA通过低秩矩阵分解来近似全量微调的效果。

# LoRA原理
# 原始权重更新: W' = W + ΔW
# LoRA近似: ΔW = BA,其中B和A是低秩矩阵

# LoRA实现
class LoRALayer:
    def __init__(self, original_layer, rank=8, alpha=16):
        self.original_layer = original_layer
        self.rank = rank
        self.alpha = alpha
        
        # 初始化低秩矩阵
        d_in = original_layer.weight.shape[0]
        d_out = original_layer.weight.shape[1]
        
        self.A = nn.Parameter(torch.randn(d_in, rank) * 0.01)
        self.B = nn.Parameter(torch.zeros(rank, d_out))
    
    def forward(self, x):
        # 原始输出
        original_output = self.original_layer(x)
        
        # LoRA输出
        lora_output = x @ self.A @ self.B * (self.alpha / self.rank)
        
        # 合并输出
        return original_output + lora_output

2. LoRA优势

# LoRA优势
优势:
  参数效率: "只训练0.1%-1%的参数"
  内存效率: "大幅减少显存占用"
  训练速度: "训练速度更快"
  效果接近: "效果接近全量微调"
  易于部署: "可以合并到原模型"

3. LoRA配置

# LoRA配置参数
配置参数:
  rank (r):
    - 低秩矩阵的秩
    - 推荐: 4-32
    - 越大效果越好但参数越多
  
  alpha:
    - 缩放因子
    - 推荐: rank的1-2倍
    - 控制LoRA的影响程度
  
  目标层:
    - 选择要应用LoRA的层
    - 通常选择注意力层
    - 可以只微调部分层

QLoRA详解

1. QLoRA原理

QLoRA结合了量化和LoRA,进一步降低资源需求。

# QLoRA特点
特点:
  量化: "将模型量化为4-bit"
  LoRA: "在量化模型上应用LoRA"
  效果: "效果接近全量微调"
  资源: "大幅降低资源需求"

量化方法:
  - 4-bit NormalFloat (NF4)
  - Double Quantization
  - Paged Optimizers

2. QLoRA使用

# QLoRA使用示例
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model

# 配置量化
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.float16
)

# 加载量化模型
model = AutoModelForCausalLM.from_pretrained(
    "model_name",
    quantization_config=bnb_config
)

# 配置LoRA
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05
)

# 应用LoRA
model = get_peft_model(model, lora_config)

指令微调

1. 指令微调概述

指令微调使用指令-回答对数据训练模型,提高模型的指令遵循能力。

# 指令微调
训练数据:
  格式: "指令-回答对"
  示例:
    指令: "解释什么是机器学习"
    回答: "机器学习是..."
  
数据来源:
  - 人工编写
  - 模型生成
  - 任务数据转换

2. 指令微调方法

# 指令微调方法
方法:
  监督微调 (SFT):
    - 使用指令-回答对
    - 标准监督学习
    - 提高指令遵循能力
  
  指令格式:
    - 统一指令格式
    - 清晰的指令描述
    - 示例演示

RLHF (强化学习人类反馈)

1. RLHF概述

RLHF通过人类反馈来优化模型输出,使模型更符合人类偏好。

# RLHF流程
流程步骤:
  1: "监督微调 (SFT): 使用人类标注数据微调"
  2: "奖励模型训练: 训练奖励模型评估回答质量"
  3: "强化学习优化: 使用PPO等算法优化模型"

2. RLHF实现

# RLHF简化示例
# 1. 监督微调
sft_model = fine_tune(base_model, human_preferences)

# 2. 训练奖励模型
reward_model = train_reward_model(human_rankings)

# 3. 强化学习优化
def rlhf_optimization():
    for episode in range(num_episodes):
        # 生成回答
        responses = sft_model.generate(prompts)
        
        # 计算奖励
        rewards = reward_model.score(responses)
        
        # PPO更新
        ppo_update(sft_model, rewards)

微调实践

1. 微调流程

# 微调流程
流程步骤:
  1: "准备数据: 准备任务相关数据"
  2: "数据预处理: 格式化数据"
  3: "选择方法: 选择微调方法(全量/LoRA等)"
  4: "配置参数: 设置学习率、批次大小等"
  5: "训练模型: 执行训练"
  6: "评估验证: 评估模型性能"
  7: "模型保存: 保存微调后的模型"

2. 微调技巧

# 微调技巧
技巧:
  学习率:
    - 预训练模型: "较小学习率 (1e-5到5e-5)"
    - 新层: "较大学习率 (1e-4)"
    - 使用学习率调度
  
  批次大小:
    - 根据显存调整
    - 使用梯度累积
    - 平衡速度和稳定性
  
  训练轮数:
    - 避免过拟合
    - 使用早停
    - 监控验证集性能

总结

大模型预训练与微调的关键要点:

  1. 预训练方法:自回归、掩码语言模型、序列到序列
  2. 预训练数据:数据来源、数据预处理
  3. 微调技术:全量微调、参数高效微调
  4. LoRA:原理、优势、配置
  5. QLoRA:量化+LoRA、使用示例
  6. 指令微调:概述、方法
  7. RLHF:流程、实现
  8. 微调实践:流程、技巧

掌握预训练与微调技术,可以根据需求训练和优化大模型,实现特定任务的最佳性能。

转载请注明:周志洋的博客 » 大模型预训练与微调

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦