#!/usr/bin/env bash # R49 H02 — rung 2 of the carrier sweep: Qwen3-1.7B-Base, 1 epoch. # # WHY THIS RUN. The 0.6B rung answered the narrow question and the operator's read # was the finding: "it's all nonsense, but it sounds like Brontë's nonsense." # Voice transferred (curly quotes 1/18 -> 18/18, worksheet collapse 3/18 -> 0/18) # while coherence did not. That separation is the premise the whole lightweight # author-voice regime rests on, so the live question is which carrier size brings # sense back while the voice stays. 1.7B is the next rung; 4B is after it. # # ⚠ THE CORPUS CHANGED, DELIBERATELY, AND IT IS A SECOND VARIABLE. # The 0.6B adapter learned the Gutenberg transcription's ~70-char line breaks along # with the prose -- its output wrapped at a mid-length-line ratio of 0.85 against # the base model's 0.00. That is typography, not style, and every further rung # would inherit it. So this trains on r49-corpus-renamed-unwrapped: same words, # reflowed into paragraphs, verified whitespace-only on all 852 records, with verse # blocks detected by median line length and their lineation preserved (0 lines # ended in a lone hyphen, so the space-join could not split a word). # CONSEQUENCE: a 0.6B-vs-1.7B comparison is now DESCRIPTIVE, not attributable -- # carrier size and corpus typography both moved. "Did sense come back at 1.7B" is a # within-arm reading and survives that; any between-rung delta does not. The 0.6B # rerun on this same corpus is chained after this run so the clean single-variable # comparison exists too. # # Everything else is held from the 0.6B run: seed 4919, rank 32, lr 1e-4, seq 4096, # batch 1 x accum 8, 1 epoch, eval+save every 25 steps so the minimum is LOCATED # rather than assumed (the 3-epoch run overfit with save_strategy="no" and left # nothing to fall back to). set -euo pipefail OUT=/home/infra-ops/r49-runs/h02-1p7b-1ep LOG=$OUT/train.log apps=$(nvidia-smi --query-compute-apps=pid --format=csv,noheader | tr -d '[:space:]') [ -n "$apps" ] && { echo "REFUSING: GPU not clear" >&2; nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv >&2; exit 1; } [ -f "$OUT/run.pid" ] && kill -0 "$(cat "$OUT/run.pid")" 2>/dev/null && { echo "REFUSING: live pid" >&2; exit 1; } [ -e "$LOG" ] && { echo "REFUSING: $LOG exists" >&2; exit 1; } mkdir -p "$OUT" echo "# launched $(date -Is) Qwen3-1.7B-Base, 1 epoch, seed 4919, UNWRAPPED corpus, eval+save every 25" > "$LOG" setsid nohup /home/infra-ops/ml/.venv/bin/python /home/infra-ops/r49-prep/train_voice_lora.py \ --corpus /home/infra-ops/r49-corpus-renamed-unwrapped \ --base /home/infra-ops/carriers/Qwen3-1.7B-Base \ --seed 4919 --epochs 1 --eval-steps 25 --save-steps 25 \ --out "$OUT" >> "$LOG" 2>&1 < /dev/null & echo $! > "$OUT/run.pid" echo "launched pid $(cat "$OUT/run.pid") -> $LOG"