# Delivcoal HATT v2.0 正式训练组交接报告

更新时间：2026-08-19  
实验批次：`20260818-hatt-formal-delivcoal`  
训练目录：`runs/20260818-0040_hatt-formal-training-sequence/`

## 1. 报告范围

本报告只汇总 Delivcoal 正式训练组，包括原组成功的 22 个任务和 OOM recovery 成功的 15 个任务，共 37 个独立 training jobs。

当前已经完成的是训练和逐 episode actor checkpoint 保存。原计划的每 50 episode、固定 32 seeds validation，以及锁定 `validation-best` 后的 128-seed held-out test 尚未完成。GPU0 即使单路评估也会升到 95℃，补评服务已经停止。因此本文的数据属于训练末期统计，用于检查学习趋势、比较消融方向和交接实验状态，不能直接作为论文最终测试表。

## 2. 实验完整性

| 项目 | 状态 |
|---|---:|
| 逻辑训练任务 | 37 |
| 最终完成 | 37/37 |
| 原组直接完成 | 22 |
| OOM 后 recovery 完成 | 15 |
| 缺失最终 `actor.pt` | 0 |
| 逐 episode actor checkpoints | 54,197 |
| 已完成正式 validation checkpoint | 0 |
| 已完成 held-out final test | 0 |

原组目录：

```text
runs/20260818-0040_hatt-formal-training-sequence/delivcoal
```

恢复组目录：

```text
runs/20260818-0040_hatt-formal-training-sequence/delivcoal-oom-recovery
```

合并时采用以下规则：原组中 `state=completed` 的 22 个 job 保留；原组中 `state=failed` 的 15 个 job 使用 recovery 组同名 job 替代。不能直接把原组的组级 `training_failed` 理解为 37 个任务全部失败。

## 3. 统一环境与训练设置

除各条件表中明确列出的差异外，全部训练使用相同设置。

### 3.1 环境

| 配置项 | 值 |
|---|---:|
| `env_name` | `delivcoal` |
| `scenario_name` | `coalition_delivery` |
| `map_size` | 1000 |
| UAV 数量 | 4 |
| UGV 数量 | 8 |
| Delivery task 数量 | 10 |
| 能力维度 `cap_dim` | 4 |
| 最大环境步数 | 750 |
| PPO `episode_length` | 750 |
| reset | `full_random` |
| reward | `shaped` |
| Idle 时间代价 | `uniform` |
| Explore action | 8 个 sector candidates |
| Explore 步长 | 200 |
| sector jitter | 0.1 |
| waypoint 到达后重新决策 | 开启 |
| 探索事件重新激活 | 开启 |
| sector 最短移动段 | 1 mobility step |

Coverage 开启时：

```yaml
explore_coverage_features: true
explore_coverage_grid_resolution: 20
hatt_shared_task_obs: false
```

`hatt_shared_task_obs=false` 是必要约束，因为 sector goal、candidate novel coverage 和 leg distance 都是 observer-relative features。

### 3.2 PPO

| 配置项 | 值 |
|---|---:|
| trainer | MAPPO，前馈共享策略 |
| `n_rollout_threads` | 1 |
| `n_training_threads` | 4 |
| `ppo_epoch` | 6 |
| `num_mini_batch` | 1 |
| actor / critic LR | `1e-4` |
| linear LR decay | 开启 |
| entropy coefficient | 0.03 |
| PPO clip | 0.1 |
| target KL | 0.03 |
| max clip fraction | 0.35 |
| max grad norm | 0.5 |
| 最大训练 episode | 1500 environment episodes |
| nominal environment steps | 1,125,000 |
| actor 保存 | 每 environment episode |

日志中的 rollout 编号可能小于 1500，因为一个 rollout 内可能完成多个 environment episodes。训练停止条件以 `env_episode >= 1500` 为准。

### 3.3 HATT v2.0

| 配置项 | 值 |
|---|---:|
| `graph_model` | `hatt_v2_0` |
| policy hidden size | 64 |
| HATT hidden size | 128 |
| attention heads | 4 |
| dropout | 0 |
| capability scale | 5 |
| recurrent policy | 关闭 |

完整 HATT actor 的结构路径为：

```text
ego / other / task encoders
        ↓
A-A relation attention → focal-agent context
        ↓
按当前 coalition ID 聚合 task-indexed sum / mean / count
        ↓
coalition-conditioned task context
        ↓
共享 agent-task candidate decoder
```

## 4. 条件矩阵、具体设置与实验目标

