fix(training): W&B actually works — submit-time key preflight, real resume semantics, dead install gate removed (MT40) - #72
Open
Mokuroh54 wants to merge 2 commits into
Conversation
Mokuroh54
force-pushed
the
fix/wandb-endpoints-main
branch
from
August 8, 2026 15:47
764e8d2 to
aca1f36
Compare
Mokuroh54
force-pushed
the
fix/mt47-cloud-log-tail
branch
from
August 8, 2026 15:47
0ccc252 to
cc6ef59
Compare
Mokuroh54
force-pushed
the
fix/mt47-cloud-log-tail
branch
from
August 10, 2026 05:20
cc6ef59 to
d83a091
Compare
Mokuroh54
force-pushed
the
fix/wandb-endpoints-main
branch
from
August 10, 2026 05:20
aca1f36 to
971886e
Compare
Mokuroh54
force-pushed
the
fix/mt47-cloud-log-tail
branch
from
August 11, 2026 14:40
d83a091 to
eb215bd
Compare
Mokuroh54
force-pushed
the
fix/wandb-endpoints-main
branch
from
August 11, 2026 14:40
971886e to
2db342a
Compare
Mokuroh54
marked this pull request as ready for review
August 11, 2026 15:55
Mokuroh54
force-pushed
the
fix/mt47-cloud-log-tail
branch
from
August 12, 2026 08:19
eb215bd to
ba5ec4c
Compare
Mokuroh54
force-pushed
the
fix/wandb-endpoints-main
branch
2 times, most recently
from
August 12, 2026 16:56
e4f414f to
47d398d
Compare
…'t smuggle wandb on, key checked before side effects (MT40) Fixes main's wandb surface per the MT40 audit, re-derived for main's code (not a port of rig's restore — rig's panel/lineage interactions arrive with the later carve train): - Install gate deleted: /system/wandb-extra*, the wandb InstallManager, and WandbInstallDialog. It was dead code — wandb is a hard transitive dep of the pinned lerobot training extra, so the probe could never fail — and its fetch-error fallthrough silently enabled wandb. Replaced by GET /system/wandb-credentials on the existing resolve_wandb_api_key (env -> ~/.netrc; boolean only, never the key). - Resume emits an explicit --wandb.enable, so a resumed checkpoint's train_config.json can never silently re-enable wandb (the MT40 core); enable/project/entity inherit server-side from the parent record (the wandb run identity rides the checkpoint; verified against lerobot v0.6.0's resume path). - Credential preflight: a wandb-enabled run with no resolvable key is refused 400 BEFORE any side effect — before the dataset Hub push and before the deferred resume-upload thread — instead of dying inside a billed GPU container 20 minutes in. - Defaults and copy: wandb defaults on when a key exists (form-level, once, never clobbering a user's choice); artifact upload defaults off; Entity/Project labeled in W&B's own vocabulary with the blank-value semantics spelled out. - URL scrape: comment corrected (lerobot's 'Track this run -->' line; wandb's own banner is WANDB_SILENT-suppressed) and run-id class widened. Known divergence kept deliberately: wandb_run_id stays on main's TrainingRequest (inert; rig removed it — reconciled by the carve train). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mokuroh54
force-pushed
the
fix/wandb-endpoints-main
branch
from
August 13, 2026 17:06
47d398d to
a684d1d
Compare
…esume upload thread Two regression guards for behaviour this branch already ships: - the W&B key is forwarded to HF Jobs in `secrets` (redacted, like HF_TOKEN), never in `env`; - a wandb-enabled deferred local->cloud resume with no resolvable key refuses before the checkpoint-upload thread is spawned, leaving no record behind. Ported from the retired rig branch's test_training_preflight.py onto this branch's fixtures. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(training): W&B actually works — submit-time key preflight, real resume semantics, dead install gate removed (MT40)
Stacked on #71 — merge that first.
What
W&B support existed but had three holes: a resume could run W&B in a billed GPU container with no API key, the "is wandb installed?" gate asked a question that could never fail while the one that mattered went unasked, and the form's defaults quietly worked against the user. This closes all three.
Why
The MT40 defect.
build_training_command's resume branch is a whitelist and emitted no--wandb.*at all, so a resumed run inherited the checkpoint's wandb settings fromtrain_config.json. A W&B-enabled parent therefore resumed with wandb on inside the container — while theWANDB_API_KEYsecret was injected only when the request saidwandb_enable, which a resume's form did not. Net effect: wandb active in-container with no API key, failing inside a paid GPU container rather than at submit time.The install gate was dead code.
/system/wandb-extra*probed whether thewandbpackage was importable. wandb is a hard transitive dependency of the pinned lerobot'strainingextra, so the answer was always yes. Worse, the toggle's probe had a fall-through bug: on any fetch error it enabled W&B anyway, so an unreachable backend silently turned logging on.The defaults fought the user. W&B logging was off even with a key sitting in
~/.netrc, and per-checkpoint artifact uploads were on by default — pushing every checkpoint to W&B on top of the Hub.Mechanism
Resume — the core fix. The resume branch now emits an explicit
--wandb.enable <bool>, so the checkpoint's config never gets a silent vote. The value is not the form's:JobRegistry.startcopieswandb_enable/wandb_project/wandb_entityoff the parent record and ignores what was sent. That is forced by lerobot, not a preference —WandBLoggerresumes withwandb.init(resume="must")using the run id in the checkpoint'strain_config.json, so a continuation always re-opens the parent's W&B run. Enabling W&B on a resume of a non-W&B parent is structurally impossible; disabling is the only other lever. Nothing else in the group is emitted, because lerobot rebuilds mode/notes/disable_artifact from the checkpoint itself — verified against the installed lerobot v0.6.0 by reloading a real checkpoint config through the resume path.Preflight — a hard 400 before any side effect. Any W&B-enabled run needs a key resolvable on this machine, on either runner: a cloud job gets it forwarded as an HF Jobs secret, and a local trainer is a non-tty subprocess in which
wandb.initcannot prompt for a login and simply dies after the record already saysrunning. Three layers:POST /jobs/trainingrefuses a fresh run with no resolvable key — the fast half, skipped for resumes because a resume's W&B state is not the request's to state.JobRegistry.startre-asks once the resume block has copied the parent's value, and before it creates a record, spawns a local subprocess, pushes a dataset, or spawns the deferred_upload_resume_then_startthread. That thread is why the check can't live deeper: it returns 201 first and uploads on a thread, so a later refusal would surface as a failed job instead of a message on the button. This check is the authority.HfCloudJobRunner.startrepeats it belt-and-braces, moved above_ensure_dataset_on_hubso a missing key can no longer leave a freshly published dataset behind for a job that never ran.Install gate → credential probe.
/system/wandb-extra*, thewandbInstallManager, andWandbInstallDialog.tsxare deleted.GET /system/wandb-credentialsreplaces them, reporting whether a key is resolvable fromWANDB_API_KEYor a~/.netrcentry forapi.wandb.ai— a boolean and a login hint, never the key.resolve_wandb_api_keyalready existed and is reused unchanged.Defaults and copy. A fresh run defaults W&B on once the probe confirms a key — applied at most once per mounted form and never overwriting a toggle the user already touched, since the probe answers asynchronously and a late "yes" must not reverse a decision made while it was in flight.
wandb_disable_artifactnow defaults true (artifacts off; per-checkpoint uploads are opt-in). Field copy adopts W&B's own vocabulary: Project with placeholderlerobot (default)(lerobot's real config default, so an empty field isn't a surprise about where runs land), and Entity with helper "Your W&B username or a team you belong to. Blank = your personal account." — the last clause defuses a real 403 a user hit by typing a placeholder word into that field, which W&B rejects only at run start.URL scrape. The comment was wrong: the URL comes from lerobot's own
logging.info("Track this run --> <coloured url>"), not from wandb'swandb: 🚀 View run at …banner — lerobot setsWANDB_SILENT=Truebefore importing wandb, suppressing that banner entirely. Corrected, and the run-id character class widened. A missing URL is normal (W&B off, offline/disabled mode, self-hosted W&B) and never an error.Tests
--wandb.enableand nothing else; a non-W&B parent forces it off.wandb_disable_artifactdefaults true and serializes both ways.job_registry.starton both runners; not blocked with a key;/system/wandb-credentialsreturns a boolean and never leaks the key.MagicMockrunners returned a Mock fromwandb_run_url(), which the watchdog wrote onto the record and persisted as JSON — silent garbage plus a pydantic serializer warning per tick. A_mock_runnerhelper plus explicitNoneon the direct mocks; zero W&B-related warnings remain.pytestgreen;ruffclean;pre-commit run --all-filesgreen.Deliberate non-ports
This is the wandb surface as main knows it, not a port of the
rigbranch's diff. Not included, and arriving with the future carve train: the compressed tabbed training panel (RunPane/OptimizerPane/ComputePane), sticks-only resume and one-row-per-leaf lineage, and chain-rewind's owner-vs-leaf inheritance. On a chain-rewound lineage the W&B run belongs to the record that wrote the chosen checkpoint, not the leaf — here, with main's single-parent resume model, those are the same record, so the simple form is correct on this branch and will need revisiting when chain-rewind lands.wandb_run_idis left in place on main.rigremoved it (it is checkpoint-inherited state, never a per-launch choice), but removing a request field is a contract change this PR wasn't asked to make, and it is inert here. Flagging it as a known divergence for whoever reconciles the branches.Note for the merger
PR #42 has since merged and this branch is reconciled with it (rebased over
921cfc4; the resume-inheritance and preflight anchors were re-verified against #42's restructuring, and the rebase-shadowing traps — duplicated regex/test definitions that would have silently reverted #42's versions — were audited out). One natural follow-up deliberately not taken here: #42's new resume-seed prefill is the right hook for showing the parent's W&B values read-only on the resume form.Also pre-existing on
mainand untouched here:npx tsc -bis red for five unrelated files (CI runs the no-opnpx tsc --noEmit), andtests/test_models.pyhas 7 environment-dependent failures that reproduce on a clean checkout.🤖 Generated with Claude Code