Files
esh-pfi-infrastructure/persistent-memory.d/2026-09-01-pfi-gx10-onboarding.md
T
vh 7d0d991fcd memory: pin the GX10 baseline's final figures
The probe finished. Median is 79.36 s/it across ten timed steps with a
min/max of 79.30 to 79.45, and peak memory is 75.1 of 121.6 GiB by
PyTorch's own max_memory_allocated -- 46 GiB spare rather than the 35 I
estimated from a live free reading, which was counting fragmentation and
the resident model rather than the allocation high-water mark.

Resolved attention backend recorded as flex_attention, read off the loaded
model rather than trusted from the request, which is the check I got wrong
the first time.
2026-09-02 01:23:50 -07:00

26 KiB
Raw Blame History

[2026-09-01] pfi-gx10 (ASUS Ascent GX10) onboarded headless — and it is the intended new home for run 3c

ASUS Ascent GX10 arrived and was registered, converted to headless, and given a rack-move playbook. It was NOT racked — the operator ran out of day. It is still on his desk, on Wi-Fi, on a temporary DHCP lease.

GPU NVIDIA GB10, driver 580.173.02, compute capability 12.1 (sm_121)
CPU 20 cores, aarch64
Memory 121 GB UNIFIED — CPU and GPU share it; not 121 GB plus VRAM
Storage 916 GB NVMe, 6% used
OS Ubuntu 24.04.4, kernel 6.17.0-1031-nvidia
Access infra-ops NOPASSWD sudo (operator-bootstrapped). lkraven has key auth but needs a password to escalate — automation must connect as infra-ops.

Purpose (operator, 2026-09-01)

Local inference experiments and the failed training — run 3c. That is the whole point: run 3c died on ana-ml2 when a kilowatt-class training box tripped a breaker (2× 300 W GPUs + dual EPYC 9254). The GX10 is a ~240 W appliance, roughly a fifth of the draw, on a different site's circuits.

The memory arithmetic favours it strongly. Run 3c is a LoRA (r=64, batch 2 × accum 8, gradient checkpointing) over gemma4-26b-a4b-it-bf16 — 49 GB of base weights, working set roughly 55–65 GB. The gemma4-charrp compose warns in capitals that "48.10 GiB of BF16 weights CANNOT be served here" on ana-ml2's shared GPU0. 121 GB unified turns that constraint into a non-issue.

What has NOT been established — do not assume any of it

  1. The box is bare. No torch, no nvcc, no CUDA stack. Docker 29.2.1 and 822 GB free.
  2. aarch64 dependency risk. torch 2.9.1+cu130 ARM64 wheels exist; transformers/TRL/PEFT are pure Python. Compiled deps — flash-attn, bitsandbytes, liger, xformers — are open questions per-arch.
  3. Triton has NO sm_121 support (established independently by comfy-dev the same day). Anything reaching for torch.compile or Triton-backed kernels is closed on this silicon.
  4. Throughput is unmeasured. Run 3c ran 16.45 s/it on a 300 W RTX PRO 6000. GB10 will be slower; how much decides whether 604 steps is an overnight run or two days. Measure this before porting anything — the recommended first move is a probe: install ARM64 torch, load the base, run ten steps, report s/it.
  5. Model transfer: 49 GB from ana-ml2 over the Anaheim↔NH3 link at a measured 32.4 MB/s — about 25 minutes. Note that is a third of the irv-ml1↔NH3 link's 99 MB/s.

The headless conversion, and the lesson inside it

playbooks/gx10-headless.yaml (1b596c8): multi-user.target, gnome-remote-desktop stopped, sleep/suspend/hibernate masked, logind ignores lid and idle, sshd keepalives, hostname corrected gx10-a745 → pfi-gx10.

⚠ gdm is a STATIC unit on Ubuntu — pulled in by display-manager.service, never "enabled". The first version guarded on is-enabled | grep enabled, which always skips, and the verify tested the same wrong property and passed. Six green verifies having not stopped the display manager. Both now test is-active. This is an instance of 2026-09-01-wrong-object-measurement.

