ChatGLM2-6B微调实战:从零开始构建领域适配模型

1次阅读
没有评论

共计 1908 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

1. 为什么需要微调大模型

大语言模型如 ChatGLM2-6B 虽然具备强大的通用能力,但在特定领域任务上往往表现不佳。微调可以让模型更好地适应特定领域的数据分布和任务需求。ChatGLM2-6B 采用 RoPE 位置编码和 FFN 结构,这些设计在微调时需要特别注意:

ChatGLM2-6B 微调实战:从零开始构建领域适配模型

  • RoPE 位置编码对长文本处理更友好,但需要保持位置编码的连续性
  • FFN 结构的参数规模较大,全参数微调显存消耗高

2. 微调方法对比

2.1 全参数微调

  • 更新所有模型参数
  • 显存占用最大(约 48GB+)
  • 效果通常最好但容易过拟合

2.2 P-Tuning

  • 只微调少量 prompt 相关参数
  • 显存占用小(可控制在 24GB 内)
  • 适合数据量少的场景

2.3 LoRA(推荐方案)

  • 通过低秩适配器更新权重
  • 显存占用中等(约 30GB)
  • 效果接近全参数微调

3. 核心实现

3.1 数据预处理

def preprocess_function(examples):
    # 处理特殊 token
    inputs = [f"[CLS]{x}[SEP]" for x in examples["text"]]

    # Tokenize
    tokenized = tokenizer(
        inputs,
        truncation=True,
        max_length=512,  # 中文建议 512
        padding="max_length",
    )

    # 添加 labels
    tokenized["labels"] = tokenized["input_ids"].copy()
    return tokenized

3.2 LoRA 微调实现

from peft import LoraConfig, get_peft_model

# LoRA 配置
lora_config = LoraConfig(
    r=8,  # 秩
    lora_alpha=32,
    target_modules=["query", "value"],  # 只适配 attention 部分
    lora_dropout=0.1,
    bias="none"
)

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

# 启用梯度检查点
model.gradient_checkpointing_enable()

3.3 学习率调度

from transformers import get_linear_schedule_with_warmup

# 总训练步数
t_total = len(train_dataloader) * num_epochs

# Warmup 步数 (建议 10% 总步数)
warmup_steps = int(0.1 * t_total)

# 创建 scheduler
scheduler = get_linear_schedule_with_warmup(
    optimizer,
    num_warmup_steps=warmup_steps,
    num_training_steps=t_total
)

4. 性能优化

4.1 混合精度训练

# FP16 训练可节省 30-40% 显存
scaler = torch.cuda.amp.GradScaler()

with torch.cuda.amp.autocast():
    outputs = model(**batch)
    loss = outputs.loss

scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()

4.2 梯度累积

  • batch_size= 4 时,梯度累积步数建议 2 -4
  • 每累积 step 次再更新参数
if (step + 1) % accumulation_steps == 0:
    optimizer.step()
    scheduler.step()
    optimizer.zero_grad()

5. 生产环境避坑指南

5.1 中文文本长度

  • 建议 max_length=512
  • 过短丢失信息,过长显存爆炸

5.2 Loss 震荡排查

  1. 检查学习率是否过大(建议 5e- 5 起)
  2. 检查 batch_size 是否过小(至少 4)
  3. 检查数据质量(去除噪声样本)

5.3 模型保存 / 加载

# 保存
model.save_pretrained("./lora_model")

# 加载
from peft import PeftModel
model = PeftModel.from_pretrained(model, "./lora_model")

6. 思考题

  1. 如何设计领域适配性的评估指标?
  2. 微调数据量不足时,如何提升效果?
  3. 如何平衡通用能力和领域专精?

7. 总结

通过 LoRA 微调 ChatGLM2-6B,我们可以在消费级 GPU(如 3090)上高效完成领域适配。关键点包括:合理设置 max_length、使用混合精度训练、配置适当的 warmup 策略。实际测试表明,这种方法可以在保持 90% 以上原模型能力的同时,显著提升特定任务的表现。

正文完
 0
评论(没有评论)