ATOM (atom-ai): code snapshot (100fae0 + batched-train), README with measured numbers, curated checkpoints (part 4)
b9301f1 verified Download scripts/train_fieldsat_branch.sh from thefinalboss/atom-ai: direct link, hf CLI and curl.
- Browser
- Download file 8.48 kB
-
https://huggingface.co/thefinalboss/atom-ai/resolve/main/scripts/train_fieldsat_branch.sh
- Command line
-
hf download hf://thefinalboss/atom-ai/scripts/train_fieldsat_branch.sh
-
curl -L -o train_fieldsat_branch.sh https://huggingface.co/thefinalboss/atom-ai/resolve/main/scripts/train_fieldsat_branch.sh
8.48 kB
| # Resumable driver for the field-leak branch (docs/FIELD_SATURATION.md). | |
| # | |
| # Continues the fieldsat branch in 8k chunks with the exact live recipe from | |
| # scripts/train_until_coherent.sh + --last-atom-dropout 0.5 + --field-leak 0.3. | |
| # Each chunk saves checkpoints/byte_tick_fieldsat/atom_native_step_<END>_d32_ms1M_lrd_b4828_fieldsat.pt, | |
| # so the run can be resumed or switched at any chunk boundary. Re-running the | |
| # script resumes from the newest existing branch checkpoint in [START_STEP, END_TARGET] | |
| # (an interrupted chunk is simply re-run) and measures any checkpoint that has no | |
| # row in docs/artifacts/field_saturation/branch_progress.tsv yet. | |
| # | |
| # Env: | |
| # THREADS=1 OMP/MKL threads for every python step (8 only when the live loop is stopped) | |
| # YIELD=1 1 = SIGSTOP this whole process group while the live b4828 chunk is in its | |
| # multi-threaded phase (docs/artifacts/field_saturation/yield_to_live.py); | |
| # requires launching via setsid (own process group). 0 = never pause. | |
| # START_STEP=4876000 END_TARGET=4916000 CHUNK=8000 | |
| # LR=1.5e-5 SLR=3.6e-5 LEAK=0.3 LADROP=0.5 | |
| # | |
| # Launch (background, own process group): | |
| # setsid nohup env THREADS=1 YIELD=1 bash scripts/train_fieldsat_branch.sh \ | |
| # >> logs/fieldsat_branch_master.log 2>&1 < /dev/null & | |
| # Stop cleanly (group may be SIGSTOPped, so CONT after TERM): | |
| # PG=$(cat logs/fieldsat/branch.pgid); kill -TERM -- -$PG; kill -CONT -- -$PG | |
| set -u | |
| cd /workspace/exports/atom-ai | |
| THREADS=${THREADS:-1} | |
| YIELD=${YIELD:-1} | |
| START_STEP=${START_STEP:-4876000} | |
| END_TARGET=${END_TARGET:-4916000} | |
| CHUNK=${CHUNK:-8000} | |
| LR=${LR:-1.5e-5} | |
| SLR=${SLR:-3.6e-5} | |
| LEAK=${LEAK:-0.3} | |
| LADROP=${LADROP:-0.5} | |
| BASE=496000 | |
| OUT=checkpoints/byte_tick_fieldsat | |
| SUF=d32_ms1M_lrd_b4828_fieldsat | |
| A=docs/artifacts/field_saturation | |
| AB=$A/branch | |
| TSV=$A/branch_progress.tsv | |
| LOGD=logs/fieldsat/branch | |
| RING=$OUT/val_ring_4876000.pt # fixed 256-transition stream-ring val (same window as the probe table) | |
| PY=.venv/bin/python | |
| export PYTHONPATH=. OMP_NUM_THREADS=$THREADS MKL_NUM_THREADS=$THREADS OPENBLAS_NUM_THREADS=$THREADS | |
| mkdir -p "$OUT" "$AB" "$LOGD" logs/fieldsat | |
| ts() { date -Is; } | |
| exec 9>logs/fieldsat/branch.lock | |
| if ! flock -n 9; then echo "$(ts) another train_fieldsat_branch.sh holds logs/fieldsat/branch.lock; exiting"; exit 1; fi | |
| PG=$(ps -o pgid= -p $$ | tr -d ' ') | |
| echo "$PG" > logs/fieldsat/branch.pgid | |
| echo "=== $(ts) fieldsat branch driver pid=$$ pgid=$PG THREADS=$THREADS YIELD=$YIELD START_STEP=$START_STEP END_TARGET=$END_TARGET CHUNK=$CHUNK LR=$LR SLR=$SLR LEAK=$LEAK LADROP=$LADROP ===" | |
| if [ "$YIELD" = "1" ]; then | |
| if [ "$PG" != "$$" ]; then | |
| echo "$(ts) YIELD=1 needs its own process group: launch with setsid (see header). exiting"; exit 1 | |
| fi | |
| # Helper in its own session (so it never stops itself); pauses/resumes only our pgid. | |
| setsid "$PY" "$A/yield_to_live.py" logs/fieldsat/branch.pgid 9>&- \ | |
| >> logs/fieldsat/branch_yield.err 2>&1 < /dev/null & | |
| echo "$(ts) yield helper pid=$! watching pgid=$PG" | |
| fi | |
| latest() { | |
| ls "$OUT"/atom_native_step_*_${SUF}.pt 2>/dev/null \ | |
| | sed -n 's/.*step_\([0-9]*\)_.*/\1/p' | sort -n \ | |
| | awk -v lo="$START_STEP" -v hi="$END_TARGET" '$1>=lo && $1<=hi' | tail -1 | |
| } | |
| has_row() { [ -f "$TSV" ] && awk -F'\t' -v s="$1" 'NR>1 && $1==s {f=1} END {exit !f}' "$TSV"; } | |
| measure() { | |
| local END=$1 CK="$OUT/atom_native_step_$1_${SUF}.pt" ML="$LOGD/measure_$1.log" | |
| echo "$(ts) measure $END start" | |
| "$PY" -u tools/eval_last_atom_ablation.py --end-steps 4876000 --ring-cache "$RING" \ | |
| --checkpoints "$CK" --out "$AB/val_ablation_$END.json" >> "$ML" 2>&1 | |
| "$PY" -u tools/diag_field_saturation.py --checkpoints "b$END=$CK" --episode-ticks 8000 \ | |
| --prefixes 3000 --probe --out "$AB/diag_$END.json" >> "$ML" 2>&1 | |
| local G="$AB/gen_coherent_$END.txt"; : > "$G" | |
| for p in "Bonjour, comment ça va ?" "Qui es-tu ?" "Il était une fois"; do | |
| RESP=$("$PY" tools/chat_atom_native.py --checkpoint "$CK" --prompt "$p" --no-role-prime \ | |
| --max-packets 96 --max-length 100 --temperature 0.8 --top-k 12 2>/dev/null | sed -n 's/^Response: //p' | head -1) | |
| echo "PROMPT: $p" >> "$G"; echo "RESP: $RESP" >> "$G" | |
| done | |
| "$PY" - "$END" "$CK" "$TSV" "$AB" "$OUT/run_metrics_${END}_${SUF}.json" <<'PYEOF' | |
| import json, os, sys | |
| end, ck, tsv, ab, rm_path = sys.argv[1:6] | |
| def load(p): | |
| try: | |
| return json.load(open(p)) | |
| except Exception: | |
| return {} | |
| rm = load(rm_path); tr = rm.get("train", {}); va = rm.get("validation", {}) | |
| ev = load(f"{ab}/val_ablation_{end}.json") | |
| ring = next(iter(ev.get("rings", {}).values()), {}).get("checkpoints", {}).get(ck, {}) | |
| dg = (load(f"{ab}/diag_{end}.json").get("rows") or [{}])[0] | |
| fork = (dg.get("shared_prefix_forks") or {}).get("3000", {}) | |
| chats = [] | |
| try: | |
| for line in open(f"{ab}/gen_coherent_{end}.txt", encoding="utf-8"): | |
| if line.startswith("RESP: "): | |
| chats.append(" ".join(line[6:].split())[:80].replace("\t", " ")) | |
| except FileNotFoundError: | |
| pass | |
| def f(x, n=4): | |
| return "" if x is None or x == "" else (f"{x:.{n}f}" if isinstance(x, (int, float)) else str(x)) | |
| cols = [ | |
| ("end_step", end), | |
| ("chunk_val_loss_own_ring", f(va.get("loss"))), | |
| ("val_loss_fixed_ring", f(ring.get("normal", {}).get("loss"))), | |
| ("val_byte_ce_fixed_ring", f(ring.get("normal", {}).get("byte_loss"))), | |
| ("field_alone_byte_ce", f(ring.get("la_zeroed", {}).get("byte_loss"))), | |
| ("a_hat_linear_next_byte_ce", f((dg.get("probe_next_byte_from_a_hat") or {}).get("test_ce"), 3)), | |
| ("train_frac_at_cap", f(tr.get("field_limited_fraction"), 3)), | |
| ("diag_frac_at_cap", f(dg.get("frac_at_cap"), 3)), | |
| ("fork_cos_alpha", f(fork.get("mean_pairwise_cos_alpha"), 3)), | |
| ("fork_cos_a_hat", f(fork.get("mean_pairwise_cos_a_hat"), 3)), | |
| ("train_steps_per_s", f(tr.get("transitions_per_second"), 1)), | |
| ("field_leak", f((rm.get("config") or {}).get("field_leak"), 2)), | |
| ("chat_bonjour", chats[0] if len(chats) > 0 else ""), | |
| ("chat_qui", chats[1] if len(chats) > 1 else ""), | |
| ("chat_il_etait", chats[2] if len(chats) > 2 else ""), | |
| ] | |
| new = not os.path.exists(tsv) | |
| with open(tsv, "a", encoding="utf-8") as fh: | |
| if new: | |
| fh.write("\t".join(c for c, _ in cols) + "\n") | |
| fh.write("\t".join(v for _, v in cols) + "\n") | |
| print("TSV:", "\t".join(v for _, v in cols)) | |
| PYEOF | |
| echo "$(ts) measure $END done" | |
| } | |
| measure_missing() { | |
| for ck in $(ls "$OUT"/atom_native_step_*_${SUF}.pt 2>/dev/null | sed -n 's/.*step_\([0-9]*\)_.*/\1/p' | sort -n); do | |
| if [ "$ck" -ge "$START_STEP" ] && [ "$ck" -le "$END_TARGET" ] && ! has_row "$ck"; then measure "$ck"; fi | |
| done | |
| } | |
| CUR=$(latest) | |
| if [ -z "$CUR" ]; then echo "$(ts) no branch checkpoint in [$START_STEP,$END_TARGET] under $OUT; exiting"; exit 1; fi | |
| while [ "$CUR" -lt "$END_TARGET" ]; do | |
| END=$((CUR + CHUNK)); [ "$END" -gt "$END_TARGET" ] && END=$END_TARGET | |
| STEPS=$((END - CUR)); SKIP=$((CUR - BASE)); [ "$SKIP" -lt 0 ] && SKIP=0 | |
| RESUME="$OUT/atom_native_step_${CUR}_${SUF}.pt" | |
| NAME="atom_native_step_${END}_${SUF}.pt" | |
| LOG="$LOGD/train_${CUR}_${END}_fieldsat.log" | |
| if [ ! -f "$OUT/$NAME" ]; then | |
| echo "$(ts) chunk $CUR->$END skip=$SKIP resume=$RESUME log=$LOG" | |
| T0=$(date +%s) | |
| "$PY" -u tools/run_atom_native.py \ | |
| --stream --data-glob 'data/corpus_fr_medium*.txt' --loop-shards --chunk-bytes 65536 \ | |
| --stream-skip-packets "$SKIP" --resume "$RESUME" --output-dir "$OUT" \ | |
| --checkpoint-name "$NAME" --steps "$STEPS" \ | |
| --d-model 32 --n-modes 32 --n-atoms-max 64 --max-span-bytes 1 \ | |
| --field-obligatory-hard --no-enable-merge --no-payload-copy --last-atom-readout \ | |
| --efference-every 10 --learning-rate "$LR" --surface-learning-rate "$SLR" --seed 20260913 \ | |
| --atom-flush-every 64 --episode-length 8000 --episode-reset --slow-every 1 \ | |
| --field-loss-weight 0.05 --field-contrast-weight 0 --allow-parallel-train \ | |
| --last-atom-dropout "$LADROP" --field-leak "$LEAK" \ | |
| > "$LOG" 2>&1 | |
| RC=$? | |
| if [ "$RC" -ne 0 ] || [ ! -f "$OUT/$NAME" ]; then | |
| echo "$(ts) chunk $CUR->$END FAILED rc=$RC (see $LOG)"; exit 1 | |
| fi | |
| cp "$OUT/run_metrics.json" "$OUT/run_metrics_${END}_${SUF}.json" | |
| cp "$OUT/run_metrics.json" "$AB/run_metrics_${END}_fieldsat.json" | |
| echo "$(ts) chunk $CUR->$END saved $NAME wall=$(( $(date +%s) - T0 ))s" | |
| else | |
| echo "$(ts) skip exists $NAME" | |
| fi | |
| measure_missing | |
| CUR=$END | |
| done | |
| measure_missing | |
| echo "$(ts) DONE fieldsat branch at $CUR (END_TARGET=$END_TARGET)" | |