The playbook refuses to stop GDM while a seat session is held (--var force_dm_stop=true to override) — automation should not yank a display out from under someone at the machine.

⚠ elway's --sudo applies only to ad-hoc --shell/--upload. Playbook steps run as the connecting user and must carry their own sudo.

The rack move, written but not run

playbooks/gx10-rack-network.yaml (a0c5fc6) — target settled: nh3-servers VLAN 50, static 10.100.50.60, clear of .40/.42/.50/.90 and below the .150 DHCP pool.

Requires nothing from the operator beyond racking it. The wired NIC has its own MAC (30:c5:99:3d:a7:45, distinct from Wi-Fi 50:bb:b5:a2:00:a8), so the post-move address AND switch port are discoverable from the UDM rather than relayed.

Design property worth preserving: the playbook never leaves itself one path back. Wi-Fi stays up while the wired interface is configured beside it; Wi-Fi teardown is explicitly a separate later change. netplan try's auto-rollback needs a TTY that elway cannot provide, so a live Wi-Fi link is what substitutes for it. Two preconditions are asserted as steps rather than assumed: carrier must be 1, and the MAC must match (interface names renumber across kernels; MACs do not).

⚠ The GX10 is NOT the Ada box. Two separate machines — see 2026-09-01-ada-migration-branch-a.

[2026-09-01 23:09] Liveness check — alive, idle, and STILL BARE (nothing has changed)

Probed at 2026-09-01T23:09:51-07:00, read-only:

host       pfi-gx10   Ubuntu 24.04.4 LTS   kernel 6.17.0-1031-nvidia   aarch64
uptime     11h48m (booted 2026-09-01 11:21)   load 0.00 0.01 0.00 — idle
GPU        NVIDIA GB10   driver 580.173.02
memory     121 GB unified, 118 GB free
disk       /dev/nvme0n1p2  916 GB, 48 G used, 822 G free (6%)
net        wlP9s9  10.100.10.226/24 (DHCP)  |  enP7s7 DOWN, NO-CARRIER (no cable)
sessions   2x lkraven desktop (seat0 + :1) — sitting at a GUI login screen

Compute stack unchanged and still absent: no torch, no nvcc, no uv. Docker daemon present but infra-ops is not in the docker group. Nothing has been installed since onboarding.

⚠ nvidia-smi reports FB Memory / BAR1 as N/A. That is CORRECT, not a fault — GB10 is a Grace Blackwell superchip with unified LPDDR5X shared between CPU and GPU, so there is no discrete VRAM figure to report. Do not chase it as a driver problem.

⚠ RACKING IS NOT A PREREQUISITE — the Wi-Fi is not the bottleneck

Assumed the temp Wi-Fi would gate getting a 49 GB base onto the box. Measured, and it does not:

link       SSID PFI, 6 GHz, 160 MHz, EHT (Wi-Fi 7), -48 dBm
           rx/tx bitrate 2401.9 Mbit/s both directions
measured   300 MB nh3-dev -> gx10 in 4.5 s = 67 MB/s over SSH
           (SSH cipher is the limiter, not the radio — link is ~300 MB/s)
implies    49 GB bf16 base transfers in ~12 min

So the throughput probe (ARM64 torch, load base, ten steps, report s/it) can proceed from the desk, today, without racking first. Racking remains one command (playbooks/gx10-rack-network.yaml, VLAN 50, static 10.100.50.60) and is worth doing for permanence, but it does not gate the decision the probe exists to answer.

[2026-09-01 23:2x] OUTFITTED (userspace) — CUDA WORKS on sm_121, full training stack imports

