Automatic Mixed Precision (AMP) reduces memory consumption and increases throughput by running forward passes in a lower-precision floating-point format while keeping weights and critical operations in float32. Modern NVIDIA GPUs have dedicated tensor cores that execute half-precision matrix multiplications several times faster than full-precision equivalents. Clorch’sDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/antlobach/clorch/llms.txt
Use this file to discover all available pages before exploring further.
clorch.amp namespace provides the two building blocks you need: the autocast macro for precision narrowing and the grad-scaler record for dynamic loss scaling.
amp/autocast
autocast is a macro that enables LibTorch’s thread-local autocast state for the duration of its body. Eligible operations in the body run in the specified dtype; unsupported operations fall back to float32 automatically. Autocast restores the previous dtype, enabled flag, and cache setting when the body exits, even on error.
| Key | Default | Description |
|---|---|---|
:device | :cuda | :cuda or :cpu |
:dtype | :bfloat16 | :float16 or :bfloat16 |
:enabled? | true | Set false to disable without removing the call site |
:cache? | true | Whether to cache autocast type promotions |
amp/grad-scaler
Float16 has a limited dynamic range; gradients near the minimum representable value underflow to zero. The grad scaler multiplies the loss by a large scale factor before backward, and then divides the gradients back before the optimizer step. If gradients overflow to Inf or NaN, the scaler discards that step and reduces the scale.
| Key | Default | Description |
|---|---|---|
:initial-scale | 65536.0 | Starting loss scale |
:growth-factor | 2.0 | Multiplier after growth-interval clean steps |
:backoff-factor | 0.5 | Multiplier after an overflow step |
:growth-interval | 2000 | Steps between scale increases |
:enabled? | true | Pass false for bfloat16 (no scaling needed) |
Scaling and Backward
amp/backward! multiplies the loss by the current scale and calls .backward. It does not unscale gradients; that happens inside amp/step!.
amp/step!
amp/step! performs the following atomically:
- Collects all gradients from the optimizer’s parameter list.
- Checks whether every gradient is finite (no
InforNaN). - In distributed training, performs an all-reduce of the finite flag so the decision is consistent across all ranks.
- If all gradients are finite, unscales them by dividing by the current scale and calls
.stepon the optimizer. - Updates the dynamic scale: increases it after
growth-intervalclean steps, decreases it after an overflow. - Returns
trueif the optimizer stepped,falseif the step was skipped.
float16 vs bfloat16
- float16
- bfloat16
- Smaller dynamic range (1e-4 to 65504)
- Requires dynamic loss scaling to avoid underflow
- Faster on older Pascal/Volta hardware
- Use
amp/grad-scalerandamp/backward!
Full AMP Training Loop
The following example shows a complete float16 AMP loop including gradient accumulation.Integration with DDP
When combining AMP and DDP, pass the scaler toddp/optimizer-step! instead of calling amp/step! directly. This ensures the overflow flag is synchronized across all distributed ranks before any rank steps the optimizer.
Inspecting Scaler State
dist/save-checkpoint! and dist/load-checkpoint!.