mstar.model.vjepa2.submodules#
NodeSubmodule wrappers for the V-JEPA 2 graph nodes.
Three submodules:
VJepa2EncoderSubmodule - ViT 3D-patch video encoder. VJepa2PredictorSubmodule - masked latent predictor (single forward per call). VJepa2ACPredictorSubmodule - action-conditioned predictor (ditto).
All three are stateless (no KV cache, no per-iteration state) and are
dispatched through StatelessEngine. preprocess stacks
per-request tensors into a batch (dim 0) — the single-request case
through _execute_sequential looks like B=1 and goes through forward;
_execute_batched with B>1 goes through forward_batched.
The masked-vs-AC choice is made by VJepa2Model.get_submodule based on
config.predictor_kind. Both predictor submodules emit the same output
edge name (predicted_hidden) so downstream consumers don’t need to
branch.
Classes
|
Action-conditioned predictor (V-JEPA 2-AC). |
|
Action-conditioned autoregressive rollout. |
|
ViT 3D-patch video encoder. |
|
Single-request K-way AC predictor forward. |
|
Score K candidate predicted latents against a goal latent. |
|
Masked latent predictor (non-AC). |
|
Masked-predictor rollout submodule — autoregressive anticipation. |
- class mstar.model.vjepa2.submodules.VJepa2ACPredictorSubmodule(predictor, config)[source]#
Bases:
ARNodeSubmoduleAction-conditioned predictor (V-JEPA 2-AC).
Additional required inputs vs the masked predictor:
actions,states, and optionallyextrinsics. Each is per-timestep, shape[T, action_embed_dim](or[T, action_embed_dim - 1]for extrinsics), delivered as a GraphEdge by the model’sprocess_prompt/get_initial_forward_pass_args. Output ispredicted_hiddenwith the same shape asencoder_hidden.- Parameters:
predictor (VisionTransformerPredictorAC)
config (VJepa2Config)
- can_batch(batch, model_inputs)[source]#
- Parameters:
batch (ExecutingBatch)
model_inputs (list[ARNodeInputs])
- Return type:
- forward(graph_walk, engine_inputs, encoder_hidden, actions, states, extrinsics=None, **kwargs)[source]#
Pure tensor → NameToTensorList computation. Compilable + CUDA-graphable.
- forward_batched(graph_walk, engine_inputs, encoder_hidden, actions, states, extrinsics=None, **kwargs)[source]#
Batched form of
forward: maps a multi-request batch to per-request outputs. Override whencan_batchreturns True.
- preprocess(graph_walk, engine_inputs, inputs)[source]#
- Parameters:
graph_walk (str)
engine_inputs (ModelInputsFromEngine)
inputs (list[ARNodeInputs])
- Return type:
- class mstar.model.vjepa2.submodules.VJepa2ACRolloutPredictorSubmodule(predictor, config)[source]#
Bases:
ARNodeSubmoduleAction-conditioned autoregressive rollout.
Optionally uses a PiecewiseCudaGraphRunner to accelerate the inner block loop. The submodule opts in via
get_piecewise_cuda_graph_configs(label"block_loop"); the engine builds the runner at warmup and passes it in throughengine_inputs.piecewise_runners.Sliding-window rollout — diverges from upstream
vjepa2/notebooks/utils/mpc_utils.py::cemwhich uses growing-context (T: 1 → rollout+1) from a single-tubelet initial encoding. Our encoder’s natural output isT=grid_depth(a full 64-frame clip), so growing-context would immediately hit the AC predictor’s pre-built causal attn-mask cap, so we slide a fixed-size window instead.- Per iter
k: Slice actions/states:
actions_k = actions[:, k : k + T_ctx](T_ctx =config.grid_depth; client supplies the full trajectory once and we slice per-iter based ondynamic_loop_iter_counts).Run
VisionTransformerPredictorAC(encoder_hidden, actions_k, states_k)— returns[B, N, D]predictions at every one of the T_ctx timesteps.Take the last tubelet group (
predicted[:, -grid² :]— shape[B, grid², D]) as the “new” imagined state, matching upstreamworld_model’snext_frame = predictor_output[:, -HW:, :]interpretation.Slide the encoder_hidden window: drop oldest
grid²tokens, append the newgrid²tokens. Fixed shape[B, N, D]every iter — torch.compile-friendly, no dynamic-shape recompiles.
actions/states(and optionallyextrinsics) are returned unchanged as identity loop-back edges so the graph dispatcher can keep routing them on every iter. Per-iter slicing happens inside the forward based oniter_idx— the tensors themselves don’t change.Shares the sibling rollout submodule’s batching contract (
B >= 2+ shape + same-iter homogeneity) andcheck_stopearly-exit semantics.- Parameters:
predictor (VisionTransformerPredictorAC)
config (VJepa2Config)
- can_batch(batch, model_inputs)[source]#
Same rule as masked rollout: B >= 2, shape-homogeneous across
encoder_hidden/actions/states(+ optionalextrinsics), and sameiter_idxfor every rid.B=1 → sequential
forwardpath (seeVJepa2EncoderSubmodule.can_batchfor the AC warm-latency regression that motivates this gate).- Parameters:
batch (ExecutingBatch)
model_inputs (list[ARNodeInputs])
- Return type:
- check_stop(request_id, request_info, outputs)[source]#
Return the set of dynamic-loop names that should stop after this step.
Runs on the worker’s slow-postprocess path after
execute_batchreturns — never insideexecute_batch. Allowed to read tensor values (.item()/.cpu()) because by this point the GPU thread is no longer blocked by it.Stops returned here are deferred by one step: they apply to the worker’s next iter’s fast postprocess. The current in-flight step (already submitted under the assumption that the rid continues) will run for that rid and its output discarded — the standard 1-wasted-step cost for any stop signal.
Default: no stops.
- declare_step(graph_walk, request_ids, inputs, slot_lease=None, piecewise_leases=None, **kwargs)[source]#
The rollout step’s KV, when the block loop runs inline.
The region declares its own work whenever it holds a slot, so this only covers the eager path — which had no declaration at all: nothing reserved its pages, so running out of KV surfaced as a RuntimeError from inside the forward instead of an admit failure the worker can push back and evict for.
- Parameters:
- Return type:
SubmoduleStep | None
- forward(graph_walk, engine_inputs, encoder_hidden, actions, states, extrinsics=None, **kwargs)[source]#
Pure tensor → NameToTensorList computation. Compilable + CUDA-graphable.
- forward_batched(graph_walk, engine_inputs, encoder_hidden, actions, states, extrinsics=None, **kwargs)[source]#
Batched form of
forward: maps a multi-request batch to per-request outputs. Override whencan_batchreturns True.
- get_piecewise_cuda_graph_configs(device, autocast_dtype, tp_world_size=1, **kwargs)[source]#
One BATCHED piecewise graph (
"block_loop") for the AC predictor.capture_seq_len = cond_tokens + N*Nis the per-frame token count (one rollout step processes one frame). The block loop reads the KV cache, so the region declares its ownKVStep/AttentionStepand takes its slot withlease_before_step=True.
- preprocess(graph_walk, engine_inputs, inputs)[source]#
- Parameters:
graph_walk (str)
engine_inputs (ModelInputsFromEngine)
inputs (list[ARNodeInputs])
- Return type:
- Per iter
- class mstar.model.vjepa2.submodules.VJepa2EncoderSubmodule(encoder, config)[source]#
Bases:
NodeSubmoduleViT 3D-patch video encoder.
Supports cross-request batching: requests with identical
video_framesshapes are stacked on dim 0 and run in a single encoder forward. Shape-heterogeneous batches fall through to the engine’s sequential path (one forward per request).Because
VJepa2Model.process_promptalways resizes + center-crops to(crop_size, crop_size)and uniformly samples toframes_per_clip, concurrent requests hitting the same serving config are shape-homogeneous by construction. Cross-config deployments (rare) naturally fall back.- Parameters:
encoder (VJEPA2Encoder)
config (VJepa2Config)
- can_batch(batch, model_inputs)[source]#
- Parameters:
batch (ExecutingBatch)
model_inputs (list[NodeInputs])
- forward(graph_walk, engine_inputs, pixel_values_videos, **kwargs)[source]#
Pure tensor → NameToTensorList computation. Compilable + CUDA-graphable.
- forward_batched(graph_walk, engine_inputs, pixel_values_videos, **kwargs)[source]#
Batched encoder forward. Returns per-rid outputs directly.
The returned per-rid
encoder_hiddenslices preserve the leading batch dim as size 1 (hidden[i:i+1]) so downstream submodules see[1, N, D]— identical shape to what the sequential path emits. That keeps thepreprocessstacking symmetric across paths and avoids a shape discrepancy at the predictor boundary.
- preprocess(graph_walk, engine_inputs, inputs)[source]#
- Parameters:
graph_walk (str)
engine_inputs (ModelInputsFromEngine)
inputs (list[NodeInputs])
- Return type:
- class mstar.model.vjepa2.submodules.VJepa2MPCPredictorSubmodule(predictor, config)[source]#
Bases:
ARNodeSubmoduleSingle-request K-way AC predictor forward.
- Inputs:
encoder_hidden:[1, N, D]— context-video latent from the precedingvideo_encodernode.actions:[K, T, 7]— K candidate action trajectories.states:[K, T, 7]— matching proprioceptive states.extrinsics(optional, use_extrinsics=True on the config).
Output:
predicted_hiddenof shape[K, N, out_dim]— all K candidates’ predicted future latents.Parity anchor:
vjepa2/notebooks/utils/mpc_utils.py::cemlines 62-64 (context expansion) + line 114 (world_model call with K-batched inputs).- Parameters:
predictor (VisionTransformerPredictorAC)
config (VJepa2Config)
- forward(graph_walk, engine_inputs, encoder_hidden, actions, states, extrinsics=None, **kwargs)[source]#
Pure tensor → NameToTensorList computation. Compilable + CUDA-graphable.
- preprocess(graph_walk, engine_inputs, inputs)[source]#
- Parameters:
graph_walk (str)
engine_inputs (ModelInputsFromEngine)
inputs (list[ARNodeInputs])
- Return type:
- class mstar.model.vjepa2.submodules.VJepa2MPCScorerSubmodule(config)[source]#
Bases:
NodeSubmoduleScore K candidate predicted latents against a goal latent.
- Inputs:
predicted_hidden:[K, N, D]— from the MPC predictor.goal_hidden:[1, N, D](or[N, D]) — pre-encoded by the client via a priorprefill_video_encoder_onlycall.
- Outputs emitted to the client:
best_index(int64 scalar): argmin of costs.costs([K]): per-candidate cost values.predicted_hidden([K, N, D]): passed through so clients that want the imagined trajectories (e.g. for visualization) get them without a second request.
- Cost function is selectable via
config.mpc_cost_fn: "l1"(default):(pred - goal).abs().mean(dim=[1, 2])— matches upstreammpc_utils.py::l1."l2": squared-error mean."cosine": 1 - cosine similarity (so argmin still picks best).
- Parameters:
config (VJepa2Config)
- forward(graph_walk, engine_inputs, predicted_hidden, goal_hidden, **kwargs)[source]#
Pure tensor → NameToTensorList computation. Compilable + CUDA-graphable.
- preprocess(graph_walk, engine_inputs, inputs)[source]#
- Parameters:
graph_walk (str)
engine_inputs (ModelInputsFromEngine)
inputs (list[NodeInputs])
- Return type:
- class mstar.model.vjepa2.submodules.VJepa2PredictorSubmodule(predictor, config)[source]#
Bases:
ARNodeSubmoduleMasked latent predictor (non-AC).
Expects
encoder_hiddenfrom the preceding encoder node. Optionally accepts pre-builtcontext_maskandtarget_maskedges; when absent, falls back to full-context / full-target defaults. Output is the predicted hidden tensor at the target positions.Supports cross-request batching when
encoder_hiddenshapes agree across the batch AND (if provided) mask shapes agree. All-defaults is the common case — the full-context / full-target masks are derived fromencoder_hidden.shapeand so are trivially homogeneous when the encoder outputs are.- Parameters:
predictor (VJEPA2Predictor)
config (VJepa2Config)
- can_batch(batch, model_inputs)[source]#
- Parameters:
batch (ExecutingBatch)
model_inputs (list[ARNodeInputs])
- Return type:
- forward(graph_walk, engine_inputs, encoder_hidden, context_mask=None, target_mask=None, **kwargs)[source]#
Pure tensor → NameToTensorList computation. Compilable + CUDA-graphable.
- forward_batched(graph_walk, engine_inputs, encoder_hidden, context_mask=None, target_mask=None, **kwargs)[source]#
Batched form of
forward: maps a multi-request batch to per-request outputs. Override whencan_batchreturns True.
- prepare_inputs(graph_walk, fwd_info, inputs, **kwargs)[source]#
parts: list[torch.Tensor] = []
- for inp in per_request_inputs:
t = inp[field_name][0] parts.append(_ensure_lead_batch_dim(t, target_rank))
return torch.cat(parts, dim=0)
- Parameters:
- Return type:
- preprocess(graph_walk, engine_inputs, inputs)[source]#
- Parameters:
graph_walk (str)
engine_inputs (ModelInputsFromEngine)
inputs (list[ARNodeInputs])
- Return type:
- class mstar.model.vjepa2.submodules.VJepa2RolloutPredictorSubmodule(predictor, config, num_output_frames=2, frames_per_second=4, anticipation_seconds=1.0)[source]#
Bases:
ARNodeSubmoduleMasked-predictor rollout submodule — autoregressive anticipation.
Parity target: upstream
vjepa2/evals/action_anticipation_frozen/modelcustom/vit_encoder_predictor_concat_ar.pyAnticipativeWrapper.forward(lines 172-224). That Python loop calls the (stateless) predictor once per rollout step, feeding a sliding window of the previous step’s prediction back as context:x_pred_input = x_full # initial encoder output for _ in range(num_steps):
x_pred = predictor(x_pred_input, ctxt_positions, tgt_positions) x_pred_input = cat([x_pred_input[:, N_pred:], x_pred], dim=1) x_accumulate = cat([x_accumulate, x_pred], dim=1)
In mstar this becomes a
Loopwhose section is a single node wrapping this submodule. On each iter:The loop-back
encoder_hiddencarries the sliding window state. Iter 0 receives it from the precedingvideo_encodernode; iter k > 0 receives the previous iter’s emittedencoder_hidden.predicted_hiddenis emitted both as a (dangling) section output — which lets the Loop’s cache_outputs machinery pick it up — and into the Loop’saccumulated_outputsfor client delivery.
The predictor nn.Module is the same instance used by
VJepa2PredictorSubmodule— weights are loaded once and shared. Only the preprocess/forward rollout-awareness differs.Uses the single-request sequential path (
can_batch=Falseinherited fromNodeSubmodule). Same cross-request batching story as the encoder — enabling it requires an engine fix.- Parameters:
predictor (VJEPA2Predictor)
config (VJepa2Config)
num_output_frames (int)
frames_per_second (int)
anticipation_seconds (float)
- can_batch(batch, model_inputs)[source]#
Batch only when every request is at the same rollout iter AND their encoder_hidden shapes agree.
Different iters can’t share a forward because the sliding-window math
torch.cat([hidden[:, n_pred:], predicted], dim=1)is symmetric across the batch dim only if all rids moved through the same number of prior iterations. The scheduler groups same-iter requests together, so this is the common case; mixed-iter batches fall through to sequential.B=1 → sequential forward; see VJepa2EncoderSubmodule.can_batch for the rationale (AC warm-latency regression when forward_batched is the only path). Rollout is especially sensitive because it calls forward_batched once per iter — amortizing a slow compile over H iters would multiply the pain.
- Parameters:
batch (ExecutingBatch)
model_inputs (list[ARNodeInputs])
- Return type:
- check_stop(request_id, request_info, outputs)[source]#
Return the set of dynamic-loop names that should stop after this step.
Runs on the worker’s slow-postprocess path after
execute_batchreturns — never insideexecute_batch. Allowed to read tensor values (.item()/.cpu()) because by this point the GPU thread is no longer blocked by it.Stops returned here are deferred by one step: they apply to the worker’s next iter’s fast postprocess. The current in-flight step (already submitted under the assumption that the rid continues) will run for that rid and its output discarded — the standard 1-wasted-step cost for any stop signal.
Default: no stops.
- forward(graph_walk, engine_inputs, encoder_hidden, **kwargs)[source]#
One rollout step. Runs the masked predictor, then slides the encoder_hidden window forward so iter k+1’s context is the concatenation of the last (N - N_pred) context tokens plus the N_pred newly-predicted tokens.
- forward_batched(graph_walk, engine_inputs, encoder_hidden, **kwargs)[source]#
Batched rollout step across shape-homogeneous same-iter requests.
can_batchguarantees all rids are at the sameiter_idx(else we fall to sequential), so the rollout-step math is a single[B, N, D]forward. Per-request early-exit (check_stop) still fires independently when each rid’srollout_horizonis reached — individual rids can drop out while others continue, and the scheduler re-batches remaining rids on the next iter.
- preprocess(graph_walk, engine_inputs, inputs)[source]#
- Parameters:
graph_walk (str)
engine_inputs (ModelInputsFromEngine)
inputs (list[ARNodeInputs])
- Return type: