返回列表

1st place approach by Flat Neurons

645. NeurIPS 2024 - Lux AI Season 3 | lux-ai-season-3

开始: 2024-12-09 结束: 2025-03-24 游戏AI AI大模型赛
Flat Neurons 团队的第一名方案 - Lux AI Season 3

Flat Neurons 团队的第一名方案

作者: TonyK (Flat Neurons)
发布日期: 2025-03-22
竞赛: Lux AI Season 3

大家好,欢迎!以下是我们在 Lux AI 第 3 季挑战中的设计、训练流程和测试策略的详细概述。

核心理念

我们使用了多智能体强化学习(RL),主要采用 IMPALA 算法,并辅以动态奖励缩放和自适应熵等增强功能。

动作空间

我们最终为每个 16 个单位确定了以下动作空间:

第一个头(移动 + 吸取决策):

  • 0: 什么都不做(原地停留)。
  • 1: 向左移动。
  • 2: 向右移动。
  • 3: 向上移动。
  • 4: 向下移动。
  • 5: 吸取(远程“攻击”)。

第二个头(吸取目标选择):

  • 如果第一个头预测为“吸取”,我们随后查看第二个头以决定哪个地块作为吸取目标。
  • 这第二个头预测单位周围 15×15 正方形内的目标(大约 ±7 的范围),以便单位可以在该边界框内选择任何地块作为吸取目标,无需掩码
  • 第二个头在第一个头选择“吸取”的时间步上进行训练,而第一个头在所有时间步上进行训练。

在推理阶段

  • 我们每个时间步都查询所有头,但仅当第一个头的动作是“吸取”时才使用第二个头的输出。
  • 如果选择的动作是“吸取”,我们查看第二个头以确定要吸取的确切地块。
  • 如果是其他任何动作(移动或静止),我们忽略该单位第二个头的输出。

观测空间与特征

我们在 24×24 的地图上每个地块使用了大约 1000+ 个特征。其中约 100 个是连续特征,其余是离散特征的独热编码版本(例如,是否存在小行星、哪个队伍的单位在地块上、上次在地块上看到敌人是多少步之前、该地块是否属于遗迹节点区域等)。

  • 时序信息:某些特征跟踪了自上次观测到地块或上次在该地块看到敌人以来经过了多少步等。
  • 状态跟踪:我们运行了一个内部状态更新器,随时间聚合发现的参数。例如,如果我们开始怀疑 nebula_tile_vision_reduction = 3,或者我们发现了哪个地块给分,我们会将其内部存储并用于计算特征。
  • 连续 + 离散编码:每个特征既以归一化的连续形式编码,又通过分箱(binning)离散化为独热向量。

我们还有一个专门的头用于预测下一时刻敌人单位的位置——即使是当前看不到的地块。这是一个使用加权二元交叉熵损失进行监督学习的头,基于部分真实值进行训练。我们将在下面更详细地解释这一点。


网络架构

network architecture
  1. 输入编码

    • 我们从每个 24×24 单元格的 ~1000 个二进制特征 + ~100 个连续特征开始,加上上一步的 3 个额外的“敌人未来预测”特征。
    • 整个集合(针对每个单元格)被压缩为大小约为 500 的内部表示,然后进一步压缩为每个单元格 128 个通道。
    • 现在我们有了一个 24×24×128 的特征图。
  2. 残差和 ConvLSTM 层

    • 我们在 24×24×128 的体积上应用 24 个残差块(形状不变)。
    • 接下来,我们应用一个 ConvLSTM(隐藏状态大小为 24×24×128),用于跟踪跨时间步的时间信息。这意味着我们的模型有效地拥有来自先前步骤的记忆。
  3. Transformer

    • 然后我们在整个地图(24×24 个位置)上应用 4 个 Transformer 块。本质上,每个单元格都可以关注其他单元格(空间注意力),以捕捉长程交互。
    • 我们将此管道的结果称为 BASE_OUTPUT,它同样是 24×24×128。
  4. 输出头 (Heads)

    • 敌人未来预测头

      • 我们将 BASE_OUTPUT 输入到一个头(一个简单的卷积层),输出一个 24×24×3 的张量,代表预测的:
      1. 下一时刻敌人单位在地块中的概率。
      2. 下一时刻地块与敌人单位位置相邻的概率。
      3. 下一时刻所有敌人单位的组合传感器掩码。
      • 这是以监督方式训练的。
      • 该头的输出随后传递给动作头。
    • 价值函数(基线)头

      • 我们将 BASE_OUTPUT 输入到一个小型 Transformer 中,它可以结合两队的知识并产生一个标量值(预期的未来回报)。这用作策略梯度方法(IMPALA / V-trace)的基线。
    • 动作头(移动 + 吸取头)

      • 补丁提取 (Patch Extraction):对于 16 个单位中的每一个,我们从 BASE_OUTPUT 中提取一个以单位位置为中心的 15×15 补丁,并结合预测头输出。地图外的位置用设置为 1 的附加特征标记。

      • 这产生了 16 × 15 × 15 × ~128 的形状(每个单位一个补丁)。

      • 我们还有一组每个单位的特征(能量、地块中的单位 ID 等),将其附加到每个单位补丁像素上,然后使用小型 MLP 进行处理。这产生了类似 16 × 15 × 15 × ~150 的最终形状。

      • 吸取目标头

      • 在 16×15×15×~150 补丁之上采用直接的基于卷积的方法,为 15×15 个可能的吸取目标单元格中的每一个产生单个 logit。

      • 因此,对于 16 个单位中的每一个,我们得到一个用于吸取动作的 15×15 logit 图。

      • 移动头

      • 我们应用几个残差块(4 个块)并进行通道压缩,为每个单位的补丁生成最终的 6 维输出:6 种可能的动作(静止、上/下/左/右移动或吸取)。

      • 因此,我们实际上得到了 16 × 6 个 logits。


