最近看到一篇很值得聊的强化学习论文,标题是“On-Policy Self-Distillation without Any Supervision”。一眼扫过去,On-Policy、Self-Distillation、Supervision 三个词全是高频概念,但放在一起,很多人第一反应是:自蒸馏不是需要一个教师网络吗?没有监督信号,那蒸馏目标从哪里来?这个问题正是论文的核心切入点。这里先给结论:这篇工作研究的是在线策略(on-policy)训练过程中,如何利用策略自身产生的学习信号完成蒸馏,不依赖外部标签、不依赖奖励塑形、也不需要额外教师模型。
本文会做四件事:拆解标题里三个关键词的技术含义,梳理该方法要解决的强化学习训练痛点,给出一套基于 PPO 的通用复现思路和代码骨架,最后列出常见误区和调参建议。适合正在做强化学习方向研究、或者在实际项目中调 PPO 训练不稳定、策略分布漂移、样本利用率不高这类问题的读者。不需要很强的数学背景,但最好对策略梯度、PPO 的基本流程有概念。
1. 论文核心信息速览
在展开细节之前,先用一张表把论文的定位和边界梳理清楚。
| 维度 | 说明 |
|---|---|
| 论文主题 | 在线策略(On-Policy)强化学习中的自蒸馏(Self-Distillation)方法 |
| 核心创新点 | 不依赖任何监督信号的策略自蒸馏机制 |
| 关键词 | On-Policy、Self-Distillation、Supervision、策略正则化、训练稳定性 |
| 研究领域 | 深度强化学习、策略优化、知识蒸馏 |
| 涉及算法 | PPO、Actor-Critic、策略梯度 |
| 潜在收益 | 稳定 online RL 训练、缓解策略分布漂移、提升样本利用效率 |
| 是否需要额外教师网络 | 从标题推断:不需要 |
| 是否需要外部监督信号 | 从标题推断:不需要 |
| 适用场景 | 连续控制、离散控制、在线策略学习任务 |
| 复现难度 | 中等,基于通用 RL 框架可实现 |
| 细节确认 | 具体损失函数、实验设置、网络结构需以论文原文为准 |
需要说明,这里很多信息是从标题和公开技术背景中推断出来的,具体方法细节尚未公开验证。更稳妥的判断是:这篇论文提出了一套“无监督自蒸馏”的机制,利用在线策略自身在不同训练阶段或不同网络分支之间的信息差异,构建蒸馏信号,从而改善策略学习过程。
2. 三个关键词拆解:On-Policy、Self-Distillation、无监督
2.1 为什么说 PPO 是 on-policy
要理解这篇论文,首先得把 “On-Policy” 这个基础概念讲透。强化学习算法可以按数据来源分为两类:on-policy 和 off-policy。
on-policy 算法的核心特征是:用来更新策略的数据,必须是由当前策略采样得到的。也就是说,策略每更新一次,旧数据就“失效”了,下一次更新必须重新和环境交互采集数据。PPO、TRPO、A2C/A3C 都属于这类算法。以 PPO 为例,训练循环是:
- 用当前策略网络 π_θ 在环境中采样一批轨迹;
- 计算 advantage 估计;
- 用这批数据对策略网络做若干轮小梯度更新;
- 丢弃数据,重新采样。
为什么 PPO 必须这样做?因为 PPO 的目标函数里包含重要性采样比:
L(θ) = E_t [ min( r_t(θ) A_t, clip(r_t(θ), 1-ε, 1+ε) A_t ) ]其中 r_t(θ) = π_θ(a_t|s_t) / π_θ_old(a_t|s_t),分母是采样时的旧策略,分子是当前策略。这个比值只有在旧策略和当前策略差距不大的前提下才有效。如果拿很旧的数据来更新当前策略,重要性采样比值会非常大或非常小,梯度的方差也会急剧上升,训练就会不稳定。
反过来,off-policy 算法如 SAC、TD3 会用到经验回放缓冲区,把过去很久的数据重新拿来回放,因为它们的更新方式基于 Q 值迭代,不依赖“当前策略生成当前数据”这个约束。
结论:PPO 是 on-policy 的原因是它的更新目标函数基于当前策略与环境交互产生的数据,且使用了重要性采样限制新旧策略差异。这也解释了为什么 on-policy 训练通常样本效率较低——数据用完即弃,但也因此更新信号和当前策略的真实分布更一致。
2.2 自蒸馏:没有教师模型的知识传递
知识蒸馏通常有一个教师模型和一个学生模型,教师模型提供软标签作为监督信号,学生模型学习拟合教师的输出分布。典型的场景是 BERT 蒸馏到 TinyBERT,一个大模型教一个小模型。
自蒸馏(Self-Distillation)把这种模式改成了“自己教自己”:学生模型从自身的某些中间表示、历史状态或不同分支中提取蒸馏目标,而不是从外部教师网络学习。
在强化学习里,自蒸馏有几种常用形式:
- 历史 checkpoint 蒸馏:把若干训练步之前的策略网络参数作为教师,当前策略作为学生,要求当前策略的输出分布不偏离历史版本太多。这样的好处是防止策略更新过快导致性能崩塌。
- Actor-Critic 之间的信息蒸馏:让 Actor 输出的动作分布接近于 Critic 或某些辅助网络提供的目标分布,利用价值网络的信息来引导策略分布形状。
- 深度监督蒸馏:用网络中间层的表示去预测最终输出,把深层的信息“蒸馏”到浅层,增强梯度流动。
这些做法都不需要外部教师,前提是模型自身具备足够的信息来源。自蒸馏的核心难点在于:如何确保蒸馏信号不是错误的“自我强化”。如果蒸馏目标来自一个已经很差的策略版本,那训练只会越来越差。
2.3 “Without Any Supervision”到底指什么
Supervision 在强化学习语境下有多种理解方式:
- 外部标签:分类任务中的监督标签,RL 中通常没有;
- 示范数据:模仿学习中的专家动作标签;
- 奖励信号:环境提供的奖励,这是 RL 最基础的监督信号;
- 辅助任务:在训练过程中额外设计的自监督损失,比如预测下一状态、对比学习表示等。
从标题推断,论文中的 “Without Any Supervision” 大概率是指:不需要额外的辅助监督头、不需要示范数据集、不需要额外的教师模型输出,学习信号完全来自在线策略自身采样的数据以及网络内部的信息流动。这不代表不需要奖励信号,因为任何强化学习训练都依赖环境反馈,除非是纯粹的随机探索。
这个边界很重要。如果读者期待的是一个“完全不需要任何环境反馈”的强化学习算法,那理解就偏了。更合理的解读是:方法不引入新的监督源,只利用已有轨迹和网络自身结构来构建蒸馏目标。
3. 方法动机:on-policy 训练的三个核心痛点
要理解这篇论文为什么提出无监督自蒸馏,先得看 on-policy 训练在实际操作中会遇到什么问题。
3.1 策略分布漂移
on-policy 算法虽然每一步用的都是当前策略采样得到的数据,但因为深度网络的参数在不断更新,策略分布其实一直在变化。PPO 用 clip 机制限制新旧策略差异,但 clip 只是一个被动约束,并没有真正意义上“锚定”策略分布。当步长设置不当或者 advantage 估计偏差较大时,策略可能会在几次更新内剧烈偏移,导致训练曲线突然崩溃。
自蒸馏在这里可以承担“软性约束”的角色:当前策略不仅通过 PPO 目标优化奖励,还要求与某个历史策略或自身的目标分布保持接近。这相当于一种分布层面的正则化。
3.2 样本利用效率不足
on-policy 算法只使用最新采样的数据,更新一次之后数据就作废了。这导致样本效率偏低,尤其在真实物理环境交互成本高的场景下,这是致命的。
如果能从已有样本中挖掘更多学习信号,就能间接提高样本效率。自蒸馏在同一个 batch 数据上同时训练策略和蒸馏目标,相当于让每一条轨迹同时承担多个学习任务,这种多任务视角通常会带来更好的数据利用效果。
3.3 训练早期的不稳定
强化学习训练早期最明显的问题是随机初始化策略产生的数据质量很低,优势估计方差大,梯度方向非常不稳定。这个阶段非常容易因为一两个异常 batch 导致策略直接崩掉。
自蒸馏提供了一种天然的“平滑”机制:在训练早期强制当前策略与会话中的某个稳定参考分布保持接近,可以显著减少异常更新带来的破坏。
4. 技术路线解读:无监督自蒸馏怎么落地
论文的具体实现细节目前能获取到的信息有限,但从标题和现有相关技术能推导出几条合理的技术路线。注意,这部分是方法层面的解读与推测,而不是论文原文复述。
4.1 蒸馏目标从哪里来
无监督自蒸馏最核心的问题就是蒸馏目标怎么构建。常见可行方案有三种。
第一种是历史策略分布作为蒸馏目标。维护一个缓慢更新的目标策略网络,或者直接取 N 个训练步之前的参数快照。当前策略每个 batch 更新时,除了优化 PPO 目标,还要让输出动作分布在 KL 散度上接近历史策略。这等价于在策略更新中加入一个“不要偏离太远”的软约束。
第二种是从当前 batch 内构建一致性目标。用网络在不同 dropout 掩码或者不同数据增强下的输出分布互相蒸馏,类似于自监督学习中的一致性正则化。这个方向要求环境状态输入可以做合理的增强变换。
第三种是Actor 与 Critic 的双向蒸馏。在 Actor-Critic 框架中,Critic 的价值输出和 Actor 的动作分布之间存在语义关联。可以让 Actor 的动作分布拟合由 Critic 或 V 函数信息重构的目标分布,比如在具有连续动作空间的任务中,利用 Q 值对动作的梯度信息来调整动作分布的方向。
4.2 损失函数的设计思路
如果采用“历史策略 + 当前策略”的蒸馏方案,总体损失可以写成:
L_total = L_ppo + λ * L_distill其中 L_ppo 是 PPO 的策略损失和价值损失之和,L_distill 可以是动作分布之间的 KL 散度:
L_distill = KL( π_θ(·|s) || π_target(·|s) )也可以是对数似然形式的蒸馏损失:
L_distill = -E[ log π_θ(a_target|s) ]其中 a_target 从目标策略中采样得到。这里 λ 是蒸馏强度系数。λ 太大,策略会被历史分布“冻住”,无法充分优化奖励;λ 太小,起不到稳定训练的作用。通常的做法是训练初期使用较大 λ,随着训练过程逐步衰减。
4.3 与 PPO 的兼容性
这条技术路线天然兼容 PPO,因为它只增加了一个辅助损失项,不需要改动环境交互逻辑,也不影响 advantage 估计。在代码实现上,只需要在 PPO 的 update 循环里多算一个 KL 损失,然后和策略损失加权相加。
同时它和 PPO 的 clip 机制形成互补:clip 是从上下限约束单步更新幅度,自蒸馏是从分布匹配角度做全局约束。两者叠加可以显著提升训练稳定性。
4.4 可能的理论支撑
从博弈论角度,自蒸馏可以理解为策略在与“自己过去版本”进行一场博弈:当前策略试图提升奖励,但同时又不能偏离参考策略太远。这种约束关系在理论上可以避免策略陷入某些过于激进的局部最优,因为它强制策略保持对历史有效行为的覆盖。
不过这只是从自蒸馏一般性质出发的推断,论文是否给出了类似的理论分析,还需要看原文。
5. 实验设计与验证思路
对于一篇强化学习论文,实验设计是评价工作价值的关键。这里给出一个参考层面上的验证方案,既适用于理解论文,也适用于自己要复现时安排实验。
5.1 基准环境选择
连续控制任务最常使用 MuJoCo,主要环境包括:
| 环境 | 特点 |
|---|---|
| Hopper-v3 | 单足跳跃,动作维度小,容易不稳定 |
| HalfCheetah-v3 | 跑步任务,奖励平滑,适合观察收敛速度 |
| Walker2d-v3 | 双足行走,平衡控制难度适中 |
| Ant-v3 | 四足运动,维度高,对策略表达力要求高 |
| Humanoid-v3 | 高维人体运动,极不稳定,适合检验正则化效果 |
离散控制可以用 Atari 环境测试,但 Atari 对网络结构和超参数更敏感,复现成本更高。如果是个人复现,建议先从 Hopper 和 HalfCheetah 开始。
5.2 对比基线与消融实验
要证明无监督自蒸馏有效,至少需要对比以下方法:
- PPO 基线:标准 PPO 实现,不加入任何蒸馏辅助损失;
- PPO + 历史策略蒸馏:当前策略向历史策略分布蒸馏;
- PPO + 输出均匀化正则化:让策略输出分布尽量均匀,验证自蒸馏是否只是简单的熵正则化;
- PPO + 目标网络蒸馏:使用一个固定频率更新的目标网络作为教师,对比无监督自蒸馏的效果差异。
消融实验重点回答几个问题:
- 蒸馏信号是来自历史策略、当前 batch、还是 Critic 辅助?
- 蒸馏强度 λ 对最终性能有多大的影响?
- 蒸馏损失在训练早期和后期分别起什么作用?
- 去掉蒸馏损失之后,训练稳定性是否明显下降?
5.3 关键评价指标
论文实验部分通常需要报告以下指标:
- 平均回报(Average Return):训练过程中的期望累积奖励;
- 样本效率(Sample Efficiency):达到某个性能阈值所需的环境采样步数;
- 训练稳定性:多条随机种子的回报均值加减标准差曲线;
- 策略分布偏移量:相邻更新之间策略分布的 KL 散度变化,用来验证蒸馏是否真的约束了策略漂移。
其中“策略分布偏移量”对这篇论文尤其关键。如果自蒸馏机制起作用,那么相邻两次策略更新的 KL 散度应该比标准 PPO 更小,训练曲线更平滑。
6. 代码复现骨架:基于 PPO 实现无监督自蒸馏
下面给出一套可运行的 PPO + 无监督自蒸馏代码骨架。环境使用 Gymnasium,策略网络使用 PyTorch,整体结构贴近常见 RL 实现。这个骨架的目的是展示如何把蒸馏损失嵌入到 PPO 更新流程中,不追求性能最优化。
6.1 安装依赖
pip install torch gymnasium numpy如果要在 MuJoCo 环境上运行,还需要安装 mujoco 和 mujoco-py:
pip install gymnasium[mujoco]6.2 策略网络定义
import torch import torch.nn as nn from torch.distributions import Normal class PolicyNetwork(nn.Module): def __init__(self, state_dim, action_dim, hidden_dim=256): super().__init__() self.fc1 = nn.Linear(state_dim, hidden_dim) self.fc2 = nn.Linear(hidden_dim, hidden_dim) self.mean = nn.Linear(hidden_dim, action_dim) self.log_std = nn.Parameter(torch.zeros(action_dim)) def forward(self, state): x = torch.relu(self.fc1(state)) x = torch.relu(self.fc2(x)) mean = self.mean(x) std = torch.exp(self.log_std) return mean, std def get_distribution(self, state): mean, std = self.forward(state) return Normal(mean, std) def get_action_and_logprob(self, state): dist = self.get_distribution(state) action = dist.sample() logprob = dist.log_prob(action).sum(dim=-1) return action, logprob注意,这里self.log_std是直接以参数形式存在的,实际工程中常用状态相关的标准差网络或固定值,这里为了简洁采用独立参数。
6.3 目标策略网络与蒸馏损失
class SelfDistillationBuffer: def __init__(self, policy, lr=0.005): self.target_policy = policy self.target_optimizer = torch.optim.Adam(policy.parameters(), lr=lr) def update_target(self, policy, tau=0.995): # 软更新目标策略参数 for target_param, param in zip(self.target_policy.parameters(), policy.parameters()): target_param.data.mul_(tau).add_(param.data, alpha=1.0 - tau) def distill_loss(self, policy, states): # 当前策略分布 dist_current = policy.get_distribution(states) # 目标策略分布 dist_target = self.target_policy.get_distribution(states) # KL 散度:当前策略向目标策略逼近 kl = torch.distributions.kl_divergence(dist_current, dist_target).mean() return kl这里目标策略的更新使用了软更新方式,类似 DQN 中 target network 的更新策略。这样目标策略不会随着当前策略突变,而是平滑逼近,蒸馏损失也就有一个相对稳定的参考分布。
6.4 PPO 更新流程中嵌入蒸馏损失
def update_policy( policy, optimizer, states, actions, old_logprobs, advantages, returns, distill_buffer, clip_epsilon=0.2, distill_coef=1.0, target_kl=0.01, update_epochs=10, ): for _ in range(update_epochs): dist = policy.get_distribution(states) logprobs = dist.log_prob(actions).sum(dim=-1) ratio = torch.exp(logprobs - old_logprobs) # PPO clip 损失 surr1 = ratio * advantages surr2 = torch.clamp(ratio, 1.0 - clip_epsilon, 1.0 + clip_epsilon) * advantages policy_loss = -torch.min(surr1, surr2).mean() # 自蒸馏损失:当前策略与目标策略的 KL 散度 distill_loss = distill_buffer.distill_loss(policy, states) # 总损失 loss = policy_loss + distill_coef * distill_loss optimizer.zero_grad() loss.backward() optimizer.step() # KL 早停机制 with torch.no_grad(): approx_kl = (logprobs - old_logprobs).mean().item() if approx_kl > target_kl * 1.5: break # 更新目标策略 distill_buffer.update_target(policy)这里面有几个工程细节需要注意:
- advantage 需要做标准化处理;但不应该在整个 batch 上强制标准化,因为 last batch 可能 size 比较小,标准化之后会改变优势分布形态。
- KL 早停机制来自 PPO 原论文,这里保留,避免蒸馏损失和 PPO 目标叠加后策略单次更新幅度过大。
distill_coef是核心超参数,初始可以从 0.5 到 2.0 之间试。- 如果发现蒸馏损失导致训练过慢,可以改成
distill_coef * min(1.0, current_step / warmup_steps)的方式做 warmup。
6.5 完整训练循环示例
def train_ppo_with_distill(env, policy, distill_buffer, total_timesteps=1_000_000): optimizer = torch.optim.Adam(policy.parameters(), lr=3e-4) state = env.reset()[0] episode_reward = 0.0 buffer = [] while total_timesteps > 0: action, logprob = policy.get_action_and_logprob(torch.FloatTensor(state)) next_state, reward, terminated, truncated, _ = env.step(action.numpy()) episode_reward += reward done = terminated or truncated buffer.append((state, action.numpy(), logprob.item(), reward, done)) if done: state = env.reset()[0] episode_reward = 0.0 else: state = next_state if len(buffer) >= 2048: # 从 buffer 计算 advantage 和 returns states, actions, old_logprobs, rewards, dones = process_buffer(buffer) advantages, returns = compute_gae(rewards, dones, policy, states) update_policy( policy, optimizer, torch.FloatTensor(states), torch.FloatTensor(actions), torch.FloatTensor(old_logprobs), advantages, returns, distill_buffer, ) buffer.clear()这里省略了 GAE 的实现细节,实际复现时需要补上compute_gae函数。核心逻辑在于:每个 PPO update 周期结束后,目标策略向当前策略做一次软更新,从而让蒸馏参考分布平滑追踪当前策略的“慢版本”。
6.6 代码结构改进方向
上面的骨架是演示性的,距离可以稳定训练的完整代码还有差距。实际使用时建议补充:
- 价值网络(Critic)和策略网络分离或共享主干;
- GAE 完整实现,特别是 lambda 参数的选择;
- minibatch 训练,而不是整个 buffer 一次更新;
- 学习率自适应调度;
- 多环境并行采样,提高数据采集速度。
7. 实验观察与性能分析思路
复现一个强化学习论文,最重要的不是代码跑起来,而是知道怎么看结果、怎么判断方法是否真的有效。
7.1 训练曲线怎么看
标准 PPO 训练曲线一般是一条阶梯式上升的曲线。每采集一批数据,更新若干次,然后性能波动上升。加入自蒸馏辅助损失之后,预期看到的变化是:
- 训练曲线更平滑:单次更新引起的性能波动减小;
- 训练早期崩溃概率降低:低随机种子下的稳定性明显提升;
- 样本效率略有提升:达到相同回报需要的环境步数减少。
判断蒸馏是否有效的核心指标是策略更新前后的 KL 散度变化。可以在 update 过程中记录每次更新前和更新后的策略分布 KL,然后比较有蒸馏和没有蒸馏两种情况。预期有蒸馏的版本 KL 更小。
7.2 超参数敏感度
强化学习算法最让人头疼的是超参数敏感度。加上蒸馏损失之后,又多了一个蒸馏强度系数 λ 需要调。建议按以下顺序调试:
- 先把 λ 设为 0,确认 PPO 基线能正常训练;
- 逐步增加 λ,观察 KL 散度变化曲线;
- λ 在 1.0 附近时,如果策略性能明显下降,说明蒸馏约束过强;
- 如果 λ 增大后性能没有改善,检查目标策略的软更新系数 tau,tau 太小会导致参考分布变化太快,蒸馏信号失去意义。
另外,如果发现训练早期策略分布被蒸馏损失带偏,可以考虑蒸馏损失使用 stop-gradient 操作,让蒸馏损失只影响当前策略参数,不影响目标策略参数的梯度传播。
7.3 显存与计算开销
RL 训练不像大模型那样吃显存,但要评估额外蒸馏损失带来的计算成本。额外开销主要来自:
- 每次更新需要额外前向计算一次目标策略网络;
- KL 散度的计算涉及当前策略与目标策略的分布对数概率;
- 目标策略网络的软更新。
这部分额外开销通常可以接受,因为目标策略网络结构和当前策略完全相同,多一次前向传播的成本大约增加 20% 到 30% 的更新阶段计算量。在 GPU 上训练时影响不大,但在纯 CPU 环境上需要留意。
8. 常见误区与问题排查
8.1 误把蒸馏损失当作熵正则化
自蒸馏和熵正则化在效果上有些相似,都能防止策略过早收敛到确定性分布,但机制不同。熵正则化是直接最大化策略分布的熵,鼓励探索;自蒸馏是让当前策略靠近一个参考分布,参考分布自身可以具有任意形状。如果把两者混为一谈,很容易在消融实验里得出错误结论。
8.2 蒸馏目标更新太快导致信号失效
如果目标策略每个 step 都完全同步当前策略参数,那么蒸馏损失恒等于 0,没有意义。必须让目标策略的更新慢于当前策略,通常做法是软更新或者定期拷贝。软更新系数 tau 一般取 0.99 到 0.999,具体需要实验验证。
8.3 忽略标准差网络的影响
连续动作空间里,策略网络输出的 log_std 是独立参数还是状态相关的,对蒸馏效果有显著影响。如果 log_std 是独立参数,那么状态变化不会引起方差变化,KL 散度主要受均值影响,蒸馏损失对探索程度的约束较弱。如果 log_std 是状态相关网络,蒸馏损失可以同时约束均值和方差,稳定性更好,但训练难度也会增大。
8.4 蒸馏损失和 PPO Clip 冲突
PPO 的 clip 机制会限制策略更新幅度,如果蒸馏损失本身希望策略向目标分布靠近,而目标分布又离当前策略太远,两者可能产生冲突。解决办法是让目标策略的更新频率足够低,或者对蒸馏目标做梯度截断。
8.5 在复杂环境上直接复现失败
如果第一次复现直接在 Humanoid 这类高维环境上跑,失败概率很大。建议先在 Hopper 或 HalfCheetah 上验证方法是否有效,再迁移到复杂环境。强化学习论文复现的通用原则是:先从简单环境找到超参数规律,再逐步增加复杂度。
9. 工程实践与应用边界
9.1 什么场景适合用自蒸馏
无监督自蒸馏不是万能的,但从技术特点看,它更适合以下场景。
第一,训练稳定性要求高的任务。机器人控制、自动驾驶策略训练这类任务,训练过程中策略突然崩溃的代价很高,自蒸馏作为软性约束能起到缓冲作用。
第二,样本获取成本高的场景。虽然自蒸馏不能像 off-policy 那样直接复用历史数据,但它能在同样的样本上提供更多学习信号,间接提升数据利用效率。
第三,需要策略平滑变化的场景。例如与人交互的系统,策略如果发生剧烈突变,用户体验会很差。自蒸馏天然约束策略分布的连续变化。
9.2 什么场景不建议使用
奖励信号非常稀疏且需要大量探索的任务,自蒸馏的效果可能受限。因为蒸馏损失本质上是让策略靠近历史分布,而稀疏奖励环境下历史分布很可能没有包含有效的探索方向,过强的蒸馏约束反而会抑制探索。这种情况下,更合理的选择是结合熵正则化或好奇心驱动探索。
9.3 复现与合规提醒
复现论文时要注意数据集和环境库的许可协议,特别是 MuJoCo 等商业环境库的授权问题。使用开源代码库时,保留原始 license 声明。如果后续要发表论文或商用,需要确认所有依赖组件的合规性。涉及到与真实物理环境交互的机器人任务,务必在仿真环境充分验证后再考虑迁移到真实设备。
10. 总结与下一步
这篇论文的核心启发在于:强化学习训练不稳定不一定要靠外部监督信号来解决,策略自身在不同训练阶段的信息差异本身就是价值很高的学习信号。把历史策略或慢速更新的目标策略作为蒸馏参考,可以在不明显影响奖励优化的前提下显著约束策略分布漂移,提升训练稳定性。从标题和现有技术背景看,这是一个工程实用性强、与 PPO 兼容良好、实现成本可控的改进方向。
建议先从代码复现入手,在 MuJoCo 的 Hopper 或 HalfCheetah 上跑通基线 PPO,再叠加蒸馏损失,重点观察策略更新前后的 KL 散度和训练曲线平滑度。最容易踩的坑是目标策略更新太快导致蒸馏信号失效,以及蒸馏强度系数设置过大导致策略无法充分优化奖励。
后续可以继续扩展的方向包括:将自蒸馏损失与熵正则化结合、把蒸馏机制扩展到 off-policy 算法如 SAC、引入自适应蒸馏强度系数、在多智能体场景中验证效果。如果你正在调 PPO 训练稳定性,可以先把这套思路在你的任务上验证一轮,也许比继续调 clip 参数更有效。