Files
ryan 4e815df327 Smoke job repo: grouped tabular dataset + config
400 rows / 200 patients, two samples each, so grouped splitting is actually
exercised. Signal is modest and noisy on purpose — a separable toy would score
1.0 with a broken model and prove nothing.
2026-08-13 21:16:22 +02:00

81 lines
3.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# hypertower-sample
A minimal **job repo** for HyperTower — the smallest thing that exercises the
repo-backed job flow end to end.
A job repo carries *configs and data*, not the framework. When a job names this
repo and a ref, the provider clones it, checks out that exact commit, and runs
with the checkout as the working directory. HyperTower itself comes from the
provider's own install via `PYTHONPATH`. That is why `configs/tabular_smoke.json`
can reference `data/smoke/labels.csv` as a plain relative path.
```
job: { repo: <this repo>, ref: main,
args: ["--config", "configs/tabular_smoke.json"] }
provider: git clone/fetch → checkout <ref> --detach → reset --hard → clean -fd
cd <checkout> && python -m hypertower_provider.orchestrator --config …
tar results/ → POST /results/<job_id>
```
## Contents
| Path | What |
|---|---|
| `configs/tabular_smoke.json` | Tabular binary classification, 3 folds, small epoch counts |
| `data/smoke/labels.csv` | 400 rows, 200 patients, 24% positive |
| `scripts/make_smoke_data.py` | Regenerates the CSV deterministically |
## The dataset
Synthetic, and shaped to catch real problems rather than flatter the pipeline:
- **Two rows per patient.** `patient_id` is the `group_column` and the config sets
`split_identity_level: 1`, so folds split by patient. If grouping ever breaks,
the two eyes of one patient land on both sides of a split and the score jumps
suspiciously — that is the bug this shape is here to expose.
- **Signal is modest and noisy.** The label depends on `age`, `iop`, `cdr` and
`rnfl` through a logistic model with added noise, so a healthy run lands around
0.850.95 AUC. A perfectly separable toy would score 1.0 even with a broken
model and tell you nothing.
- **`noise_feat` is pure noise** and `notes` is free text listed in `exclude_cols`.
Both are here so that column handling is actually exercised.
- **`site` is categorical**, covering the `cat_cols` path.
Regenerate with:
```bash
python scripts/make_smoke_data.py
```
## Submitting it
```bash
curl -X POST https://hypertower.example.com/jobs \
-H "x-token: $HT_ADMIN_TOKEN" -H 'content-type: application/json' \
-d '{
"run_name": "tabular_smoke",
"args": ["--config", "configs/tabular_smoke.json"],
"repo": "https://git.sticknife.com/ryan/hypertower-sample.git",
"ref": "main",
"constraints": {"device": "cpu", "min_memory_mb": 2000}
}'
```
Submission needs the **admin** token; a provider token cannot queue jobs.
`device: cpu` is deliberate — this model is a small MLP on ten-ish features, so a
GPU buys nothing, and constraining it to CPU means the job can be picked up by any
provider rather than waiting on a GPU box.
Jobs dedup on `(args, repo, ref)`. Re-submitting the same config at the same ref
returns the original `job_id` instead of queueing a duplicate; commit a change and
submit against the new ref to get a genuinely new run.
## Adding a real dataset
Keep large data **out** of git. The provider runs `git clean -fd` without `-x`
before every job, so gitignored paths survive between runs on the same machine —
put real data under `datasets/` (already ignored) and stage it onto the provider
once, rather than cloning it every job.