训练流程

核心算法:IMPALA + V-trace

我们使用大规模 IMPALA 设置训练我们的代理,使用 V-trace 以及 Upgo、TD 损失和熵项等额外修改。我们通过让代理在环境中竞争来生成经验,在部分游戏中面对其最新的自我,但也与冻结的旧模型或教师模型(如下所述)竞争。

当纯自我对弈达到瓶颈时,我们引入了额外的技术:

  • 教师 KL 和教师基线损失

    • 我们保留了一个“冻结的教师代理”,即我们要目前为止最好的模型。
    • 我们在学生策略和教师策略之间添加了 KL 散度损失,以及教师基线损失以对齐价值头。
    • 这防止了遗忘先前学到的技能。
  • 冻结对手池

    • 我们不仅总是让代理的最新版本与自身进行自我对弈,还让代理在部分游戏中面对一组旧的(较弱或中等)对手。
    • 这提高了代理的鲁棒性,防止过拟合到单一自我对弈风格。
  • 来自外部回放的行为克隆 (BC)

    • 我们实现了在训练时将 RL 批次与来自回放数据的 BC 批次混合的可能性,因为 Frog Parade 当时占据主导地位,但最终我们没有采用这一点,因为没有它我们也看到了显著的改进。

动态奖励

在训练期间,我们使用奖励缩放机制来保持目标值范围一致。通常,我们的基线头(价值函数)可能会预测 [-5, +5] 范围内的回报。但来自环境事件(例如收集遗物点数)的实际奖励在训练的不同阶段可能太小或太大。

  1. 我们跟踪了约 5000 个批次的真实回报的滑动平均值。
  2. 我们计算了一个乘数,以便缩放后的回报能整齐地落在 [-5, +5] 范围内。

例如,在早期,如果你的代理很少得分,那么它得分的几次可能会导致很大的缩放奖励。随着时间的推移,随着它定期得分,乘数会缩小以保持值在范围内。

动态熵

我们还对两个动作头(移动与吸取目标)使用了动态熵策略。我们没有设置固定的熵系数,而是:

  1. 为每个头定义一个目标熵,开始时很高(例如,移动为 0.9,吸取目标为 3.9),并在 1 亿步内线性衰减到 0。
  2. 通过自动调整熵系数,强制策略的实际熵跟踪此目标。

实际上,这意味着在训练早期,代理进行大量探索(高熵)。随着时间的推移,随着目标熵下降,代理变得更加利用性(exploitative)。

当我们继续训练超过 1 亿步时,我们将目标熵重置为较小的初始值(例如 0.45 和 2.0)并再次衰减。这可能会导致短期性能下降,但通常会产生更强的最终策略。

下图显示了最终模型最后一次迭代的训练进度:

Training Progress 1 Training Progress 2 Training Progress 3

最终奖励

我们尝试了许多塑造奖励,例如:

  • + 收集遗物点数
  • - 对手收集遗物点数
  • + 赢得比赛
  • - 输掉比赛
  • + 发现或从潜在遗迹节点区域移除单元格
  • + 造成伤害
  • - 受到伤害
  • +- 死亡
  • + 拥有更大的传感器范围
  • + 看到对手

最终,我们转向了稀疏(比赛结果)方案:

  • ±1 赢得或输掉比赛。
  • ±2.5 整场比赛的点数总结(我们收集时为正,对手收集时为负)

具体来说:

  • 如果你赢得所有比赛并收集了最大可能的遗物点数(而对手收集零),你那场比赛的最终回报可能是 +7.5,对手得到 -7.5。
  • 遗物点数的部分评分有助于防止“什么都不做”的停滞,当代理认为它将保证获胜或失败时。

实现细节:翻转、数据增强、时间限制、动作选择

始终从 (0, 0) 开始