✅ RULING: BARE METAL, not Proxmox/VM. Settled, do not re-litigate.

  1. Proxmox VE has no aarch64 build. It ships x86_64 only; the ARM ports are unofficial community work. Running an unsupported hypervisor under a compute asset is a bad trade.
  2. The GPU cannot be cleanly passed through. GB10 is a superchip: the GPU sits on NVIDIA's own on-package root complex (bridges 22ce/22d0/22d1, GPU at 000f:01:00.0) and is cache-coherent with the CPU over NVLink-C2C, sharing the same physical LPDDR5X. Passing it to a guest means partitioning unified memory — which destroys the entire value proposition, since 121.6 GiB GPU-addressable is the reason this box exists.
  3. Vendor's supported path is bare metal — it already runs NVIDIA's own kernel flavour (6.17.0-1031-nvidia).
  4. Fleet convention agrees: ana-ml2 and irv-ml1 are both bare-metal GPU hosts. Hypervisors are separate machines in this fleet, never under the accelerators.
  5. Single tenant. VM isolation buys multi-tenancy nobody needs; the rollback benefit is better served by containers + uv venvs, which is what the rest of the fleet does.

Installed and verified (all userspace, NO sudo needed)

uv                0.12.9 (aarch64), ~/.local/bin, wired into .bashrc + .profile
venv              ~/ml/.venv  (python 3.12)
torch             2.14.0+cu130   cuda runtime 13.0, cudnn 92400, triton 3.8.0
stack             numpy 2.5.2, transformers 5.16.1, accelerate 1.14.0, peft 0.20.0,
                  trl 1.12.0, datasets 5.0.1, safetensors 0.8.0, hf_hub 1.29.0,
                  bitsandbytes 0.50.2   -- ALL import clean on aarch64

The "per-arch unknowns" warning did not materialise for the training stack. Everything imported first try.

✅ MEASURED GPU COMPUTE — it works, and the memory is the point

device        NVIDIA GB10, capability sm_121, driver 580.173.02
GPU memory    121.6 GiB total / 110.8 GiB free   <- unified, fully CUDA-addressable
bf16 8192^3   ~93 TFLOP/s        fp16 ~93 TFLOP/s
fp32+tf32     38.2 TFLOP/s       fp32 (no tf32) 19.5 TFLOP/s
bf16/fp32     4.9x -> tensor cores ARE engaged

~93 TFLOP/s dense bf16 is roughly A6000-class throughput with 2.5x the memory. Capacity, not speed, is what this box buys. A 49 GB bf16 base fits with ~70 GB to spare.

⚠⚠ I NEARLY REPORTED A PHANTOM PROBLEM — NO WARMUP MEANS YOU MEASURE THE JIT

First benchmark (10 iterations, no warmup) read 27.0 TFLOP/s bf16 — slower than a 3090 — and I was one step from reporting "tensor cores are not engaging on sm_121." Adding 5 warmup iterations moved it to 93 TFLOP/s. The first measurement was timing the PTX JIT compile.

⚠ This is exactly docs/pfi/training-throughput-playbook.md §4: a run that completes, reports plausible numbers, and is wrong. It would have sent us chasing a cuBLAS fallback that does not exist. Always warm up before timing anything on this box — see the JIT note below for why it bites harder here than elsewhere.

⚠ sm_121 IS NOT IN TORCH'S COMPILED ARCH LIST — everything JITs from sm_120 PTX

torch.cuda.get_arch_list() -> ['sm_80','sm_90','sm_100','sm_110','sm_120']
device capability          -> sm_121

There is no sm_121 cubin in the wheel; it runs by PTX forward-compat JIT from sm_120. Consequences:

  • First use of every kernel pays a JIT compile (cached afterward in ~/.nv/ComputeCache). This is what corrupted the benchmark above.
  • ⚠ Any library shipping cubin-only binaries with no PTX will simply fail here. That is the real shape of the "per-arch unknown" risk — not source builds, but prebuilt kernels.

✅ PRIVILEGED HALF DONE — and I WAS NEVER BLOCKED

