File size: 9,283 Bytes
adc02fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# Cluster Usage

This page describes generic Slurm launchers for large-scale DoVLA-CIL generation, training,
scaling, and evaluation. Templates live under `scripts/slurm/` and contain placeholders only.

## Environment Variables

Common runtime variables:

```bash
export PROJECT_DIR="/path/to/dovla-cil"
export VENV_PATH="$PROJECT_DIR/.venv"
export DOVLA_LOG_DIR="$PROJECT_DIR/logs/slurm"
export DOVLA_PARTITION="<partition>"
export DOVLA_CPUS_PER_TASK="8"
export DOVLA_GPUS_PER_TASK="1"
export DOVLA_MEM="64G"
export DOVLA_TIME="24:00:00"
```

Some Slurm installations do not expand shell variables in `#SBATCH` headers. If yours does not,
pass those values with `sbatch --partition ... --gres ...` or edit the template header before
submitting.

## Python Environment

Venv:

```bash
python -m venv "$PROJECT_DIR/.venv"
source "$PROJECT_DIR/.venv/bin/activate"
pip install -e ".[dev]"
```

Conda:

```bash
conda create -n dovla-cil python=3.10
conda activate dovla-cil
cd "$PROJECT_DIR"
pip install -e ".[dev]"
```

Optional distributed generation:

```bash
pip install -e ".[ray]"
```

Install ManiSkill3, Genesis, CUDA-specific wheels, and cluster modules separately. They are not
required by the base install.

## Secure VLM Configuration

Set OpenClaude-compatible variables in the job environment or scheduler secret store:

```bash
export OPENCLAUDE_BASE_URL="https://open-claude.com/v1"
export OPENCLAUDE_API_KEY="<your-key>"
export OPENCLAUDE_MODEL="<model>"
```

Do not put real keys in Slurm scripts, Git-tracked files, `.env`, command lines, job names, or
shell traces. Avoid `set -x` in jobs that touch secrets. The VLM client redacts configured API keys
from logs, but scheduler logs can still capture environment or command-line mistakes.

For no-network smoke jobs:

```bash
export OPENCLAUDE_MOCK=1
```

## Recommended Directory Layout

```text
$PROJECT_DIR/
  configs/
  data/
    tasks/
    cil_array/
    cil_merged/
  logs/
    slurm/
  runs/
    dovla_base/
    scaling/
    baselines/
  reports/
  paper_artifacts/
```

Use scratch storage for large shards when possible. Copy manifests, indices, checkpoints, reports,
and paper artifacts back to persistent storage.

## Generation Arrays

```bash
export PROJECT_DIR="/path/to/dovla-cil"
export TASKS_PATH="$PROJECT_DIR/data/tasks/tasks.jsonl"
export OUT_ROOT="$PROJECT_DIR/data/cil_array"
export DOVLA_ARRAY="0-31"
export NUM_WORKERS="8"
export STATES_PER_TASK="1000"
export K="32"
export SHARD_SIZE="10000"

sbatch scripts/slurm/generate_cil_array.sbatch
```

Each array task writes one dataset part:

```text
$OUT_ROOT/part_${SLURM_ARRAY_TASK_ID}
```

## Resume Generation

```bash
export RESUME_FLAG=1
sbatch scripts/slurm/generate_cil_array.sbatch
```

Resume mode reads existing `group_index.jsonl`, skips deterministic completed `group_id`s, and
writes `distributed_manifest.json` with planned, skipped, generated, and completed counts.

## Aggregate Shards

Inspect individual parts:

```bash
python scripts/inspect_shard.py "$OUT_ROOT/part_0"
python scripts/report_dataset.py --dataset "$OUT_ROOT/part_0" --out reports/part_0
```

Merge parts through the sharding API:

```bash
python - <<'PY'
from pathlib import Path
from dovla_cil.data.sharding import ShardReader, write_cil_shards

parts = sorted(Path("data/cil_array").glob("part_*"))
records = []
for part in parts:
    records.extend(ShardReader(part).iterate_records())

write_cil_shards(
    records,
    output_dir="data/cil_merged",
    max_records_per_shard=10000,
    dataset_name="cil_merged",
    backend="toy",
    k=32,
    task_count=0,
    seed=0,
)
PY
```

## Training

```bash
export DATASET="$PROJECT_DIR/data/cil_merged"
export OUT_DIR="$PROJECT_DIR/runs/dovla_base"
export EPOCHS="5"
export BATCH_GROUPS="8"
export RECORDS_PER_GROUP="8"
export HIDDEN_DIM="256"
export LR="0.001"

sbatch scripts/slurm/train_dovla.sbatch
```

## Scaling

```bash
export OUT_DIR="$PROJECT_DIR/runs/scaling_toy"
export TOTAL_RECORDS="4096"
export K_VALUES="1,2,4,8,16,32"
export EPOCHS="3"

sbatch scripts/slurm/run_scaling.sbatch
```

## External VLA Baseline Bridge

Full SmolVLA/OpenVLA policy baselines should run in a separate environment or container because
their dependency stacks can conflict with the pinned ManiSkill/DoVLA stack. First export one expert
action per CIL group with deterministic task-balanced sampling:

```bash
export PROJECT_DIR="/path/to/dovla-cil"
export DATASET="/scratch/$USER/dovla/experiments/maniskill_presuccess_six_task_collection"
export OUT="$PROJECT_DIR/runs/external_vla/lerobot_export"
export SELECTION="expert"
export GROUP_SAMPLING="task_balanced"
export SEED="0"
sbatch scripts/slurm/export_lerobot_dataset.sbatch
```

Then write a dry-run plan for the external VLA environment:

```bash
export PROJECT_DIR="/path/to/dovla-cil"
export DATASET="$PROJECT_DIR/runs/external_vla/lerobot_export"
export OUT="$PROJECT_DIR/runs/external_vla/smolvla_plan"
export MODEL_FAMILY="smolvla"
export DRY_RUN=1
sbatch scripts/slurm/run_external_vla_baseline.sbatch
```

The generated `external_vla_baseline_plan.json` contains secret-free commands for creating the
isolated env, downloading the pinned public checkpoint, and running the adapter. The repository
ships a SmolVLA expert-only candidate-selection adapter; other model families can provide the same
entrypoint contract.

If the pinned SmolVLA directory only contains config files, download the public weights through the
containerized Hugging Face CLI before the measured run:

    export PROJECT_DIR="/path/to/dovla-cil"
    export LOCAL_DIR="/scratch/$USER/dovla/models/smolvla_base-c83c316"
    export REVISION="c83c3163b8ca9b7e67c509fffd9121e66cb96205"
    export DRY_RUN=1
    sbatch scripts/slurm/download_smolvla_checkpoint.sbatch

    # After checking the dry-run log:
    export DRY_RUN=0
    sbatch scripts/slurm/download_smolvla_checkpoint.sbatch

The downloader writes `dovla_download_manifest.json` with file sizes and SHA256 digests. It does
not pass Hugging Face tokens on the command line. For gated/private repos, authenticate through the
cluster secret store or an interactive login inside the isolated environment.

If the dry-run log reports `Network is unreachable`, the current compute partition cannot reach the
Hub. Use a network-enabled login/data-transfer node to stage the public checkpoint into `LOCAL_DIR`,
or copy a verified local snapshot there, then rerun the downloader with `DRY_RUN=0` only to write
the manifest and verify file digests.

On the reference cluster, compute-node Hub access is unavailable. The pinned checkpoint was staged
from the login node and verified at revision
`c83c3163b8ca9b7e67c509fffd9121e66cb96205`. Its `model.safetensors` SHA256 is
`7cd549ac2351fb069c0ddb3c34ad2d09cfc92b56a15dccdfc2e41467aaca01eb`. Keep LeRobot in a separate
environment because stable `0.4.3` requires `transformers>=4.57.1,<5` and
`huggingface-hub>=0.34.2,<0.36`.

The validated aligned run uses `configs/external/smolvla_cil_aligned.json`. Export job `14555244`
created 3,500 expert episodes in 39 seconds; GPU job `14555245` loaded the pinned checkpoint,
fine-tuned for 1,000 steps, and evaluated 700 held-out groups in 4 minutes 42 seconds on an H100
40 GB MIG slice. The run peaked at about 3.7 GiB host RSS. Its metrics are copied to
`outputs/external_vla/`; no network access or API secret is required at runtime.

After installing that isolated runtime, run a local-only GPU load test:

```bash
export LEROBOT_WHEEL="/scratch/$USER/dovla/wheels/lerobot-0.4.3-py3-none-any.whl"
sbatch scripts/slurm/install_smolvla_env.sbatch

export CHECKPOINT="/scratch/$USER/dovla/models/smolvla_base-c83c316"
export PYTHON="/scratch/$USER/dovla/envs/smolvla/bin/python"
sbatch scripts/slurm/smoke_smolvla_checkpoint.sbatch
```

The installer is intentionally offline: it uses the staged LeRobot wheel plus pinned compatible
packages from the Compute Canada CVMFS wheelhouse and passes `--no-index`. This prevents compute
jobs from silently changing dependency versions or hanging on unavailable egress.

The job sets `HF_HUB_OFFLINE=1` and `TRANSFORMERS_OFFLINE=1` and writes a JSON smoke artifact with
the resolved device, policy class, parameter count, and load time.

```bash
export CHECKPOINT="/scratch/$USER/dovla/models/smolvla_base-c83c316"
sbatch scripts/slurm/run_smolvla_cil_baseline.sbatch
```

The included adapter returns measured same-state candidate-selection metrics, not online rollout
metrics. A custom adapter function receives `(spec_dict, plan_dict)` and must return JSON. Do not
place Hugging Face tokens or API keys in the Slurm script, job name, or command line; use your
cluster secret store or an interactive `hf auth login` in the isolated environment if needed.

## Evaluation and Reports

```bash
export CHECKPOINT="$PROJECT_DIR/runs/dovla_base/best.pt"
export OUT_PATH="$PROJECT_DIR/runs/dovla_base/causalstress.json"
export NUM_TASKS="20"
export K="16"

sbatch scripts/slurm/eval_causalstress.sbatch
```

Aggregate and prepare artifacts:

```bash
python scripts/report_eval.py \
  --inputs "$PROJECT_DIR/runs/scaling_toy/*/metrics.json" \
  --out "$PROJECT_DIR/reports/scaling_toy"

python scripts/make_paper_artifacts.py \
  --runs "$PROJECT_DIR/runs" \
  --out "$PROJECT_DIR/paper_artifacts"
```