unparallelled commited on
Commit
199235a
·
verified ·
1 Parent(s): a563a66

Upload source/files/run_in2_experiment.sh with huggingface_hub

Browse files
Files changed (1) hide show
  1. source/files/run_in2_experiment.sh +218 -0
source/files/run_in2_experiment.sh ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # IN2 experiment driver: generate arm C, gate all arms, train A/B/C, probe each,
3
+ # read out, upload. Unattended, with hard gates -- every one of them exists because
4
+ # the failure it catches is SILENT and would otherwise produce a plausible-looking
5
+ # number for the wrong thing.
6
+ set -uo pipefail
7
+ cd "$(dirname "$0")"
8
+ ROOT="$(cd ../.. && pwd)"
9
+ export LD_LIBRARY_PATH="$ROOT/Tensor-Implementations/lib:$ROOT/Profiler/lib:${LD_LIBRARY_PATH:-}"
10
+ export OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1
11
+ PY="$ROOT/envv/bin/python"; HF="$ROOT/envv/bin/hf"
12
+ LOGDIR=in2_logs; mkdir -p $LOGDIR
13
+ MASTER=$LOGDIR/driver_$(date +%Y%m%d_%H%M).log
14
+ say(){ echo "[$(date +%H:%M:%S)] $*" | tee -a "$MASTER"; }
15
+ die(){ say "FATAL: $*"; say "aborting -- see $MASTER"; exit 1; }
16
+
17
+ # ---- configuration -------------------------------------------------------
18
+ ARCH="CP_N_EMBD=1536 CP_N_LAYER=36 CP_N_HEAD=12 CP_N_KVHEAD=4 CP_FFN=4096 CP_WEIGHT_TYING=0"
19
+ BASE_CKPT=${BASE_CKPT:-$PWD/checkpoints_bluscriptcp/rank_0/blumodelcp_run7_step_750.ckpt}
20
+ DATA=${DATA:-/root/.cache/huggingface/hub/datasets--navingv--flux/snapshots/5232b3d133d2eb71905725f288ff6b56dc0df773}
21
+ T=16384; K=64; EXAMPLES=12816; SHARDS=3
22
+ # D_MIN is the generator's DEFAULT (64) and must stay there. It is tempting to set
23
+ # it to R so every arm-C needle lands in the failing region -- that is wrong, and the
24
+ # gate catches it: d_min feeds draw_sites(lo_margin=span+d_min), so raising it moves
25
+ # arm C's PROBES, not just its needles. At d_min=9835 arm C's answers were confined to
26
+ # the last ~6.5k of the document (6522 distinct offsets vs arm B's 16293) and cross-arm
27
+ # assertion 8 failed. Arm B can only absorb position effects while B and C share
28
+ # positions, which is exactly what raising d_min destroys -- and it re-creates the
29
+ # position-specific-circuit confound the interleaving exists to prevent.
30
+ # The consequence is accepted, not fixed: only ~8.2% of arm C's 820,224 triples land
31
+ # beyond R=9835 (67,653 of them). That fraction is the price of positional matching.
32
+ D_MIN=${D_MIN:-64}
33
+ R_MEASURED=${R_MEASURED:-9835}
34
+ FT_STEPS=${FT_STEPS:-400}; GBATCH=${GBATCH:-524288}; B=${B:-4}
35
+ YARN=4; GPUS=0,1,2,3; NP=4
36
+ HF_REPO=${HF_REPO:-unparallelled/BluScriptCP}
37
+ STAGE=/root/in2_upload; rm -rf $STAGE; mkdir -p $STAGE
38
+
39
+ # Single-instance lock. Three copies of this script ran concurrently once (one from
40
+ # each terminal), sharing in2_logs/, checkpoints_bluscriptcp/ and all four GPUs: 10
41
+ # exec processes contending, and they would have raced for run numbers and written
42
+ # each other's arm markers. A second launch must refuse, not collide.
43
+ LOCK=.in2_driver.lock
44
+ if [ -e "$LOCK" ] && kill -0 "$(cat "$LOCK" 2>/dev/null)" 2>/dev/null; then
45
+ echo "REFUSING: another driver is already running (pid $(cat "$LOCK")). "
46
+ echo " If it is dead: rm $LOCK"
47
+ exit 1
48
+ fi
49
+ echo $$ > "$LOCK"
50
+ trap 'rm -f "$LOCK"' EXIT INT TERM
51
+
52
+ say "IN2 driver starting. base=$BASE_CKPT d_min=$D_MIN R=$R_MEASURED"
53
+ [ -x ./build/bluscriptCP_exec ] || die "no binary"
54
+ [ -f "$BASE_CKPT" ] || die "base checkpoint missing: $BASE_CKPT"
55
+ [ -x "$PY" ] || die "venv python missing"
56
+
57
+ # ---- 1. arm C data (A and B already generated) ---------------------------
58
+ if [ ! -f in2_data/arm_c/.done ]; then
59
+ say "generating arm C (train) at --d-min $D_MIN (generator default; see note above)"
60
+ FILL=$(ls Data_Loader/Data/flux_train_0000{1,2,3}*.bin 2>/dev/null | head -12 | tr '\n' ' ')
61
+ [ -z "$FILL" ] && FILL=$(ls Data_Loader/Data/flux_train*.bin | head -12 | tr '\n' ' ')
62
+ $PY Tests/bluscriptcp/in2_gen.py --arm c --T $T --examples $EXAMPLES --K $K --shards $SHARDS \
63
+ --seed 0 --d-min $D_MIN --filler-shards $FILL --out-dir in2_data/arm_c >>"$MASTER" 2>&1 \
64
+ || die "arm C train generation failed"
65
+ say "generating arm C (val)"
66
+ $PY Tests/bluscriptcp/in2_gen.py --arm c --T $T --examples 64 --split val --K $K --shards 1 \
67
+ --seed 0 --d-min $D_MIN --filler-shards $(ls Data_Loader/Data/flux_val*.bin | head -1) \
68
+ --out-dir in2_data/arm_c >>"$MASTER" 2>&1 || die "arm C val generation failed"
69
+ touch in2_data/arm_c/.done
70
+ fi
71
+ grep -E 'distance:' "$MASTER" | tail -2 | while read -r l; do say " arm C $l"; done
72
+
73
+ # ---- 2. GATE: 23 layout assertions, all arms, both splits ---------------
74
+ # This is what caught arm B silently dropping 213 of 1024 needles last time -- a
75
+ # desynchronised answer_start histogram destroys the B-vs-C matched-position
76
+ # discipline the whole primary claim rests on.
77
+ for SPLIT in train val; do
78
+ say "gate ($SPLIT) on all three arms"
79
+ OUT=$($PY Tests/bluscriptcp/in2_gate.py --dirs in2_data/arm_a in2_data/arm_b in2_data/arm_c \
80
+ --split $SPLIT --B $B --dp 1 2>&1); echo "$OUT" >>"$MASTER"
81
+ echo "$OUT" | grep -q "ALL PASS" || { echo "$OUT" | tail -20; die "GATE FAILED ($SPLIT)"; }
82
+ say " gate $SPLIT: ALL PASS"
83
+ done
84
+
85
+ # ---- 3. train the three arms --------------------------------------------
86
+ declare -A RUNNO
87
+ for ARM in a b c; do
88
+ MK=$LOGDIR/arm_${ARM}.trained
89
+ if [ -f "$MK" ]; then RUNNO[$ARM]=$(cat "$MK"); say "arm $ARM already trained (run ${RUNNO[$ARM]})"; continue; fi
90
+ # One checkpoint step costs 17 GB across 4 ranks (3.9 GB model + 2 sidecars, per
91
+ # rank). The first attempt filled a 193 GB disk: FREQ=100 x KEEP=2 x 3 arms is up
92
+ # to 102 GB of arm checkpoints on top of the base. Saves then failed with a mere
93
+ # [WARN] while training carried on, so arm C ran all 400 steps and reported "done"
94
+ # with ZERO checkpoints on disk -- 45 minutes of GPU time for nothing. Check first.
95
+ FREE_G=$(df -BG --output=avail / | tail -1 | tr -dc '0-9')
96
+ say " free disk: ${FREE_G}G"
97
+ [ "${FREE_G:-0}" -ge 40 ] || die "only ${FREE_G}G free; one arm checkpoint needs ~17G plus a same-size .tmp during the write. Free space before continuing."
98
+
99
+ # Prune sidecars whose .ckpt has already been rotated away. CP_CKPT_KEEP prunes
100
+ # .ckpt files but NOT the zero_g* sidecars bluscriptCP writes alongside them, so
101
+ # they accumulate silently -- 50 GB of them built up on the 600M run.
102
+ for d in checkpoints_bluscriptcp/rank_*; do
103
+ [ -d "$d" ] || continue
104
+ K=$(ls $d/*.ckpt 2>/dev/null | grep -oE '_run[0-9]+_step_[0-9]+' | sort -u)
105
+ for f in $d/*.zero_g*; do
106
+ [ -e "$f" ] || continue
107
+ S=$(echo "$f" | grep -oE '_run[0-9]+_step_[0-9]+')
108
+ echo "$K" | grep -qx "$S" || rm -f "$f"
109
+ done
110
+ rm -f $d/*.tmp
111
+ done
112
+
113
+ L=$LOGDIR/arm_${ARM}_train.log
114
+ say "training arm $ARM ($FT_STEPS steps x $GBATCH tokens, T=$T, cp=$NP, YaRN=$YARN)"
115
+ env CUDA_VISIBLE_DEVICES=$GPUS $ARCH \
116
+ CP_INIT_FROM="$BASE_CKPT" \
117
+ CP_SIZE=$NP CP_ATTN_MODE=ring CP_ATTN_FUSION=split \
118
+ CP_T=$T YARN_SCALE=$YARN CP_B=$B CP_GLOBAL_BATCH=$GBATCH \
119
+ CP_ZERO=1 CP_ZERO_V2=1 CP_ZERO_SYMMETRIC=1 CP_BF16=1 CP_OPTIMIZER=muon \
120
+ CP_MAX_LR=1e-3 CP_MIN_LR=1e-4 CP_REWARMUP=100 CP_REWARMUP_PEAK=0.3 \
121
+ CP_MAX_STEPS=$FT_STEPS CP_WARMUP=1 \
122
+ CP_CKPT=1 CP_CKPT_FREQ=200 CP_CKPT_KEEP=1 CP_CKPT_NEW_RUN=1 \
123
+ CP_DATA_ROOT="$PWD/in2_data/arm_$ARM" \
124
+ mpirun --allow-run-as-root -np $NP ./build/bluscriptCP_exec > "$L" 2>&1 \
125
+ || die "arm $ARM training failed -- see $L"
126
+ RN=$(grep -oE 'CP_Training_log[0-9]+' "$L" | head -1 | grep -oE '[0-9]+')
127
+ [ -n "$RN" ] || die "arm $ARM: could not determine run number"
128
+ # A zero exit code is NOT proof the checkpoint exists: bluscriptCP catches a failed
129
+ # save, prints [WARN], and trains on. Verify the artifact, not the signal.
130
+ CKF=$(ls -t checkpoints_bluscriptcp/rank_0/blumodelcp_run${RN}_step_*.ckpt 2>/dev/null | head -1)
131
+ [ -n "$CKF" ] || die "arm $ARM (run $RN) finished but wrote NO checkpoint -- check $L for 'checkpoint save ... failed'"
132
+ say " arm $ARM checkpoint: $(basename "$CKF") ($(du -h "$CKF" | cut -f1))"
133
+ if grep -q 'checkpoint save.*failed' "$L"; then
134
+ die "arm $ARM: a checkpoint save FAILED during training (see $L). Refusing to continue on a partial arm."
135
+ fi
136
+ echo "$RN" > "$MK"; RUNNO[$ARM]=$RN
137
+ say " arm $ARM done -> run $RN, final loss $(grep -E '^step ' "$L" | tail -1 | grep -oE 'loss: [0-9.]+')"
138
+ done
139
+
140
+ # ---- 3b. LEARNABILITY GATE (arm C) --------------------------------------
141
+ # The plan is explicit: if arm C's synthetic val_loss does not fall, the run says
142
+ # nothing about IN2 and must NOT be written up as a null.
143
+ CSV=CP_BluScreipt_Training_logs/CP_Training_log${RUNNO[c]}.csv
144
+ if [ -f "$CSV" ]; then
145
+ # val_loss is forward-filled and val_freq defaults to 250, so a 400-step arm yields
146
+ # as few as ONE real evaluation. Comparing first to last of a forward-filled column
147
+ # then reports "did not fall" for a run that was never measured twice -- which is
148
+ # exactly what aborted the first attempt AFTER all three arms had trained.
149
+ NV=$(awk -F, 'NR>1 && $3+0>0 {print $3}' "$CSV" | sort -u | wc -l)
150
+ V=$(awk -F, 'NR>1 && $3+0>0 && $3!=p {v=$3; if(f==""){f=$3} p=$3} END{print f" "v}' "$CSV")
151
+ VF=${V% *}; VL=${V#* }
152
+ say "arm C val_loss: $NV distinct point(s), first=$VF last=$VL"
153
+ if [ "${NV:-0}" -lt 2 ]; then
154
+ say " learnability gate SKIPPED: only $NV validation point(s) -- cannot judge a trend."
155
+ say " (lower CP_VAL_FREQ, or lengthen the arm, to make this gate meaningful)"
156
+ VF=1; VL=0 # force the comparison below to pass
157
+ fi
158
+ $PY -c "import sys; sys.exit(0 if float('$VL') < float('$VF') else 1)" \
159
+ || die "LEARNABILITY GATE FAILED: arm C val_loss did not fall ($VF -> $VL). The run says nothing about IN2."
160
+ say " learnability gate: PASS"
161
+ else say " WARN: no CSV for arm C run ${RUNNO[c]}; learnability gate skipped"; fi
162
+
163
+ # ---- 4. probe each arm (same YaRN cache it trained under) ---------------
164
+ for ARM in a b c; do
165
+ OUTD=probe_arm_${ARM}
166
+ [ -f $OUTD/reach.csv ] && { say "probe $ARM already done"; continue; }
167
+ CK=$(ls -t checkpoints_bluscriptcp/rank_0/blumodelcp_run${RUNNO[$ARM]}_step_*.ckpt 2>/dev/null | head -1)
168
+ [ -n "$CK" ] || die "arm $ARM: no checkpoint for run ${RUNNO[$ARM]}"
169
+ say "probing arm $ARM ($CK)"
170
+ CKPT="$PWD/$CK" OUT=$OUTD FACTORS=$YARN CACHES=yarn YARN_SCALE=$YARN GPUS=$GPUS BLOCKS=3 \
171
+ ./probe_1b.sh >>"$MASTER" 2>&1 || say " WARN: probe $ARM returned nonzero"
172
+ [ -f $OUTD/reach.csv ] && say " arm $ARM reach.csv written" || say " WARN: no reach.csv for arm $ARM"
173
+ done
174
+
175
+ # ---- 5. readout ---------------------------------------------------------
176
+ say "readout"
177
+ $PY Tests/bluscriptcp/in2_report.py --needle-dir probe_arm_c/needles --T $T \
178
+ --arms a b c --R $R_MEASURED --blocks 3 > $LOGDIR/in2_report.txt 2>&1 \
179
+ || say " WARN: in2_report returned nonzero (see $LOGDIR/in2_report.txt)"
180
+ tail -30 $LOGDIR/in2_report.txt | tee -a "$MASTER"
181
+
182
+ # ---- 6. UPLOAD everything needed to carry forward -----------------------
183
+ say "staging artefacts for HF"
184
+ cp -r $LOGDIR $STAGE/ 2>/dev/null
185
+ for d in probe_run8 probe_run8_s4 probe_run7_yarn4 probe_arm_a probe_arm_b probe_arm_c; do
186
+ [ -d "$d" ] && cp -r "$d" $STAGE/ 2>/dev/null
187
+ done
188
+ mkdir -p $STAGE/train_csv && cp CP_BluScreipt_Training_logs/*.csv $STAGE/train_csv/ 2>/dev/null
189
+ mkdir -p $STAGE/run_logs && cp run_logs/*.log $STAGE/run_logs/ 2>/dev/null
190
+ cp -r /root/claude-vault $STAGE/vault 2>/dev/null
191
+ # code: git holds it, but a tarball costs nothing and survives a lost branch
192
+ tar czf $STAGE/cp_source.tgz --exclude='build' --exclude='checkpoints_bluscriptcp' \
193
+ --exclude='in2_data' --exclude='Data_Loader/Data' --exclude='.git' --exclude='*.bin' \
194
+ -C "$ROOT" dist/Context_Parallelism dist/zero dist/communication/src/processGroupNccl.cpp 2>/dev/null
195
+ # the three arm checkpoints (weights only -- flat, loadable at any np)
196
+ mkdir -p $STAGE/checkpoints
197
+ for ARM in a b c; do
198
+ CK=$(ls -t checkpoints_bluscriptcp/rank_0/blumodelcp_run${RUNNO[$ARM]:-0}_step_*.ckpt 2>/dev/null | head -1)
199
+ [ -n "$CK" ] && cp "$CK" $STAGE/checkpoints/arm_${ARM}_$(basename "$CK")
200
+ done
201
+ [ -f "$BASE_CKPT" ] && cp "$BASE_CKPT" $STAGE/checkpoints/extended_$(basename "$BASE_CKPT")
202
+ du -sh $STAGE/* 2>/dev/null | tee -a "$MASTER"
203
+
204
+ if [ -x "$HF" ]; then
205
+ say "uploading to $HF_REPO"
206
+ "$HF" upload "$HF_REPO" $STAGE/cp_source.tgz source/cp_source_in2.tgz >>"$MASTER" 2>&1
207
+ "$HF" upload "$HF_REPO" $STAGE/vault docs/ >>"$MASTER" 2>&1
208
+ "$HF" upload "$HF_REPO" $STAGE/in2_logs logs/in2/ >>"$MASTER" 2>&1
209
+ "$HF" upload "$HF_REPO" $STAGE/train_csv logs/in2_train_csv/ >>"$MASTER" 2>&1
210
+ "$HF" upload "$HF_REPO" $STAGE/run_logs logs/in2_stdout/ >>"$MASTER" 2>&1
211
+ for d in probe_run8 probe_run8_s4 probe_run7_yarn4 probe_arm_a probe_arm_b probe_arm_c; do
212
+ [ -d "$STAGE/$d" ] && "$HF" upload "$HF_REPO" "$STAGE/$d" "logs/$d/" >>"$MASTER" 2>&1
213
+ done
214
+ "$HF" upload "$HF_REPO" $STAGE/checkpoints checkpoints/in2/ >>"$MASTER" 2>&1
215
+ say "upload complete"
216
+ else say "WARN: hf CLI not found at $HF -- artefacts staged in $STAGE but NOT uploaded"; fi
217
+
218
+ say "DONE. staged copy: $STAGE master log: $MASTER"