Parent: #933
Work type: infra
Area: other
Scope: Standard,1 PR;实施前需单独确认本 issue
一句话问题
单 GPU gpu_resident 仍要求 collector 写完整 CPU shared ReplayBuffer._storage,learner 再增量复制到同容量 _gpu_storage;host R 无法释放。
为什么现在做
#901 已确认完整 replay 在 host/device 各分配一次。当前 src/unilab/ipc/replay_buffer.py 负责 collector add,src/unilab/ipc/replay_pipelines/gpu_resident.py 只镜像 host ring;因此不能靠改默认配置消除 host R。PR #806/#898 也表明现有吞吐依赖下一批 replay 工作与当前 learner update 重叠,改存储 owner 不能把 add/H2D/sample 串回 learner 边界。
最小交付结果
单 GPU CUDA/MPS 的 gpu_resident 使用一份完整 device-authoritative replay。collector 只写固定深度、容量无关的 transition ingress slots;device copy 完成后才提交 ptr/size。本 PR 保留旧 CPU pipeline 与配置分支,作为迁移期 fallback。
In scope
- 在 replay owner layer 分离 packed transition 组装、bounded ingress 与完整 device ring;host allocation 只随单次 collection chunk/in-flight slot 数增长,不随 replay capacity 增长。
- collector 在发布 slot 前完成 terminal next obs/critic patch;learner 按 ring span 写 device storage,completion event 完成后再推进 committed pointer,并以 backpressure 防止 slot 被提前复用。
- 保持单 GPU synchronized 与
no_sync_collection 两种现有 collection 模式;保留 learning-start、freshness、ring wrap、seed、hot/cold batch、graph packed layout 行为。
- reward normalization、trace、logger counter 与 NaN 诊断改从 ingress/committed metadata 获取所需数据,不得保留隐藏的 host full replay。
- 保持稳态
add(N+1) → H2D/commit → sample/gather(N+1) 与 update(N) overlap;CUDA 使用安全 side stream/background submission,MPS 仍只由 learner thread 提交 device work。
- 更新 replay 内存预算、定向测试与本 issue 所需的 CUDA/MPS 对比记录;不新增永久 benchmark gate。
Non-goals
- 不处理多 GPU;不删除
cpu_pinned_double_buffer、training.replay_pipeline 或旧测试。
- 不改变 replay freshness、batch schema、learner update、checkpoint、runner lifecycle 或 collection 同步语义。
- 不承诺加速或收敛提升;但相对当前 main
gpu_resident 端到端吞吐不退化是合并 gate。
- 不用后台 Metal submission 绕过 MPS learner-thread 约束。
Owner 与预计改动
主 owner:src/unilab/ipc/replay_buffer.py、src/unilab/ipc/replay_pipelines/gpu_resident.py;相邻 owner:off-policy worker/单 GPU runner、memory budget 和对应测试。预计 10–14 个文件、600–800 行净手写改动、1 PR。永久维护项是一个 bounded ingress 状态与 CUDA/MPS 两种已有提交方式,不新增公共 runner contract。
Acceptance criteria
- 改变 replay capacity 的分配测试证明 host replay bytes 不变,device 仅有一份完整
R;首次大额分配前预算分别检查 device R 与 bounded host slots。
- 定向测试覆盖发布顺序、slot backpressure、ring wrap、terminal patch、未 commit 行不可采样、freshness、seed,以及同步/异步 collection。
- trace 证明稳态下一批 add、H2D/commit、sample/gather 落在当前 learner update 窗口;下一 tick 边界不新增同步 add/copy/sample critical path。
- 在固定 commit、同硬件/config/seed/warm-up 下,当前 main 与新实现于单 CUDA和真实 MPS 各至少 5 次越过 ring wrap 的对比;报告逐 run 数据、中位数/IQR。新实现中位数
Steps/s 不低于基线、iteration wall 不高于基线,且 replay boundary wait 不增长。
- 现有 CPU pipeline 仍可选且行为不变;本 PR 通过定向测试和
make test-all。
Stop conditions
若需要 host O(capacity) storage、新 runner/lifecycle 或独立同步协议,预计超过 15 文件/800 行,任一目标硬件稳定吞吐退化,或 MPS 无法同时满足 learner-thread submission 与无退化,暂停并回到 #933 决策,不扩张本 issue。
一句话问题
单 GPU
gpu_resident仍要求 collector 写完整 CPU sharedReplayBuffer._storage,learner 再增量复制到同容量_gpu_storage;hostR无法释放。为什么现在做
#901 已确认完整 replay 在 host/device 各分配一次。当前
src/unilab/ipc/replay_buffer.py负责 collector add,src/unilab/ipc/replay_pipelines/gpu_resident.py只镜像 host ring;因此不能靠改默认配置消除 hostR。PR #806/#898 也表明现有吞吐依赖下一批 replay 工作与当前 learner update 重叠,改存储 owner 不能把 add/H2D/sample 串回 learner 边界。最小交付结果
单 GPU CUDA/MPS 的
gpu_resident使用一份完整 device-authoritative replay。collector 只写固定深度、容量无关的 transition ingress slots;device copy 完成后才提交ptr/size。本 PR 保留旧 CPU pipeline 与配置分支,作为迁移期 fallback。In scope
no_sync_collection两种现有 collection 模式;保留 learning-start、freshness、ring wrap、seed、hot/cold batch、graph packed layout 行为。add(N+1) → H2D/commit → sample/gather(N+1)与update(N)overlap;CUDA 使用安全 side stream/background submission,MPS 仍只由 learner thread 提交 device work。Non-goals
cpu_pinned_double_buffer、training.replay_pipeline或旧测试。gpu_resident端到端吞吐不退化是合并 gate。Owner 与预计改动
主 owner:
src/unilab/ipc/replay_buffer.py、src/unilab/ipc/replay_pipelines/gpu_resident.py;相邻 owner:off-policy worker/单 GPU runner、memory budget 和对应测试。预计 10–14 个文件、600–800 行净手写改动、1 PR。永久维护项是一个 bounded ingress 状态与 CUDA/MPS 两种已有提交方式,不新增公共 runner contract。Acceptance criteria
R;首次大额分配前预算分别检查 deviceR与 bounded host slots。Steps/s不低于基线、iteration wall 不高于基线,且 replay boundary wait 不增长。make test-all。Stop conditions
若需要 host
O(capacity)storage、新 runner/lifecycle 或独立同步协议,预计超过 15 文件/800 行,任一目标硬件稳定吞吐退化,或 MPS 无法同时满足 learner-thread submission 与无退化,暂停并回到 #933 决策,不扩张本 issue。