feat(diffusion): encoder_hub — family-dispatched frozen-encoder logic - #96
Merged
Conversation
zhihengy
added a commit
that referenced
this pull request
Aug 6, 2026
…training-only Review feedback (PR #90): TrainPipelineConfig drives the training backend only. Encoder loading/encoding now lives in miles/rollout/encoder_hub (stacked base PR #96), dispatched by args.diffusion_model_family; the Wan-specific 4k+1 frame constraint validates there too. Encoders load from the explicit --sft-encoder-checkpoint, which also replaces hf_checkpoint in the per-sample cache key since it is what determines cache content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rockdu
reviewed
Aug 6, 2026
| embeds[:, int(inputs.attention_mask[0].sum()) :] = 0 | ||
|
|
||
| return { | ||
| "latent": latent[0].to(torch.float16).cpu(), |
Collaborator
There was a problem hiding this comment.
The dtypes here need to be double-checked.
Collaborator
Author
There was a problem hiding this comment.
done (173abc6) — aligned with sglang-d's Wan pipeline config (vae_precision fp32, text_encoder_precisions fp32, DiT bf16): UMT5 now computes in fp32 like the rollout engine, VAE stays fp32, and both cached tensors store bf16 — the precision the DiT boundary sees on the rollout path. Note for anyone with an existing .sft_cache: the cache key does not encode dtypes, so clear it manually to re-encode.
…ogic Review feedback on PR #90: TrainPipelineConfig should only drive the training backend, so frozen-encoder loading/encoding lives in its own rollout-side hub, dispatched by the resolved diffusion model family. Wan2.2 provides UMT5+VAE loading (from the explicit --sft-encoder-checkpoint introduced by the consumer PR), sample encoding, and its 4k+1 frame-count constraint. No callers in this PR; the SFT PR (#90) is stacked on top and wires argument validation and the encode actor pool to this hub. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Match the rollout engine's Wan pipeline config (vae_precision fp32, text_encoder_precisions fp32, DiT bf16): UMT5 now computes in fp32, and both cached tensors store bf16 — the precision the DiT boundary sees on the rollout path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
zhihengy
force-pushed
the
feat/encoder-hub
branch
from
August 7, 2026 11:50
173abc6 to
28a93be
Compare
zhihengy
added a commit
that referenced
this pull request
Aug 7, 2026
…training-only Review feedback (PR #90): TrainPipelineConfig drives the training backend only. Encoder loading/encoding now lives in miles/rollout/encoder_hub (stacked base PR #96), dispatched by args.diffusion_model_family; the Wan-specific 4k+1 frame constraint validates there too. Encoders load from the explicit --sft-encoder-checkpoint, which also replaces hf_checkpoint in the per-sample cache key since it is what determines cache content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
zhihengy
added a commit
that referenced
this pull request
Aug 8, 2026
* feat(diffusion): add SFT loss hub and pre-encoded data manager * feat(diffusion): add frame stride to SFT encode script * feat(diffusion): auto-build SFT cache via family encode hooks * fix(sft): per-sample content-addressed cache, atomic writes, seeded VAE sampling * refactor(sft): plug into RolloutManager via rollout-function/convert/log hooks with lazy encoder pool * feat(sft): image datasets for Wan (single-frame media branch) * refactor(sft): pick dual-expert via uniform anchor index * refactor(sft): seat encoder pool via the rollout placement view * chore(sft): encoder pool inherits the engine's 0.3 GPU share * refactor(sft): reuse --diffusion-height/width/output-num-frames; add --fsdp-flow-shift Review feedback (PR #90): the media geometry args describe the generated media regardless of whether it comes from preprocessing or the rollout engine, so SFT reuses --diffusion-height/--diffusion-width/ --diffusion-output-num-frames instead of its own --sft-* trio. The SFT training sigma grid is regenerated on the training side, so its shift is now --fsdp-flow-shift (fsdp_* namespace), leaving --diffusion-flow-shift as the rollout-engine launch parameter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(sft): validate explicit plugin paths instead of auto-wiring defaults Review feedback (PR #90): follow Miles LLM convention — the sample script passes the five SFT plugin paths explicitly and the framework validates the combination instead of silently rewriting args. Misconfigured runs now fail at argument validation with the exact flag to set, rather than deep in the RL data path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor: make --train-only an explicit flag; --debug-train-only becomes its alias Review feedback (PR #90): no silent inference of train_only from loss_type. --train-only is now a real user-facing flag (argparse alias keeps --debug-train-only working) and sft_loss validates it is set instead of setting it. The rollout placement view keeps its seats unconditionally: engine startup is gated by args.train_only, and rollout-side actor pools (the SFT encoder pool) seat there. The debug_rollout_only/train_only exclusion assert now runs before the debug_rollout_only reconfiguration so the combo fails with the intended message. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(sft): move frozen-encoder logic to encoder_hub; TPC back to training-only Review feedback (PR #90): TrainPipelineConfig drives the training backend only. Encoder loading/encoding now lives in miles/rollout/encoder_hub (stacked base PR #96), dispatched by args.diffusion_model_family; the Wan-specific 4k+1 frame constraint validates there too. Encoders load from the explicit --sft-encoder-checkpoint, which also replaces hf_checkpoint in the per-sample cache key since it is what determines cache content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * style: black-format the train_only exclusion assert Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(sft): support disaggregated encoder GPUs Treat explicit --rollout-num-gpus in train-only jobs as a dedicated rollout-side producer pool while preserving the colocated default. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci): lazy-load rollout manager from placement helper Keep CPU placement tests from importing optional SGLang runtime modules during collection. Co-authored-by: Cursor <cursoragent@cursor.com> * Revert "fix(ci): lazy-load rollout manager from placement helper" This reverts commit 4d2450c. * fix(ci): expose SGLang source package to CPU tests Put the checked-out Python package ahead of the workspace root so multimodal_gen imports resolve under SGLang's current layout. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(sglang): defer diffusion-only imports until engine startup Use SGLang's common process helper at module load so CPU-side orchestration can import without GPU-only diffusion dependencies. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.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.
What
New
miles/rollout/encoder_hub/package holding frozen-encoder logic per model family, dispatched by the resolvedargs.diffusion_model_family(same decentralization mechanism as the TPC registry). Motivated by review on #90: TrainPipelineConfig should only drive the training backend; encoders are an independent, rollout-side concern.Each family module provides three functions:
load_encoder(args, device)(frozen tokenizer/text-encoder/VAE from the explicit--sft-encoder-checkpointHF name/path),encode_sample(encoder, pixels, prompt, generator)(one media/prompt pair → clean latent + cond kwargs), andvalidate_args(args)(family-specific encode constraints — for Wan2.2, the(num_frames-1) % 4 == 0VAE temporal-stride rule, which is an encoder property, not a global SFT rule).Wan2.2 is the only entry; unsupported families are rejected at dispatch with a clear error.
Stack
This PR is the base of a three-PR stack (bottom → top):
feat/encoder-hub) →main: additive module, no callers, no behavior change;feat/sft) → this PR: SFT wires argument validation and its encode actor pool to this hub, defines--sft-encoder-checkpoint, and removes the encoder methods from TrainPipelineConfig;fix/sft-rng-scoping) → feat(diffusion): add SFT loss hub and pre-encoded data manager #90: scopes deterministic training randomness in the SFT loss hub.Merge order: this PR → #90 → #102.