配音

微调评估与部署

课程简介

微调模型评估、灾难性遗忘检测、模型部署。

🎬 本课程视频:Finetuning LLMs — 大模型微调


微调评估与部署

一、微调后最重要的一个问题

微调完成后,摆在面前最重要的问题是:模型真的变好了吗?

这个问题不是表面上看起来那么简单。微调可能提升模型在目标任务上的表现,但同时可能导致通用能力的下降。这种「进步」是否真的值得?需要全面的评估体系来回答。

二、三维度评估体系

2.1 任务表现评估

评估指标选择

根据任务类型选择合适的指标:
- 分类任务:准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1 分数
- 生成任务:BLEU(机器翻译)、ROUGE(文本摘要)、Perplexity(语言模型)
- 问答任务:精确匹配(EM)、F1 分数

测试集设计

def build_test_set():
    '''构建高质量的测试集'''
    test_set = []

    # 1. 正常场景(65%)
    for example in normal_cases:
        test_set.append({
            "input": example.input,
            "expected": example.output,
            "category": "normal"
        })

    # 2. 边界场景(20%)
    for example in edge_cases:
        test_set.append({
            "input": example.input,
            "expected": example.output,
            "category": "edge"
        })

    # 3. 对抗样本(10%)
    for example in adversarial_cases:
        test_set.append({
            "input": example.input,
            "expected": example.output,
            "category": "adversarial"
        })

    # 4. 未见过的场景(5%)
    for example in unseen_cases:
        test_set.append({
            "input": example.input,
            "expected": example.output,
            "category": "unseen"
        })

    return test_set

注意事项
- 测试集绝对不能与训练集重叠
- 测试集要具有挑战性——太简单的测试集无法区分模型好坏
- 测试规模:至少 100 条,建议 200-500 条

2.2 灾难性遗忘检测

这是微调评估中最容易被忽视的环节。灾难性遗忘是指模型在学习新任务的过程中,遗忘了之前在预训练阶段学到的通用能力。

def evaluate_catastrophic_forgetting(original_model, finetuned_model):
    '''检测灾难性遗忘'''
    benchmarks = {
        "mmlu": evaluate_mmlu,        # 多任务语言理解
        "hellaswag": evaluate_hellaswag,  # 常识推理
        "gsm8k": evaluate_gsm8k,     # 数学推理
        "human_eval": evaluate_human_eval  # 代码生成
    }

    results = {}
    for benchmark_name, eval_fn in benchmarks.items():
        original_score = eval_fn(original_model)
        finetuned_score = eval_fn(finetuned_model)

        change = finetuned_score - original_score
        results[benchmark_name] = {
            "before": original_score,
            "after": finetuned_score,
            "change": change
        }

        if change < -0.05:  # 下降超过 5%
            print(f"警告:{benchmark_name}下降了 {change:.2%}")

    return results

基准测试套件
- MMLU:涵盖 57 个学科的多任务准确率
- HellaSwag:常识推理能力
- GSM8K:小学数学推理
- HumanEval:代码生成能力

如果微调后通用基准测试的分数下降超过 5%,说明存在明显的灾难性遗忘。

2.3 稳定性测试

def stability_test(model, test_inputs, num_runs=5):
    '''测试模型输出的稳定性'''
    results = []

    for test_input in test_inputs:
        outputs = []
        for _ in range(num_runs):
            output = model.generate(test_input, temperature=0)
            outputs.append(output)

        # 计算一致性
        consistency = compute_consistency(outputs)
        results.append({
            "input": test_input,
            "outputs": outputs,
            "consistency": consistency
        })

    return results

三、部署策略

3.1 完整模型 vs PEFT 适配器

维度 完整模型 PEFT 适配器
部署复杂度 低(单文件) 中(基础模型 + 适配器)
推理延迟 相同 相同(LoRA 无额外延迟)
存储空间 大(~16GB for 7B) 小(~10MB for LoRA)
灵活性 低(一个模型一个任务) 高(切换任务只需换适配器)
批处理效率 中(需合并权重)

3.2 推理优化

# 合并 LoRA 权重(提高批处理效率)
from peft import PeftModel

# 合并权重
merged_model = peft_model.merge_and_unload()

# 或使用 vLLM 部署优化
from vllm import LLM

llm = LLM(
    model="./my_finetuned_model",
    tensor_parallel_size=2,  # 多卡并行
    gpu_memory_utilization=0.9
)

3.3 持续监控

部署后的持续监控体系:

class ModelMonitor:
    '''微调模型的生产监控'''

    def monitor(self, predictions, feedback):
        metrics = {
            "latency_p50": compute_percentile(predictions.latency, 50),
            "latency_p99": compute_percentile(predictions.latency, 99),
            "user_satisfaction": compute_satisfaction_rate(feedback),
            "error_rate": compute_error_rate(predictions),
            "drift_detection": detect_distribution_drift(predictions)
        }

        # 如果检测到性能下降,触发告警
        if metrics["error_rate"] > 0.1:
            alert("错误率超过 10%,建议检查模型")

        if metrics["drift_detection"]:
            alert("检测到数据分布漂移,可能需要增量微调")

        return metrics

四、增量微调

微调不是一次性的工作。当模型在生产环境中运行一段时间后,可能需要基于新的数据进行增量更新:

def incremental_finetune(base_model, new_data, lora_weights=None):
    '''增量微调'''
    if lora_weights:
        # 在现有 LoRA 基础上继续训练
        model = PeftModel.from_pretrained(base_model, lora_weights)
    else:
        # 从头训练新的 LoRA
        model = get_peft_model(base_model, lora_config)

    # 混合新旧数据进行训练
    combined_data = balance_datasets(old_data, new_data)

    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=combined_data
    )
    trainer.train()

    return model

五、微调失败模式

常见失败模式及解决方案:

失败模式 表现 解决方案
过拟合 训练 loss 低,验证 loss 高 减少 epoch、增加数据多样性
欠拟合 训练 loss 不下降 增大学习率、增加训练数据
灾难性遗忘 通用基准测试下降 混合通用数据训练、降低学习率
数据偏差 只对训练数据分布有效 增加数据多样性、检查数据分布
格式过拟合 模型只会输出训练数据的格式 增加输出格式的多样性

六、总结

微调后的评估体系需要覆盖任务表现、灾难性遗忘和稳定性三个维度。任务评估用测试集指标验证核心任务的效果,通用基准测试检测灾难性遗忘的程度,稳定性测试确保输出的可靠性。部署时需要在完整模型和 PEFT 适配器之间做出权衡,持续的监控体系保障生产环境的稳定运行。微调不是一次性的动作,持续监控和增量优化才是长期维护模型质量的正确姿势。

六、灾难性遗忘的应对策略

6.1 什么是灾难性遗忘

灾难性遗忘(Catastrophic Forgetting)是指微调过程中,模型在提升特定任务性能的同时,丢失了预训练阶段学到的一般知识和能力。

6.2 检测方法

  1. 通用能力评估:在微调前后评估模型在通用 benchmark 上的表现
  2. 能力对比:对比微调前后在“无关任务”上的表现差异
  3. 知识探测:用特定的知识探测问题测试模型的知识保留

6.3 缓解策略

七、部署方案选择

条件 推荐方案
日请求量 < 1000 云端 API 调用
日请求量 1000-10000 私有化部署
日请求量 > 10000 GPU 集群部署
延迟要求 < 100ms 模型蒸馏 + 量化
需要数据隐私 本地私有化部署

八、总结

关键要点回顾:
- 微调评估需要任务评估和通用评估两个维度
- 灾难性遗忘是微调的主要风险
- 评估数据集应该全面的覆盖各种场景
- 部署方案需综合考虑成本、延迟、隐私等因素
- 微调是一个“实验-评估-调整”的迭代过程

六、灾难性遗忘的应对策略

6.1 什么是灾难性遗忘

灾难性遗忘(Catastrophic Forgetting)是指微调过程中,模型在提升特定任务性能的同时,丢失了预训练阶段学到的一般知识和能力。

6.2 检测方法

  1. 通用能力评估:在微调前后评估模型在通用 benchmark 上的表现
  2. 能力对比:对比微调前后在“无关任务”上的表现差异
  3. 知识探测:用特定的知识探测问题测试模型的知识保留

6.3 缓解策略

七、部署方案选择

条件 推荐方案
日请求量 < 1000 云端 API 调用
日请求量 1000-10000 私有化部署
日请求量 > 10000 GPU 集群部署
延迟要求 < 100ms 模型蒸馏 + 量化
需要数据隐私 本地私有化部署

八、总结

关键要点回顾:
- 微调评估需要任务评估和通用评估两个维度
- 灾难性遗忘是微调的主要风险
- 评估数据集应该全面的覆盖各种场景
- 部署方案需综合考虑成本、延迟、隐私等因素
- 微调是一个“实验-评估-调整”的迭代过程

六、灾难性遗忘的应对策略

6.1 什么是灾难性遗忘

灾难性遗忘(Catastrophic Forgetting)是指微调过程中,模型在提升特定任务性能的同时,丢失了预训练阶段学到的一般知识和能力。

6.2 检测方法

  1. 通用能力评估:在微调前后评估模型在通用 benchmark 上的表现
  2. 能力对比:对比微调前后在“无关任务”上的表现差异
  3. 知识探测:用特定的知识探测问题测试模型的知识保留

6.3 缓解策略

七、部署方案选择

条件 推荐方案
日请求量 < 1000 云端 API 调用
日请求量 1000-10000 私有化部署
日请求量 > 10000 GPU 集群部署
延迟要求 < 100ms 模型蒸馏 + 量化
需要数据隐私 本地私有化部署

八、总结

关键要点回顾:
- 微调评估需要任务评估和通用评估两个维度
- 灾难性遗忘是微调的主要风险
- 评估数据集应该全面的覆盖各种场景
- 部署方案需综合考虑成本、延迟、隐私等因素
- 微调是一个“实验-评估-调整”的迭代过程

延伸阅读