HATT 设计讨论摘要

当前对话最后三轮:架构判断、规模与资源估算、HATT 到 Actor 的信息流,以及实施更新大纲。

问题一:另一份独立建议与当前讨论是否本质一致?是否应放弃当前预设 GATConv?

1. 架构判断

两份建议的核心结论一致:当前网络把所有 Task 信息压缩到一个 Agent 向量后,再用固定线性层输出任务编号,导致图表示与具体 Task 动作之间缺少可追踪对应关系。

应放弃的是“单个同质 GATConv 同时处理 A-A、A-T、T-A,并只保留 Agent embedding”的方案,而不是放弃所有预设神经网络组件。
现有结构建议结构
A/T 共用节点变换AgentEncoder 与 TaskEncoder
A-A、A-T 共用注意力关系独立的 Attention
只输出 Agent embedding保留 Agent 与 Task 表示
固定动作编号线性层逐 Task 的关系级动作解码

可以继续复用 nn.LinearLayerNormsoftmaxeinsum。需要自行定义的是类型编码、关系聚合、融合方式和任务级动作解码。

AgentEncoder
TaskEncoder
AA Relation Attention
TA Relation Attention
Relation Fusion
Task Action Decoder

现有 PyG GATConv 建议保留,作为论文中的同质 GAT 消融基线。

问题二:A=30、T=100 时还能否使用稠密张量?当前规模下资源开销如何?HATT 输出什么?

2. 稠密张量能否扩展

第一版 HATT 主要计算 A-A 与 A-T 关系,其关系数量为:

Nrel = A2 + A·T
规模A-AA-T总关系数
A=12, T=13144156300
A=30, T=10090030003900

每个状态 3900 个关系仍适合稠密计算。只有当 T 达到数百到上千,或每个 Agent 只感知极少任务时,稀疏图才明显更合适。

不要显式展开 [B,A,T,H]。在 B=750、A=30、T=100、H=128、FP32 时,仅一个此类张量就约占 1.15 GB。

应直接计算低维分数矩阵:

Z = QAKTT / √d + b(EAT),   Z ∈ RB×A×T

3. 显存与训练时间估算

假设 H=128、4 个 head、FP32、PPO 状态批次 B≈750、一层 AA+TA Attention。

Mattention = B(A2 + A·T)·heads·4 bytes
项目当前 12/13 规模预估
Attention map约 3.6 MB
新增 Actor 激活显存约 100–400 MB
整体显存变化通常增加约 0.1–0.5 GB
相对当前 PyG GAT 耗时约 0.8–1.3 倍
相对 NoGAT 耗时约 1.5–2 倍

扩展到 30/100 时,关系计算约为当前的 13 倍。建议把 num_mini_batch 从 1 调到 4 或 8,使显存随 minibatch 大小线性下降。

4. HATT 的输入与输出

输入

X_A:    [B,A,F_A]     Agent 特征
X_T:    [B,T,F_T]     Task 特征
M_AA:   [B,A,A]       A-A mask
M_AT:   [B,A,T]       A-T / available mask
E_AA:   A-A 关系特征
E_AT:   A-T 关系特征

类型编码

HA0 = φA(XA),    HT0 = φT(XT)

A-A 关系聚合

sikAA = QAA(hi)TKAA(hk)/√d + bAA(eik)
ciAA = Σk αikAAVAA(hk)

Task→Agent 关系聚合

sijTA = QTA(hi)TKTA(hj)/√d + bTA(eij)
ciTA = Σj αijTAVTA(hj)

Agent 更新

HA = LayerNorm(HA0 + MLPA[HA0, CAA, CTA])

第一版可以暂不更新 Task,令 HT = HT0

HATT 应输出 Agent 上下文表示 HA 和仍保留任务轴的 Task 表示 HT,不能只返回一个聚合后的 Agent 向量。

5. 如何送入 Actor

Agent / Task 类型编码
A-A 与 Task→Agent 关系 Attention
HA:[B,A,H] HT:[B,T,H]
TaskActionDecoder 逐任务比较
logits:[B,A,T]
available_actions mask + softmax

任务级动作解码:

qi = WqHA,i,    kj = WkHT,j
zij = qiTkj/√d + g(EAT,ij)