| 条件 | Seeds | 相对统一设置的变化 | 对比或消融目标 |
|---|---:|---|---|
| HATT full | 1–5 | HATT v2.0；coverage on；event；A-A on；coalition context on | 主方法，作为所有 HATT 消融的共同参照 |
| MAPPO64 | 1–5 | `use_gat=false`；`hidden_size=64` | 判断结构化 actor 相对标准 MLP MAPPO 是否有收益 |
| MAPPO288 | 1–5 | `use_gat=false`；`hidden_size=288` | 参数量匹配控制，排除 MAPPO64 容量不足解释 |
| HATT no-coalition | 1–5 | `hatt_use_coalition_context=false` | 隔离 task-indexed coalition sum/mean/count 的独立贡献 |
| HATT no-AA | 1–5 | `hatt_use_aa_attention=false` | 隔离 A-A relation attention 的独立贡献 |
| HATT no-coverage | 1–3 | `explore_coverage_features=false` | 检验 observer-relative exploration-state representation 的作用 |
| MAPPO64 no-coverage | 1–3 | MAPPO64；coverage off | 形成 architecture × coverage 交叉对照 |
| HATT legacy | 1–3 | `reconfiguration_mode=legacy` | 比较旧重构时序与 event 决策语义 |
| HATT always | 1–3 | `reconfiguration_mode=always` | 检验无约束频繁重构是否破坏学习与联盟稳定性 |

### 4.1 结构消融实现

结构消融保留网络参数和张量形状，只把对应信息路径替换为零，避免参数量变化混入消融结论。

关键实现位于 `algorithms/algorithm/HATTV20Network.py`：

```python
if self.use_aa_attention:
    aa_context, aa_weights = self.aa_attention(
        self_h, other_h, aa_features, other_mask.bool()
    )
else:
    aa_context = torch.zeros_like(self_h)

coalition_sum, coalition_mean, coalition_count = self._aggregate_coalitions(...)
if not self.use_coalition_context:
    coalition_sum = torch.zeros_like(coalition_sum)
    coalition_mean = torch.zeros_like(coalition_mean)
    coalition_count = torch.zeros_like(coalition_count)
```

这个设计回答的是“某条信息路径是否提供增益”，不是“小网络是否比大网络更容易训练”。

### 4.2 Event 条件

主条件固定：

```yaml
reconfiguration_mode: event
reconfiguration_interval: 10
reconfiguration_switch_cost: 0.0
```

Event 条件只在有效决策事件发生时重新采样动作；inactive steps 保持 last action，并通过 active mask 避免把非决策时刻作为 PPO 新动作样本。

## 5. 数据口径

本文从每个 job 的训练日志中解析：

```text
env_episode, sent percentage, completed tasks, episode reward
```

对每个 seed 选取 `env_episode >= 1350` 的记录，即训练最后 10% 窗口；先在 seed 内求均值，再对同一条件的 training seeds 求均值与总体标准差。

注意：

- `sent ratio` 是训练 episode 中的配送比例代理指标。
- `episode reward` 含 shaped reward，只适合相同环境和奖励下的诊断比较。
- `completed` 是日志时刻环境快照中的完成任务数，并非正式 success rate。
- 训练轨迹使用随机采样动作，状态分布随策略变化。
- 这些值不能替代固定 scenarios 上的 deterministic evaluation。

## 6. 条件级汇总

| 条件 | Seeds | 末期记录数 | Sent ratio | Completed snapshot | Episode reward |
|---|---:|---:|---:|---:|---:|
| HATT full | 5 | 717 | **0.8879 ± 0.0269** | 5.162 ± 0.204 | **54.08 ± 6.43** |
| MAPPO64 | 5 | 737 | 0.8204 ± 0.0225 | 5.121 ± 0.252 | 31.40 ± 2.94 |
| MAPPO288 | 5 | 733 | 0.8248 ± 0.0175 | 4.833 ± 0.495 | 40.48 ± 2.26 |
| HATT no-coalition | 5 | 723 | 0.8685 ± 0.0311 | 5.063 ± 0.810 | 48.61 ± 6.12 |
| HATT no-AA | 5 | 721 | 0.8986 ± 0.0163 | 5.226 ± 0.461 | 54.13 ± 4.22 |
| HATT no-coverage | 3 | 433 | 0.8935 ± 0.0006 | 5.687 ± 0.286 | 56.53 ± 0.78 |
| MAPPO64 no-coverage | 3 | 440 | 0.8404 ± 0.0211 | 4.904 ± 0.242 | 36.09 ± 3.47 |
| HATT legacy | 3 | 426 | 0.9075 ± 0.0220 | 4.807 ± 0.293 | 59.04 ± 5.72 |
| HATT always | 3 | 451 | **0.4983 ± 0.1722** | 1.920 ± 1.305 | **−22.98 ± 33.11** |

