Download scripts/ext64k_b5.sh from unparallelled/BluScriptCP: direct link, hf CLI and curl.
- Browser
- Download file 10.9 kB
-
https://huggingface.co/unparallelled/BluScriptCP/resolve/main/scripts/ext64k_b5.sh
- Command line
-
hf download hf://unparallelled/BluScriptCP/scripts/ext64k_b5.sh
-
curl -L -o ext64k_b5.sh https://huggingface.co/unparallelled/BluScriptCP/resolve/main/scripts/ext64k_b5.sh
10.9 kB
| # ============================================================================= | |
| # ext64k_b5.sh -- YaRN extension 32k -> 64k on b5, deadline-aware. | |
| # | |
| # PHASE 1 3-step probe: does 64k fit at cp=4 on 143 GB, and how fast is a step? | |
| # PHASE 2 train as many steps as fit before HARD_STOP, WSD tail sized so the | |
| # FINAL checkpoint is DECAYED and comparable to the 32k results | |
| # PHASE 3 eval 4 lengths IN PARALLEL on the 4 GPUs (wall clock = slowest job) | |
| # PHASE 4 upload ckpt + sidecar + logs | |
| # | |
| # WHY b5: documents are 65,536-131,072 tokens, so the MINIMUM equals the 64k | |
| # window and every training sample is one contiguous document. b4 (32-64k) | |
| # would straddle in roughly half its samples. Same reasoning that made b4 the | |
| # right choice at 32k. | |
| # | |
| # PARENT: b4 full-epoch step 2227 -- the best 32k model (70.0/58.0/43.0 at | |
| # 8k/16k/32k). CP_INIT_FROM loads WEIGHTS ONLY, so its cp=2 shard layout is | |
| # irrelevant to this cp=4 run, and no sidecar is needed (none is read). | |
| # | |
| # YaRN INVARIANT: SCALE * ORIG_MAXPOS must equal seq_len EXACTLY and ORIG_MAXPOS | |
| # must be the length the parent was actually trained at. 2 * 32768 = 65536. | |
| # | |
| # LR: CP_MAX_LR / CP_MIN_LR DO NOT EXIST -- bluscriptCP.cpp:131-132 hardcodes | |
| # 6e-4 / 6e-5 and the env block never reads them. Real schedule is | |
| # 6e-4 * CP_REWARMUP_PEAK(0.3) = 1.8e-4 peak, 6e-5 floor -- the same values | |
| # every previous run used, so results stay comparable. | |
| # | |
| # DEADLINE: HARD_STOP is a UTC epoch. Step count is derived from the MEASURED | |
| # probe rate, not an estimate, so the run lands inside the window. | |
| # ============================================================================= | |
| set -uo pipefail | |
| cd "$(dirname "$0")" | |
| ROOT="$(cd ../.. && pwd)" | |
| export LD_LIBRARY_PATH="$ROOT/Tensor-Implementations/lib:$ROOT/Profiler/lib:${LD_LIBRARY_PATH:-}" | |
| export OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 | |
| PY=/root/envv/bin/python3 | |
| HF=/root/envv/bin/hf | |
| EXE=./build/bluscriptCP_exec | |
| CK=checkpoints_bluscriptcp/rank_0 | |
| LOG=ext64k_logs; mkdir -p "$LOG" | |
| M="$LOG/master.log" | |
| REPO=unparallelled/BluScriptCP | |
| say(){ echo "[$(date -u +%H:%M:%S)] $*" | tee -a "$M" >&2; } | |
| die(){ say "FATAL: $*"; exit 1; } | |
| T=65536; NP=4; GPUS=0,1,2,3 | |
| ORIG=32768; SCALE=2 # 2 * 32768 == 65536 | |
| DATA=lendata/b5_65536_131072 | |
| PARENT="$CK/b4epoch32k_step2227.ckpt" | |
| HAY="$PWD/lendata/haystack/b2val_haystack.bin" | |
| WARM=100; TAIL=${TAIL:-2}; FREQ=50; KEEP=2 | |
| GB=524288 | |
| # 23:30 IST = 18:00 UTC today | |
| HARD_STOP=${HARD_STOP:-$(date -u -d "$(date -u +%Y-%m-%d) 18:00:00" +%s)} | |
| RESERVE_MIN=${RESERVE_MIN:-50} # eval (28) + upload (20) + slack | |
| $PY -c "import tiktoken" 2>/dev/null || die "tiktoken missing" | |
| [ -x "$EXE" ] || die "$EXE not built" | |
| [ -f "$PARENT" ] || die "parent missing: $PARENT" | |
| [ -f "$HAY" ] || die "haystack missing: $HAY" | |
| [ -d "$DATA" ] || die "$DATA missing" | |
| [ $((SCALE*ORIG)) -eq $T ] || die "YaRN invariant: $SCALE * $ORIG != $T" | |
| ntr=$(ls "$DATA"/*train*.bin 2>/dev/null | wc -l) | |
| nva=$(ls "$DATA"/*val*.bin 2>/dev/null | wc -l) | |
| [ "$ntr" -ge 1 ] && [ "$nva" -ge 1 ] || die "need train+val shards in $DATA (have $ntr/$nva)" | |
| have=$(( $(du -cb "$DATA"/*train*.bin | tail -1 | cut -f1) / 2 )) | |
| say "=== 32k -> 64k YaRN extension on b5 (4x H200, cp=$NP) ===" | |
| say "parent: b4 full epoch step 2227 (best 32k model)" | |
| say "YaRN SCALE=$SCALE ORIG=$ORIG -> $((SCALE*ORIG)) == CP_T=$T OK" | |
| say "b5: $ntr train shards = $(echo "scale=3; $have/1000000000" | bc) B tokens available" | |
| say "hard stop $(date -u -d @$HARD_STOP +%H:%M) UTC = $(date -u -d @$((HARD_STOP+19800)) +%H:%M) IST, reserving ${RESERVE_MIN}m" | |
| COMMON="CP_SIZE=$NP CP_ATTN_MODE=ring CP_ATTN_FUSION=split CP_T=$T \ | |
| YARN_SCALE=$SCALE YARN_ORIG_MAXPOS=$ORIG \ | |
| CP_ZERO=1 CP_ZERO_V2=1 CP_ZERO_SYMMETRIC=1 CP_BF16=1 CP_OPTIMIZER=muon \ | |
| CP_WARMUP=$WARM CP_REWARMUP=$WARM CP_REWARMUP_PEAK=0.3" | |
| ARCH="CP_N_EMBD=1536 CP_N_LAYER=36 CP_N_HEAD=12 CP_N_KVHEAD=4 CP_FFN=4096 CP_WEIGHT_TYING=0" | |
| # ---- PHASE 1: fit + speed -------------------------------------------------- | |
| if [ ! -f "$LOG/probe.ok" ]; then | |
| say "PHASE 1: 3-step probe (64k at cp=4 projects to 108.8 GB of 143 GB)" | |
| env $ARCH $COMMON CP_STABLE=0 CP_CKPT=0 \ | |
| CP_INIT_FROM="$PWD/$PARENT" CP_DATA_ROOT="$PWD/$DATA" \ | |
| CP_B=1 CP_GLOBAL_BATCH=65536 CP_MAX_STEPS=3 \ | |
| CUDA_VISIBLE_DEVICES=$GPUS mpirun --allow-run-as-root -np $NP "$EXE" \ | |
| > "$LOG/probe.log" 2>&1 | |
| if grep -qaiE 'out of memory|bad_alloc' "$LOG/probe.log"; then | |
| say "PROBE OOM -- 64k does not fit at cp=$NP even on 143 GB cards." | |
| grep -aoE 'cudaMallocAsync\(size=[0-9]+\) failed' "$LOG/probe.log" | head -2 | sed 's/^/ /' >&2 | |
| exit 1 | |
| fi | |
| grep -aE '^step +[0-9]+ \|' "$LOG/probe.log" | sed 's/^/ /' >&2 | |
| say "PROBE OK: peak $(grep -aoE 'mem: [0-9]+MB' "$LOG/probe.log" | tail -1)" | |
| touch "$LOG/probe.ok" | |
| fi | |
| # ---- derive the step count from the MEASURED rate -------------------------- | |
| # The probe used a tiny global batch, so its dt is NOT the real per-step cost. | |
| # Scale it: real grad_accum is GB/T vs the probe's 65536/T. | |
| SPS=$($PY - "$LOG/probe.log" $GB $T <<'PYEOF' | |
| import re,sys,statistics | |
| t=open(sys.argv[1],errors='ignore').read() | |
| d=[float(x) for x in re.findall(r'dt: ([0-9.]+)ms', t)] | |
| probe_accum=65536//int(sys.argv[3]) or 1 | |
| real_accum=int(sys.argv[2])//int(sys.argv[3]) | |
| per=statistics.median(d[1:]) if len(d)>2 else d[-1] | |
| print(f"{per/1000.0*real_accum/probe_accum:.3f}") | |
| PYEOF | |
| ) | |
| say "measured step cost at real batch: ${SPS} s/step" | |
| if [ -n "${STEPS_OVERRIDE:-}" ]; then | |
| say "STEPS_OVERRIDE=$STEPS_OVERRIDE -- the probe ran grad_accum=1 so its dt x8" | |
| say " overstated the real step cost 5.8x (74.0 vs a measured 12.85 s/step)." | |
| fi | |
| STEPS=$($PY - "$SPS" "$HARD_STOP" "$RESERVE_MIN" "$have" "$GB" "$WARM" "$TAIL" <<'PYEOF' | |
| import sys,time,math | |
| sps=float(sys.argv[1]); stop=int(sys.argv[2]); res=int(sys.argv[3]) | |
| have=int(sys.argv[4]); gb=int(sys.argv[5]); warm=int(sys.argv[6]); tail=int(sys.argv[7]) | |
| budget=stop-time.time()-res*60 | |
| n=int(budget/sps) | |
| n=min(n, have//gb) # never wrap the data | |
| n=max(n, warm+tail+10) # schedule must be legal | |
| print(n) | |
| PYEOF | |
| ) | |
| STEPS=${STEPS_OVERRIDE:-$STEPS} | |
| STABLE=$(( STEPS - WARM - TAIL )) | |
| [ "$STABLE" -lt 1 ] && STABLE=1 | |
| say "PHASE 2: $STEPS steps = $(echo "scale=3; $STEPS*$GB/1000000000" | bc) B tokens = $(echo "scale=0; $STEPS*$GB*100/866000000" | bc)% of a b5 epoch" | |
| say " WSD: warmup $WARM, stable $STABLE, decay tail $TAIL -> FINAL checkpoint IS decayed" | |
| if [ -f "$LOG/ext.ckpt" ] && [ -f "$(cat "$LOG/ext.ckpt")" ]; then | |
| say "already trained -> $(cat "$LOG/ext.ckpt")" | |
| else | |
| env $ARCH $COMMON CP_STABLE=$STABLE \ | |
| CP_CKPT=1 CP_CKPT_FREQ=$FREQ CP_CKPT_KEEP=$KEEP CP_CKPT_NEW_RUN=1 \ | |
| CP_INIT_FROM="$PWD/$PARENT" CP_DATA_ROOT="$PWD/$DATA" \ | |
| CP_B=1 CP_GLOBAL_BATCH=$GB CP_MAX_STEPS=$STEPS \ | |
| CUDA_VISIBLE_DEVICES=$GPUS mpirun --allow-run-as-root -np $NP "$EXE" \ | |
| > "$LOG/ext.log" 2>&1 | |
| grep -qaiE 'out of memory|bad_alloc' "$LOG/ext.log" && die "OOM in the full run" | |
| RN=$(grep -aoE 'CP_Training_log[0-9]+' "$LOG/ext.log" | head -1 | grep -oE '[0-9]+') | |
| [ -n "$RN" ] || die "no run number" | |
| CKF=$(ls -t $CK/blumodelcp_run${RN}_step_*.ckpt 2>/dev/null | head -1) | |
| [ -n "$CKF" ] || die "run $RN wrote NO checkpoint" | |
| n=$(ls checkpoints_bluscriptcp/rank_*/"$(basename "$CKF")" 2>/dev/null | wc -l) | |
| [ "$n" -ge "$NP" ] || die "only $n/$NP rank shards for $(basename "$CKF")" | |
| echo "$CKF" > "$LOG/ext.ckpt"; echo "$RN" > "$LOG/runnum" | |
| say "ext64k -> run $RN, $(basename "$CKF"), loss $(grep -aE '^step ' "$LOG/ext.log" | tail -1 | grep -oE 'loss: [0-9.]+')" | |
| say " peak mem $(grep -aoE 'mem: [0-9]+MB' "$LOG/ext.log" | tail -1)" | |
| say " final lr $(grep -aE '^step ' "$LOG/ext.log" | tail -1 | grep -oE 'lr [0-9.e-]+') (should be ~6e-05 = decayed)" | |
| fi | |
| # ---- PHASE 3: eval, 4 lengths in PARALLEL on 4 GPUs ------------------------ | |
| EXT=$(basename "$(cat "$LOG/ext.ckpt")") | |
| say "PHASE 3: eval ext64k -- 4 lengths, one GPU each" | |
| # 65512 + MAX_NEW 24 = 65536 exactly; 65528 would pad to 65792 and abort. | |
| for LEN in 8192 16360 32744 65512; do | |
| ( GEN_DATA_ROOT=$DATA HAY="$HAY" PY=$PY OUT=ext64k_len_$LEN TASKS="niah_single" \ | |
| CKPTS="ext64k" N=100 PROMPT_LEN=$LEN MAX_NEW=24 T=$T \ | |
| DEPTHS="0.0,0.25,0.5,0.75,1.0" YARN_ORIG=$ORIG YARN=$SCALE \ | |
| GPUS=$(( (LEN==8192)?0:(LEN==16360)?1:(LEN==32744)?2:3 )) JOBS_PER_GPU=1 \ | |
| BF16=1 GREEDY=1 CKPT_EXTRA="ext64k=$EXT" ./run_longeval.sh \ | |
| >> "$LOG/eval_$LEN.log" 2>&1 ) & | |
| done | |
| wait | |
| for LEN in 8192 16360 32744 65512; do | |
| [ -s "ext64k_len_$LEN/summary.csv" ] && say " len $LEN -> $(sed -n 2p ext64k_len_$LEN/summary.csv)" \ | |
| || say " len $LEN -> NO RESULT" | |
| done | |
| # ---- PHASE 4: upload ------------------------------------------------------- | |
| say "PHASE 4: upload" | |
| { | |
| echo "# 32k -> 64k YaRN extension on b5 -- $(date -u +%Y-%m-%d)" | |
| echo | |
| echo "Parent: b4 full-epoch step 2227 (best 32k model: 70.0/58.0/43.0 at 8k/16k/32k)." | |
| echo "Data: b5_65536_131072 -- min doc 65,536 == the window, so every sample is" | |
| echo " ONE contiguous document." | |
| echo "YaRN: SCALE=2 ORIG_MAXPOS=32768 -> 65536 exactly." | |
| echo "Train: $STEPS steps x $GB = $(echo "scale=3; $STEPS*$GB/1000000000" | bc) B tokens" | |
| echo " = $(echo "scale=0; $STEPS*$GB*100/866000000" | bc)% of b5's 0.866 B train split (no wrap)." | |
| echo " WSD warmup $WARM / stable $STABLE / decay tail $TAIL -- final ckpt DECAYED." | |
| echo " LR peak 1.8e-4, floor 6e-5 (CP_MAX_LR is a no-op; see B4 results doc)." | |
| echo " 4x H200, cp=4, B=1 x grad_accum $((GB/T))." | |
| echo "Eval: niah_single, N=100, greedy, shared haystack b2_8192_16384 val." | |
| echo | |
| echo "## Results"; echo | |
| echo "| context | niah_single |"; echo "|---|---|" | |
| for LEN in 8192 16360 32744 65512; do | |
| v=$(sed -n 2p "ext64k_len_$LEN/summary.csv" 2>/dev/null | cut -d, -f2) | |
| printf "| %s | %s |\n" "$LEN" "${v:-n/a}" | |
| done | |
| echo | |
| echo "For comparison, the 32k parent at the same lengths: 70.0 / 58.0 / 43.0 / n/a" | |
| echo "(it cannot run at 64k -- its RoPE cache is sized 32,768)." | |
| echo | |
| echo "NOTE: this is a PARTIAL b5 epoch, sized to a wall-clock deadline. It is a" | |
| echo "first 64k data point, not a converged extension." | |
| } > "$LOG/RESULTS.md" | |
| up(){ [ -e "$1" ] || return 0 | |
| $HF upload "$REPO" "$1" "$2" >>"$LOG/upload.log" 2>&1 && say " ok $2" || say " FAIL $2"; } | |
| up "$LOG/RESULTS.md" docs/EXT64K_B5_RESULTS_$(date -u +%Y-%m-%d).md | |
| for LEN in 8192 16360 32744 65512; do up "ext64k_len_$LEN" "logs/ext64k_len_$LEN/"; done | |
| up "$LOG" logs/ext64k/ | |
| up ext64k_b5.sh scripts/ext64k_b5.sh | |
| RN=$(cat "$LOG/runnum" 2>/dev/null) | |
| for r in 0 1 2 3; do | |
| for e in ckpt zero_g1; do | |
| up "checkpoints_bluscriptcp/rank_$r/blumodelcp_run${RN}_step_${STEPS}.$e" \ | |
| "checkpoints/ext64k_b5_rank${r}_step_${STEPS}.$e" | |
| done | |
| done | |
| say "=== EXT64K DONE ===" | |