1. 传统SFT的困境与ProFit的诞生
作为一名长期从事大语言模型研究的从业者,我深刻体会到监督微调(SFT)过程中的痛点。想象一下,你花费大量时间标注数据,却发现模型在训练后变得"死板"——它只会机械地复现训练样本中的特定表达方式,而丧失了预训练模型原有的灵活性和泛化能力。这正是ProFit想要解决的核心问题。
在传统SFT中,我们强制模型学习单一参考答案的每个token,却忽视了语言表达的多样性本质。比如在数学推理任务中,"3+5=8"和"五加三等于八"本质相同,但模型会被惩罚没有严格遵循训练样本的表述方式。这种"一刀切"的训练方式导致两个严重后果:
- 表面模式过拟合 :模型过度关注无关紧要的表述细节(如"首先"vs"第一步")
- 核心能力抑制 :重要推理步骤的学习信号被大量琐碎token的梯度更新所淹没
关键发现:通过分析超过10,000个标注样本,研究团队发现低预测概率的token往往对应可替换的表达方式,而高概率token才是承载核心语义的"骨架"。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ProFit的核心原理与技术实现
2.1 概率引导的token选择机制
ProFit的核心思想异常简洁却深刻:让模型自己告诉我们哪些token值得学习 。具体实现分为三个关键步骤:
- 前向计算 :对每个训练样本进行常规的前向传播,得到每个目标token的预测概率分布
- 概率过滤 :设置动态阈值τ(论文推荐τ=0.1),屏蔽预测概率低于τ的token
- 梯度更新 :仅对未被屏蔽的token计算损失并进行反向传播
python复制# ProFit的核心代码逻辑(简化版)
def compute_loss(logits, targets):
probs = torch.softmax(logits, dim=-1)
target_probs = probs.gather(-1, targets.unsqueeze(-1)).squeeze(-1)
mask = (target_probs > self.tau).float() # 创建掩码
loss = F.cross_entropy(logits, targets, reduction='none')
