# Harbor Qwen GRPO 项目分层架构

> 更新时间：2026-08-30  
> 状态：本文描述已经完成验证的历史运行拓扑。腾讯云CVM、云硬盘及相关计费资源已释放，k3s、BuildKit、PVC、sandbox和verifier当前不在线；恢复项目时需要重新创建资源和凭证，不能把本文地址或资源ID视为仍然有效。

## 1. 六层抽象

```mermaid
flowchart TB
    L6["操作层<br/>Makefile + scripts"]
    L5["定制层<br/>patches + 项目控制代码 + 配置"]
    L4["应用层<br/>Harbor + rLLM + verl + vLLM + mini-swe-agent"]
    L3["环境层<br/>Mac + AutoDL Conda/Ray + k3s/BuildKit/Sandbox"]
    L2["网络层<br/>EIP + KubeConfig/RBAC + Gateway + Registry + mTLS tunnel"]
    L1["资源层<br/>Mac + A800 80GB + CVM 32C64G/100G+500G + Registry"]

    L6 --> L5 --> L4 --> L3 --> L2 --> L1
```

| 层次 | 历史验证组件 | 职责 |
|---|---|---|
| 资源层 | Mac；AutoDL A800 80GB；腾讯CVM 32 vCPU/64GiB；100GiB系统盘；500GiB数据盘；TCR主仓/ACR迁移源 | 源码、GPU训练、CPU沙箱、持久存储和镜像仓库 |
| 网络层 | CVM EIP；安全组；k3s 6443；最小权限KubeConfig；AutoDL公网Gateway；BuildKit mTLS tunnel | 连接三台执行主体，并限制管理和运行权限 |
| 环境层 | Mac Docker；AutoDL Conda/Ray；k3s v1.36.3；containerd；local-path；rootful BuildKit | 提供构建、训练、调度和隔离运行环境 |
| 应用层 | Harbor、rLLM、verl、vLLM、mini-swe-agent 2.3.0、mini-coder-4b、SWE-Smith | 生成轨迹、执行代码、验证reward并训练策略 |
| 定制层 | ACK adapter兼容层、离线verifier、超时/重试、Gateway修复、镜像重写、skopeo搬运 | 将上游库接入k3s、OCI Registry和中国网络环境 |
| 操作层 | Makefile、`scripts/`、`src/`、测试和文档 | 把跨机器操作收敛为可验证的阶段命令 |

`ACK_*` 和 `environment_type=ack` 是上游兼容接口名称；历史运行时它们指向腾讯k3s，当前不表示存在在线集群。

## 2. 部署关系

```mermaid
flowchart LR
    subgraph MAC["Mac：开发与管理员"]
        CODE["源码 / patches / 文档"]
        ADMIN["管理员 KubeConfig"]
        DM["Docker 镜像搬运回退"]
    end

    subgraph GPU["AutoDL：GPU训练"]
        TRAIN["rLLM + verl + Ray"]
        MODEL["vLLM + mini-coder-4b"]
        GW["rLLM Model Gateway"]
        IMPORT["冻结版本导入 / 注册"]
    end

    subgraph CVM["腾讯CVM：单节点k3s"]
        CURATE["Harbor CPU curation<br/>plan/download/filter/Oracle/freeze"]
        API["k3s API / RBAC"]
        BK["BuildKit + 100Gi PVC"]
        POD["Sandbox Pods + verifier"]
        SKOPEO["可选 skopeo 镜像搬运"]
    end

    REGISTRY["OCI Registry<br/>TCR当前主仓 / ACR迁移源"]
    HUB["Docker Hub / 可选代理"]

    CODE --> TRAIN
    ADMIN --> API
    CURATE -->|"最小权限 KubeConfig"| API
    CURATE -->|"本地port-forward + mTLS"| BK
    API --> BK
    API --> POD
    POD -->|"OpenAI兼容API"| GW
    GW --> MODEL
    POD -->|"Oracle日志 / reward"| CURATE
    BK --> REGISTRY
    REGISTRY --> POD
    HUB --> DM --> REGISTRY
    HUB --> SKOPEO --> REGISTRY
    CURATE -->|"可迁移冻结版本"| IMPORT --> TRAIN
```

## 3. 三方职责

### Mac

- 固定上游commit并维护补丁。
- 生成AutoDL发布包和BuildKit证书。
- 使用管理员KubeConfig创建命名空间、RBAC、Secret和BuildKit。
- 使用腾讯云CLI初始化TCR个人版命名空间和80个任务分片仓库，并管理TCR凭证文件。
- 在CVM代理无法覆盖长尾镜像时承担Docker搬运回退。

### AutoDL

