常见Bug与调参(Common Bugs and Debugging Guide)
一句话定位
汇总世界模型训练中的典型问题(KL collapse、posterior collapse、表示学习失效)的诊断方法和调参解决方案。
前置依赖
核心思想
问题分类框架
三类核心问题:
- 训练不收敛:loss不下降或震荡
- 后验崩溃:潜在表示失效
- 性能不佳:收敛但效果差
诊断流程:
观察指标
├── loss不下降 → 学习率/梯度/初始化问题
├── KL异常 → KL collapse相关
├── 重建模糊 → 解码器/潜在表示问题
└── reward预测差 → reward建模问题
数学推导
KL散度基础
KL散度定义:
在世界模型中:
:近似后验(encoder输出) :先验(dynamics prior)
Posterior Collapse
Posterior collapse条件:
当
这意味着后验完全坍缩到先验,观察信息丢失。
数学表现:
原因分析:
- 先验过强(deterministic prior)
- KL weight 过低
- 解码器过强(即使没有潜在信息也能重建)
KL Weight与表示的关系
不平衡的梯度:
当
问题1:KL Collapse
诊断指标
观察KL值:
# 日志记录
kl = compute_kl(q_mean, q_std, p_mean, p_std)
logger.log({"kl_divergence": kl, "kl_per_dim": kl / z_dim})正常范围:
- KL per dimension: 0.01 ~ 0.5 nats
- Total KL: z_dim × 0.1 ~ z_dim × 0.5 nats
现象识别
| KL值 | 状态 | 表现 |
|---|---|---|
| ≈ 0 | Posterior collapse | 潜在表示无效 |
| > 5 nats/dim | 过大 | 表示过散 |
| 0.1 ~ 0.5 nats/dim | 正常 | 平衡 |
解决方案
方案1:KL退火(KL Annealing)
kl_weight_schedule:
type: linear
start_value: 0.001
end_value: 0.1
warmup_steps: 10000从小的KL weight开始,逐步增加,让decoder先学习重建。
方案2:KL砍断(KL Clipping)
# 伪代码
kl_per_dim = kl_divergence / z_dim
kl_clipped = tf.clip_by_value(kl_per_dim, clip_value_min=0.01, clip_value_max=10.0)方案3:自由KL(Free Nats)
kl_free_nats: 0.1 # 允许一定的KL,不计入损失方案4:调整先验-后验比例
kl_balance: 0.8 # 80% posterior, 20% prior使用加权几何平均而非简单平均。
验证方法
def diagnose_kl_collapse(kl_values, thresholds):
"""诊断KL是否发生collapse"""
mean_kl = np.mean(kl_values[-100:]) # 最近100步平均
std_kl = np.std(kl_values[-100:])
if mean_kl < thresholds["collapse"]:
return "POSSIBLE_COLLAPSE"
elif mean_kl > thresholds["too_high"]:
return "KL_TOO_HIGH"
else:
return "HEALTHY"问题2:观察重建模糊
诊断指标
观察重建质量:
# 计算重建PSNR
psnr = 10 * log10(1 / mse)
# 正常:PSNR > 20 dB
# 优秀:PSNR > 25 dB原因分析
| 原因 | 表现 | 验证方法 |
|---|---|---|
| 潜在表示信息不足 | 重建图像整体模糊 | 检查KL是否过小 |
| 解码器容量不足 | 细节缺失 | 增加解码器深度 |
| 损失函数不当 | 高频信息丢失 | 使用感知损失 |
| 序列长度过短 | 时序信息丢失 | 增加seq_len |
解决方案
方案1:检查潜在维度
stochastic_channels: 32 # 尝试增加到64或128方案2:添加感知损失(Perceptual Loss)
# 基于VGG的感知损失
vgg = VGG16(pretrained=True)
perceptual_loss = F.mse_loss(vgg(recon), vgg(target))方案3:使用Diffusion解码器 参见 1-Diffusion for World Modeling
方案4:特征匹配损失
def feature_matching_loss(real_features, recon_features):
return sum(F.l1_loss(r, f) for r, f in zip(real_features, recon_features))问题3:梯度异常
诊断指标
# 梯度统计日志
for name, param in model.named_parameters():
grad_norm = param.grad.norm().item()
if grad_norm > 10.0:
print(f"Large gradient: {name}, norm={grad_norm}")常见梯度问题
| 问题 | 阈值 | 原因 | 解决 |
|---|---|---|---|
| 梯度爆炸 | > 100 | 学习率过高 | 梯度裁剪 |
| 梯度消失 | < 1e-6 | 初始化不当 | 调整初始化 |
| NaN梯度 | - | 数值不稳定 | 减小学习率,加eps |
解决方案
梯度裁剪:
grad_clip: 100.0 # L2范数裁剪到100.0学习率调整:
lr: 5e-5 # 从1e-4降到5e-5权重初始化调整:
# 对某些层使用较小的初始化
nn.init.orthogonal_(layer.weight, gain=0.01)NaN处理:
# 检查是否有NaN
if torch.isnan(loss):
logger.warning("NaN loss detected, skipping batch")
continue问题4:Reward预测失效
诊断指标
# Reward预测质量
reward_mse = F.mse_loss(pred_rewards, true_rewards)
reward_corr = np.corrcoef(pred_rewards, true_rewards)[0, 1]
# 正常:MSE < 0.1, Corr > 0.8原因分析
| 原因 | 表现 | 解决 |
|---|---|---|
| Reward信号稀疏 | 预测趋于常数 | 密集奖励工程 |
| 表示学习不足 | reward预测与观察无关 | 增加潜在维度 |
| 延迟奖励 | 只关注immediate reward | 使用γ折扣 |
解决方案
密集奖励设计:
def dense_reward(reward, obs, next_obs):
# 添加进度奖励
progress = distance_to_goal(next_obs) - distance_to_goal(obs)
return reward + 0.1 * progress延迟reward处理: 使用 n-step return 或 TD(λ):
def compute_n_step_return(rewards, gamma, n):
returns = []
for t in range(len(rewards)):
G = sum(gamma**i * rewards[t+i] for i in range(min(n, len(rewards)-t)))
returns.append(G)
return returns问题5:动作预测不准确
诊断指标
# 动作准确率(离散动作)
action_acc = (pred_actions == true_actions).float().mean()
# 连续动作MSE
action_mse = F.mse_loss(pred_actions, true_actions)原因分析
| 原因 | 表现 | 解决 |
|---|---|---|
| 动作随机性高 | MSE高但策略有效 | 使用随机策略评估 |
| 状态表示不足 | 无法区分动作 | 增加表示能力 |
| 因果混淆 | 动作影响状态但状态不影响动作 | 改用autoregressive |
解决方案
动作序列建模:
# Autoregressive action prediction
for t in range(seq_len):
action_pred = net(state, prev_actions[:t])课程学习: 从简单任务开始,逐步增加难度。
调参经验汇总
敏感性排序
| 参数 | 敏感性 | 调整建议 |
|---|---|---|
| KL weight | 高 | 先调 |
| 学习率 | 高 | 其次 |
| 潜在维度 | 中 | 如需更多表示能力 |
| 序列长度 | 中 | 长任务需增加 |
| Decoder容量 | 中 | 视觉质量差时调整 |
调参优先级
第一优先级(出现问题先调):
- 学习率
- KL weight
- 梯度裁剪
第二优先级(效果不好时调):
- 潜在维度
- 序列长度
- 损失权重比例
第三优先级(最后微调):
- 优化器参数(betas, eps)
- 学习率调度参数
- EMA decay
章节摘要
本章系统整理了世界模型训练的常见问题及解决方案:
- KL Collapse:从诊断指标到KL退火/KL砍断的解决方案
- 重建模糊:潜在表示不足和decoder容量问题
- 梯度异常:梯度裁剪和数值稳定性处理
- Reward预测失效:稀疏奖励和延迟奖励问题
- 动作预测不准确:autoregressive和课程学习策略
- 调参优先级:敏感性排序和调整建议
遇到问题时,按照诊断流程定位原因,再针对性地调整参数。
关键词
KL Collapse Posterior Collapse 梯度爆炸 梯度消失 调参 重建模糊 奖励预测 动作预测 诊断指标 调试指南