表中 `±` 是独立 training-seed 聚合值之间的总体标准差，不是 eval-seed uncertainty。

## 7. 每个 seed 的详细数据

| 条件 | Seed | Sent ratio | Completed snapshot | Episode reward |
|---|---:|---:|---:|---:|
| HATT full | 1 | 0.9219 | 4.877 | 63.96 |
| HATT full | 2 | 0.8902 | 5.441 | 53.01 |
| HATT full | 3 | 0.9044 | 4.993 | 57.51 |
| HATT full | 4 | 0.8417 | 5.299 | 44.69 |
| HATT full | 5 | 0.8812 | 5.199 | 51.23 |
| MAPPO64 | 1 | 0.8519 | 5.490 | 34.41 |
| MAPPO64 | 2 | 0.8358 | 5.247 | 34.51 |
| MAPPO64 | 3 | 0.7897 | 4.824 | 27.71 |
| MAPPO64 | 4 | 0.8016 | 4.852 | 28.18 |
| MAPPO64 | 5 | 0.8231 | 5.190 | 32.19 |
| MAPPO288 | 1 | 0.8025 | 4.351 | 37.79 |
| MAPPO288 | 2 | 0.8239 | 5.075 | 38.88 |
| MAPPO288 | 3 | 0.8500 | 4.959 | 42.55 |
| MAPPO288 | 4 | 0.8096 | 5.565 | 39.48 |
| MAPPO288 | 5 | 0.8378 | 4.214 | 43.71 |
| HATT no-coalition | 1 | 0.8912 | 4.646 | 50.55 |
| HATT no-coalition | 2 | 0.8954 | 6.085 | 56.59 |
| HATT no-coalition | 3 | 0.8820 | 4.317 | 50.71 |
| HATT no-coalition | 4 | 0.8102 | 6.000 | 37.94 |
| HATT no-coalition | 5 | 0.8638 | 4.269 | 47.28 |
| HATT no-AA | 1 | 0.8915 | 5.752 | 52.50 |
| HATT no-AA | 2 | 0.9001 | 4.930 | 54.63 |
| HATT no-AA | 3 | 0.9086 | 4.528 | 55.62 |
| HATT no-AA | 4 | 0.8721 | 5.238 | 47.48 |
| HATT no-AA | 5 | 0.9205 | 5.683 | 60.44 |
| HATT no-coverage | 1 | 0.8927 | 6.076 | 56.19 |
| HATT no-coverage | 2 | 0.8942 | 5.583 | 55.80 |
| HATT no-coverage | 3 | 0.8934 | 5.400 | 57.62 |
| MAPPO64 no-coverage | 1 | 0.8682 | 4.562 | 39.18 |
| MAPPO64 no-coverage | 2 | 0.8357 | 5.054 | 37.84 |
| MAPPO64 no-coverage | 3 | 0.8172 | 5.095 | 31.25 |
| HATT legacy | 1 | 0.9300 | 4.493 | 65.33 |
| HATT legacy | 2 | 0.8777 | 4.731 | 51.48 |
| HATT legacy | 3 | 0.9147 | 5.199 | 60.31 |
| HATT always | 1 | 0.5995 | 3.440 | −3.36 |
| HATT always | 2 | 0.6396 | 0.253 | 4.02 |
| HATT always | 3 | 0.2560 | 2.066 | −69.62 |

## 8. 初步对比结果

### 8.1 HATT full 与 MAPPO

HATT full 相对 MAPPO64：

- sent ratio：`+0.0675`，约 +6.8 个百分点；
- episode reward：`+22.68`。

HATT full 相对 MAPPO288：

- sent ratio：`+0.0631`，约 +6.3 个百分点；
- episode reward：`+13.60`。

训练轨迹支持 HATT full 优于标准 MAPPO，并且扩大 MAPPO 参数量没有消除差距。正式结论仍需 held-out test。

### 8.2 Coalition context

去掉 coalition sum/mean/count 后：

- sent ratio 从 0.8879 降到 0.8685，差 `−0.0194`；
- reward 从 54.08 降到 48.61，差 `−5.47`；
- seed 间波动略有增加。

