Skip to content

feat(vlm): enable validation under pipeline parallelism - #3759

Draft
HuiyingLi wants to merge 2 commits into
mainfrom
huiyingl/feat/vlm-pp-validation
Draft

feat(vlm): enable validation under pipeline parallelism#3759
HuiyingLi wants to merge 2 commits into
mainfrom
huiyingl/feat/vlm-pp-validation

Conversation

@HuiyingLi

Copy link
Copy Markdown
Contributor

What does this PR do ?

Enables VLM validation under pipeline parallelism. Previously the recipe logged "Validation is not supported for pipeline parallelism" and skipped it, so any PP finetune ran blind on val_loss. Split out of #3614 to keep that PR focused on the Engine boundary.

Validation batches go through the same _forward_backward_step path as training — media staging, stage-shape updates, CP sharding included — but through a new forward-only AutoPipeline.eval(). The eval entry shares step()'s kwargs-chunk-spec save/restore, which a bare schedule.eval(...) call (the LLM recipe's pattern) would silently drop for models that declare get_pipeline_kwargs_chunk_dims (e.g. Qwen3.5-MoE's media layouts). The last PP stage sums per-microbatch losses and broadcasts the epoch loss to the other stages.

Changelog

  • recipes/vlm/finetune.py: remove the PP validation gate; add _run_pp_validation_epoch (loss DP-allreduced with CP, token count without, last-stage broadcast, clear error when drop_last leaves zero supervised tokens); setup requires validation_dataloader.drop_last=true under PP (AutoPipeline uses a fixed outer batch size) and threads packing_attn_implementation / pp_n_microbatches into the validation dataloader build.
  • distributed/pipelining/autopipeline.py: public AutoPipeline.eval(); step/eval share one _run_schedule implementation.
  • recipes/base_recipe.py: _broadcast_from_last_pp_stage moves up from the LLM recipe so both recipes share one collective.
  • tests/functional_tests/parallelism/compare_parallel_parity.py: --metric {loss,val_loss}; L2_Parallelism_VLM_Gemma4_PP2_Parity.sh now also asserts validation-loss parity, so a regression back to skipping validation fails the L2 test.
  • Example VLM PP configs set validation_dataloader.drop_last: true.

Validation

  • 2×GPU end-to-end: Gemma4 proxy, pp_size=2 vs single rank — val_loss matches within 0.014 nats (tolerance 0.05) with identical supervised-token counts (1461) on both legs.
  • Unit: 275 passed across the VLM recipe, autopipeline, parity-script, and LLM recipe suites (new coverage: PP validation setup wiring, forward-only scheduling, zero-denominator rejection, val_loss metric parsing).
  • ruff format / ruff check clean on changed files.

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you add or update any necessary documentation?

Draft pending full CI.

Additional Information

🤖 Generated with Claude Code

Route validation batches through the same _forward_backward_step path as
training but via a forward-only AutoPipeline.eval() (which preserves the
model-owned kwargs chunk spec that a bare schedule.eval() would drop),
broadcast the last-stage loss, and require validation drop_last under PP
since AutoPipeline uses a fixed outer batch size. The parity script gains
a val_loss metric and the Gemma4 PP2 L2 test now asserts validation
parity, so a stale PP validation skip cannot pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@HuiyingLi

Copy link
Copy Markdown
Contributor Author

/claude review

@claude

claude Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

LGTM

Keep the pipeline-validation aggregation and broadcast behavior identical to the LLM recipe so the common path can be extracted later. Retain AutoPipeline.eval() as the VLM-specific chunk-spec adapter.

Signed-off-by: HuiyingLi <willwin.lee@gmail.com>
@HuiyingLi

Copy link
Copy Markdown
Contributor Author

/ok to test 38d7e03

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