-
Notifications
You must be signed in to change notification settings - Fork 0
Generate the calibration scripts instead of keeping one by hand #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
354a5f1
5a2bc3a
5c49763
70cb9c7
8b2c3ee
22566ea
3a8e00e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| #!/usr/bin/env python3 | ||
| """Generate the per-task slurm/*_calibrate.sh runs that size the sweep jobs. | ||
|
|
||
| One dataset, every arm, one seed, twenty tasks at the full trial budget, in a | ||
| 2-hour allocation. This is the run that says whether a 24-hour job fits: the | ||
| result rows carry the token spend, so tokens / elapsed = throughput, and | ||
| episodes x tokens-per-task / throughput = wall clock. Twenty also takes | ||
| g-memory past its twentieth task, where merge_insights runs. | ||
|
|
||
| uv run slurm/generate_calibration.py # every dataset | ||
| uv run slurm/generate_calibration.py --task fever pddl | ||
|
|
||
| The cluster, the model and the arms are generate_slurm.py's; what a calibration | ||
| does differently is here. | ||
| """ | ||
| import argparse | ||
|
|
||
| from generate_slurm import ( | ||
| CLEANUP, | ||
| SEEDS, | ||
| TASKS, | ||
| every_arm, | ||
| preamble, | ||
| run_command, | ||
| write_script, | ||
| ) | ||
|
|
||
| SEEDS_CALIBRATED = SEEDS[:1] | ||
| MAX_TASKS = 20 | ||
| TIME_LIMIT = "02:00:00" | ||
| DB_DIR = "$HOME/GMemory/.db-calibration" | ||
|
|
||
| # Tasks whose full budget will not calibrate inside that window, and the smaller | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is way too much info, you should /caveman just 1 or 2 lines here
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cut to two: # Jericho's prompt tokens grow with the square of its 100-trial budget, so 20
# tasks would be ~288M tokens - an 18-hour job. Five at 20 trials is ~8M.
OVERRIDES = {"jericho": {"max_tasks": 5, "max_trials": 20}}The curve it was quoting is in |
||
| # shakedown that will. Jericho runs 100 trials rather than 30 and its prompt | ||
| # tokens grow with the square of the budget - about 1.44M per task by the curve | ||
| # in data/data.md, so twenty tasks over ten arms is ~288M tokens, an 18-hour job | ||
| # at the throughput the other calibrations measured. Cut to the 2-hour window it | ||
| # would report a tenth of its arms and nothing about the rest, which reads as an | ||
| # arm that failed rather than one that never ran. Five tasks at 20 trials is | ||
| # ~8M tokens and answers what a calibration of Jericho can: whether it runs. | ||
| # Sizing its real job needs a job of its own. | ||
| OVERRIDES = {"jericho": {"max_tasks": 5, "max_trials": 20}} | ||
|
|
||
| SUMMARY = """ | ||
|
|
||
| echo "==== calibration ====" | ||
| column -s, -t < ${DB_DIR}/overall_results.csv | ||
|
|
||
| python3 -c ' | ||
| import csv, sys | ||
| rows = list(csv.DictReader(open(sys.argv[1]))) | ||
| tokens = sum(int(r["completion_tokens"]) + int(r["prompt_tokens"]) for r in rows) | ||
| scored = sum(int(r["tasks_scored"]) for r in rows) | ||
| print(f"{len(rows)} arms, {scored} tasks scored, {tokens:,} tokens") | ||
| print(f"{tokens/max(scored, 1):,.0f} tokens per task") | ||
| ' ${DB_DIR}/overall_results.csv | ||
|
|
||
| cat ${DB_DIR}/*/*/*/*/failed_tasks.csv 2>/dev/null | ||
| """ | ||
|
|
||
|
|
||
| def scope_flags(task: str) -> str: | ||
| overrides = OVERRIDES.get(task, {}) | ||
| flags = f"\n\t--max_tasks {overrides.get('max_tasks', MAX_TASKS)} \\" | ||
| if "max_trials" in overrides: | ||
| flags += f"\n\t--max_trials {overrides['max_trials']} \\" | ||
| return flags | ||
|
|
||
|
|
||
| def render(task: str) -> str: | ||
| return ( | ||
| preamble( | ||
| f"vllm-{task}-calibrate", | ||
| f"out/{task}-calibrate-%x.%j.%t.out", | ||
| f"{task}_calibrate.sh", | ||
| time_limit=TIME_LIMIT, | ||
| db_dir=DB_DIR, | ||
| ) | ||
| + "\n" | ||
| + run_command( | ||
| task, | ||
| every_arm(task), | ||
| cross_task=False, | ||
| seeds=SEEDS_CALIBRATED, | ||
| scope=scope_flags(task), | ||
| ) | ||
| + SUMMARY | ||
| + CLEANUP | ||
| ) | ||
|
|
||
|
|
||
| def main() -> None: | ||
| parser = argparse.ArgumentParser(description=__doc__) | ||
| parser.add_argument( | ||
| "--task", | ||
| nargs="+", | ||
| choices=TASKS, | ||
| default=TASKS, | ||
| help="the datasets to calibrate (default: all of them)", | ||
| ) | ||
| for task in parser.parse_args().task: | ||
| write_script(f"{task}_calibrate.sh", render(task)) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should separate the calibrate generation to a separate python file to keep the two clean
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done — It holds what a calibration is: one seed, the twenty-task cap, the 2-hour window, Jericho's smaller shakedown and the summary the job prints. uv run slurm/generate_calibration.py # every dataset
uv run slurm/generate_calibration.py --task fever pddlAlso merged |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should make all these args with defaults so they can be changed easily when running the script
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done —
--seed,--max_tasks,--max_trials,--time_limitand--db_dir, each defaulting to what the constant held:--max_trialsis new — it was only reachable before through the per-dataset table. A flag given on the command line beats that table, so--max_tasks 30means 30 for Jericho too, rather than its entry holding it to 5.Generating with no flags writes byte-identical scripts to the ones the constants wrote.