动作 mask 与策略:

ij = zij if available, otherwise −∞
πi(a=j | oi) = softmaxj(z̃ij)

直观上,HATT 负责让 Agent 理解团队和任务上下文;TaskActionDecoder 负责让 Agent 逐个比较 Task。Categorical、PPO log-prob、entropy、Buffer 与 Critic 的主体不需要改变。

问题三:设计更新大纲,不写具体代码,但明确需要完成的工作和完整数据流。

6. 第一版更新边界

第一版只实现必要结构:

Agent / Task 类型编码
A-A 关系注意力
Task→Agent 关系注意力
Agent 上下文融合
Task-specific Action Decoder
available_actions mask

暂不加入 Agent→Task 联盟聚合、显式排斥通道、多层传播和 Graph Critic。Critic 继续使用当前 centralized state MLP,避免 Actor 与 Critic 同时变化。

7. 观测与关系契约

Agent 公共基础状态

position(2)
capabilities(4)
load(1)
battery(1)
coalition_id(1)
agent_type(1)
living(1)

共 11 维。Ego 可以附加当前任务类型和发现比例等 focal 决策上下文,但公共 Agent 字段应与 Others 对齐。

Task 状态

position(2)
requirements(4)
demand(1)
task_type(1)

关系特征

关系第一版特征Mask
A-Arelative_xy、same_coalition可见、存活、排除 self row
A-Trelative_xy、currently_assignedavailable_actions

能力和需求已经存在于节点特征中,第一版不额外提供能力差、需求差或距离标量。

8. 去中心化批量数据流

Runner 可以批量计算全部 Agent,但每个 focal Agent 只能使用自己的局部观测:

ego:               [B,A,F_ego]
others:            [B,A,A,F_agent]
tasks:             [B,A,T,F_task]
available_actions: [B,A,T]
不再像旧 GAT 那样跨观察者平均 Tasks,或利用其他 Agent 的观测恢复当前 Agent 的图。修改 Agent i 的局部观测,不应污染其他环境样本。
Env:ego / others / tasks / available_actions
Wrapper 与 Buffer:保持 Dict 和 Agent 维度
SelfAgentEncoder / OtherAgentEncoder / TaskEncoder
A-A Attention 与 Task→Agent Attention 分别聚合
Relation Fusion:生成 agent_context [B,A,H]
TaskActionDecoder:结合 agent_context 与 task_h
logits [B,A,T] → mask → Categorical
PPO:action / log_prob / entropy;Critic 走独立 state 路径

9. 模块职责

模块输入输出与职责
SelfAgentEncoderEgofocal Agent 表示 [B,A,H]
OtherAgentEncoderOthers其他 Agent 表示 [B,A,A,H]
TaskEncoderTasks逐观察者 Task 表示 [B,A,T,H]
AAAttentionSelf、Others、AA mask团队上下文 [B,A,H]
TAAttentionSelf、Tasks、AT mask总体任务上下文 [B,A,H]
RelationFusionSelf、AA、TA contextAgent 决策上下文 [B,A,H]
TaskActionDecoderAgent context、Task、AT relation逐任务 logits [B,A,T]
HATT 负责关系上下文,TaskActionDecoder 负责具体任务动作。不能再把单个 Agent 向量送入固定任务编号的线性输出头。

10. Policy、PPO 与模型管理

11. 实施顺序与验收

  1. 固定 NoGAT 与旧 GAT 基线结果。
  2. 统一 Ego/Others 的 Agent 字段契约。
  3. 完成类型编码器、AA/TA Attention 和关系融合。
  4. 完成 Task-specific Decoder 与动作 mask。
  5. 接入 Policy、优化器、保存与日志。
  6. 验证 Task 置换后 logits 同步置换。
  7. 验证不可用任务概率为零、各分支梯度非零。
  8. 验证 rollout 与训练阶段的 action log-prob 一致。
  9. 分别运行 NoGAT、旧 GAT、HATT 冒烟训练。
  10. 最后测试 A=30、T=100 的显存和更新时间。

第一版稳定后,再通过消融决定是否加入 Agent→Task 联盟聚合、显式竞争通道和多层关系传播。