blob: 7402111fa3ddaf8476bc90ec2cf2a1c6a7a31ea1 (
plain)
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
|
#!/usr/bin/env bash
# One-click ZBP scaling ladder. Clone -> ./scripts/run_ladder.sh (run on the H200 node, nohup-able)
#
# Configurable via env vars (defaults in brackets):
# SIZES="s60 m124 l350" model configs from configs/model/ [s60 m124 l350]
# ARMS="bp zbp_n16 zbp_n64" train configs from configs/train/ [bp zbp_n16 zbp_n64]
# NPROC=8 GPUs per run [auto: nvidia-smi -L]
# TOKENS=2e9 override token budget per run [per train config]
# DATA=data/fineweb token shards (prepared if missing) [data/fineweb]
# PREP_TOKENS=3e9 tokens to tokenize if DATA missing [3e9]
# OUT=runs output root [runs]
# MICRO_BS=8 per-GPU micro batch [8]
# SET="k=v k2=v2" extra --set overrides for every run (e.g. vocab=8192 seq_len=256)
# DRY=1 print the plan and exit
# PUSH_RESULTS=0 skip the auto collect + git-push of results JSONL [on]
# HF_UPLOAD=1 [HF_CKPT=1] also upload to a private HF repo (needs HF_TOKEN; see README)
#
# Runs are sequential (each takes the whole node), resume-safe: a finished run leaves OUT/<name>/DONE
# and is skipped on re-invocation, so the script can be re-run after interruptions.
set -euo pipefail
cd "$(dirname "$0")/.."
SIZES=${SIZES:-"s60 m124 l350"}
ARMS=${ARMS:-"bp zbp_n16 zbp_n64"}
NPROC=${NPROC:-$(nvidia-smi -L 2>/dev/null | wc -l)}
DATA=${DATA:-data/fineweb}
PREP_TOKENS=${PREP_TOKENS:-3e9}
OUT=${OUT:-runs}
MICRO_BS=${MICRO_BS:-8}
EXTRA="--set ${TOKENS:+tokens=$TOKENS} ${SET:-}"
[ "$EXTRA" = "--set " ] && EXTRA=""
echo "== zbp-scaling ladder: sizes=[$SIZES] arms=[$ARMS] nproc=$NPROC data=$DATA out=$OUT ${TOKENS:+tokens=$TOKENS}"
[ "$NPROC" -ge 1 ] || { echo "no GPUs detected; set NPROC"; exit 1; }
# --- environment bootstrap: current env first; VENV=1 creates ./.venv (fresh nodes) ---
PY=${PY:-python3}
if [ "${VENV:-0}" = 1 ]; then
[ -d .venv ] || "$PY" -m venv .venv
. .venv/bin/activate
fi
python -c "import zbp_scaling" 2>/dev/null || pip install -e . -q || {
echo "pip install failed; on managed nodes run with VENV=1 (creates ./.venv) or install into your conda env"; exit 1; }
python scripts/env_check.py || exit 1
if [ ! -f "$DATA/train.bin" ]; then
echo "== preparing data ($PREP_TOKENS tokens -> $DATA) — run this on the training node"
[ "${DRY:-0}" = 1 ] || python scripts/prepare_data.py --tokens "$PREP_TOKENS" --out "$DATA"
fi
for size in $SIZES; do
for arm in $ARMS; do
[ -f "configs/model/$size.yaml" ] || { echo "missing configs/model/$size.yaml"; exit 1; }
[ -f "configs/train/$arm.yaml" ] || { echo "missing configs/train/$arm.yaml"; exit 1; }
name="${size}_${arm}"
dir="$OUT/$name"
if [ -f "$dir/DONE" ]; then echo "== skip $name (done)"; continue; fi
echo "== run $name (model=configs/model/$size.yaml train=configs/train/$arm.yaml)"
[ "${DRY:-0}" = 1 ] && continue
mkdir -p "$dir"
if [ "$NPROC" -gt 1 ]; then
torchrun --standalone --nproc_per_node="$NPROC" scripts/train.py \
--model "configs/model/$size.yaml" --train "configs/train/$arm.yaml" \
--data "$DATA" --out "$dir" --micro_bs "$MICRO_BS" $EXTRA 2>&1 | tee -a "$dir/stdout.log"
else
python scripts/train.py --model "configs/model/$size.yaml" --train "configs/train/$arm.yaml" \
--data "$DATA" --out "$dir" --micro_bs "$MICRO_BS" $EXTRA 2>&1 | tee -a "$dir/stdout.log"
fi
touch "$dir/DONE"
done
done
TAG=${HF_TAG:-$(hostname)-$(date +%Y%m%d)}
if [ "${PUSH_RESULTS:-1}" = 1 ] && [ "${DRY:-0}" != 1 ]; then
# zero-token default: collect the small JSONL results and push them back over this clone's git auth
if python scripts/collect.py --runs "$OUT" --out "results/$TAG"; then
git add results
git -c user.email=ladder@zbp -c user.name=ladder commit -m "results: $TAG" || true # nothing new is fine
git push || echo "!! git push failed — push manually later or send results/$TAG"
else
echo "!! collect found no finished runs — skipping push"
fi
fi
if [ "${HF_UPLOAD:-0}" = 1 ]; then
# optional direct-to-HF (needs HF_TOKEN in the environment; see README Security)
python scripts/collect.py --runs "$OUT" --out "results/$TAG"
python scripts/upload_hf.py --results "results/$TAG" ${HF_REPO:+--repo "$HF_REPO"} ${HF_CKPT:+--with-ckpt "$OUT"}
fi
echo "== ladder complete: $OUT"
|