nav: two-head sigmoid (λ_soft, λ_hard) — .cvcnav format v2 - #436
Merged
Merged
Conversation
Extend the deployable cvc::nav::coef_mlp policy with the paper's TWO learned,
sigmoid-bounded reroute strengths (lam_soft AND lam_hard), matching the
coef_energy_net / material_nav two-head form (lam = lam_max*sigmoid(head)).
coef_mlp.h/.cpp:
- Bump kFormatVersion 1->2; the loader ACCEPTS {1,2} (v1 files still load and
forward identically; a v2 file hard-fails on a pre-v2 host, which is safe).
- Add kFlagLamSigmoid (1<<3): lam output columns (index >= 3) are
lam_max*sigmoid(raw); alpha/beta/gamma stay softplus(log(expm1)). lam columns
carry no out_bias offset (their bias lives in the last Linear layer).
- Add lam_soft_max_/lam_hard_max_ (5.0/10.0, per coef_energy_net) + getters,
has_lam_hard() (out>=5, col 4), lam_sigmoid(). v2 writes the two ceilings after
the out_bias block (abg-only, length 3); a plain net stays v1, byte-unchanged.
- from_layers carries the sigmoid flag + maxes; forward() applies the per-column
activation; save() round-trips the v2 trailer.
drive.cpp: drive_step_material and drive_step_material_ext extract the learned
lam_hard (5th output) into md.lam_hard when has_lam_hard(), mirroring the existing
lam_soft extraction. lam_hard is never gated (material.h). drive_telemetry gains a
lam_hard field, captured at the force site.
tests (nav_material_deploy_test): v2 round-trip keeps out=5/has_lam_hard/maxes;
forward parity vs a numpy-equivalent reference (~1e-4) + lam bounds in [0,max];
the sigmoid ceiling clamps under extreme input; the on-disk v2 byte layout the
Python exporter must match; v1 back-compat (out<=4, no sigmoid flag, all-softplus);
and a learned-lam_hard hard-hazard reroute case.
Byte-compatible with GRL-SNAM's coef_export/coef_train two-head v2 path.
transfix
added a commit
that referenced
this pull request
Sep 27, 2026
…uard gRPC deps off wasm (rev 2->3) (#438) Coordinated wasm-mt republish so the catalog carries the coef_mlp .cvcnav format v2 (two-head sigmoid, #436), and to fix two wasm defects: - CVC_STATE_EXEC was wrongly forced OFF in the wasm build; the state_exec evaluator has no gRPC dependency and must always build. Turned ON. - the gRPC/xmlrpc transport deps (openssl/c-ares/re2/abseil/protobuf/grpc) were declared for ALL platforms incl wasm, but wasm builds without that transport and they are not published for wasm -> 'cvcpkg install cvc/libcvc --platform wasm-mt' could not resolve. Guarded to the native build matrix (linux/macos/windows). cvc_revision 2->3 so publish-cvcgl-wasm produces a fresh 3.4.0+cvc.3.
transfix
added a commit
that referenced
this pull request
Sep 28, 2026
…bcvc (#449) The published pycvc-cp311/312/313 +cvc.2 link a PRE-v2 libcvc, so the torch<->C++ coef_mlp parity test (GRL-SNAM test_coef_mlp_parity::test_two_head_sigmoid_matches_torch) skips on 'unsupported .cvcnav format version'. Bump so publish-cvcpkg rebuilds pycvc against the v2 libcvc (.cvcnav format v2 / two-head sigmoid, #436) and the parity test runs. Recipe-only revision bump; disjoint from the wasm-guard change (#448).
This was referenced Sep 29, 2026
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.
What
Extend the deployable hot-loop policy
cvc::nav::coef_mlpwith the paper's two learned, sigmoid-bounded reroute strengths —lam_softandlam_hard(matchingcoef_energy_net/material_nav,lam = lam_max*sigmoid(head)). Previously the deployed net learned onlylam_soft(a single softplus 4th output) andlam_hardwas a fixedmaterial_configdial. This introduces.cvcnavformat v2, byte-compatible with the Python exporter.Companion (produces the v2 blob): CVC-Lab/GRL-SNAM#105 —
coef: two-head sigmoid (λ_soft, λ_hard) — .cvcnav format v2.Format contract (v2)
kFormatVersionbumped 1 → 2; the loader accepts {1, 2} — a v1 file still loads and forwards identically, and a v2 file hard-fails on a pre-v2 host (safe: no silent misread). A plain/all-softplus net still writes v1 so it loads on old hosts; only a sigmoid-lam net bumps the version.kFlagLamSigmoid = 1u << 3: lam output columns (index ≥ 3) arelam_max*sigmoid(raw); α/β/γ (cols 0..2) staysoftplus(net + log(expm1(bias))). The lam columns carry noout_biasoffset — their bias lives in the last Linear layer, exactly as torch.lam_soft_max_/lam_hard_max_(5.0 / 10.0, percoef_energy_net.h) members + getters;has_lam_hard()(out ≥ 5, col 4). A v2 file writes the two ceilings after theout_biasblock (out_biaslength 3, abg only), before the meta trailer.Changes
coef_mlp.h/.cpp: version + flag + maxes; per-column activation inforward();from_layers()carries the sigmoid flag + maxes;save()round-trips the v2 trailer;default_biased()/legacy nets stay v1.drive.cpp:drive_step_materialanddrive_step_material_extextract the learnedlam_hard(5th output) intomd.lam_hardwhenhas_lam_hard(), mirroring the existinglam_softextraction.lam_hardis never gated (material.h), so it needs no witness gate.drive_telemetrygains alam_hardfield, captured at the force site.lam_softpath overridesmd.lam_softand thereby bypasses the witness gate (drive.cpp ~757).lam_hardmirrors this and is never gated; thelam_softgate-bypass is left as-is (out of scope).Tests (
nav_material_deploy_test.cpp, +6)out=5/has_lam_hard()/ maxes intact; forward byte-identical across the round-trip.[0, max]; the sigmoid ceiling clamps under extreme input (saturates to{0, max}).out_bias_len == 3, two ceilings, exact EOF).lam_hardnet reroutes harder away from a near hard hazard than a small-lam_hardnet.Test results (lean nav build, CUDA/pycvc off)
nav_material_deploy_test: 12 passed (6 new v2).nav_material_test: 28 passed;nav_test: 46 passed;nav_coef_train_test: 8 passed — v1 back-compat confirmed across the whole nav suite.NOT in this PR (human owns)
Retrain / A-B / republish (step 9). The published
libcvc-matext+cvc-dbg-weightsrecipes will need acvc_revisionbump at republish — not touched here (leaves a clean "ready to retrain" state).