Instructions to use Motif-Technologies/optimizer with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Kernels
How to use Motif-Technologies/optimizer with Kernels:
# !pip install kernels from kernels import get_kernel # a version (or an explicit revision) is required; see the "Files and versions" tab for the available ones kernel = get_kernel("Motif-Technologies/optimizer", version=1) - Notebooks
- Google Colab
- Kaggle
qk_clip: value-only fix — keep original structure, drop per-row rewrite [skip-build]
Browse filesRevert the per-row expand_row_scales restructure. qk_clip keeps its exact
original reshape + named-slice shape; only the multiplied values change:
compute_scales now returns raw per-head γ, and each sub-region is raised to
its exponent inline (q_nope γ^(1-r), q_pe γ, k_nope γ^r, MHA √γ). The q_pe
line is byte-identical to before — it is now correct because scales is raw γ.
muon.py sharded path stays per-head (no per-row vectors); it just applies the
content exponent to match the raw-γ contract, preserving its prior behavior.
The sharded path's pre-existing MLA sub-region limitation (q_pe/v scaled by the
content exponent) is left as-is and documented, not addressed here.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- torch-ext/optimizer/muon.py +37 -26
- torch-ext/optimizer/qk_clip.py +31 -38
|
@@ -20,8 +20,7 @@ from .newton_schulz import (COMM_DTYPE, DEFAULT_CHUNK_SIZE_RATIO,
|
|
| 20 |
zeropower_via_newtonschulz5,
|
| 21 |
zeropower_via_newtonschulz5_batched)
|
| 22 |
from .pipeline import muon_chunk_pipeline, prelaunch_first_gather
|
| 23 |
-
from .qk_clip import
|
| 24 |
-
qk_clip)
|
| 25 |
|
| 26 |
logger = logging.getLogger(__name__)
|
| 27 |
|
|
@@ -480,20 +479,26 @@ class Muon(torch.optim.Optimizer):
|
|
| 480 |
p, qk_clip_state, n
|
| 481 |
) if qk_clip_state is not None else None
|
| 482 |
if scales_full is not None:
|
| 483 |
-
#
|
| 484 |
-
#
|
| 485 |
-
# per-head form
|
| 486 |
-
#
|
| 487 |
-
|
| 488 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 489 |
idx0 = local_indices[0]
|
| 490 |
if isinstance(idx0, slice):
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
row_scales =
|
| 496 |
-
full_row_scales.device)]
|
| 497 |
p._local_tensor.mul_(row_scales.view(-1, 1))
|
| 498 |
|
| 499 |
if not batch_params:
|
|
@@ -565,20 +570,26 @@ class Muon(torch.optim.Optimizer):
|
|
| 565 |
p, qk_clip_state, n
|
| 566 |
) if qk_clip_state is not None else None
|
| 567 |
if scales_full is not None:
|
| 568 |
-
#
|
| 569 |
-
#
|
| 570 |
-
# per-head form
|
| 571 |
-
#
|
| 572 |
-
|
| 573 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 574 |
idx0 = local_indices[0]
|
| 575 |
if isinstance(idx0, slice):
|
| 576 |
-
|
| 577 |
-
|
| 578 |
-
|
| 579 |
-
|
| 580 |
-
row_scales =
|
| 581 |
-
full_row_scales.device)]
|
| 582 |
p._local_tensor.mul_(row_scales.view(-1, 1))
|
| 583 |
|
| 584 |
def _setup_parallel(self, names, params, group, qk_logits):
|
|
|
|
| 20 |
zeropower_via_newtonschulz5,
|
| 21 |
zeropower_via_newtonschulz5_batched)
|
| 22 |
from .pipeline import muon_chunk_pipeline, prelaunch_first_gather
|
| 23 |
+
from .qk_clip import compute_scales, get_qk_clip_info, qk_clip
|
|
|
|
| 24 |
|
| 25 |
logger = logging.getLogger(__name__)
|
| 26 |
|
|
|
|
| 479 |
p, qk_clip_state, n
|
| 480 |
) if qk_clip_state is not None else None
|
| 481 |
if scales_full is not None:
|
| 482 |
+
# scales_full is raw per-head γ; apply the content
|
| 483 |
+
# exponent per head (MHA √γ, wq_b γ^(1-r), wkv_b
|
| 484 |
+
# γ^r). NOTE: this per-head form cannot resolve the
|
| 485 |
+
# MLA rotary/value sub-regions (q_pe → full γ, v
|
| 486 |
+
# untouched) — see qk_clip; the sharded path scales
|
| 487 |
+
# q_pe/v by the content exponent instead.
|
| 488 |
+
if not qk_clip_state.is_mla:
|
| 489 |
+
e = 0.5
|
| 490 |
+
elif qk_clip_state.kind == 'wq_b':
|
| 491 |
+
e = 1.0 - qk_clip_state.k_ratio
|
| 492 |
+
else:
|
| 493 |
+
e = qk_clip_state.k_ratio
|
| 494 |
+
ratio = p.shape[0] // scales_full.shape[0]
|
| 495 |
idx0 = local_indices[0]
|
| 496 |
if isinstance(idx0, slice):
|
| 497 |
+
start = idx0.start or 0
|
| 498 |
+
idx0 = torch.arange(start,
|
| 499 |
+
idx0.stop,
|
| 500 |
+
device=scales_full.device)
|
| 501 |
+
row_scales = (scales_full**e)[idx0 // ratio]
|
|
|
|
| 502 |
p._local_tensor.mul_(row_scales.view(-1, 1))
|
| 503 |
|
| 504 |
if not batch_params:
|
|
|
|
| 570 |
p, qk_clip_state, n
|
| 571 |
) if qk_clip_state is not None else None
|
| 572 |
if scales_full is not None:
|
| 573 |
+
# scales_full is raw per-head γ; apply the content
|
| 574 |
+
# exponent per head (MHA √γ, wq_b γ^(1-r), wkv_b
|
| 575 |
+
# γ^r). NOTE: this per-head form cannot resolve the
|
| 576 |
+
# MLA rotary/value sub-regions (q_pe → full γ, v
|
| 577 |
+
# untouched) — see qk_clip; the sharded path scales
|
| 578 |
+
# q_pe/v by the content exponent instead.
|
| 579 |
+
if not qk_clip_state.is_mla:
|
| 580 |
+
e = 0.5
|
| 581 |
+
elif qk_clip_state.kind == 'wq_b':
|
| 582 |
+
e = 1.0 - qk_clip_state.k_ratio
|
| 583 |
+
else:
|
| 584 |
+
e = qk_clip_state.k_ratio
|
| 585 |
+
ratio = p.shape[0] // scales_full.shape[0]
|
| 586 |
idx0 = local_indices[0]
|
| 587 |
if isinstance(idx0, slice):
|
| 588 |
+
start = idx0.start or 0
|
| 589 |
+
idx0 = torch.arange(start,
|
| 590 |
+
idx0.stop,
|
| 591 |
+
device=scales_full.device)
|
| 592 |
+
row_scales = (scales_full**e)[idx0 // ratio]
|
|
|
|
| 593 |
p._local_tensor.mul_(row_scales.view(-1, 1))
|
| 594 |
|
| 595 |
def _setup_parallel(self, names, params, group, qk_logits):
|
|
@@ -130,9 +130,9 @@ def compute_scales(p, qk_clip_state, name: str = ''):
|
|
| 130 |
|
| 131 |
Returns a per-head tensor of γ (1.0 for heads under the threshold) if any
|
| 132 |
head requires clipping, else None. The per-region exponent on γ is NOT
|
| 133 |
-
applied here — it is applied at multiply time
|
| 134 |
-
|
| 135 |
-
k_nope, v) with different exponents.
|
| 136 |
|
| 137 |
wkv_b with k_ratio=0 returns None: the whole reduction is placed on Q and
|
| 138 |
the key projection is left unclipped.
|
|
@@ -178,37 +178,9 @@ def compute_scales(p, qk_clip_state, name: str = ''):
|
|
| 178 |
return scales_full
|
| 179 |
|
| 180 |
|
| 181 |
-
def expand_row_scales(gamma, info):
|
| 182 |
-
"""Per-head raw γ ([H]) → per-row multiplier ([H*stride]) = γ ** exponent,
|
| 183 |
-
where the exponent depends on the row's sub-region within its head.
|
| 184 |
-
|
| 185 |
-
Each logit component ends up reduced by exactly γ:
|
| 186 |
-
MHA : √γ on every row (√γ · √γ = γ).
|
| 187 |
-
MLA q_nope : γ^(1-k_ratio) ┐ content: γ^(1-k_ratio)·γ^k_ratio = γ.
|
| 188 |
-
k_nope : γ^k_ratio ┘
|
| 189 |
-
MLA q_pe : γ (exponent 1) — the decoupled rotary key is shared and
|
| 190 |
-
left unchanged, so the rotary query carries the whole γ for
|
| 191 |
-
every k_ratio; γ^(1-k_ratio) here would under-clip rotary.
|
| 192 |
-
MLA v rows : γ^0 = 1, i.e. untouched.
|
| 193 |
-
|
| 194 |
-
Shared by both apply paths: qk_clip (whole tensor) and the sharded DTensor
|
| 195 |
-
path in muon.py (which indexes the returned vector by global row).
|
| 196 |
-
"""
|
| 197 |
-
r, n = info.k_ratio, info.qk_nope_head_dim
|
| 198 |
-
if not info.is_mla:
|
| 199 |
-
exps = torch.full((info.head_dim, ), 0.5)
|
| 200 |
-
elif info.kind == 'wq_b':
|
| 201 |
-
exps = torch.cat(
|
| 202 |
-
[torch.full((n, ), 1.0 - r),
|
| 203 |
-
torch.ones(info.qk_rope_head_dim)])
|
| 204 |
-
else: # wkv_b: k_nope → γ^r, v rows → γ^0 = 1
|
| 205 |
-
exps = torch.cat([torch.full((n, ), r), torch.zeros(info.v_head_dim)])
|
| 206 |
-
exps = exps.to(gamma.device) # [stride]
|
| 207 |
-
return (gamma[:, None]**exps[None, :]).reshape(-1) # [H*stride], head-major
|
| 208 |
-
|
| 209 |
-
|
| 210 |
def qk_clip(p, scales, info):
|
| 211 |
-
"""Apply QK-clip to a Q/K projection weight
|
|
|
|
| 212 |
|
| 213 |
Args:
|
| 214 |
p: Parameter (nn.Parameter or raw tensor).
|
|
@@ -216,10 +188,31 @@ def qk_clip(p, scales, info):
|
|
| 216 |
unclipped heads, as returned by ``compute_scales``.
|
| 217 |
info: QKClipInfo with kind, head_dim, k_ratio and MLA sub-head dims.
|
| 218 |
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
"""
|
| 223 |
W = p.data if isinstance(p, torch.nn.Parameter) else p
|
| 224 |
-
|
| 225 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
|
| 131 |
Returns a per-head tensor of γ (1.0 for heads under the threshold) if any
|
| 132 |
head requires clipping, else None. The per-region exponent on γ is NOT
|
| 133 |
+
applied here — it is applied at multiply time (``qk_clip`` for the whole
|
| 134 |
+
tensor, or the sharded path in muon.py) so that one per-head γ can drive
|
| 135 |
+
different sub-regions (q_nope, q_pe, k_nope, v) with different exponents.
|
| 136 |
|
| 137 |
wkv_b with k_ratio=0 returns None: the whole reduction is placed on Q and
|
| 138 |
the key projection is left unclipped.
|
|
|
|
| 178 |
return scales_full
|
| 179 |
|
| 180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
def qk_clip(p, scales, info):
|
| 182 |
+
"""Apply QK-clip to a Q/K projection weight; each sub-region is raised to
|
| 183 |
+
its own exponent so every logit component is reduced by exactly γ.
|
| 184 |
|
| 185 |
Args:
|
| 186 |
p: Parameter (nn.Parameter or raw tensor).
|
|
|
|
| 188 |
unclipped heads, as returned by ``compute_scales``.
|
| 189 |
info: QKClipInfo with kind, head_dim, k_ratio and MLA sub-head dims.
|
| 190 |
|
| 191 |
+
Exponents:
|
| 192 |
+
MHA : √γ on all rows.
|
| 193 |
+
MLA q_nope : γ^(1-k_ratio), k_nope : γ^k_ratio (content product = γ).
|
| 194 |
+
MLA q_pe : γ (full) — the decoupled rotary key is shared and left
|
| 195 |
+
unchanged, so the rotary query carries the whole γ for
|
| 196 |
+
every k_ratio; γ^(1-k_ratio) here would under-clip rotary.
|
| 197 |
+
MLA v rows : untouched.
|
| 198 |
"""
|
| 199 |
W = p.data if isinstance(p, torch.nn.Parameter) else p
|
| 200 |
+
r = info.k_ratio
|
| 201 |
+
|
| 202 |
+
if not info.is_mla:
|
| 203 |
+
W.view(-1, info.head_dim, W.shape[1]).mul_((scales**0.5).view(-1, 1, 1))
|
| 204 |
+
return
|
| 205 |
+
|
| 206 |
+
if info.kind == 'wq_b':
|
| 207 |
+
qk_nope = info.qk_nope_head_dim
|
| 208 |
+
qk_head_dim = qk_nope + info.qk_rope_head_dim
|
| 209 |
+
W_3d = W.view(-1, qk_head_dim, W.shape[1]) # [H, qk_head_dim, in_dim]
|
| 210 |
+
W_3d[:, :qk_nope, :].mul_((scales**(1.0 - r)).view(-1, 1, 1)) # q_nope → γ^(1-r)
|
| 211 |
+
W_3d[:, qk_nope:, :].mul_(scales.view(-1, 1, 1)) # q_pe → γ (full)
|
| 212 |
+
|
| 213 |
+
elif info.kind == 'wkv_b':
|
| 214 |
+
qk_nope = info.qk_nope_head_dim
|
| 215 |
+
kv_stride = qk_nope + info.v_head_dim
|
| 216 |
+
W_3d = W.view(-1, kv_stride, W.shape[1]) # [H, kv_stride, in_dim]
|
| 217 |
+
W_3d[:, :qk_nope, :].mul_((scales**r).view(-1, 1, 1)) # k_nope → γ^r
|
| 218 |
+
# v rows: untouched (shared rotary key k_rope is unchanged)
|