nemo_automodel.components.models.common.rope_triton
nemo_automodel.components.models.common.rope_triton
Fused Triton rotary embedding for DeepSeek V4.1, forward and backward in one kernel each.
_apply_rope in nemo_automodel.components.models.deepseek_v41.attention rotates the
last 2 * rotary_pairs channels of a [batch, sequence, channels] or
[batch, sequence, heads, channels] tensor as adjacent complex pairs and copies the remaining
channels. Eagerly that is a complex multiply plus torch.cat in the forward and several
zero-filled slice gradients in the backward, so every call streams the full tensor through
memory more than once. This module writes the copied and the rotated channels in a single
pass, and its backward rotates the incoming gradient by the conjugate in one pass as well.
angles never receives a gradient here; inputs whose angles require one, inputs that are
not on CUDA, and dtypes outside BF16/FP16/FP32 take the eager path.
Numerics follow the eager path by construction wherever PyTorch allows it:
- The frequencies come from the same
torch.polar(torch.ones_like(angles), angles)call the eager path runs, so thecos/sinbits are identical rather than relying on libdevice agreeing with the CUDA math library PyTorch was built with. They are computed once per forward call and saved for the backward, which is the same footprint as the eager path’s savedfrequencies. - The complex product is evaluated in FP32 with explicit FMAs. Eager CUDA complex multiplication contracts the imaginary component differently across PyTorch/CUDA builds and devices. A small eager multiplication selects the matching order once per device; only that choice is cached for the process lifetime. The same order is used for the conjugate in the backward. Unrecognized arithmetic defaults to the first-product order.
- The FP32 result is rounded to
values.dtypewith round-to-nearest-even, exactly asTensor.torounds.
Module Contents
Classes
Functions
Data
API
Bases: Function
Rotate with the fused kernel and rotate the gradient by the conjugate frequency.
Eager rotation, mirroring attention._apply_rope so the fallback needs no circular import.
Parameters:
Tensor of shape [batch, sequence, channels] or [batch, sequence, heads, channels].
Complex tensor of shape [batch, sequence, rotary_pairs].
Conjugate the rotation.
Returns: torch.Tensor
Tensor with the shape and dtype of values, in independent storage.
Identify eager complex multiplication’s contraction for this CUDA device.
The bounded, process-local cache retains only the arithmetic choice, not tensors. Calibration synchronizes on first use, before the first Triton kernel compilation. FP64 CPU products distinguish the two FP32 FMA orders without using a CUDA FMA implementation as the reference or changing the random-number generator state.
Parameters:
CUDA device on which the eager reference will execute.
Returns: bool
Whether the eager reference matches the second-product contraction exactly.
Run the fused kernel over values and return a new contiguous tensor.
Parameters:
CUDA tensor of shape [batch, sequence, channels] or [batch, sequence, heads, channels]. Any leading strides are read in place; a strided channel dimension is made contiguous first.
Contiguous FP32 tensor of shape [batch, sequence, pairs, 2].
Rotate by the conjugate frequency.
Returns: torch.Tensor
Contiguous tensor with the shape and dtype of values.
Copy the leading channels and rotate the trailing pairs of BLOCK_R rows.
Every row is read once as BLOCK_K adjacent channel pairs and written once. Pairs
before the rotary block are passed through tl.where rather than multiplied by a
unit frequency, so non-finite prefix values are copied bit for bit.
Parameters:
Input viewed as [batch, sequence, heads, channels] with a unit channel
stride; heads is 1 for three-dimensional inputs.
Contiguous FP32 tensor of shape [batch * sequence, pairs, 2] holding (cos, sin) per rotary pair.
Contiguous output of shape [rows, channels].
batch * sequence * heads.
Sequence length.
Head count, 1 for three-dimensional inputs.
Channel count.
Rotary pair count; the last 2 * pairs channels rotate.
Channel pairs preceding the rotary block, rounded up so the pair grid covers channel 0 (it then starts at channel -1 for an odd prefix, masked off).
Input batch stride in elements.
Input sequence stride in elements.
Input head stride in elements; ignored when heads is 1.
Rotate by the conjugate frequency.
Fuse x1 * cos in the imaginary component
to match the installed eager CUDA complex multiplication.
Rows handled by one program.
Power-of-two pair extent per row, at least pair_offset + pairs.
Check the shared kernel’s device, layout, dtype, and autograd contract.
Parameters:
Tensor of shape [batch, sequence, channels] or [batch, sequence, heads, channels].
Complex tensor of shape [batch, sequence, rotary_pairs].
Returns: bool
Whether the inputs can use the Triton implementation.
Rotate trailing channel pairs using a model’s cached complex frequencies.
Parameters:
Tensor of shape [batch, sequence, channels] or [batch, sequence, heads, channels]. Leading dimensions may be strided.
Complex tensor of shape [batch, sequence, rotary_pairs]. The rotary width must fit within channels. CUDA BF16/FP16/FP32 values and cached complex64 frequencies use Triton; other inputs use eager operations, preserving frequency gradients when required.
Whether to conjugate the rotation.
Returns: torch.Tensor
New contiguous tensor with the shape and dtype of values. Its input
Rotate the final channels of values with the fused Triton kernel.
Drop-in for attention._apply_rope: the last 2 * angles.shape[-1] channels are
rotated as adjacent pairs by exp(i * angles) (its conjugate when inverse) and the
remaining channels are copied, all in one pass. The backward rotates the gradient by the
conjugate in one pass; angles receives no gradient. Inputs that are not on CUDA, whose
angles require a gradient, or whose dtype is outside BF16/FP16/FP32 use the eager path.
Parameters:
Tensor of shape [batch, sequence, channels] or [batch, sequence, heads, channels]; non-contiguous inputs are accepted.
FP32 tensor of shape [batch, sequence, rotary_pairs].
Conjugate the rotation, as for the attention output.
Returns: torch.Tensor
New contiguous tensor with the shape and dtype of values.
Raises:
ValueError:anglesdoes not describe an even rotary width withinvalues.