- 承载模型权重、vLLM、rLLM Gateway、Ray、verl和W&B客户端。
- 校验并导入CVM冻结版本，重新定位task路径并注册到训练环境。
- 只在Canary/GRPO期间使用最小权限ServiceAccount调度sandbox。

### 腾讯CVM（历史职责，资源已释放）

- 运行单节点k3s控制面、CoreDNS、local-path provisioner和containerd。
- `/dev/vdb` 挂载到 `/var/lib/rancher`，保存k3s状态、containerd和PVC。
- 运行BuildKit及每条Harbor trial的环境、agent和verifier。
- 运行不含GPU训练栈的Harbor CPU curation环境。
- 承担plan、download、filter、镜像搬运、NOP/Oracle、freeze和版本导出。

## 4. 归档状态与恢复边界

2026-08-30完成腾讯云资源释放后，以下运行态均不可假设仍存在：

- CVM实例、系统盘、数据盘及`/var/lib/rancher`中的k3s状态；
- local-path BuildKit PVC、containerd缓存和历史sandbox Pod；
- 原EIP、k3s API端点、KubeConfig/RBAC token及BuildKit端口转发；
- AutoDL到sandbox的model gateway公网映射。

源码、补丁、冻结数据契约、checkpoint与评测报告是可迁移资产；集群状态不是。未来恢复至少需要：新建CPU节点和持久盘、安装并验收k3s、重建namespace/RBAC/Secret、部署BuildKit与PVC、验证Registry镜像覆盖、重新生成或下发KubeConfig和证书、建立GPU model gateway，并依次通过BuildKit smoke、sandbox network smoke和项目preflight。恢复前不得直接启动训练或评测。

## 5. 核心链路

### 5.1 构建与运行

```text
CVM Harbor Oracle
  → 本机k3s API创建trial
  → CVM buildctl经本地mTLS tunnel访问BuildKit
  → BuildKit推任务镜像到当前Registry
  → k3s启动sandbox并执行NOP/Oracle/verifier
  → 结果写回CVM curation版本

AutoDL rLLM训练
  → k3s API创建trial
  → AutoDL buildctl经mTLS tunnel访问BuildKit
  → BuildKit拉基础镜像并推任务镜像到当前Registry
  → k3s从当前Registry启动sandbox Pod
  → Pod调用AutoDL Gateway/vLLM
  → verifier返回reward和日志
```

BuildKit使用100Gi `local-path` PVC。CVM已扩至32核/64GiB、500GiB数据盘，并把kubelet root-dir迁移到 `/var/lib/rancher/kubelet`；每个sandbox默认请求2 CPU、4GiB内存和20GiB临时存储，当前按10任务并发验证。

### 5.2 数据和镜像

```mermaid
flowchart LR
    HF["SWE-Smith Filtered"] --> PLAN["CVM plan / download"]
    PLAN --> STATIC["static filter"]
    STATIC --> IMAGES["base image plan"]
    IMAGES --> MIRROR["Mac Docker 或 CVM skopeo"]
    MIRROR --> COVERAGE["Registry coverage"]
    COVERAGE --> ORACLE["NOP + Oracle"]
    ORACLE --> FREEZE["repo-isolated freeze"]
    FREEZE --> EXPORT["portable export"] --> IMPORT2["AutoDL import/register"]
    IMPORT2 --> CANARY["Canary"]
    IMPORT2 --> GRPO["GRPO"]
```

镜像队列由 pending、completed、skipped 和 rewrites四份JSON组成。CVM/Linux入口已把3个infra镜像和84个可用基础镜像从ACR迁移到TCR并验证，3个超限镜像保持skipped，pending为0。`registry-migrate-linux` 负责infra/基础镜像和队列状态；`registry-task-migrate` 单独负责已accepted的历史任务镜像。

TCR任务镜像使用80个仓库和 `base-sharded-tags`：每个基础镜像最多映射到5个子分片，先以 `basecache-*` 标签预热到对应任务仓库；精确计划为357个基础镜像-仓库组合，已全部通过digest校验。当前布局的单仓库最大投影标签数为93，低于TCR个人版100标签配额。

### 5.3 GRPO训练

1. rLLM从冻结train split选择任务，为每个任务创建多条rollout。
2. k3s sandbox执行mini-swe-agent Bash轨迹，Gateway记录模型trace。
3. verifier reward与trace组成GRPO batch。
4. verl计算相对优势并执行loss/backward/update。
5. 新权重版本通过Gateway管理接口同步给推理端。

Oracle以180秒绝对上限筛除长尾verifier；GRPO通过 `TRAIN_VERIFIER_TIMEOUT_MULTIPLIER=0.06` 将SWE-Smith任务自带的3000秒上限等效限制为180秒，避免单条rollout长期占用sandbox。