方向支持 task-indexed coalition context 的作用，训练期效应幅度中等。

### 8.3 A-A attention

去掉 A-A attention 后：

- sent ratio 为 0.8986，比 full 高 0.0107；
- reward 为 54.13，与 full 基本相同；
- seed 间波动没有恶化。

训练期数据没有显示 A-A attention 的独立正贡献。当前核心 claim 更适合集中在 coalition-conditioned task representation 和 shared candidate decoder。后续需要通过 held-out test 以及 coalition-composition counterfactual states 判断 A-A context 是否只在困难状态发挥作用。

### 8.4 Coverage

在匹配的 seeds 1–3 上：

| 方法 | Coverage on sent | Coverage off sent | 差值 |
|---|---:|---:|---:|
| HATT | 约 0.9055 | 0.8935 | −0.0120 |
| MAPPO64 | 约 0.8258 | 0.8404 | +0.0146 |

训练轨迹没有复现此前独立评估中 coverage 的强增益。可能原因是训练 episode 的探索状态分布随策略变化，sent/reward 不是固定场景上的可比测试指标。Coverage 的判断必须等待 paired held-out scenarios。

### 8.5 Reconfiguration semantics

匹配 seeds 1–3 时，event/full 和 legacy 的训练末期指标接近：

- event/full sent 约 0.9055；
- legacy sent 约 0.9075。

训练期数据不能说明 event 优于 legacy。Event 的价值需要在响应时间、切换次数、inactive-step sample semantics 和 held-out 稳定性中评估。

Always reconfiguration 出现明确退化：

- sent ratio 约下降 40.7 个百分点；
- reward 约下降 81；
- 三个 seeds 的差异很大。

该结果支持对重新决策时机施加约束，不能单独证明 event 比 legacy 更好。

## 9. OOM 与 recovery 记录

最初调度器错误地按约 1.2 GiB/HATT job 估计显存。实际 Delivcoal HATT 进程约占 2.37 GiB；随着较小的 MAPPO jobs 完成并被 HATT jobs 替换，同时驻留的 HATT 数增加，GPU1 只剩 26–55 MiB，15 个新 job 在首次 forward 时 OOM。

失败任务均未产生 checkpoint，因此完整重跑。Recovery 使用：

```yaml
scheduling:
  gpu_limits: {0: 0, 1: 8}
  gpu_memory:
    1:
      assumed_total_mb: 24576
      reserve_mb: 4096
      default_job_mb: 2500
```

Recovery 最终 15/15 成功。OOM 是资源调度错误，不是算法或消融实现错误。

## 10. 尚未完成的正式评估

预注册目标协议为：

1. 每 50 environment episodes 保存候选 actor；
2. 每个候选使用固定、配对的 32 validation seeds；
3. 按预注册指标从全部候选锁定 `validation-best`；
4. 使用独立的 128 held-out seeds 测试 `validation-best` 和 `last`；
5. 所有算法使用同一 validation/test seed sets；
6. 报告 success、task completion、sent/delivery、episode length、response time 和切换行为。

GPU0 当前不适合承担该任务：8 路、2 路和单路评估分别达到约 95℃、92℃和 95℃。单路在完成 3/32 seeds 后也触发温控暂停，停止 CUDA context 后才降温。因此评估队列暂时关闭。

后续推荐：

- 等全部正式训练结束后，在 GPU1 上分阶段回填 validation；或修复 GPU0 散热/硬件后恢复；
- 先完成 HATT full、MAPPO64、MAPPO288、no-coalition、no-AA 五个关键条件；
- 再完成 coverage 交叉消融和 reconfiguration 条件；
- 最终结果必须合并 original/recovery 的逻辑 job，不按物理 run directory 分组；
- 训练末期表只保留为诊断/附录，不替代正式主表。

## 11. 关键文件

```text
experiments/sweeps/20260818_hatt-formal-delivcoal.yaml
experiments/sweeps/20260818_hatt-formal-delivcoal-oom-recovery.yaml
scripts/experiments/prepare_hatt_formal_sweeps.py
scripts/experiments/prepare_failed_training_recovery.py
scripts/experiments/run_staged_validation_queue.py
algorithms/algorithm/HATTV20Network.py
train/sweep.py
```

原组状态保留 OOM 历史，Recovery 状态记录重跑结果。任何后续分析脚本都应按 job name 合并两组，并让 recovery 中的 completed job 覆盖原组同名 failed job。