⚠⚠ The block was my own bad test. infra-ops has had NOPASSWD sudo since account creation (/etc/sudoers.d/infra-ops, installed 11:31 with the account). I probed with sudo -n -v, which returns non-zero on sudo >= 1.9.15 because -v refreshes an auth timestamp that a NOPASSWD-only rule never creates — and asked the operator for a password that was never needed.

pfi-gx10    sudo 1.9.15p5   sudo -n -v rc=1   sudo -n true rc=0
nh3-docker  sudo 1.9.13p3   sudo -n -v rc=0   sudo -n true rc=0
ana-docker  sudo 1.9.13p3   sudo -n -v rc=0   sudo -n true rc=0
irv-ml1     sudo 1.9.13p3   sudo -n -v rc=0   sudo -n true rc=0

Always sudo -n true. Fixed in scripts/elway (which carried the same probe and would have started falsely prompting fleet-wide as hosts pass sudo 1.9.13) and in auto-memory reference_infra_ops_sudo_identity, which recommended the broken test. feedback_assert_effective_value_not_substring

⚠ Same shape twice in one session. I also reported "nvcc: ABSENT" from command -v nvcc when the CUDA toolkit was installed all along at /usr/local/cuda/bin/nvcc, just not on PATH. Both times I checked a proxy and reported it as the thing itself.

Credential: the temp password was infra-ops's, not lkraven's. Rotated to 32 random chars and vaulted at pfi-gx10/infra-ops-password (round-trip verified). Kept rather than locked — deviating from the canonical bootstrap's no-password posture deliberately, because this box has no iDRAC/BMC, so a console break-glass credential is the only way back if key auth breaks. ⚠ lkraven (uid 1000, GUI desktop user, sudo group) has a password nobody knows; out of scope, but it is a gap.

⚠ DOCKER'S BUILDKIT DB WAS ALREADY CORRUPT — the restart surfaced it, did not cause it

nvidia-ctk runtime configure + systemctl restart docker failed with error initializing buildkit: error creating buildkit instance: invalid database. Not the nvidia config — daemon.json was valid and nvidia-container-runtime was present. dockerd had been running on a process whose on-disk buildkit state was already bad; it simply could not come back. Remediated by removing /var/lib/docker/buildkit (108 KB of cache, and the box had 0 images, 0 containers), then daemon-reload + reset-failed + start.

⚠ A long-running daemon can be unable to restart for hours before anyone finds out. Nothing reported unhealthy until something asked it to restart.

✅ FINAL STATE — playbook green, 5/5 verifies

playbooks/gx10-outfit-privileged.yaml -> steps 1 ok / 1 changed / 0 failed / 6 skipped
                                         verify 5 ok / 0 failed

NOPASSWD sudo                    OK
nvcc                             /usr/local/cuda/bin/nvcc (NOT on default PATH)
docker socket as infra-ops       OK (docker group)
CUDA container sees the GB10     OK (nvidia/cuda:13.0.0-base -> nvidia-smi -L reports GB10)
userspace torch still sees GPU   OK
docker Runtimes                  nvidia runc io.containerd.runc.v2

The box is fully outfitted for inference + training, bare metal, containers available.

Historical note — what the block looked like before it was disproved

⚠ infra-ops does NOT have NOPASSWD sudo on pfi-gx10 (sudo -n -v -> "a password is required"), unlike the rest of the fleet — see reference_infra_ops_sudo_identity, which should be corrected: gx10 is an exception. No gx10 credential is in the vault (secret list --prefix pfi-gx10 -> 0 items), and scripts/elway prompts via getpass, which a non-interactive session cannot answer.

Still outstanding, all needing root:

- CUDA toolkit / nvcc (absent -- needed to COMPILE kernels, not to run torch)
- NVIDIA Container Toolkit + add infra-ops to the docker group
  (docker daemon runs; infra-ops gets "permission denied" on the socket)
- NOPASSWD sudo for infra-ops, so this box stops being a fleet exception
- racking (playbooks/gx10-rack-network.yaml) -- optional, NOT a prerequisite

Nothing above blocks the run-3c throughput probe, which needs only the driver and torch.

[2026-09-01 23:5x] Run-3c throughput probe — IN FLIGHT, and the ana-ml2 baseline is now on record

The baseline nobody had written down: ana-ml2's real s/it for run 3c

Extracted from /tank/erp-tune/run-03c.log (the actual run, before the breaker killed it):

step 10   10.81 s/it       step 20   12.88 s/it       step 24   15.76 s/it
=> 604 steps on ana-ml2 ~= 2.2-2.7 h

This is the number the GX10 has to be compared against, and it was sitting in a log nobody had reduced. Anything under ~45 s/it on the GX10 makes 604 steps an overnight run.

Exact run-3c geometry (from run-03c.json + a real adapter_config.json)

base            /tank/aimodels/gemma4-26b-a4b-it-bf16   49 GB
                gemma4, 30 layers, hidden 2816, 16 heads / 8 KV, MoE (A4B),
                vocab 262144, sliding_window 1024, multimodal (vision+audio configs)
LoRA            r 64, alpha 128, dropout 0.0, bias none, 205 target modules
                (q/k/v/o + gate/up/down across all 30 language-model layers)
shape           max_seq_len 16384, per_device_batch 2, grad_accum 8 (effective 16)
other           gradient_checkpointing true, bf16, cosine, warmup 0.1, wd 0.01
length          604 optimizer steps, 1 epoch, save_steps 50

⚠ THE BACKEND-DELTA TRAP — CHECKED, and it is NOT present

CLAUDE.md warns that two frontier-panel conclusions were voided because a benchmark and a trainer had silently different attention backends. Enumerated both sides before running:

ana-ml2   flash_attn NOT installed in /tank/erp-tune/venv  -> falls back to sdpa
pfi-gx10  flash_attn not available for aarch64/sm_121      -> falls back to sdpa

Same backend both sides. ⚠ Library versions DO differ and it is recorded rather than assumed harmless:

ana-ml2   torch 2.13.0        transformers 5.15.1   peft 0.20.0   accelerate 1.14.0
pfi-gx10  torch 2.14.0+cu130  transformers 5.16.1   peft 0.20.0   accelerate 1.14.0

The probe reads the resolved _attn_implementation back off the loaded model rather than trusting the request, so the comparison is checkable rather than assumed.

Probe design (§4-disciplined)

~/ml/probe_3c.py on the GX10. Real geometry, synthetic batches — it measures step cost, and padding on the real run is 0.0% so the corpus does not change per-step cost materially.

  • 12 steps, first 2 discarded as warmup. Non-negotiable here: an unwarmed benchmark on this box already read 27 TFLOP/s when the true figure was 93, because it was timing the PTX JIT. sm_121 is not in torch's arch list.
  • Reports the step-time distribution (median, min/max, every step), not a mean beside a settings dump.
  • Emits every provenance key always, null when unused — present-and-null, not absent.

Transfer

49 GB relayed ana-ml2 -> nh3-dev -> pfi-gx10, ~33 MB/s, ~25 min. Relayed rather than direct because ana-ml2's key is not authorised for infra-ops@pfi-gx10 — and relaying costs nothing extra, since the Wi-Fi leg is the bottleneck either way. Deliberately did not add an access grant just to save a hop.

[2026-09-02] GX10 BASELINE + TOOLING VERIFIED — ~79.35 s/it on the run-3c shape

⚠ PURPOSE, stated by the operator so it is not misread later: this was a BASELINE for the box and a check that the tooling loads. It was NOT a decision about where run 3c runs, and no port was undertaken. The placement reasoning below is a byproduct — real and worth keeping, but the deliverable was the number and the working stack.

Deliverable 1 — the tooling loads and runs. aarch64 + sm_121 runs the full training stack: torch 2.14.0+cu130, transformers, accelerate, peft, trl, datasets, safetensors, bitsandbytes, plus the harness's own flex_attention backend and chunked-loss path. Nothing exotic was needed beyond python3-dev. This box can train.

