Repository navigation
[hardware, perf] feat: add TPUSplashAttention, SimpleFSDP, torch.compile, and DEFER_AND_FUSE to TorchTitanTPUEngine - #39
Merged
wuxibin89 merged 1 commit intoOct 8, 2026
Conversation
…ile, and DEFER_AND_FUSE to TorchTitanTPUEngine Port the four TPU TorchTitan performance optimizations into verl-hardware-plugin: 1. TPUSplashAttention: Pallas splash attention kernel with dynamic power-of-two block sizing (512/256/128) and segment-id document masking, skipping dense [1, 1, S, S] causal mask construction. 2. SimpleFSDP: wraps model_spec.parallelize_fn with torchtitan.experiments.graph_trainer.simple_fsdp.data_parallel so FSDP all-gather/reduce-scatter collectives are traced into each compiled TransformerBlock, marks blocks spmd_safe, preserves tied embedding weights, scales loss by 1/dp_size, and aligns micro-batch sequence/response bucket shapes across ranks via a single CPU MAX all_reduce. 3. Per-block torch.compile(backend='tpu'): configures Dynamo static-shape compilation (automatic_dynamic_shapes=False, assume_static_by_default=True, capture_scalar_outputs=True, recompile_limit=64) across Ray actor RPCs and compiles compute_entropy_from_logits. 4. DEFER_AND_FUSE eager mode + vectorized logprobs_from_logits_naive: fuses ops outside compiled blocks (LM head, log-prob/loss, grad norm, optimizer step) and replaces row-by-row logprobs_from_logits_v2 on TPU with vectorized gather+logsumexp. Co-authored-by: gemini-code-assist Signed-off-by: Jialei Chen <jialeic@google.com>
jialei777
requested review from
heavyrain-lzy and
physics31415926
as code owners
October 7, 2026 22:46
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 does this PR do?
Ports the four TPU TorchTitan training performance optimizations (
TPUSplashAttention,SimpleFSDP, per-blocktorch.compile(backend="tpu"), andDEFER_AND_FUSEeager execution mode, plus vectorized TPU log-prob computation) intoverl-hardware-plugin(TorchTitanTPUEngineWithLMHeadandverl_hardware_plugin.engines.tpu_utils), bringing compiled TPU trainer throughput (~6.4s/stepvs~61.4s/stepeager on Qwen3-0.6B GSM8K GRPO) to upstreamverl+verl-hardware-pluginwithout requiring changes to upstreamverl.verl-project/verl-hardware-pluginandjialei777/verl-hardware-plugin; no open PR portsTPUSplashAttention,SimpleFSDP,configure_torch_compile_for_tpu, orDEFER_AND_FUSEintoverl-hardware-plugin.Checklist Before Starting
[{modules}] {type}: {description}(This will be checked by the CI)Test
All 7 hooks (
ruff,ruff-format,mypy,check-license,check-no-bytedance-copyright,check-naming-conventions,compileall) pass.tests/test_tpu_engine.py):Ran all 16 unit tests in
tests/test_tpu_engine.pyonray-tpu-v6e-cluster-head-9v898, coveringsplash_block_size_for,apply_splash_attention_tpu(including CPU/unaligned fallback),pad_packed_inputs_for_tpu(..., build_attention_mask=False)+ cross-rank aligned bucket lengths,configure_torch_compile_for_tpu,extend_torchtitan_engine_config, andresolve_tpu_torchtitan_options.Qwen3-0.6Bon GSM8K):Validated on
jialeic-tpu-v6e8-2s-spot(8 trainer v6e chips + 8 rollout v6e chips) withuse_torch_compile=True,use_splash_attention=True,use_simple_fsdp=True, andtpu_eager_mode=DEFER_AND_FUSE.API and Usage Example
When
actor_rollout_ref.actor.torchtitan.use_torch_compile=Trueis set on TPU,TorchTitanTPUEngineWithLMHeadautomatically enablesuse_splash_attention=True,use_simple_fsdp=True(for pure FSDP/HSDP where TP/PP/CP/EP == 1), andtpu_eager_mode=DEFER_AND_FUSE. Each option can also be explicitly configured viaactor_rollout_ref.actor.torchtitan.*orVERL_TPU_*environment variables:Design & Code Changes
verl_hardware_plugin/engines/tpu_utils.py:extend_torchtitan_engine_config()&resolve_tpu_torchtitan_options(): registers optionaluse_splash_attention,use_simple_fsdp, andtpu_eager_modefields onTorchtitanEngineConfigand resolves TPU defaults whenuse_torch_compile=True.configure_torch_compile_for_tpu(): configurestorch._dynamo.config(and_config[name].defaultso settings persist across Ray actor RPCs) withautomatic_dynamic_shapes=False,assume_static_by_default=True,capture_scalar_outputs=True, andrecompile_limit=64.splash_block_size_for(),TPUSplashAttention,apply_splash_attention_tpu(): integrates the Pallassplash_sdpakernel with dynamic power-of-two block sizes (512,256,128) and packed-documentsegment_idsmasking, skipping dense[1, 1, S, S]causal mask construction inpad_packed_inputs_for_tpu(..., build_attention_mask=False).make_simple_fsdp_parallelize_fn()&align_micro_batch_shapes_across_ranks(): wrapsmodel_spec.parallelize_fnviatpu_torchtitan_config_overrides(use_simple_fsdp=...)to shard parameters with TorchTitanSimpleFSDP(Shard(0)DTensors traced into each compiledTransformerBlock), marks blocksspmd_safe, preserves tied embedding weights, and aligns micro-batch sequence/response bucket lengths across ranks with a single CPUall_reduce(MAX).tpu_eager_mode_context(): wraps forward/backward and optimizer steps intorch_tpu._internal.execution_mode.set_eager_mode(EagerMode.DEFER_AND_FUSE).verl_hardware_plugin/engines/torchtitan_tpu.py:configure_torch_compile_for_tpu,TPUSplashAttention,SimpleFSDP,align_micro_batch_shapes_across_ranks, andtpu_eager_mode_contextintoTorchTitanTPUEngineWithLMHead.TPUEngineEvalModeCtxto guardsubmodule.reshard()withisinstance(submodule, FSDPModule)whenSimpleFSDPis active.1.0 / dp_sizebeforesynchronize_tpu_loss(loss)andloss.backward()underSimpleFSDP.logprobs_from_logits_naiveon TPU inprepare_model_outputsinstead of row-by-rowlogprobs_from_logits_v2.verl_hardware_plugin/platforms/platform_tpu.py:extend_torchtitan_engine_config()at platform load time so driver processes have the extendedTorchtitanEngineConfigdataclass fields.tests/test_tpu_engine.py:splash_block_size_for,apply_splash_attention_tpu,pad_packed_inputs_for_tpu(..., build_attention_mask=False),configure_torch_compile_for_tpu, andresolve_tpu_torchtitan_options.Checklist Before Submitting
pre-commit install && pre-commit run --all-files --show-diff-on-failure --color=alwaysEnd-to-End 10-Step GRPO Benchmark on TPU v6e-8 (2 Slices: 8 Trainer + 8 Rollout Chips)
Tested with
Qwen/Qwen3-0.6Bon GSM8K (examples/tpu/grpo/run_qwen3_0_6b_torchtitan.sh,train_batch_size=32,rollout.n=8,max_prompt_length=512,max_response_length=1024) ongke_tpu-pytorch_us-central2_jialeic-tpu-v6e8-2s-spot:Steady-State Comparison (Steps 5–10 Mean)
verltpu-main(d435b6ad)verlPR #34 +verl-hardware-pluginmain(Eager)verlPR #34 + This PR (#2) (Compiled + Splash + SimpleFSDP)timing_s/old_log_prob1.32s13.76s1.86stiming_s/ref1.08s12.76s1.05stiming_s/update_actor3.97s38.52s3.87sold_log_prob + ref + update_actor)6.38s65.04s6.78stiming_s/step(Full Step Time)72.81s75.51s64.06sperf/throughput(tokens/s)178.9 tok/s169.0 tok/s196.2 tok/sactor/grad_norm0.4690.5010.491rollout_actor_probs_pearson_corr0.9970.9970.997critic/rewards/mean0.2720.3030.309val-core/openai/gsm8k/acc/mean@1)47.66%(0.4766)Per-Step Breakdown (PR #34 + This PR #2)
gen(s)old_log_prob(s)ref(s)update_actor(s)update_weights(s)step(s)grad_normpearson_corrreward_mean