Skip to content

feat(pipeline): sequential H-Net pipeline, flat stages instead of a nested trunk - #567

Draft
ElmoPA wants to merge 1 commit into
rldb/usocket-heterofrom
pipeline/seq-stages
Draft

feat(pipeline): sequential H-Net pipeline, flat stages instead of a nested trunk#567
ElmoPA wants to merge 1 commit into
rldb/usocket-heterofrom
pipeline/seq-stages

Conversation

@ElmoPA

@ElmoPA ElmoPA commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Dissolves DualstreamTrunk (which nests level i.inner = level i+1 and recurses
mid-forward) into an explicit, flat stages list. Every stage declares reads
and writes, so the wiring is inspectable from the config alone rather than
implied by nesting.

stages_seq.py StreamTrunk, Framewise, Chunk, Dechunk, Apex, Mix, Rename,
ScheduledRatioLoss, ObsNoise, VisualEncode, ObsEmbed, Fuse,
TimePos -- the encoder is stages too, so obs routing is
visible instead of hidden inside an encoder module.
config_graph.py builds the routing graph by INSTANTIATING each stage and
reading its declared reads/writes (ground truth, not a yaml
parse), with a lint for dim/key mismatches and a 3D viewer.

Configs: 7 arms -- a baseline plus shared/separate encoder and attention-window
variants, on circle+small_circle and circle+u_socket.

Also carried over from the working stack, without which the above cannot run:
per-stream trunk options (multi_stream_trunk), route_on / separate_boundaries
on DualStreamRouter, SharedObsEncoders + DeriveVelocity (stages_io), StreamMLP
(stages_hnet), the hetero denoiser and per-embodiment codec (stages_flow), and
confidence_ssl.

Strictness: CondEncoderModule gains strict_keys and Theta/RotVec gain strict,
both default True. A mis-typed key was previously a silent no-op -- an encoder
would train on the remaining inputs (vision with no proprio) with no error, and
a rotvec transform would leave the angle un-encoded while downstream still
sliced for (cos, sin). Transforms and encoders see KEY_MAP ALIASES, not zarr
paths; get_rotvec_transform_list previously passed
"observations.pusher_cmd_pose", a zarr path that could never match.

Verified from this repo (not the working stack): all symbols import including
the pre-existing PadGripperZeros, strict=True raises and strict=False passes
through, and all 7 configs instantiate with a clean lint, producing node/edge
counts identical to the stack that is currently training them.

…ested trunk

Dissolves DualstreamTrunk (which nests level i.inner = level i+1 and recurses
mid-forward) into an explicit, flat stages list. Every stage declares `reads`
and `writes`, so the wiring is inspectable from the config alone rather than
implied by nesting.

  stages_seq.py   StreamTrunk, Framewise, Chunk, Dechunk, Apex, Mix, Rename,
                  ScheduledRatioLoss, ObsNoise, VisualEncode, ObsEmbed, Fuse,
                  TimePos -- the encoder is stages too, so obs routing is
                  visible instead of hidden inside an encoder module.
  config_graph.py builds the routing graph by INSTANTIATING each stage and
                  reading its declared reads/writes (ground truth, not a yaml
                  parse), with a lint for dim/key mismatches and a 3D viewer.

Configs: 7 arms -- a baseline plus shared/separate encoder and attention-window
variants, on circle+small_circle and circle+u_socket.

Also carried over from the working stack, without which the above cannot run:
per-stream trunk options (multi_stream_trunk), route_on / separate_boundaries
on DualStreamRouter, SharedObsEncoders + DeriveVelocity (stages_io), StreamMLP
(stages_hnet), the hetero denoiser and per-embodiment codec (stages_flow), and
confidence_ssl.

Strictness: CondEncoderModule gains strict_keys and Theta/RotVec gain strict,
both default True. A mis-typed key was previously a silent no-op -- an encoder
would train on the remaining inputs (vision with no proprio) with no error, and
a rotvec transform would leave the angle un-encoded while downstream still
sliced for (cos, sin). Transforms and encoders see KEY_MAP ALIASES, not zarr
paths; get_rotvec_transform_list previously passed
"observations.pusher_cmd_pose", a zarr path that could never match.

Verified from this repo (not the working stack): all symbols import including
the pre-existing PadGripperZeros, strict=True raises and strict=False passes
through, and all 7 configs instantiate with a clean lint, producing node/edge
counts identical to the stack that is currently training them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant