
持续学习Continual Learning
引言 现实世界在不断变化:新知识产生、旧信息更新、领域边界扩展。大语言模型在训练完成后,其知识即被冻结。如何让模型持续吸收新知识,同时不遗忘已学内容?这就是持续学习(Continual Learning,也称终身学习)要解决的核心问题。本文探讨大模型场景下持续学习的挑战、方法和工程实践。 核心挑战:灾难性遗忘 什么是灾难性遗忘 当模型在新数据上微调时,新数据会覆盖模型在旧数据上学到的知识和能力。这种现象称为灾难性遗忘——模型"记住"了新知识,却"忘记"了旧知识。 遗忘的严重性 灾难性遗忘的程度取决于多种因素: 数据分布差异:新数据与原始训练数据分布差异越大,遗忘越严重 模型规模:较小模型往往遗忘更严重(容量限制) 训练强度:学习率越高、训练轮数越多,遗忘越严重 任务相关性:新任务与旧任务越不相关,遗忘越严重 遗忘的检测 def evaluate_forgetting(model, old_eval_set, new_eval_set): """评估灾难性遗忘程度""" old_score = evaluate(model, old_eval_set) new_score = evaluate(model, new_eval_set) return { 'old_task_score': old_score, # 旧任务表现 'new_task_score': new_score, # 新任务表现 'forgetting_rate': 1 - old_score, # 遗忘率 'learning_rate': new_score, # 学习率 'overall_score': (old_score + new_score) / 2 # 综合表现 } 持续学习方法 方法一:经验回放(Experience Replay) 在训练新数据时,混入部分旧数据: class ReplayBuffer: def __init__(self, capacity=10000): self.capacity = capacity self.buffer = [] def add(self, data): self.buffer.extend(data) if len(self.buffer) > self.capacity: # 随机采样保留 self.buffer = random.sample(self.buffer, self.capacity) def sample(self, batch_size): return random.sample(self.buffer, min(batch_size, len(self.buffer))) def train_with_replay(model, new_data, replay_buffer, replay_ratio=0.3): """带经验回放的训练""" for epoch in range(epochs): for new_batch in get_batches(new_data): # 混合新数据和回放数据 replay_batch = replay_buffer.sample(int(len(new_batch) * replay_ratio)) mixed_batch = new_batch + replay_batch random.shuffle(mixed_batch) loss = model.compute_loss(mixed_batch) loss.backward() optimizer.step() # 将新数据加入回放缓冲区 replay_buffer.add(new_data) 优势:简单有效、通用性强 劣势:需要存储旧数据、可能违反数据隐私 方法二:弹性权重整合(EWC) 通过正则化保护重要参数不被大幅修改: ...