这两个配置互相独立：`CURATION_ORACLE_VERIFIER_TIMEOUT_SEC` 仅影响数据治理的NOP/Oracle job；`TRAIN_VERIFIER_TIMEOUT_MULTIPLIER` 由 `scripts/50_train_grpo.sh` 通过Hydra传给rLLM/Harbor runtime，仅影响Canary之后的GRPO rollout。调整任何一个都不能假定另一个会同步变化。

Oracle选批按split和仓库确定性轮询，避免按任务名顺序导致仓库集中；停止条件是 `dataset-freeze-check` 返回 `freeze_ready=true`，同时满足350/75/75和至少70个冻结仓库，而不是仅判断accepted总数。

单卡smoke在BF16、关闭CPU offload和 `TRAIN_GPU_MEMORY_UTILIZATION=0.35` 下完成完整更新。随后原始双卡collective定位到当前AutoDL机器的NCCL Direct P2P/CUMEM死锁；设置 `NCCL_P2P_DISABLE=1` 后，两卡FSDP2与两卡传统FSDP1完整GRPO均通过。严格A/B确认rank 0动作正常、rank 32在 `dummy_dtensor` 首次adapter同步路径生成乱码；LoRA现改为以 `safetensors` 直接初始化rollout基础权重。

## 6. 身份和安全边界（历史）

| 身份/凭证 | 保存位置 | 权限 |
|---|---|---|
| k3s管理员KubeConfig | Mac项目外 | 集群初始化、RBAC、Secret、BuildKit管理 |
| 最小权限ServiceAccount KubeConfig | CVM/AutoDL项目外各一份 | 仅runtime/builder命名空间所需资源；不能读取nodes/namespaces/kube-system；CVM server使用127.0.0.1 |
| Registry凭证 | Mac/CVM auth文件和k3s pull secret | 推送或拉取ACR/TCR项目镜像 |
| BuildKit mTLS证书 | Mac生成，CVM和AutoDL客户端按阶段持有，k3s保存server secret | 访问BuildKit TCP Service |
| 模型API key | AutoDL `.env` | sandbox调用Gateway |

公网6443只允许Mac和AutoDL出口IP；CVM SSH只允许可信来源。凭证不进入Git和发布包。

## 7. 配置映射

| 配置 | 下游对象 |
|---|---|
| `KUBECONFIG_PATH`、`KUBE_CONTEXT` | kubectl、Harbor adapter、BuildKit tunnel |
| `ACK_NAMESPACE` | `harbor-qwen-grpo` runtime namespace |
| `ACK_BUILDER_NAMESPACE` | `harbor-qwen-build` BuildKit namespace |
| `ACK_SANDBOX_NODE_SELECTOR_JSON` | `harbor-role=sandbox` 节点选择 |
| `ACK_BUILDKIT_STORAGE_CLASS` | k3s `local-path` |
| `ACK_REGISTRY_PREFIX` | ACR或TCR任务镜像和基础镜像目标 |
| `ACK_TASK_IMAGE_LAYOUT`、`ACK_TASK_IMAGE_SHARDS`、`ACK_TASK_IMAGE_BASE_SHARDS` | ACR每任务仓库兼容布局，或TCR个人版80仓库、每基础镜像5个子分片的tag布局 |
| `ACK_BASE_IMAGE_REWRITES_FILE` | Docker Hub基础镜像到当前Registry的确定性映射 |
| `RLLM_GATEWAY_PUBLIC_URL` | sandbox可达的Gateway origin；不能附加重复 `/v1` |
| `MINI_SWE_AGENT_MAX_TOKENS=2048` | 单步输出预算，防止32K上下文溢出 |
| `CURATION_RUNTIME=cpu` | CVM激活最小 `.venv-curation`，不加载GPU训练栈 |
| `CURATION_ORACLE_BATCH_SIZE=40`、`CURATION_ORACLE_CONCURRENCY=10`、`CURATION_ORACLE_VERIFIER_TIMEOUT_SEC=180` | CVM批量Oracle的批大小、环境并发和绝对verifier上限 |
| `CURATION_POC_TRAIN/VALIDATION/TEST`、`CURATION_POC_MIN_REPOSITORIES` | freeze-check/freeze的350/75/75和至少70仓库停止条件 |
| `CURATION_*` | 候选规模、可迁移路径、静态筛选、Oracle、冻结和export/import |
| `DATASET_IMAGE_*` | Mac/Linux镜像重试、大小上限、代理和authfile |
| `TRAIN_VERIFIER_TIMEOUT_MULTIPLIER=0.06` | 训练rollout的Harbor verifier倍率；3000秒任务等效为180秒 |
| `TRAIN_MODEL_DTYPE=bf16`、`TRAIN_GPU_MEMORY_UTILIZATION=0.35` | 已验证的单卡colocated显存组合 |
| `make fsdp2-smoke` | 两卡最小NCCL/FSDP2/backward/optimizer验证；不连接Harbor或CVM |
| `TRAIN_*` | verl/vLLM显存、上下文、LoRA、rollout和checkpoint |

