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
Merge pull request #32 from MotifTechnologies/feat/qk-clip-k-ratio
Browse filesfeat: add k_ratio for Q/K split control in MLA QK clipping [skip-build]
- torch-ext/optimizer/muon.py +4 -4
- torch-ext/optimizer/pipeline.py +1 -1
- torch-ext/optimizer/qk_clip.py +47 -15
torch-ext/optimizer/muon.py
CHANGED
|
@@ -362,7 +362,7 @@ class Muon(torch.optim.Optimizer):
|
|
| 362 |
qk_clip_state = get_qk_clip_info(self.clip_config, n, qk_logits)
|
| 363 |
|
| 364 |
scales_full = compute_scales(
|
| 365 |
-
p, qk_clip_state) if qk_clip_state is not None else None
|
| 366 |
if scales_full is not None:
|
| 367 |
qk_clip(p, scales_full, qk_clip_state)
|
| 368 |
|
|
@@ -409,7 +409,7 @@ class Muon(torch.optim.Optimizer):
|
|
| 409 |
qk_clip_state = get_qk_clip_info(self.clip_config, n,
|
| 410 |
qk_logits)
|
| 411 |
scales_full = compute_scales(
|
| 412 |
-
p, qk_clip_state) if qk_clip_state is not None else None
|
| 413 |
if scales_full is not None:
|
| 414 |
qk_clip(p, scales_full, qk_clip_state)
|
| 415 |
|
|
@@ -476,7 +476,7 @@ class Muon(torch.optim.Optimizer):
|
|
| 476 |
qk_clip_state = get_qk_clip_info(
|
| 477 |
self.clip_config, n, qk_logits)
|
| 478 |
scales_full = compute_scales(
|
| 479 |
-
p, qk_clip_state
|
| 480 |
) if qk_clip_state is not None else None
|
| 481 |
if scales_full is not None:
|
| 482 |
ratio = p.shape[0] // scales_full.shape[0]
|
|
@@ -555,7 +555,7 @@ class Muon(torch.optim.Optimizer):
|
|
| 555 |
qk_clip_state = get_qk_clip_info(
|
| 556 |
self.clip_config, n, qk_logits)
|
| 557 |
scales_full = compute_scales(
|
| 558 |
-
p, qk_clip_state
|
| 559 |
) if qk_clip_state is not None else None
|
| 560 |
if scales_full is not None:
|
| 561 |
ratio = p.shape[0] // scales_full.shape[0]
|
|
|
|
| 362 |
qk_clip_state = get_qk_clip_info(self.clip_config, n, qk_logits)
|
| 363 |
|
| 364 |
scales_full = compute_scales(
|
| 365 |
+
p, qk_clip_state, n) if qk_clip_state is not None else None
|
| 366 |
if scales_full is not None:
|
| 367 |
qk_clip(p, scales_full, qk_clip_state)
|
| 368 |
|
|
|
|
| 409 |
qk_clip_state = get_qk_clip_info(self.clip_config, n,
|
| 410 |
qk_logits)
|
| 411 |
scales_full = compute_scales(
|
| 412 |
+
p, qk_clip_state, n) if qk_clip_state is not None else None
|
| 413 |
if scales_full is not None:
|
| 414 |
qk_clip(p, scales_full, qk_clip_state)
|
| 415 |
|
|
|
|
| 476 |
qk_clip_state = get_qk_clip_info(
|
| 477 |
self.clip_config, n, qk_logits)
|
| 478 |
scales_full = compute_scales(
|
| 479 |
+
p, qk_clip_state, n
|
| 480 |
) if qk_clip_state is not None else None
|
| 481 |
if scales_full is not None:
|
| 482 |
ratio = p.shape[0] // scales_full.shape[0]
|
|
|
|
| 555 |
qk_clip_state = get_qk_clip_info(
|
| 556 |
self.clip_config, n, qk_logits)
|
| 557 |
scales_full = compute_scales(
|
| 558 |
+
p, qk_clip_state, n
|
| 559 |
) if qk_clip_state is not None else None
|
| 560 |
if scales_full is not None:
|
| 561 |
ratio = p.shape[0] // scales_full.shape[0]
|
torch-ext/optimizer/pipeline.py
CHANGED
|
@@ -322,7 +322,7 @@ def _update_params(
|
|
| 322 |
state = param_to_state[id(p)]
|
| 323 |
if state.qk_clip_state is None:
|
| 324 |
continue
|
| 325 |
-
scales_full = compute_scales(p, state.qk_clip_state)
|
| 326 |
if scales_full is not None:
|
| 327 |
ratio = p.shape[0] // scales_full.shape[0]
|
| 328 |
idx0 = state.rank_indices[rank][0]
|
|
|
|
| 322 |
state = param_to_state[id(p)]
|
| 323 |
if state.qk_clip_state is None:
|
| 324 |
continue
|
| 325 |
+
scales_full = compute_scales(p, state.qk_clip_state, state.name)
|
| 326 |
if scales_full is not None:
|
| 327 |
ratio = p.shape[0] // scales_full.shape[0]
|
| 328 |
idx0 = state.rank_indices[rank][0]
|
torch-ext/optimizer/qk_clip.py
CHANGED
|
@@ -63,6 +63,9 @@ class QKClipInfo:
|
|
| 63 |
qk_nope_head_dim: int = 0
|
| 64 |
qk_rope_head_dim: int = 0
|
| 65 |
v_head_dim: int = 0
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
|
| 68 |
def get_qk_clip_info(clip_config, n, qk_logits):
|
|
@@ -85,6 +88,7 @@ def get_qk_clip_info(clip_config, n, qk_logits):
|
|
| 85 |
threshold = clip_config.get('threshold')
|
| 86 |
kind, layer_idx = parse_qk_layer(n)
|
| 87 |
is_mla = clip_config.get('is_mla', False)
|
|
|
|
| 88 |
|
| 89 |
logit, indices = None, []
|
| 90 |
if qk_logits is not None and kind is not None:
|
|
@@ -110,6 +114,7 @@ def get_qk_clip_info(clip_config, n, qk_logits):
|
|
| 110 |
qk_nope_head_dim=clip_config['qk_nope_head_dim'],
|
| 111 |
qk_rope_head_dim=clip_config['qk_rope_head_dim'],
|
| 112 |
v_head_dim=clip_config['v_head_dim'],
|
|
|
|
| 113 |
)
|
| 114 |
else:
|
| 115 |
return QKClipInfo(
|
|
@@ -121,35 +126,62 @@ def get_qk_clip_info(clip_config, n, qk_logits):
|
|
| 121 |
)
|
| 122 |
|
| 123 |
|
| 124 |
-
def compute_scales(p, qk_clip_state):
|
| 125 |
"""Compute per-head scaling factors for QK clipping.
|
| 126 |
|
| 127 |
-
Returns scales tensor
|
| 128 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
"""
|
| 130 |
kind = qk_clip_state.kind
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
indices = qk_clip_state.indices
|
| 132 |
head_dim = qk_clip_state.head_dim
|
| 133 |
threshold = qk_clip_state.threshold
|
| 134 |
logit = qk_clip_state.logit
|
| 135 |
|
| 136 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
head_scales = {}
|
| 138 |
for logit_idx, head_idx in enumerate(indices):
|
| 139 |
v_ele = float(logit[logit_idx])
|
| 140 |
if v_ele > threshold:
|
| 141 |
-
new_scale =
|
| 142 |
if head_idx not in head_scales or new_scale < head_scales[head_idx]:
|
| 143 |
head_scales[head_idx] = new_scale
|
| 144 |
logger.info(
|
| 145 |
-
f"[{kind}] Head {head_idx} exceeded threshold "
|
| 146 |
f"(value={v_ele:.4f}, threshold={threshold:.4f}) -> applying scale={new_scale:.4f}"
|
| 147 |
)
|
| 148 |
|
| 149 |
if not head_scales:
|
| 150 |
return None
|
| 151 |
|
| 152 |
-
#
|
| 153 |
if qk_clip_state.is_mla and kind == 'wkv_b':
|
| 154 |
effective_head_dim = qk_clip_state.qk_nope_head_dim + qk_clip_state.v_head_dim
|
| 155 |
else:
|
|
@@ -167,12 +199,13 @@ def qk_clip(p, scales, info):
|
|
| 167 |
|
| 168 |
Args:
|
| 169 |
p: Parameter (nn.Parameter or raw tensor).
|
| 170 |
-
scales: [n_heads] tensor
|
|
|
|
| 171 |
info: QKClipInfo with kind, head_dim, and MLA sub-head dimensions.
|
| 172 |
|
| 173 |
-
MLA
|
| 174 |
-
|
| 175 |
-
|
| 176 |
"""
|
| 177 |
W = p.data if isinstance(p, torch.nn.Parameter) else p
|
| 178 |
|
|
@@ -186,13 +219,12 @@ def qk_clip(p, scales, info):
|
|
| 186 |
qk_nope = info.qk_nope_head_dim
|
| 187 |
qk_head_dim = qk_nope + info.qk_rope_head_dim
|
| 188 |
W_3d = W.view(-1, qk_head_dim, W.shape[1]) # [H, qk_head_dim, in_dim]
|
| 189 |
-
W_3d[:, :qk_nope, :].mul_(scales.view(-1, 1, 1)) # q_nope →
|
| 190 |
-
W_3d[:, qk_nope:, :].mul_(
|
| 191 |
-
1)) # q_pe → γ
|
| 192 |
|
| 193 |
elif info.kind == 'wkv_b':
|
| 194 |
qk_nope = info.qk_nope_head_dim
|
| 195 |
kv_stride = qk_nope + info.v_head_dim
|
| 196 |
W_3d = W.view(-1, kv_stride, W.shape[1]) # [H, kv_stride, in_dim]
|
| 197 |
-
W_3d[:, :qk_nope, :].mul_(scales.view(-1, 1, 1)) # k_nope →
|
| 198 |
# v rows: not touched (k_R shared rotary unchanged)
|
|
|
|
| 63 |
qk_nope_head_dim: int = 0
|
| 64 |
qk_rope_head_dim: int = 0
|
| 65 |
v_head_dim: int = 0
|
| 66 |
+
# Fraction of log-reduction assigned to K (wkv_b). Q gets (1-k_ratio).
|
| 67 |
+
# 0.0 = all Q (K not clipped), 0.5 = equal split (MHA-like), 1.0 = all K.
|
| 68 |
+
k_ratio: float = 0.0
|
| 69 |
|
| 70 |
|
| 71 |
def get_qk_clip_info(clip_config, n, qk_logits):
|
|
|
|
| 88 |
threshold = clip_config.get('threshold')
|
| 89 |
kind, layer_idx = parse_qk_layer(n)
|
| 90 |
is_mla = clip_config.get('is_mla', False)
|
| 91 |
+
k_ratio = float(clip_config.get('k_ratio', 0.0))
|
| 92 |
|
| 93 |
logit, indices = None, []
|
| 94 |
if qk_logits is not None and kind is not None:
|
|
|
|
| 114 |
qk_nope_head_dim=clip_config['qk_nope_head_dim'],
|
| 115 |
qk_rope_head_dim=clip_config['qk_rope_head_dim'],
|
| 116 |
v_head_dim=clip_config['v_head_dim'],
|
| 117 |
+
k_ratio=k_ratio,
|
| 118 |
)
|
| 119 |
else:
|
| 120 |
return QKClipInfo(
|
|
|
|
| 126 |
)
|
| 127 |
|
| 128 |
|
| 129 |
+
def compute_scales(p, qk_clip_state, name: str = ''):
|
| 130 |
"""Compute per-head scaling factors for QK clipping.
|
| 131 |
|
| 132 |
+
Returns scales tensor per head if any head exceeds threshold, else None.
|
| 133 |
+
|
| 134 |
+
Scale convention (let γ = threshold/value):
|
| 135 |
+
MHA/GQA wq/wk : scale = √γ on both Q and K; product = γ.
|
| 136 |
+
MLA wq_b : scale = γ^(1 - k_ratio). Q carries (1-k_ratio) of the
|
| 137 |
+
log-reduction; k_ratio=0 → full γ on Q only (K unclipped).
|
| 138 |
+
MLA wkv_b : scale = γ^k_ratio applied to k_nope rows only (v rows
|
| 139 |
+
untouched). Returns None when k_ratio=0 (K unclipped).
|
| 140 |
+
Together wq_b × wkv_b deliver γ^(1-k_ratio) × γ^k_ratio = γ end-to-end.
|
| 141 |
"""
|
| 142 |
kind = qk_clip_state.kind
|
| 143 |
+
|
| 144 |
+
# MLA wkv_b: skip entirely when k_ratio=0 (all reduction on Q).
|
| 145 |
+
if qk_clip_state.is_mla and kind == 'wkv_b' and qk_clip_state.k_ratio == 0.0:
|
| 146 |
+
return None
|
| 147 |
+
|
| 148 |
indices = qk_clip_state.indices
|
| 149 |
head_dim = qk_clip_state.head_dim
|
| 150 |
threshold = qk_clip_state.threshold
|
| 151 |
logit = qk_clip_state.logit
|
| 152 |
|
| 153 |
+
# Exponent for (threshold/v_ele)^exponent:
|
| 154 |
+
# MLA wq_b → 1 - k_ratio (Q carries this fraction of log-reduction)
|
| 155 |
+
# MLA wkv_b → k_ratio (K carries the rest; applied to k_nope rows only)
|
| 156 |
+
# MHA/GQA → 0.5 (equal split; equivalent to k_ratio=0.5)
|
| 157 |
+
#
|
| 158 |
+
# Principled k_ratio for Q:K = G:1 GQA: 1 / (1 + sqrt(G))
|
| 159 |
+
# K's gradient is a sum of G Q-head terms that partially cancel, so its
|
| 160 |
+
# effective recovery signal scales as 1/sqrt(G) (random-walk argument).
|
| 161 |
+
# Setting clip/recovery equal for both sides:
|
| 162 |
+
# (1-r)/1 = r/(1/sqrt(G)) => r = 1/(1+sqrt(G))
|
| 163 |
+
# G=1 → 0.5 (recovers MHA), G=4 → ≈0.33, G=8 → ≈0.26.
|
| 164 |
+
if qk_clip_state.is_mla:
|
| 165 |
+
exponent = (1.0 - qk_clip_state.k_ratio) if kind == 'wq_b' else qk_clip_state.k_ratio
|
| 166 |
+
else:
|
| 167 |
+
exponent = 0.5
|
| 168 |
+
|
| 169 |
head_scales = {}
|
| 170 |
for logit_idx, head_idx in enumerate(indices):
|
| 171 |
v_ele = float(logit[logit_idx])
|
| 172 |
if v_ele > threshold:
|
| 173 |
+
new_scale = (threshold / v_ele) ** exponent
|
| 174 |
if head_idx not in head_scales or new_scale < head_scales[head_idx]:
|
| 175 |
head_scales[head_idx] = new_scale
|
| 176 |
logger.info(
|
| 177 |
+
f"[{kind}] {name} Head {head_idx} exceeded threshold "
|
| 178 |
f"(value={v_ele:.4f}, threshold={threshold:.4f}) -> applying scale={new_scale:.4f}"
|
| 179 |
)
|
| 180 |
|
| 181 |
if not head_scales:
|
| 182 |
return None
|
| 183 |
|
| 184 |
+
# wkv_b row-stride per head = qk_nope + v_head_dim (not head_dim)
|
| 185 |
if qk_clip_state.is_mla and kind == 'wkv_b':
|
| 186 |
effective_head_dim = qk_clip_state.qk_nope_head_dim + qk_clip_state.v_head_dim
|
| 187 |
else:
|
|
|
|
| 199 |
|
| 200 |
Args:
|
| 201 |
p: Parameter (nn.Parameter or raw tensor).
|
| 202 |
+
scales: [n_heads] tensor of per-head scale factors (γ^exponent).
|
| 203 |
+
Exponent semantics depend on kind — see compute_scales docstring.
|
| 204 |
info: QKClipInfo with kind, head_dim, and MLA sub-head dimensions.
|
| 205 |
|
| 206 |
+
MLA wq_b: γ^(1-k_ratio) applied uniformly to q_nope and q_pe rows.
|
| 207 |
+
MLA wkv_b: γ^k_ratio applied to k_nope rows only; v rows untouched.
|
| 208 |
+
MHA/GQA: √γ applied to all rows in each head.
|
| 209 |
"""
|
| 210 |
W = p.data if isinstance(p, torch.nn.Parameter) else p
|
| 211 |
|
|
|
|
| 219 |
qk_nope = info.qk_nope_head_dim
|
| 220 |
qk_head_dim = qk_nope + info.qk_rope_head_dim
|
| 221 |
W_3d = W.view(-1, qk_head_dim, W.shape[1]) # [H, qk_head_dim, in_dim]
|
| 222 |
+
W_3d[:, :qk_nope, :].mul_(scales.view(-1, 1, 1)) # q_nope → γ^(1-k_ratio)
|
| 223 |
+
W_3d[:, qk_nope:, :].mul_(scales.view(-1, 1, 1)) # q_pe → γ^(1-k_ratio)
|
|
|
|
| 224 |
|
| 225 |
elif info.kind == 'wkv_b':
|
| 226 |
qk_nope = info.qk_nope_head_dim
|
| 227 |
kv_stride = qk_nope + info.v_head_dim
|
| 228 |
W_3d = W.view(-1, kv_stride, W.shape[1]) # [H, kv_stride, in_dim]
|
| 229 |
+
W_3d[:, :qk_nope, :].mul_(scales.view(-1, 1, 1)) # k_nope → γ^k_ratio
|
| 230 |
# v rows: not touched (k_R shared rotary unchanged)
|