Skip to content

Commit 1ffe4dc

Browse files
Zhiyu Liclaude
andcommitted
docs(swe-teacher): add clean run-only runbook
New SWE_TEACHER_CP16_RUNBOOK.md — how-to-run only (TL;DR, working config, cluster facts, reaper exemption, required settings, monitor). The detailed root-cause / debugging history stays in SWE_TEACHER_CP16_REPRO.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 076fee6 commit 1ffe4dc

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

SWE_TEACHER_CP16_RUNBOOK.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Run: Nemotron-3-Ultra 550B SWE-Teacher GRPO (cp16, 48× GB200)
2+
3+
Clean runbook for the `swe_teacher_cp16` async-GRPO run on OCI-HSG (GB200, InfiniBand).
4+
Recipe: `examples/configs/ultra/swe_teacher_cp16.yaml` · Launcher: `swe_teacher_cp16_launch.sh`.
5+
(For root-cause / debugging history, see `SWE_TEACHER_CP16_REPRO.md`.)
6+
7+
## TL;DR — run it
8+
9+
```bash
10+
cd <repo-root> # the RL checkout on lustre
11+
# creds sourced on the LOGIN node only, never inside the compute container:
12+
source /lustre/fs1/portfolios/llmservice/projects/llmservice_nemo_reasoning/users/zhiyul/secrets.sh > >(grep -v HF_TOKEN) 2>&1
13+
bash swe_teacher_cp16_launch.sh # submits a 48-node job via ultra_launch.sh -> ray.sub
14+
```
15+
16+
Then **immediately register the GPU-idle exemption** (below) or the reaper kills the job during the
17+
~30-min 550B load.
18+
19+
## Working config (committed defaults — use as-is)
20+
21+
`swe_teacher_cp16.yaml`: `max_total_sequence_length: 65536`, **`train_global_batch_size: 32`**
22+
(`num_prompts_per_step: 8` × `num_generations_per_prompt: 4`), `mtp_num_layers: 5`
23+
(`mtp_loss_scaling_factor: 0.3`), CP16 / EP32 / TP8 / PP1, 48 nodes (32 train + 16 gen),
24+
`SEGMENT_SIZE=8`. This config trains from scratch, CP-clean.
25+
26+
> **Do not raise `train_global_batch_size` above 32** — GBS=128 triggers a `CONTEXT_PARALLEL_GROUP`
27+
> `all_to_all` hang (600s watchdog). 65k or 190k seq length both work at GBS ≤ 32.
28+
29+
## Cluster / launch facts
30+
31+
- **Account** `nemotron_sw_post` · **partition** `batch` · **QOS** `short` (2× priority, MaxWall 2h) · **walltime** `1:59:00`.
32+
- **48 nodes** = 32 train + 16 generation (`NUM_TRAIN_NODES=32`, `NUM_GEN_NODES=16`), 4 GPU/node.
33+
- **Container:** `$Z/enroot-images/nvcr.io+nvidian+nemo-rl+nightly.2026-07-13.squashfs`
34+
where `Z=/lustre/fsw/portfolios/llmservice/users/zhiyul`. The mcore worker venv builds at runtime via
35+
`uv run --extra mcore` (~5-min transformer-engine compile).
36+
- Model / data / SIFs are all under `$Z` (see the launcher's `MODEL_PATH`, `TRAIN_PATH`, `swe_sifs`).
37+
38+
## GPU-idle reaper exemption (REQUIRED)
39+
40+
The 550B dist-ckpt load sits at SM≈0 for ~30 min; the auto-reaper cancels idle jobs after 30 min. Set
41+
the exemption **while PENDING or right after RUNNING**:
42+
43+
```bash
44+
JOB=<jobid>
45+
scontrol update jobid=$JOB Comment='{"OccupiedIdleGPUsJobReaper":{"exemptIdleTimeMins":"120","reason":"benchmarking","description":"550B dist-ckpt load ~30min SM~0; SWE rollouts idle GPUs"}}'
46+
squeue -j $JOB -o %k # verify the JSON is set
47+
```
48+
49+
## Required settings (keep these — the recipe depends on them)
50+
51+
| Setting | Value |
52+
|---|---|
53+
| MoE backend (vLLM) | `moe_backend: triton` |
54+
| Expert parallel | `expert_model_parallel_size: 32` |
55+
| Seq-len divisor | `make_sequence_length_divisible_by: 256` |
56+
| MTP head | `mtp_num_layers: 5`, `mtp_loss_scaling_factor: 0.3` |
57+
| Batch size | `train_global_batch_size: 32` (do not exceed) |
58+
| SWE concurrency | `swe_agents concurrency: 64` |
59+
| Topology | `cluster.segment_size: 8` + `SEGMENT_SIZE=8` (`--segment`), one EP group per NVLink rack |
60+
| NCCL transport | `ray.sub` head+worker env: `NCCL_NET=IB`, `NCCL_NVLS_ENABLE=1`, `NCCL_GIN_*`, `HYBRID_EP_CACHE_DIR` |
61+
62+
`checkpointing.save_period=1` (launcher) writes a 550B checkpoint **every step** — drop it for anything
63+
but short runs.
64+
65+
## Running as a different user (within HSG)
66+
67+
Read paths (model, data, container, SIFs) are world-readable under `.../users/zhiyul` — no copy needed.
68+
Write targets are scoped per-user via `WRITE_ROOT` (default `/lustre/fsw/portfolios/llmservice/users/$USER`:
69+
HF cache, uv caches, per-agent venvs, results/checkpoints/logs). A teammate needs to:
70+
- have Slurm account `nemotron_sw_post` (or override `SLURM_ACCOUNT`);
71+
- optionally `export WRITE_ROOT=<your writable dir>`;
72+
- provide their own creds for `source .../secrets.sh` (the model is local, so `HF_TOKEN` is usually
73+
unnecessary). Do **not** rely on zhiyul's `secrets.sh`.
74+
75+
## Monitor
76+
77+
```bash
78+
JOB=<jobid>; LD=results/ultra-swe-teacher-cp16/ray_logs/$JOB-logs
79+
grep -aoE "training_step=[0-9]+|Watchdog caught|EngineDeadError" "$LD/ray-driver.log" | sort | uniq -c
80+
```
81+
82+
- Healthy: `number of parameters on` → rollout → `training_step=0``1` → … Step 0 can take ~1 h on a
83+
hard SWE batch (rollout-bound, not a hang — check worker-log mtimes are fresh, not the driver log).
84+
- **Success:** `training_step` advances with **zero `Watchdog caught`** and zero `EngineDeadError`.
85+
- If `Watchdog caught … CONTEXT_PARALLEL_GROUP`: batch size too large — keep GBS ≤ 32.
86+
- If `EngineDeadError` / `Hit N global ClientOSError`: generation overload — lower `concurrency` or raise the `ray.sub` ulimit.
87+
88+
## Security
89+
90+
`HF_TOKEN` is sourced on the login node and must be redacted from all output (`grep -v HF_TOKEN`); never
91+
bake it into logs. The model is local, so the token is typically unneeded.

0 commit comments

Comments
 (0)