RoPE¶
rope
¶
Rotary Position Embedding (RoPE) primitives.
apply_rotary_emb
¶
Apply RoPE rotation to x.
Computes x * cos + rotate_half(x) * sin where cos and
sin are expanded from the half-dim shape returned by
:func:rope_frequencies_1d / :func:rope_frequencies_nd to match
the full last-dim of x.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
array
|
|
required |
cos
|
array
|
|
required |
sin
|
array
|
|
required |
interleaved
|
bool
|
See :func: |
True
|
Returns:
| Type | Description |
|---|---|
array
|
Rotated tensor, same shape as |
meshgrid_nd
¶
Build an "ij"-indexed N-D meshgrid of integer positions.
Returns one (S,) flattened position grid per axis, where
S = prod(sizes). Use these grids as the position_grids
argument to :func:rope_frequencies_nd.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sizes
|
Sequence[int]
|
Number of positions along each axis (e.g.
|
required |
Returns:
| Type | Description |
|---|---|
list[array]
|
List of |
list[array]
|
shape |
rope_frequencies_1d
¶
rope_frequencies_1d(dim: int, positions: array, theta: float = 10000.0, *, theta_rescale_factor: float = 1.0, interpolation_factor: float = 1.0) -> tuple[array, array]
Compute 1-axis RoPE (cos, sin) for the given positions.
The output has shape (S, dim // 2) and represents the per-pair
rotation angle θ_k = pos / theta^(2k/dim) for k ∈ [0, d/2).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dim
|
int
|
Head dimension this axis covers (must be even). |
required |
positions
|
array
|
|
required |
theta
|
float
|
RoPE base. |
10000.0
|
theta_rescale_factor
|
float
|
NTK-aware rescaling (Reddit user bloc97):
|
1.0
|
interpolation_factor
|
float
|
Position-interpolation factor for context
extension (Chen et al., 2023). Positions are scaled by
this factor before frequency computation. Use |
1.0
|
Returns:
| Type | Description |
|---|---|
array
|
|
array
|
func: |
rope_frequencies_nd
¶
rope_frequencies_nd(dims_per_axis: Sequence[int], position_grids: Sequence[array], theta: float = 10000.0, *, theta_rescale_factor: float | Sequence[float] = 1.0, interpolation_factor: float | Sequence[float] = 1.0) -> tuple[array, array]
Compose multi-axis RoPE by concatenating per-axis frequencies.
For a video transformer with head_dim = sum(dims_per_axis) and
each token addressed by a tuple of positions (t, h, w), each
axis is RoPE'd independently and the resulting half-angles are
concatenated along the last dim.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dims_per_axis
|
Sequence[int]
|
Per-axis head-dim allocation, must sum to the attention head dim. All entries must be even. |
required |
position_grids
|
Sequence[array]
|
One |
required |
theta
|
float
|
Base frequency, broadcast across axes. |
10000.0
|
theta_rescale_factor
|
float | Sequence[float]
|
Either a scalar (broadcast) or one
factor per axis. See :func: |
1.0
|
interpolation_factor
|
float | Sequence[float]
|
Same as above. |
1.0
|
Returns:
| Type | Description |
|---|---|
tuple[array, array]
|
|
rotate_half
¶
Rotate halves of x for RoPE application.
For interleaved=True (RoPE-paper / Matrix-Game): pairs are
adjacent; transforms [x0, x1, x2, x3, ...] into
[-x1, x0, -x3, x2, ...].
For interleaved=False (HuggingFace Llama / GPT-NeoX): pairs
span halves; transforms [x_left, x_right] into
[-x_right, x_left].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
array
|
Tensor with even last dim. |
required |
interleaved
|
bool
|
Selects the convention. |
True
|
Returns:
| Type | Description |
|---|---|
array
|
Tensor of the same shape with paired elements rotated. |
rope
¶
Rotary Position Embeddings (RoPE) — N-axis composable primitives.
RoPE rotates pairs of features in each query/key vector by an angle that depends on the token's position, encoding position into the attention dot product. The math is identical across most models; the practical pitfalls are:
-
Pair layout. Two conventions are in the wild:
-
Interleaved (Llama2 paper, Matrix-Game, RoFormer original): pairs are adjacent — pair k consists of features
(x[2k], x[2k+1]). - Half-rotated (HuggingFace Transformers default for Llama, GPT-NeoX):
pairs span halves — pair k consists of
(x[k], x[k + d/2]).
The two compute identical attention scores, but the cos/sin layout
and rotate_half form differ. This module supports both via
interleaved=True (default, RoPE-paper convention) or
interleaved=False.
-
Multi-axis (N-D) composition. Video / image models split the head dim across spatial axes — e.g. CogVideoX uses
[t, h, w]withrope_dim_list = [16, 56, 56]. Each axis gets a 1-D RoPE over its own position grid; the resulting per-axis(cos, sin)are concatenated along the feature axis. See :func:rope_frequencies_nd. -
mx.fast.rope. MLX ships
mx.fast.ropefor the standard 1-D case but does NOT cover N-axis composition or arbitrary frequency schedules (Megatron non-interleaved, log-spaced SPLIT). This module fills that gap with portable, slow-but-correct primitives.
Model-specific variants (ERNIE-Image Megatron, LTX SPLIT log-spaced) should stay in their ports — arsenal only covers the "standard" case. The shapes returned here mirror the most common HF / Matrix-Game convention.
rope_frequencies_1d
¶
rope_frequencies_1d(dim: int, positions: array, theta: float = 10000.0, *, theta_rescale_factor: float = 1.0, interpolation_factor: float = 1.0) -> tuple[array, array]
Compute 1-axis RoPE (cos, sin) for the given positions.
The output has shape (S, dim // 2) and represents the per-pair
rotation angle θ_k = pos / theta^(2k/dim) for k ∈ [0, d/2).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dim
|
int
|
Head dimension this axis covers (must be even). |
required |
positions
|
array
|
|
required |
theta
|
float
|
RoPE base. |
10000.0
|
theta_rescale_factor
|
float
|
NTK-aware rescaling (Reddit user bloc97):
|
1.0
|
interpolation_factor
|
float
|
Position-interpolation factor for context
extension (Chen et al., 2023). Positions are scaled by
this factor before frequency computation. Use |
1.0
|
Returns:
| Type | Description |
|---|---|
array
|
|
array
|
func: |
rope_frequencies_nd
¶
rope_frequencies_nd(dims_per_axis: Sequence[int], position_grids: Sequence[array], theta: float = 10000.0, *, theta_rescale_factor: float | Sequence[float] = 1.0, interpolation_factor: float | Sequence[float] = 1.0) -> tuple[array, array]
Compose multi-axis RoPE by concatenating per-axis frequencies.
For a video transformer with head_dim = sum(dims_per_axis) and
each token addressed by a tuple of positions (t, h, w), each
axis is RoPE'd independently and the resulting half-angles are
concatenated along the last dim.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dims_per_axis
|
Sequence[int]
|
Per-axis head-dim allocation, must sum to the attention head dim. All entries must be even. |
required |
position_grids
|
Sequence[array]
|
One |
required |
theta
|
float
|
Base frequency, broadcast across axes. |
10000.0
|
theta_rescale_factor
|
float | Sequence[float]
|
Either a scalar (broadcast) or one
factor per axis. See :func: |
1.0
|
interpolation_factor
|
float | Sequence[float]
|
Same as above. |
1.0
|
Returns:
| Type | Description |
|---|---|
tuple[array, array]
|
|
rotate_half
¶
Rotate halves of x for RoPE application.
For interleaved=True (RoPE-paper / Matrix-Game): pairs are
adjacent; transforms [x0, x1, x2, x3, ...] into
[-x1, x0, -x3, x2, ...].
For interleaved=False (HuggingFace Llama / GPT-NeoX): pairs
span halves; transforms [x_left, x_right] into
[-x_right, x_left].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
array
|
Tensor with even last dim. |
required |
interleaved
|
bool
|
Selects the convention. |
True
|
Returns:
| Type | Description |
|---|---|
array
|
Tensor of the same shape with paired elements rotated. |
apply_rotary_emb
¶
Apply RoPE rotation to x.
Computes x * cos + rotate_half(x) * sin where cos and
sin are expanded from the half-dim shape returned by
:func:rope_frequencies_1d / :func:rope_frequencies_nd to match
the full last-dim of x.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
array
|
|
required |
cos
|
array
|
|
required |
sin
|
array
|
|
required |
interleaved
|
bool
|
See :func: |
True
|
Returns:
| Type | Description |
|---|---|
array
|
Rotated tensor, same shape as |
meshgrid_nd
¶
Build an "ij"-indexed N-D meshgrid of integer positions.
Returns one (S,) flattened position grid per axis, where
S = prod(sizes). Use these grids as the position_grids
argument to :func:rope_frequencies_nd.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sizes
|
Sequence[int]
|
Number of positions along each axis (e.g.
|
required |
Returns:
| Type | Description |
|---|---|
list[array]
|
List of |
list[array]
|
shape |