Deliverable 2 — the baseline.

The number

pfi-gx10    MEDIAN 79.36 s/it   min/max 79.30 / 79.45   (10 timed steps, 0.19% spread;
            warmup 85.90 then 79.32, discarded)
            peak memory 75.1 / 121.6 GiB -- 46 GiB SPARE, comfortably not memory-bound
            attn_resolved: flex_attention (matched to the harness, read off the model)
            FINAL, from the probe's own provenance block on the box
            -> 604 steps ~= 13.3 h
            peak 75.1 / 121.6 GiB (PyTorch max_memory_allocated) -- 46 GiB spare
ana-ml2     10.8-15.8 s/it (run-03c.log, the real run)
            -> 604 steps ~= 2.2-2.7 h

⚠ 6x slower where raw compute predicts 2.7x (93 TFLOP/s bf16 measured here vs an RTX PRO 6000 Blackwell's ~250). Hypothesis, not a measurement: the limiter is memory bandwidth — GB10's unified LPDDR5X against dedicated graphics memory, on a workload built to be bandwidth-hungry (seq 16384 with gradient checkpointing, which trades compute for memory traffic by design). Confirming it needs a bandwidth-bound microbenchmark that has not been run.

⚠ THE GX10 IS A CAPACITY BOX, NOT A THROUGHPUT BOX. 121 GB holds models nothing else in the fleet can. It is not the box to move a time-sensitive run to.

Byproduct: IF run 3c ever moves here, the GX10 is the right home — and infra-ops' reversal was WRONG

⚠⚠ infra-ops recommended ana-ml2 and the operator overruled it, correctly. The error is worth more than the recommendation: I costed the failure in the units I was measuring. I had step times, so I priced a breaker trip as "≤50 steps ≈ 11 minutes of lost training" — the recompute cost. That is not what a breaker trip at Anaheim costs.

Operator, 2026-09-02: "when the breaker trips at ana, that's a 40 minute drive to reset it. it's not 25 minutes, it's a giant pain in the ass."

The real cost of an Anaheim breaker trip:

a 40-minute drive EACH WAY, on the operator's time, whenever he notices
13 hosts down: ana-ml2, ana-docker, pfi-pve (hypervisor for most of them),
  pfi-postgres, pbs-ana (the fleet's PRIMARY backup server), ana-wg (WireGuard),
  pfi-ana-webhost, ana-filebot, pfi-pteradactyl, pfi-tacticalrmm
⚠ including THREE SureFire CLIENT hosts (sfsrv-ana, sf-ana-container, sf-r630)
  -- a client's production machines, under a hosting agreement

⚠ save_steps 100 → 50 caps the RECOMPUTE, not the OUTAGE. It was never the mitigation I claimed; it only bounds the cheapest component of the loss.

So: 13.3 h unattended on a desk in NH3, drawing desktop-class power and unable to take down anything, beats 2.5 h that can put a client's hosts dark until someone drives to Anaheim. The GX10's slowness is close to free here — nothing is waiting on this run — and the risk it removes is expensive and lands on the operator personally.

⚠ GENERAL FORM, and the reason this is recorded at length: when you recommend between options, check whether you priced the failure mode in the units you happened to be measuring. A metric in hand will volunteer itself as the unit of risk.

⚠ Power-capping ana-ml2 is a WEAK lever — measured, do not spend time on it

2x RTX PRO 6000 Blackwell Max-Q: limit 300 W, default 300 W, min 250 W, max 325 W

Capping both GPUs to the floor saves 100 W total on a box drawing ~1 kW. Not nothing, but nowhere near enough to make an Anaheim training run safe, and it costs throughput to buy it. Recorded so nobody re-derives it as a clever third option.

Probe methodology — five launches, five distinct causes, all recorded

1. reaped SSH             long remote job piped through a reapable foreground ssh.
                          FIX: setsid nohup, log ON the box. Work survived; output did not.
2. bare LoRA target names q_proj/k_proj/... also match Gemma-4's VISION and AUDIO towers,
                          whose projections are Gemma4ClippableLinear -- PEFT cannot wrap
                          them. FIX: the real run's 205 fully-qualified names, sha recorded.
3. missing python3-dev    Triton JITs a C shim at FIRST USE and needs Python.h. Torch
                          imports, model loads, LoRA attaches, THEN step 1 dies with a bare
                          CalledProcessError -- Triton devnulls the compiler's stdout.
4. naive-loss OOM (32 GiB) the 262,144-wide vocab x 32,768 positions logits tensor in fp32.
                          ⚠ NOT a GX10 limit -- the harness docstring says it OOMs "on a
                          95.60 GiB card (measured)", i.e. on ana-ml2 too.
5. self-inflicted VRAM leak a stuck orphan held 80 GB while PyTorch reported 0 bytes
                          allocated; every relaunch was doomed before it started and blamed
                          the NEW run. ⚠ ASSERT THE GPU IS CLEAR BEFORE EVERY LAUNCH.

⚠ THE BACKEND-DELTA TRAP WAS PRESENT AND I FIRST DECLARED IT ABSENT

CLAUDE.md records two frontier-panel conclusions voided by a benchmark and a trainer having silently different attention backends. I checked for it by asking whether flash-attn was installed — the wrong discriminator entirely — and reported "no delta". The harness sets ATTN_IMPLEMENTATION = "flex_attention" explicitly in code, with tuned kernel options; its own comment records peak 74.3 GiB under flex vs sdpa's 79.71.

⚠ Read the configured value in the code. Absence of an alternative is not evidence of the default. The probe now requests flex_attention and reads _attn_implementation back off the loaded model. RESOLVED: flex_attention — it compiles and runs on sm_121, which was a real open risk (flex compiles through Triton; sm_121 is not in torch's arch list).

Faithfulness of the probe (what makes the number comparable)

LoRA         the real run's 205 fully-qualified modules, sha256 c9ee070c0d67eb08
loss path    copied from the harness: trunk hidden states, DROP IGNORE_INDEX before the
             head, chunk lm_head+CE at loss_chunk_tokens=1024 under checkpoint, softcap 30.0
loss ratio   28.4% of positions masked to match the real 13,310,930 / 18,600,057 loss/ctx
             ratio -- observed 23,351-23,638 loss tokens/step against a 23,449 target
tokens       sampled [1000, 250000) to stay below every multimodal special token
             (boi 255999, boa 256000, image 258880, audio 258881, eoi/eoa/video 258882-4)
warmup       first 2 steps discarded; sm_121 JITs from sm_120 PTX on first use

⚠ NOT DONE, and deliberately: the run-3c port

Scoped but not executed — operator stood it down; the baseline was the goal. Scope, so it does not have to be re-derived:

harness eitri-smithy   26 MB      corpus /mnt/smithy/.../derived   2.3 GB
recipe-r3             485 KB      holdout                           82 MB
run-03c manifests      70 MB      -> ~2.5 GB, ~75 s at 33 MB/s
venv                  3.2 GB      NOT portable (x86-64) -- rebuild on aarch64

⚠ No encode cache to preserve. The launch script's "609 MB encode cache / ~4.3 hours" comment carries its own correction to 145.5 s, and run 3c's log shows [encode] done in 14.4s on 32 workers. Nothing worth moving.

⚠ Copy the corpus; do NOT mount /mnt/smithy over NFS on this box. A desk machine on Wi-Fi is the wrong place for a hard NFS dependency under a 13-hour unattended run — the fleet has already lost a host to a hard mount wedging into unkillable D-state (incident_esh_docker_nfs_boot_race).

The only untested piece is the harness's own 26 MB of Python; every library it leans on is verified above.