Repository navigation
perf(flce): drop host syncs that do not feed the computation - #1622
Open
SuperGoodGame wants to merge 1 commit into
Open
SuperGoodGame wants to merge 1 commit into
SuperGoodGame wants to merge 1 commit into
Conversation
The Triton FLCE synchronizes the device twice per step: the forward reads the non-ignored token count with .item(), and the backward compares grad_output with 1.0 through torch.equal. A sync waits for everything queued on the device. With activation offload on a side stream, the forward sync waits for the whole offload backlog before the loss head can launch, which stalls a GPU-bound step. Forward: read the count and the target-weight sum on the host only for reduction="mean", which is the only reduction that divides by them, and the class-weight sum only with label smoothing, which is the only term that uses it. Token accuracy divides by the count on the device. Backward: always launch the scaling kernels and let element_mul_kernel skip the multiply on the device when grad_output is 1.0 (new SKIP_IF_ONE constexpr, off by default so other callers compile the same kernel). Losses and gradients are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Summary
Resolves #1621.
The Triton FLCE synchronizes the host twice per step on values the computation does not need. With activation offload on a side stream, the forward sync blocks the host until the whole device-to-host backlog drains, so the loss head and the backward start late. This PR drops both syncs where possible. Losses and gradients are unchanged.
reduction="mean", the only reduction that divides by them. Read the class-weight sum only whenlabel_smoothing > 0; the kernel multiplies it byeps = label_smoothing / V, so it has no effect otherwise. Token accuracy now divides by the count on the device. For"sum"and"none", the kernel and thecross_entropy_loss_and_gradimplementations (Triton, cutedsl) do not read the placeholder values.grad_output == 1.0check onto the device.element_mul_kernelgets aSKIP_IF_ONEconstexpr. It defaults toFalse, so every other caller compiles the same kernel as before. Whengrad_outputis 1.0, each program returns right after loading it; otherwise it scales as before.Details
reduction="mean"still syncs. Avoiding that needs the count passed to the kernel as a device pointer, so it is left for a follow-up.use_token_scalingkeeps a data-dependent boolean index that also syncs. It is out of scope here.cross_entropy_backwardhas the sametorch.equalcheck, but there it also setsgrad_scaled_in_place, which guardsretain_graph=True, so I left it unchanged. The cutedsl, cutile and ascend backends are untouched..item()->nonzero()). I'm happy to rebase on whichever lands first. If row compaction is kept, it could run only when the count is needed anyway (reduction="mean"), or behind an opt-in flag, so that"sum"stays sync-free.Results on one H200:
loss.backward()host time with a 2 GB D2H copy queued (BT=8192, H=4096, V=128256, bf16)grad_output = 1.0grad_output = 0.5With
grad_output = 1.0, launching the early-exit programs costs about 0.05 ms.Testing Done
New
test_no_host_sync_without_mean_reduction(24 cases): runs forward and backward undertorch.cuda.set_sync_debug_mode("error")and checks loss, gradients and token accuracy against PyTorch. It covers:reductionin {sum,none};grad_outputin {1.0, 0.37};All 24 fail on main and pass here.
Hardware Type: NVIDIA H200 (141 GB); torch 2.14.1 (CUDA 13.3), triton 3.8.0, transformers 5.8.1
run
make testto ensure correctness: 5686 passed, 40 failed. The same 40 fail on main in this environment and are unrelated:cutlass.cute has no attribute 'ReductionKind'(older CuTe DSL here);test_rms_norm.py::test_torch_compile_backward_matches_eager;test_low_probability_vocab_block_is_finiteNaN.All FLCE tests pass (
test/transformers165,test/ops171), and so do the otherelement_mul_kernelusers' tests.run
make checkstyleto ensure code style:ruff checkandruff format --checkare clean on the changed files (ruff 0.16.6; pre-commit pins 0.14.11).run
make test-convergenceto ensure convergence: everything passes except failures that are identical on main in this environment:mini_llama4bf16 loss mismatch;mini_paligemma/mini_paligemma2/mini_gemma3(view size is not compatible);mini_qwen3_5/mini_qwen3_5_moe(TileLang layout error).