解释PPO与SAC在离散动作空间的选择

解读

国内Unity项目里,强化学习落地场景主要集中在智能NPC、自动战斗、关卡难度自适应、资源调度与自动化测试。面试官问“离散动作空间该选PPO还是SAC”,并不是想听论文公式,而是想看你是否把算法特性、工程代价、Unity实时性要求、团队AI能力四件事一起权衡。答得太学术会被认为“不接地气”;只答“PPO简单”又显得没深度。必须给出可落地的决策链条:动作空间维度、奖励稀疏程度、采样效率、训练稳定性、热更新成本、移动端算力、团队调参人力。

知识点

  1. 离散动作空间:动作分支可数,如MOBA英雄技能槽位、战棋格子移动、卡牌出牌索引,输出用Categorical Distribution而非高斯。
  2. PPO(Proximal Policy Optimization):On-policy,重要性采样+Clip,每批数据只用一次,超参只有clip_ratiolambdalr训练代码<200行就能跑通,TensorBoard曲线平滑,失败案例少
  3. SAC(Soft Actor-Critic):Off-policy,最大化熵正则,用Categorical重参数化,需维护两套Q网络+一个策略网络+一个目标Q网络,更新链路长,梯度爆炸/冷启动常见,超参alphatarget_entropy需自动调,代码量翻倍
  4. Unity实时性:Inference在C#端运行,IL2CPP编译后不支持Python热插拔,训练好的.onnx必须<30 MB,SAC双Q网络体积×2,移动端首包敏感。
  5. 国内团队现状:大多数项目组只有1~2名算法兼程,GPU训练机是共享的1080TiPPO 2小时出初版能先给策划玩,SAC往往调参3天还在震荡,容易被砍需求。

答案

在Unity离散动作场景里,优先选PPO,理由分四层:

  1. 数据效率与稳定性:离散空间奖励通常稀疏且延迟(如卡牌胜负只有一局结束才有±1),PPO的On-policy+Clip能强制探索不跑偏,同一批数据内梯度单调提升,训练曲线方差小,国内策划能肉眼判断“是不是过拟合”;SAC虽然理论采样效率更高,但离散版需维护Categorical重参数化Q值过估计在稀疏奖励下更明显,调不好直接崩盘
  2. 工程落地成本:PPO网络结构只有策略+价值两个头,导出.onnx2~5 MB,Unity端用Barracuda推理0.3 ms/帧;SAC需要双Q网络,体积翻倍,Android低端机加载时额外+40 ms,首包敏感项目无法接受。
  3. 热更新与版本迭代:国内发行要求每周小包更新,PPO超参只有3个,策划可自行调;SAC的alpha自调度需运行时熵跟踪,热更新脚本里多10行代码就可能引入浮点误差,出包风险高。
  4. 团队人力与排期:按国内平均节奏,算法程序+1名后端配合,PPO从0到 playable prototype ≤3个工作日;SAC需至少5天调参+2天踩坑排期评审容易被砍

例外情况:若动作空间**>500维离散**(如多英雄技能组合爆炸)且奖励密集(每帧即时反馈),SAC的Off-policy重用机制可把样本需求降一个量级,此时先砍网络宽度(Q网络128→64)+共享Encoder,再强制alpha=0.1不自动调,才值得上SAC。否则一律PPO

拓展思考

  1. 混合动作空间:国内新出的SLG项目同时有离散兵种技能+连续兵力分配,可用PPO+Gumbel-Softmax把离散松弛成连续,一套代码解决,避免SAC离散/连续两套loss。
  2. 多Agent并行:Unity的ML-Agents在2022.3之后支持GPU并行采样,PPO的On-policy可把2048并行环境跑满一张3060,单分钟收集1M帧;SAC的Replay Buffer在多Agent下锁竞争,Python端CPU瓶颈明显,需要自定义共享内存才能追上PPO速度。
  3. 生产级监控:上线后要在Sentry里埋点版本号+超参hash,PPO的单调提升特性允许自动回滚(连续3局胜率<50%即回退上一版.onnx);SAC因熵震荡可能出现**“假死”**(胜率突然掉到0%又回升),回滚策略需加滑动窗口实现复杂度×2