尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

无监督自蒸馏:让大模型自己教自己提升推理能力

无监督自蒸馏:让大模型自己教自己提升推理能力 大模型优化到现在团队之间最大的差距已经不是“谁的显卡多”而是“谁能拿到高质量的训练信号”。过去两年大家默认的推理能力提升路径无非两条要么请人标注思维链做微调要么构建人类偏好数据做强化学习。思路没问题但成本是实打实的。标注一个高质量推理步骤的代价比标注一个普通分类样本高出一个数量级而且越往专家领域走能标注的人越少。所以当看到“不需要任何标注大模型自己教自己提升推理能力”这类方法时第一反应不应该是不屑而应该意识到它换了一条完全不同的路。这条路不依赖外部人工标签而是把模型自身生成的多样化解路径当作学习材料再用某种内部信号筛选出“相对更好”的样本反过来训练模型自己。听起来像循环论证为什么它能work这正是这篇文章想拆解清楚的问题。我先把判断放在前面无监督自蒸馏并不是要取代微调和强化学习它的价值在于改变推理优化的成本结构。它把“获取高质量监督”这件事从外部专家转移到模型自身的结构和采样过程中。这件事做成了推理能力的迭代周期可以大幅缩短但做不好模型也会在错误的方向上自我强化。所以读懂它的原理和边界比直接跑一个实验更重要。这篇文章会按这个顺序展开先理清蒸馏、自蒸馏、无监督这三个词在推理场景下的准确含义再拆解无监督自蒸馏的通用技术流程解释为什么“无标注”能形成有效学习信号随后给出一个最小概念实现、一套效果验证方案最后讨论这类方法最常见的坑和工程落地的建议。1. 为什么要关注大模型无监督自蒸馏推理能力优化最稀缺的资源从来不是模型架构而是高质量监督数据。你可以把监督数据分成两类一类是“标准答案”另一类是“推理过程”。标准答案相对容易获取但过程很难。对于数学题、代码题、逻辑推理题答案对错能判断但中间路径千万条哪一条是好路径需要人类或强模型逐一判断。这种依赖带来的结果就是每提升一次推理能力就要重新做一轮数据生产。而数据生产的速度决定了模型迭代的速度。无监督自蒸馏想绕过这道工序。它的核心思路是不再从外部要标签而是利用模型自身在多次采样中表现出的规律。同一个问题让模型用不同的温度、不同的解码策略生成多条推理路径如果多条路径最终收敛到同一个答案那么这个答案大概率是对的这条路径也就值得学习。整个过程里没有人类去写标准答案也没有强模型去批改过程。模型既是老师也是学生。这种做法的两个直接收益是数据生产和模型训练可以同时进行推理能力优化不再受标注产能限制。但代价也很明显模型自身的判断不一定可靠如果它在某个问题上系统性偏差自蒸馏只会放大这种偏差。所以无监督自蒸馏的关键不是“生成”和“训练”而是“筛选”。筛选信号的设计才是这类方法的真正技术壁垒。2. 三个容易混淆的概念蒸馏、自蒸馏与无标签自训练论文标题里每一个词都有特定含义先做一次概念清理。2.1 知识蒸馏传统知识蒸馏是一个跨模型知识迁移过程。一个大的教师模型在训练数据上推理把输出分布或中间表示教给一个小的学生模型。学生学到的不是硬标签而是教师的“软知识”包括教师对答案的置信度分布。在这个过程中教师和学生是两个不同的模型教师提供监督信号学生负责学习数据仍然依赖原始标注集。2.2 自蒸馏自蒸馏把教师和学生统一成了同一个模型或者同一模型的快照。模型先以教师的身份生成一批输出然后以学生的身份在自己的输出上继续训练。通常还会给训练过程加约束例如和学生模型参考版本计算 KL 散度防止学生偏离初始模型太远。自蒸馏要解决的核心问题是如果学生和教师是同一个模型学习的增量从哪里来答案来自采样和选择的不对称性。教师阶段通过多样化解采样相当于在推理路径空间中做探索选出部分路径作为学习目标学生阶段通过梯度更新把选中的路径编码进参数。探索发生在采样空间收敛发生在参数空间二者之间的不对称性就是改进的来源。2.3 无监督自蒸馏无监督自蒸馏的重点落在监督信号来源上。它不依赖人工标注的答案或偏好等级而是依赖模型内部的一致性、置信度或其他自动化规则从自己生成的路径中筛选“相对正确”的样本再用这些样本训练自己。这三层概念的关系可以用一个表格概括方法类别教师学生监督信号来源典型用途知识蒸馏大模型小模型教师输出分布模型压缩、知识迁移自蒸馏同一模型同一模型模型自身采样 选择规则推理能力持续优化无监督自蒸馏同一模型同一模型一致性等无标签信号降低推理优化数据成本通俗类比知识蒸馏是“名师带徒弟”自蒸馏是“自己出题自己做再自己批改”无监督自蒸馏是“自己出题、自己解题、批改标准也不依靠外部答案而是看多种解法是不是指向同一个结果”。看起来最绕但指向的问题也最前沿。3. 无监督自蒸馏的通用技术框架这类方法虽然在不同论文里有不同名字但拆开看技术流程高度一致。通常可以归纳为三个阶段生成候选结构、筛选高置信样本、自蒸馏训练。这里我用“通用框架”来描述具体论文会在某个环节上做强化设计。3.1 第一层多样化解采样输入是一批无标注问题。问题本身不需要答案只需要把大模型可能遇到的推理场景暴露出来。针对每个问题模型需要生成多条推理路径生成时通常希望路径之间有足够的差异。实现方式包括调高 temperature、使用 top_p 随机采样、加入不同的提示前缀、随机打乱解题提示等。目标是扩大搜索空间让同一道题出现多种解题思路其中有些能得出同一个答案有些不能。这种差异是后续无监督信号的来源。生成阶段最容易犯的错是把 temperature 设置过低。temperature 接近 0 时多次生成结果几乎一样一致性过滤就失去了区分度。没有多样性就没有“多路径收敛”可言。3.2 第二层无监督样本筛选筛选阶段决定整条路线是否成立。这一环要回答的核心问题是在没有标准答案的情况下怎么判断哪条路径值得学。主流的筛选信号包括四类自洽性对同一问题多次采样统计最终答案的分布。出现频率最高的答案被视为可信答案生成该答案的路径被选入训练集。分步验证让模型对推理步骤做自解释或自校验删除校验不通过的过程但这一步本质上仍然依赖模型自身会引入噪声。置信度估计根据模型生成 token 的对数概率或熵来评估路径可靠性选择低熵路径。启发式约束比如答案长度、是否包含计算过程、是否符合特定格式等这类信号很弱通常配合其他信号一起用。在实际论文里自洽性用得最多因为它不需要任何外部模型和标签只需要让模型生成多次再做多数投票。它的合理性依赖于一个观察虽然模型单个采样可能犯错但当多个采样从不同起点出发得到同一答案时错误概率显著下降。这让我想起了集成学习只不过这里集成的是同一个模型的多次推理轨迹。3.3 第三层自蒸馏训练筛选出的高质量路径形成训练集后模型在自己的输出上继续训练。训练目标和正常监督微调类似让模型在给定问题后生成选中路径的内容损失函数通常是交叉熵在此基础上往往会加一个正则化项防止模型塌缩到只学自己生成的数据。常见正则化是 KL 散度约束计算当前模型与一个参考模型通常是开始自蒸馏前的模型快照在同一问题上的输出分布差异把差异限制在一定范围内。参考模型相当于“安全锚”它的作用不是提供答案而是保证模型在优化推理路径的同时不会丢掉原有的通用能力。自蒸馏训练可以迭代多轮。每轮训练完后新的模型再次生成路径、筛选、训练。但迭代轮次不是越多越好这一块在后面的常见问题里会展开说明。4. “没有标注”为什么能兜住推理质量两大关键机制很多读者看到“无监督自蒸馏”第一反应是模型自己教自己会不会陷入‘自己觉得对就是真的对’的死循环在回答这个问题前需要先理解这类方法依赖的两个底层机制。4.1 采样空间中的探索补偿了模型的单次偏差大模型在单次推理时会犯各种错误这些错误往往不是随机的而是来自训练数据中的偏见。比如对某类数学题的中间步骤模型可能总是跳过单位换算这类错误在单次采样中反复出现。但采样会让问题发生微妙变化。当同一个问题以不同温度、不同提示被多次生成时模型会被迫在不同概率路径上做选择。有些场景下它可能选择正确的单位换算路径更多时候它可能走原来的错误路径。如果正确路径被采样到且稳定地生成正确答案多数投票就会把正确路径的权重放大。这说明一个关键点无监督自蒸馏提升的不是模型的单次推理上限而是模型在“自身能力空间”中的路径选择能力。它让模型更倾向于选择那些在多次尝试中更稳定的推理方式。如果模型完全没有能力生成正确路径那么自蒸馏也无法凭空创造正确路径充其量只是强化错误路径。这就是这条路线的第一道边界。4.2 一致性筛选等价于隐式的软标签学习多数投票在数学上非常直接如果 8 条采样中 6 条都给出同一个答案这个答案成为高置信样本的概率就很高。这很像一种弱标签过程——我们没有直接标注“正确路径是什么”但通过对齐多个样本间接让正确路径在统计上被选中。这个过程和强化学习里的 reward 设计有点相似。强化学习不直接告诉模型哪个动作是对的而是通过累积回报让模型去选择更优的轨迹。无监督自蒸馏的一致性和置信度信号就是推理任务上的一种 reward 函数。它不一定完美但和一个简单的“是否达成目标结果”的信号相比它能提供更为细粒度的过程偏好。所以无监督自蒸馏并不是真的没有监督。它的监督藏在模型自身的统计规律里。只是这个监督的获得成本从人工转移到了模型推理资源上每条样本需要多次采样、多次筛选推理开销会成倍增加。5. 概念实验从零搭建一个无监督自蒸馏最小循环这一节给出一个概念实现目的是让读者理解整个流程在代码层面如何组织不针对任何特定论文做完全复现。如果你想在自己的小模型上验证这套思路可以参考这个骨架。5.1 整体训练循环# 文件路径unsupervised_self_distill.py from typing import List, Dict from collections import Counter import torch from transformers import AutoModelForCausalLM, AutoTokenizer class UnsupervisedSelfDistillLoop: def __init__(self, model_name: str, device: str cuda): self.tokenizer AutoTokenizer.from_pretrained(model_name) self.model AutoModelForCausalLM.from_pretrained(model_name).to(device) self.reference_model AutoModelForCausalLM.from_pretrained(model_name).to(device) self.reference_model.eval() self.device device def generate_paths(self, question: str, num_paths: int 8, temperature: float 0.8) - List[Dict]: 对一个无标注问题采样多条推理路径。 prompt f请解下面的题并给出推理过程{question}\n回答 messages [ {role: user, content: prompt} ] inputs self.tokenizer.apply_chat_template( messages, return_tensorspt, add_generation_promptTrue ).to(self.device) paths [] for _ in range(num_paths): outputs self.model.generate( inputs, max_new_tokens1024, temperaturetemperature, top_p0.95, do_sampleTrue, ) text self.tokenizer.decode(outputs[0][inputs.shape[-1]:], skip_special_tokensTrue) answer self.extract_answer(text) paths.append({prompt: prompt, text: text, answer: answer}) return paths staticmethod def extract_answer(text: str) - str: 说明这里只做最简单抽取实际项目需要根据任务调整。 return text.strip().split(\n)[-1][:50] def filter_by_consistency(self, paths: List[Dict], threshold: float 0.6) - List[Dict]: 用多路径一致性过滤高置信样本全程不依赖人工标注。 answers [p[answer] for p in paths] counter Counter(answers) selected [] for path in paths: ratio counter[path[answer]] / len(paths) if ratio threshold: selected.append(path) return selected def train_on_paths(self, selected: List[Dict], kl_weight: float 0.1, lr: float 1e-5, epochs: int 3) - Dict[str, float]: 在选中路径上自蒸馏训练并带 KL 正则防止能力退化。 optimizer torch.optim.AdamW(self.model.parameters(), lrlr) history [] self.model.train() for epoch in range(epochs): total_loss 0.0 for sample in selected: inputs self.tokenizer(sample[prompt], return_tensorspt).to(self.device) targets self.tokenizer(sample[text], return_tensorspt).to(self.device) labels torch.cat( [torch.full_like(inputs[input_ids], -100), targets[input_ids]], dim1 ) input_ids torch.cat([inputs[input_ids], targets[input_ids]], dim1) attention_mask torch.cat([inputs[attention_mask], targets[attention_mask]], dim1) outputs self.model( input_idsinput_ids, attention_maskattention_mask, labelslabels, ) loss outputs.loss # KL 正则相对初始参考模型不要偏离太远 with torch.no_grad(): ref_outputs self.reference_model( input_idsinput_ids, attention_maskattention_mask, ) ref_logits ref_outputs.logits cur_logits outputs.logits kl_loss torch.nn.functional.kl_div( torch.log_softmax(cur_logits, dim-1), torch.log_softmax(ref_logits, dim-1), reductionbatchmean, log_targetTrue, ) total loss kl_weight * kl_loss total.backward() torch.nn.utils.clip_grad_norm_(self.model.parameters(), 1.0) optimizer.step() optimizer.zero_grad() total_loss total.item() history.append(total_loss / max(len(selected), 1)) self.model.eval() return {avg_loss: sum(history) / len(history)}这个示例代码展示了三个阶段的核心结构generate_paths负责多样化解采样filter_by_consistency负责用一致性做无监督筛选train_on_paths负责自蒸馏训练。需要特别说明的是示例里的extract_answer只做了最简单的抽取真实项目要根据任务类型设计专门的抽取器否则会影响一致性统计的准确性。5.2 启动脚本# 运行最小无监督自蒸馏示例 python unsupervised_self_distill.py \ --model_name meta-llama/Llama-3.1-8B-Instruct \ --question_file questions.jsonl \ --num_paths 8 \ --temperature 0.8 \ --consistency_threshold 0.6 \ --epochs 3运行前需要确认两个依赖transformers和torch。如果本地推理资源有限可以先把模型换成 1B 左右的小模型做流程验证不要一上来就跑到 70B成本容易失控。5.3 无标注问题集格式questions.jsonl只需要问题本身不需要任何答案{question: 一个矩形的长是宽的两倍周长为 36求面积。} {question: 12 和 18 的最小公倍数是多少} {question: 假设 x y 10且 x - y 4求 x 和 y 的值。}这也是“无监督”的直观体现数据收集成本极低只要问题描述不需要人工写标准答案。6. 如何验证效果评估设计和对比基准很多实现跑完自蒸馏后看着 loss 下降就认为有效这是不严谨的。无监督自蒸馏最大的风险是 loss 下降但推理能力没有真实提升甚至可能只是在拟合自身的分布。验证效果要围绕四个层次做设计。6.1 第一层标准推理基准对比在同等条件下分别评测自蒸馏前后的模型。建议选择数学推理、代码生成、逻辑推理、常识问答四类任务每类至少两个公开基准。对比指标包括准确率、稳定性、推理质量人工评测分数。重点看的不是绝对分数而是提升幅度和是否出现单点退化。6.2 第二层退化检测自蒸馏最常见的副作用是“偏科”。模型可能在某些任务上变好但在通用能力、指令遵循、事实问答上明显变差。所以在评测中需要加入一组通用能力测试比如通用知识问答、文本摘要、开放性写作等。如果推理分数上升、通用能力下降超过可接受范围就要调低训练步数或增大 KL 正则系数。6.3 第三层多次运行稳定性无监督自蒸馏的一大特点是随机性。不同随机种子、不同采样顺序、不同温度下得到的结果可能差异很大。做实验时不要只跑一次应该在多个随机种子和不同温度条件下重复实验报告均值和标准差。如果结果忽高忽低说明筛选信号不够稳定模型没有真正学到可迁移的推理规则。6.4 第四层对抗性验证在选中的高置信样本上做手动抽样检查看这些样本是不是真的“高质量”。这一步不能省。因为一致性只能保证“多路径收敛到同一答案”不能保证答案本身正确。例如模型如果系统性把“先把括号展开”当作错误步骤多路径会一致地给出错误的过程但最终答案可能恰好一致。人工抽检能及时发现这类系统性偏差。# 文件路径evaluate_after_distill.py import random from collections import Counter def majority_vote_accuracy(model, tokenizer, eval_samples, num_samples5): 推理时做多次采样用多数投票判断最终答案。 correct 0 total 0 for sample in eval_samples: answers [] for _ in range(num_samples): outputs model.generate( tokenizer(sample[question], return_tensorspt).to(model.device), max_new_tokens512, temperature0.4, do_sampleTrue, ) text tokenizer.decode(outputs[0], skip_special_tokensTrue) answers.append(extract_final_answer(text)) predicted Counter(answers).most_common(1)[0][0] if predicted sample[gold_answer]: correct 1 total 1 return correct / max(total, 1)这里推荐把评估时的 temperature 设置在 0.3 到 0.5 之间。这个区间既能保证采样有一定多样性又不会让答案分布过于离散。温度太高会导致多数投票失效温度太低则退化为单次推理。7. 常见问题与排查思路问题现象可能原因排查方式解决方案自蒸馏后推理准确率没有提升生成路径多样性不足筛选失去了区分度或筛选阈值过低检查多次采样的答案分布观察是否集中在少数几个答案上提高 temperature、增加采样路径数、加入不同提示模板模型在通用能力评测上明显退化训练步数过多或 KL 正则权重过小对比训练前后在通用评测集上的分数变化增加 KL 权重、降低学习率、减少训练轮次多数投票答案明显错误模型对该类问题存在系统性偏差人工抽检被选中的高置信样本引入更细粒度的分步验证信号或把该问题类从无监督数据中剔除筛选后样本数量过少一致性阈值过高或模型对问题本身的采样方差过大查看每道题答案分布降低阈值、增加采样次数、补充更多无标注问题loss 下降但效果不升反降模型开始记忆自生成样本而不是学习推理规则对比验证集和训练集分布增加数据多样性加入参考模型 KL 约束训练过程中显存不足同时加载模型和参考模型显存占用翻倍查看显存占用情况使用梯度累积、参考模型冻结并开启 bf16或把参考模型放到 CPU第六条值得多说一句。无监督自蒸馏如果只在固定的少量问题上反复迭代模型很容易进入“输入问题回忆曾生成过的路径”的捷径模式。解决方法是保证无标注问题集有足够的规模和多样性每轮自蒸馏尽量使用新采样结果而不是复用固定答案。8. 最佳实践与工程落地建议如果想把无监督自蒸馏真正用进项目建议遵循下面几条实践原则。8.1 用参考模型做安全锚自蒸馏训练过程中始终保留一个冻结的参考模型也就是自蒸馏开始前的基础模型。训练目标中加入 KL 散度约束让模型在不同问题上的输出分布不偏离参考模型太多。参考模型的唯一作用不是给学生答案而是防止学生跑偏。这个设计在几乎所有自蒸馏类方法中都是必要的。8.2 把自蒸馏当作“过程优化”而不是“知识注入”自蒸馏能调整模型对推理路径的偏好但它不能注入模型原本不知道的新知识。如果你想提升的是事实类问答能力需要先通过检索或外部知识库补知识再做推理优化。顺序不要搞反。8.3 先在小模型上验证整套流程不要一开始就在大模型上跑完整循环。先在 1B 到 3B 的模型上验证筛选出来的样本是不是真的高质量、训练后效果是否为正、KL 正则参数在什么范围最稳。流程跑通后再放大规模可以省下大量的消融实验成本。8.4 人工抽检是必要的质检阀即使叫“无监督”工程落地也不能完全放弃人工质检。可以每轮随机抽 50 到 100 条被选中的样本做人工确认看有没有明显的系统性错误。如果发现某个问题类型持续产生假阳性样本直接把该类型从本轮训练数据中剔除。人工抽检的比例不需要高但它能防止模型在错误方向上走太远。8.5 记录版本和数据血缘无监督自蒸馏的数据是模型生成的这给数据管理带来很大挑战。要记录每个训练样本来自哪个基础模型、什么采样参数、哪一轮自蒸馏形成完整的数据血缘。否则出了问题时很难定位是模型架构问题、数据问题还是筛选信号问题。8.6 与监督信号混合使用无监督自蒸馏不是替代人工标注而是降低人工标注需求量。最稳妥的落地方式是把两者结合大规模问题用无监督自蒸馏自动产生训练数据少量高价值问题保留人工标注混合训练。这样既控制了成本又保证了模型的底线质量。9. 总结与下一步学习方向无监督自蒸馏的核心价值一句话说清让大模型在没有外部标注的情况下通过自身多路径采样的一致性信号优化自己的推理路径选择。它真正降下来的不是算法复杂度而是推理优化对人工标注的依赖是从“数据生产”这个环节改变了大模型的迭代方式。但也要清楚它的边界。它不是万能的推理增强器更不是让人工标注完全消失的手段。它的可靠性建立在模型自身具备一定推理基础之上当模型在某个领域尚未形成正确路径时无监督自蒸馏无法凭空创造正确路径。它可以放大模型已有能力却很难补足模型完全没有的能力。如果你准备继续深入建议按这个顺序学习先理解知识蒸馏和自蒸馏的区别再看自洽性、置信度筛选这类无监督信号的具体实现然后跑通最小循环在新的任务领域里验证筛选信号是否可靠。多看几篇这类论文时重点比较它们用的筛选信号和正则化策略这两处往往是方法差异最大、最值得借鉴的地方。最后提醒一句无监督自蒸馏的工程成本和实验周期不比传统微调少只是把成本从“标注人力”转移到了“模型推理资源”上。评估一条无监督技术路线是否适合你的项目核心判断标准不是它听起来多前沿而是你的场景里获取人工标注和消耗 GPU 推理算力哪一个更贵哪一个更可控。把这个账算清楚再决定要不要把整套流程引入团队。
返回列表