我们强制我们的代理始终从 \((0, 0)\) 开始。如果它实际上被分配为“第二玩家”方,我们翻转观测和动作,以便代理的视角保持一致。本质上,第二玩家的任何坐标都被镜像或旋转,以与从 \((0,0)\) 开始的视角对齐。

Kaggle 推理:基于翻转的数据增强

在 Kaggle 上,我们更进一步,在推理期间通过翻转 x/y 坐标应用数据增强。这有助于消除地图方向带来的任何偏差。但是,如果我们使用了超过 30 秒 的加时时间,我们禁用此增强以将推理时间减半并避免超时。

动作选择:训练 vs. Kaggle

  • 训练期间:我们从策略的概率分布中采样(随机)。这鼓励探索。
  • 在 Kaggle 推理上:我们选择最可能(贪婪)的动作。这最大化了预期性能,避免了关键比赛中不必要的随机性。

比较代理:实时胜率

我们通过运行数千场自我对弈比赛来比较代理。接近尾声时,我们还可以跟踪与旧版本教师版本的实时胜率。这提供了快速反馈,让我们确认每个新迭代是否真正优于之前的策略。


硬件与训练规模

我们拥有大量的计算资源。最终模型训练了约 3-4 天,进行了约 15 亿个环境步骤,分 2 亿步的迭代完成。在整个比赛期间,我们在各种实验中总共超过了 200 亿步。

一些性能提升器:

  • bfloat16 用于降低精度训练。
  • PyTorch 2.0 compile() 带来约 1.5 倍的速度提升。

公开测试策略

一个独特的挑战是在 Kaggle 排行榜上测试新模型,同时不让某些“模仿学习 (IL)"对手复制我们的最佳策略。

首先,让我们强调一些激发我们提交解决方案方法的观察结果:

  1. 查看其他参与者的比赛,我们看到某些代理模仿更强对手的动作。因此,IL 可能会复制你的解决方案。
  2. 如果 IL 训练得好,它最终可能与捐赠者打成 50/50。但我们不确定基于少量强玩家训练的 IL 是否真的能超越他们。
  3. 如果模型显著优于其他模型,我们宁愿直到最后也不透露这一优势。

当时,我们已经有一个模型可以可靠地保持在排行榜第 3 名,并且还有一些执行时间剩余。

基于此,我们制定了以下计划:

  1. 在解决方案中包含两个模型。第一个是已经能够达到顶部的 Kaggle 测试版本。第二个是我们想要评估的更强大的模型。
  2. 当比赛开始时,我们85% 的时间选择较弱的模型来玩整场比赛。在剩余 15% 的情况下,我们使用更强的模型。
  3. 在代理日志中记录每场比赛参与了哪个模型。
  4. 使用 Python 脚本收集比赛数据,按 main_submission_idenemy_submission_idis_strong 等因素分组,然后计算对对手的实际胜率。

视觉上,我们的结果数据框看起来像这样(其中 count - 总比赛数,sum - 获胜比赛数):

winrate dataframe

此策略的关键好处:

  1. 因为第一个模型已经占据第 3 名并且最常被使用,我们确保了顶级排名,并且仍然面对我们在意的对手。
  2. 顶级玩家每天收集大约 1,000 场比赛,提供了足够的数据来准确评估强模型的胜率。
  3. 如果 IL 是在我们的获胜游戏上训练的,区分哪个模型(强或弱)负责变得困难得多,特别是因为它们可能有不同的输入和策略,进一步使 IL 训练复杂化。

接近比赛结束时,当我们测试更大的模型时,我们稍微调整了我们的方法,因为两个大模型无法放入单个提交中。

相反,我们以固定概率向模型的 logits 注入噪声以削弱我们的提交。我们还开始不在单独的比赛中使用更强版本,而是在每场比赛的某些轮次中使用。

这是我们在截止日期前几天基于游戏片段统计的示例(敌人对我们解决方案的胜率):

winrate by episodes

结语

在整个比赛过程中,我们的主要教训是:

  1. 大规模自我对弈与先进的模型架构(ResNet, ConvLSTM, Transformers)可以产生非常强大的多智能体策略。
  2. 自适应奖励缩放动态熵对于稳定训练信号非常有帮助,特别是当环境复杂且最终目标(如遗物点数或比赛胜利)可能是稀疏或非平稳的时候。
  3. 教师 - 学生框架防止丢失过去的知识,对手池避免过拟合到自身最新版本。
  4. 仔细测试至关重要:你希望在排行榜上看到真实的性能,但不一定向潜在的模仿者透露你的整个高级策略。

总之,我们在所有实验中训练了超过 200 亿步,最终模型利用了先进的探索策略、部分信息推理(猜测看不见的敌人)和复杂的多智能体行为。我们希望这份总结能让大家深入了解构建我们第 3 季 Lux AI 机器人背后的复杂性。

同比赛其他方案