No mixed precision (autocast/GradScaler), no torch.compile #47
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
grepfinds noautocast, noGradScaler, nobfloat16, notorch.compileanywhere in
giant/. For a project whose stated target is a ~10×native-Geant4 eval budget, and whose flow/AR path costs
k_max × stepssequential model calls per physics step, bf16 autocast on the training loop and
torch.compileon the sampler are likely worth more wall-clock than anyarchitectural change in the modularity batch of issues.
Two caveats to check first:
_route_forward(
giant/model/trunks.py:58, 65) allocates its accumulator withtorch.zeros(..., device=x.device)and nodtype, which will needdtype=x.dtypeunder autocast; andtorch.compileinteracts poorly with theeval-mode grouped
out[mask] = expert(...)dispatch (data-dependent shapes →recompiles), so the routed path likely wants
dynamic=Trueor an explicitcompile opt-out.
Migrated from
issues.md(v0.3.0 branch review, 2026-08-13), Issue 22.Fixed in
7897876on fix/issue-47.Implemented the bf16-autocast half of this issue: a new
train.precisionconfig key ("fp32"default,"bf16"opt-in) wraps the training step (bothFlowDDPMStageTrainerandWGANStageTrainer) intorch.autocast, resolved via a newgiant.training.amp.resolve_autocast.Decisions made during planning/implementation:
giant/model/routers.py's three1e-8epsilons (below fp16's ~6e-8 subnormal floor) and overflowsgradient_penalty's grad norm at ordinary early-WGAN-GP magnitudes. Every training GPU in the fleet (A100/L40S/H200/RTX 4070) has native bf16; fp16 would only matter for pre-Ampere V100s.resolve_autocastraises loudly (naming the device) if bf16 is requested on hardware that can't do it, instead of silently training in fp32.val_loss/best-checkpoint selection stays fp32, so it's comparable across every run recorded so far. Inference/the samplers are untouched (also sidesteps.cpu().numpy()calls that would otherwise hitTypeError: Got unsupported ScalarType BFloat16)._route_forward's mixture accumulator (giant/model/trunks.py) was a hard-fp32torch.zeroswith no dtype, so under autocast aRoutedTrunksilently returned a different output dtype than an unroutedExpertTrunkpurely becauserouter.enabledwas set — same config knob, different model output dtype. Fixed to match the experts' dtype (regression test intests/test_router.py).autocast(enabled=False)) around spots that are correct in fp32 but degrade quietly (not a crash) in bf16: the router's balance/entropy losses and gate softmax, the stage-2 stick-breaking cumprod, andgradient_penalty's double-backward + grad norm.Benchmarked on the local RTX 4070 against
configs/baseline.toml's hyperparams (hidden_dim 512/6 blocks, bs 4096) on a synthetic dataset: bf16 gave 1.05-1.35x training throughput and 18-33% lower peak GPU memory across one-shot/routed/autoregressive stage-2 configs, with the autoregressive path (the dominant cost per baseline.toml's own measurements) benefiting most on both axes.Deliberately left open, per discussion during planning:
torch.compile— the other half of this issue — is a much larger surface (the routed trunk's data-dependentout[mask] = expert(x[mask])dispatch, the autoregressive sampler'sif finished.all(): breakand per-slot recompiles,sample_ddim's.item()calls, androllout.py's arbitrary post-filter batch dimension all need real restructuring, not just a decorator). Happy to file that as its own follow-up issue if wanted.