## 8. 历史持久化与重启方式（当前不适用）

以下内容描述CVM仍被保留时的历史恢复方式。2026-08-30资源已经彻底释放，因此当前不能按“重新开机”恢复，也不能假设旧系统盘、数据盘、k3s数据库、PVC、EIP或KubeConfig仍存在。历史上仅关机且EIP保持不变时，再开机需要：

1. 确认 `/var/lib/rancher` 已挂载。
2. 确认 `k3s` active、节点Ready、BuildKit Pod可用。
3. 在当前执行端重新启动BuildKit tunnel：CVM做Oracle时在CVM启动，AutoDL做Canary/GRPO时在AutoDL启动。
4. 依次执行 `make buildkit-status`、`make buildkit-smoke` 和相应preflight，成功后才恢复Oracle/训练。

Oracle的权威持久状态是 `${CURATION_ROOT}/${CURATION_VERSION}/oracle/results.jsonl`，job目录只是可审计执行记录。如果基础设施事故导致一批任务被误ingest，必须先停止bulk，再将修复前备份、受影响batch/task ID和修复后计数记录到 `oracle/recovery/<incident>/`。恢复必须按task ID精确进行，不能按异常类型批量删除。

当前属于资源重建场景，必须重新处理TLS SAN、KubeConfig、RBAC、PVC、Registry Secret和资源注册；不能沿用上述快速开机流程。

## 9. 2026-08-11历史状态与下一门槛

| 模块 | 状态 |
|---|---|
| k3s、RBAC、PVC、BuildKit、TCR、Gateway | 已打通并验证；32C64GiB及500GiB数据盘迁移完成 |
| 历史100任务POC | 101验证、100接受，冻结37/15/7；仅作早期闭环记录 |
| Canary | 新validation 10/10无异常；平均reward 0.1，其中1条reward 1 |
| GRPO rollout到backward | 已打通 |
| GRPO optimizer step | 单卡与两卡FSDP1均已完成；该批reward与梯度为0，只作为链路验收 |
| 多卡训练 | 禁用当前机器故障的Direct P2P后，两卡FSDP2与FSDP1完整链路均通过 |
| 3000候选/500冻结任务扩容 | 3000已下载，2614静态通过；Oracle最终1440/981，已正式冻结350/75/75 |
| CVM/Linux镜像搬运 | 84完成、3超限、0缺失、0错误 |
| TCR迁移 | 3个infra、84个基础镜像、166个历史任务镜像及357个预热组合已迁移并验收；80分片最大投影标签93/100 |
| freeze、导出与导入 | `freeze_ready=true`；正式500条覆盖77仓库，manifest内嵌语义摘要为 `8e29a24910b727e72b63fed539cb834fda47994b8d963c2e002ffa8deb23e654`，JSON文件SHA-256为 `0e23cbcf8c7a1d0eba498a867898514344f2a1e8826130cf0937691dc36077e5`；AutoDL已导入/注册350/75/75 |

数据导入、注册、新Canary、两卡通信、GRPO链路与LoRA rank 32 `safetensors`动作生成复测均已完成。本节的“下一步”已被后续PPO和统一64K P0取代。

## 10. 2026-08-17历史增量：freeze与计划中的PPO

本节覆盖第8节中已经过时的“下一门槛”，不改写历史验收记录。当前训练数据是`swesmith-curated-grpo-267-v1`，split为187/42/38、覆盖89个仓库；267/267个任务镜像已验证。`Klear-AgentForge-8B-SFT`在该数据集validation抽样30题、64K上下文下得到12/30且无异常。

PPO不增加新的数据、镜像或sandbox层。共同链路到Harbor terminal reward为止；PPO特有部分包括critic/value forward、GAE、actor clipped update、critic value update以及actor LoRA/critic model-only checkpoint。现有GRPO入口和历史两卡结果不变；PPO已在4卡trainer加1卡单vLLM的分离拓扑完成两轮20步GPU验收。最终统一64K P0中SFT与parent step20在test38和Verified27均持平，因此项目停止扩卡和追加step，并在释放腾讯云运行面后归档。细节见[`PPO_TRAINING_RUNBOOK.md`](PPO_TRAINING_RUNBOOK.md)。
