SaylorTwift HF Staff commited on
Commit
b6f8fe5
·
verified ·
1 Parent(s): 0298809

RECIPE: document per-checkpoint eval worker

Browse files
Files changed (1) hide show
  1. RECIPE.md +34 -6
RECIPE.md CHANGED
@@ -144,13 +144,40 @@ the job's own public URL → start the 30-min watchdog → train (GPU 0) → fin
144
  + the matching API key also works if you prefer those backends; then the Jobs-proxy
145
  plumbing is unnecessary.)
146
 
147
- ### Evaluation (built into the job)
148
 
149
- After training, the job restarts vLLM with `--enable-lora --lora-modules trained=$ADAPTER_REPO`
150
- and runs all 250 test tasks twice — base model vs trained adapter — through the same
151
- harness/sandbox path (`purpose="eval"`, required when passing `eval_sampling`).
152
- Pass@1 for each lands in the adapter repo at `eval/final_results.json`.
153
- A standalone version (`run_eval.sh`) runs the same comparison on any checkpoint.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
 
155
  ---
156
 
@@ -199,6 +226,7 @@ A standalone version (`run_eval.sh`) runs the same comparison on any checkpoint.
199
  | `train_lora.py` | trainer + worker wiring, reward, LoRA config, upload & heartbeat callbacks |
200
  | `run_job.sh` | job entrypoint: setup, seam patch, 3 processes, watchdog, final eval |
201
  | `run_eval.sh` | standalone base-vs-adapter eval job |
 
202
  | `eval_adapter.py` | held-out eval loop (pass@1, agreement breakdown) |
203
  | `prepare_tasks.py` + `data/` | pinned, hash-checked task materialization (+ `docker_image` patch) |
204
  | `serve_policy.sh` / `serve_env.sh` | the two servers, for multi-machine setups |
 
144
  + the matching API key also works if you prefer those backends; then the Jobs-proxy
145
  plumbing is unnecessary.)
146
 
147
+ ### Evaluation (two layers)
148
 
149
+ **Per-checkpoint, live** — a separate eval-worker job (`run_eval_watch.sh`, 1×H200)
150
+ polls the adapter repo; every time a new `checkpoint-N` appears it hot-loads it as a
151
+ LoRA into its running vLLM (runtime LoRA updates, no restart) and evals it on a fixed
152
+ 100-task test subset. Base-model cells are computed once and reused. Results:
153
+ `eval/<checkpoint-N>_results.json` + a rolling **`eval/summary.json` — the live
154
+ learning curve**. Launch it alongside training:
155
+
156
+ ```bash
157
+ uv run --with 'huggingface_hub>=1.29' python - <<'EOF'
158
+ import os
159
+ from huggingface_hub import run_job
160
+ token = os.popen("hf auth token").read().strip()
161
+ run_job(
162
+ image="vllm/vllm-openai:v0.31.0",
163
+ command=["bash", "-c",
164
+ "pip -q install huggingface_hub && "
165
+ "hf download YOU/lfm-opencode-lora-rl-code --local-dir /app && "
166
+ "bash /app/run_eval_watch.sh"],
167
+ flavor="h200", timeout="48h",
168
+ env={"ADAPTER_REPO": "YOU/LFM2.5-2.6B-opencode-lora-RL", "N_TASKS": "100"},
169
+ secrets={"HF_TOKEN": token},
170
+ expose_public=[8000],
171
+ token=token,
172
+ )
173
+ EOF
174
+ ```
175
+
176
+ **Final, full** — after training, the training job itself restarts vLLM with the
177
+ final adapter and runs all 250 test tasks twice (base vs final) →
178
+ `eval/final_results.json`. (`purpose="eval"` is required when passing
179
+ `eval_sampling`.) A standalone version (`run_eval.sh`) runs the same comparison on
180
+ any checkpoint.
181
 
182
  ---
183
 
 
226
  | `train_lora.py` | trainer + worker wiring, reward, LoRA config, upload & heartbeat callbacks |
227
  | `run_job.sh` | job entrypoint: setup, seam patch, 3 processes, watchdog, final eval |
228
  | `run_eval.sh` | standalone base-vs-adapter eval job |
229
+ | `run_eval_watch.sh` + `eval_watch.py` | per-checkpoint eval worker (live learning curve) |
230
  | `eval_adapter.py` | held-out eval loop (pass@1, agreement breakdown) |
231
  | `prepare_tasks.py` + `data/` | pinned, hash-checked task materialization (+ `docker_image` patch) |
232
  | `serve_policy.sh` / `serve_env.sh` | the two servers, for multi-machine setups |