kernels-bot commited on
Commit
0213eef
·
verified ·
1 Parent(s): 2e7a731

Uploaded using `kernel-builder`.

Browse files
build/torch-rocm/__init__.py CHANGED
@@ -1,4 +1,10 @@
1
  from . import layers
2
- from .layers import CrossEntropyOutput, LigerForCausalLMLoss
3
 
4
- __all__ = ["layers", "LigerForCausalLMLoss", "CrossEntropyOutput"]
 
 
 
 
 
 
 
1
  from . import layers
2
+ from .layers import LigerForCausalLMLoss, liger_rotary_pos_emb
3
 
4
+
5
+ __all__ = [
6
+ "layers",
7
+ # kept for BC
8
+ "LigerForCausalLMLoss",
9
+ "liger_rotary_pos_emb",
10
+ ]
build/torch-rocm/_ops.py CHANGED
@@ -4,7 +4,13 @@ def get_backend() -> str:
4
  """Detect the backend by inspecting torch."""
5
  import torch
6
 
7
- if hasattr(torch, "neuron"):
 
 
 
 
 
 
8
  # Needs to be sorted before specific Torch builds, since Neuron
9
  # extension can be loaded into e.g. CUDA Torch builds.
10
  return "neuron"
@@ -22,7 +28,7 @@ def get_backend() -> str:
22
 
23
  def _find_ops_name() -> str:
24
  kernel_name = "liger_kernels"
25
- unique_id = "ab435e2"
26
  backend = get_backend()
27
  return f"_{kernel_name}_{backend}_{unique_id}"
28
 
 
4
  """Detect the backend by inspecting torch."""
5
  import torch
6
 
7
+ if hasattr(torch.backends, "tpu"):
8
+ # torch_tpu sets torch.backends.tpu when it is imported (via
9
+ # torch's device-backend autoload), regardless of whether TPU
10
+ # hardware is present — analogous to torch.version.cuda being
11
+ # set on CUDA builds without a GPU.
12
+ return "tpu"
13
+ elif hasattr(torch, "neuron"):
14
  # Needs to be sorted before specific Torch builds, since Neuron
15
  # extension can be loaded into e.g. CUDA Torch builds.
16
  return "neuron"
 
28
 
29
  def _find_ops_name() -> str:
30
  kernel_name = "liger_kernels"
31
+ unique_id = "a5e3c9a"
32
  backend = get_backend()
33
  return f"_{kernel_name}_{backend}_{unique_id}"
34
 
build/torch-rocm/cross_entropy.py CHANGED
@@ -11,6 +11,8 @@ from .utils import element_mul_kernel
11
  from .utils import is_hip
12
  from .utils import infer_device
13
  from .utils import is_npu_available
 
 
14
 
15
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
16
  try:
@@ -372,44 +374,45 @@ def cross_entropy_forward(
372
  if target.stride(-1) != 1:
373
  target = target.contiguous()
374
 
375
- # Here we use a trick to store X_ptr gradient in X_ptr so we can save memory
376
- liger_cross_entropy_kernel[(n_rows,)](
377
- X_ptr=_input,
378
- X_stride=_input.stride(-2),
379
- Y_ptr=target,
380
- Y_stride=target.stride(-1), # always 1
381
- weight_ptr=weight, # dummy if None
382
- loss_ptr=loss_1d,
383
- z_loss_ptr=z_loss_1d,
384
- loss_stride=loss_1d.stride(-1), # always 1
385
- token_accuracy_ptr=token_accuracy_1d,
386
- token_accuracy_stride=token_accuracy_1d.stride(-1)
387
- if return_token_accuracy
388
- else 0, # always 1 if accuracy is enabled
389
- predicted_tokens_ptr=predicted_tokens_1d,
390
- predicted_tokens_stride=predicted_tokens_1d.stride(-1)
391
- if return_predicted_tokens
392
- else 0, # always 1 if predicted tokens is enabled
393
- n_cols=V,
394
- n_non_ignore=n_non_ignore,
395
- sum_non_ignore_weight=sum_non_ignore_weight,
396
- ignore_index=ignore_index,
397
- weight_sum=weight_sum,
398
- lse_square_scale=lse_square_scale,
399
- label_smoothing=label_smoothing,
400
- reduction=reduction,
401
- softcap=softcap,
402
- RETURN_Z_LOSS=return_z_loss,
403
- RETURN_TOKEN_ACCURACY=return_token_accuracy,
404
- RETURN_PREDICTED_TOKENS=return_predicted_tokens,
405
- BLOCK_SIZE=BLOCK_SIZE,
406
- HAS_WEIGHT=True if weight is not None else False,
407
- HAS_SOFTCAPPING=True if softcap is not None else False,
408
- HAS_GRADIENTS=_input.requires_grad,
409
- # TODO: 32 seems to give the best performance
410
- # Performance is quite sensitive to num_warps
411
- num_warps=32 if not is_hip() else 16,
412
- )
 
413
 
414
  if reduction == "none":
415
  loss = loss_1d
@@ -437,18 +440,19 @@ def cross_entropy_backward(_input, grad_output):
437
  # We use a Triton kernel instead of a PyTorch operation because modifying inputs in-place
438
  # for gradient storage and backward multiple times causes anomalies with PyTorch but not with Triton.
439
  else:
440
- BT, V = _input.shape
441
- n_rows = BT
442
- BLOCK_SIZE = min(MAX_FUSED_SIZE, triton.next_power_of_2(V))
443
-
444
- element_mul_kernel[(n_rows,)](
445
- _input,
446
- _input.stride(-2),
447
- grad_output,
448
- V,
449
- BLOCK_SIZE=BLOCK_SIZE,
450
- num_warps=32 if not is_hip() else 16,
451
- )
 
452
 
453
  return _input
454
 
 
11
  from .utils import is_hip
12
  from .utils import infer_device
13
  from .utils import is_npu_available
14
+ from .utils import device_context
15
+
16
 
17
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
18
  try:
 
374
  if target.stride(-1) != 1:
375
  target = target.contiguous()
376
 
377
+ with device_context(_input.device):
378
+ # Here we use a trick to store X_ptr gradient in X_ptr so we can save memory
379
+ liger_cross_entropy_kernel[(n_rows,)](
380
+ X_ptr=_input,
381
+ X_stride=_input.stride(-2),
382
+ Y_ptr=target,
383
+ Y_stride=target.stride(-1), # always 1
384
+ weight_ptr=weight, # dummy if None
385
+ loss_ptr=loss_1d,
386
+ z_loss_ptr=z_loss_1d,
387
+ loss_stride=loss_1d.stride(-1), # always 1
388
+ token_accuracy_ptr=token_accuracy_1d,
389
+ token_accuracy_stride=token_accuracy_1d.stride(-1)
390
+ if return_token_accuracy
391
+ else 0, # always 1 if accuracy is enabled
392
+ predicted_tokens_ptr=predicted_tokens_1d,
393
+ predicted_tokens_stride=predicted_tokens_1d.stride(-1)
394
+ if return_predicted_tokens
395
+ else 0, # always 1 if predicted tokens is enabled
396
+ n_cols=V,
397
+ n_non_ignore=n_non_ignore,
398
+ sum_non_ignore_weight=sum_non_ignore_weight,
399
+ ignore_index=ignore_index,
400
+ weight_sum=weight_sum,
401
+ lse_square_scale=lse_square_scale,
402
+ label_smoothing=label_smoothing,
403
+ reduction=reduction,
404
+ softcap=softcap,
405
+ RETURN_Z_LOSS=return_z_loss,
406
+ RETURN_TOKEN_ACCURACY=return_token_accuracy,
407
+ RETURN_PREDICTED_TOKENS=return_predicted_tokens,
408
+ BLOCK_SIZE=BLOCK_SIZE,
409
+ HAS_WEIGHT=True if weight is not None else False,
410
+ HAS_SOFTCAPPING=True if softcap is not None else False,
411
+ HAS_GRADIENTS=_input.requires_grad,
412
+ # TODO: 32 seems to give the best performance
413
+ # Performance is quite sensitive to num_warps
414
+ num_warps=32 if not is_hip() else 16,
415
+ )
416
 
417
  if reduction == "none":
418
  loss = loss_1d
 
440
  # We use a Triton kernel instead of a PyTorch operation because modifying inputs in-place
441
  # for gradient storage and backward multiple times causes anomalies with PyTorch but not with Triton.
442
  else:
443
+ with device_context(_input.device):
444
+ BT, V = _input.shape
445
+ n_rows = BT
446
+ BLOCK_SIZE = min(MAX_FUSED_SIZE, triton.next_power_of_2(V))
447
+
448
+ element_mul_kernel[(n_rows,)](
449
+ _input,
450
+ _input.stride(-2),
451
+ grad_output,
452
+ V,
453
+ BLOCK_SIZE=BLOCK_SIZE,
454
+ num_warps=32 if not is_hip() else 16,
455
+ )
456
 
457
  return _input
458
 
build/torch-rocm/dyt.py CHANGED
@@ -9,6 +9,8 @@ from .utils import ensure_contiguous
9
  from .utils import get_npu_core_count
10
  from .utils import infer_device
11
  from .utils import is_npu_available
 
 
12
 
13
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
14
  try:
@@ -107,16 +109,17 @@ def liger_dyt_fwd(x, alpha, gamma, beta):
107
 
108
  y = torch.empty_like(x)
109
 
110
- grid = lambda meta: (triton.cdiv(N, meta["BLOCK_N"]), M)
111
- _dyt_fwd_kernel[grid](
112
- x,
113
- y,
114
- alpha,
115
- gamma,
116
- beta,
117
- HAVE_BETA,
118
- N,
119
- )
 
120
  return y.view(input_shape)
121
 
122
 
@@ -139,8 +142,9 @@ def liger_dyt_bwd(dy, x, alpha, gamma, beta):
139
  db = torch.empty(NUM_SMS, N, dtype=torch.float32, device=x.device) if HAVE_BETA else None
140
  dx = torch.empty_like(dy)
141
 
142
- grid = lambda meta: (triton.cdiv(N, meta["BLOCK_N"]), NUM_SMS)
143
- _dyt_bwd_kernel[grid](dy, dx, da, dg, db, x, alpha, gamma, HAVE_BETA, M, N)
 
144
  if HAVE_BETA:
145
  db = db.sum(0).to(x.dtype)
146
  dg = dg.sum(0).to(gamma.dtype)
 
9
  from .utils import get_npu_core_count
10
  from .utils import infer_device
11
  from .utils import is_npu_available
12
+ from .utils import device_context
13
+
14
 
15
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
16
  try:
 
109
 
110
  y = torch.empty_like(x)
111
 
112
+ with device_context(x.device):
113
+ grid = lambda meta: (triton.cdiv(N, meta["BLOCK_N"]), M)
114
+ _dyt_fwd_kernel[grid](
115
+ x,
116
+ y,
117
+ alpha,
118
+ gamma,
119
+ beta,
120
+ HAVE_BETA,
121
+ N,
122
+ )
123
  return y.view(input_shape)
124
 
125
 
 
142
  db = torch.empty(NUM_SMS, N, dtype=torch.float32, device=x.device) if HAVE_BETA else None
143
  dx = torch.empty_like(dy)
144
 
145
+ with device_context(x.device):
146
+ grid = lambda meta: (triton.cdiv(N, meta["BLOCK_N"]), NUM_SMS)
147
+ _dyt_bwd_kernel[grid](dy, dx, da, dg, db, x, alpha, gamma, HAVE_BETA, M, N)
148
  if HAVE_BETA:
149
  db = db.sum(0).to(x.dtype)
150
  dg = dg.sum(0).to(gamma.dtype)
build/torch-rocm/fused_linear_cross_entropy.py CHANGED
@@ -7,6 +7,7 @@ from .utils import amp_custom_fwd
7
  from .utils import element_mul_kernel
8
  from .utils import is_hip
9
  from .utils import infer_device
 
10
 
11
  # The hard limit of TRITON_MAX_TENSOR_NUMEL is 1048576 https://github.com/triton-lang/triton/blob/ba42a5c68fd0505f8c42f4202d53be0f8d9a5fe0/python/triton/language/core.py#L19
12
  # However, setting limit as 65536 as in LayerNorm tutorial is faster because of less register spilling
@@ -147,42 +148,43 @@ def fused_linear_cross_entropy_forward(
147
  logits_chunk = logits_chunk.contiguous()
148
  target_chunk = target_chunk.contiguous()
149
 
150
- # Here we calculate the gradient of logits_chunk in place so we can save memory.
151
- liger_cross_entropy_kernel[(n_rows,)](
152
- X_ptr=logits_chunk,
153
- X_stride=logits_chunk.stride(-2),
154
- Y_ptr=target_chunk,
155
- Y_stride=target_chunk.stride(-1), # always 1
156
- weight_ptr=ce_weight,
157
- loss_ptr=loss_1d_slice,
158
- z_loss_ptr=z_loss_1d_slice,
159
- loss_stride=loss_1d_slice.stride(-1), # always 1
160
- token_accuracy_ptr=token_accuracy_1d_slice,
161
- token_accuracy_stride=token_accuracy_1d_slice.stride(-1)
162
- if return_token_accuracy
163
- else 0, # always 1 if accuracy is enabled
164
- predicted_tokens_ptr=predicted_tokens_1d_slice,
165
- predicted_tokens_stride=predicted_tokens_1d_slice.stride(-1)
166
- if return_predicted_tokens
167
- else 0, # always 1 if predicted tokens is enabled
168
- n_cols=V,
169
- n_non_ignore=total_n_non_ignore,
170
- sum_non_ignore_weight=total_sum_non_ignore_ce_weight,
171
- weight_sum=ce_weight_sum,
172
- ignore_index=ignore_index,
173
- lse_square_scale=lse_square_scale,
174
- label_smoothing=label_smoothing,
175
- reduction=reduction,
176
- softcap=softcap,
177
- RETURN_Z_LOSS=return_z_loss,
178
- RETURN_TOKEN_ACCURACY=return_token_accuracy,
179
- RETURN_PREDICTED_TOKENS=return_predicted_tokens,
180
- HAS_WEIGHT=True if ce_weight is not None else False,
181
- HAS_SOFTCAPPING=True if softcap is not None else False,
182
- HAS_GRADIENTS=input_requires_grad,
183
- BLOCK_SIZE=BLOCK_SIZE,
184
- num_warps=32 if not is_hip() else 16,
185
- )
 
186
 
187
  # Apply token scaling if requested
188
  if use_token_scaling:
@@ -247,47 +249,48 @@ def fused_linear_cross_entropy_forward(
247
  def fused_linear_cross_entropy_backward(grad_output, grad_input, grad_weight, grad_bias):
248
  # If cross entropy is the last layer, grad_output is 1.0. Skip the mul to save time
249
  if not torch.equal(grad_output, torch.tensor(1.0, device=grad_output.device)):
250
- # We use a Triton kernel instead of a PyTorch operation because modifying inputs in-place
251
- # for gradient storage and backward multiple times causes anomalies with PyTorch but not with Triton.
252
- BT, H = grad_input.shape
253
- n_rows = BT
254
- BLOCK_SIZE = min(MAX_FUSED_SIZE, triton.next_power_of_2(H))
255
-
256
- element_mul_kernel[(n_rows,)](
257
- grad_input,
258
- grad_input.stride(-2),
259
- grad_output,
260
- H,
261
- BLOCK_SIZE=BLOCK_SIZE,
262
- num_warps=32 if not is_hip() else 16,
263
- )
264
-
265
- # handle grad_weight
266
- if grad_weight is not None:
267
- V, H = grad_weight.shape
268
- n_rows = V
269
 
270
  element_mul_kernel[(n_rows,)](
271
- grad_weight,
272
- grad_weight.stride(-2),
273
  grad_output,
274
  H,
275
  BLOCK_SIZE=BLOCK_SIZE,
276
  num_warps=32 if not is_hip() else 16,
277
  )
278
 
279
- if grad_bias is not None:
280
- V = grad_bias.shape[0]
281
- n_rows = V
282
-
283
- element_mul_kernel[(n_rows,)](
284
- grad_bias,
285
- grad_bias.stride(-1),
286
- grad_output,
287
- 1,
288
- BLOCK_SIZE=BLOCK_SIZE,
289
- num_warps=32 if not is_hip() else 16,
290
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  return grad_input, grad_weight, grad_bias
292
 
293
 
 
7
  from .utils import element_mul_kernel
8
  from .utils import is_hip
9
  from .utils import infer_device
10
+ from .utils import device_context
11
 
12
  # The hard limit of TRITON_MAX_TENSOR_NUMEL is 1048576 https://github.com/triton-lang/triton/blob/ba42a5c68fd0505f8c42f4202d53be0f8d9a5fe0/python/triton/language/core.py#L19
13
  # However, setting limit as 65536 as in LayerNorm tutorial is faster because of less register spilling
 
148
  logits_chunk = logits_chunk.contiguous()
149
  target_chunk = target_chunk.contiguous()
150
 
151
+ with device_context(device):
152
+ # Here we calculate the gradient of logits_chunk in place so we can save memory.
153
+ liger_cross_entropy_kernel[(n_rows,)](
154
+ X_ptr=logits_chunk,
155
+ X_stride=logits_chunk.stride(-2),
156
+ Y_ptr=target_chunk,
157
+ Y_stride=target_chunk.stride(-1), # always 1
158
+ weight_ptr=ce_weight,
159
+ loss_ptr=loss_1d_slice,
160
+ z_loss_ptr=z_loss_1d_slice,
161
+ loss_stride=loss_1d_slice.stride(-1), # always 1
162
+ token_accuracy_ptr=token_accuracy_1d_slice,
163
+ token_accuracy_stride=token_accuracy_1d_slice.stride(-1)
164
+ if return_token_accuracy
165
+ else 0, # always 1 if accuracy is enabled
166
+ predicted_tokens_ptr=predicted_tokens_1d_slice,
167
+ predicted_tokens_stride=predicted_tokens_1d_slice.stride(-1)
168
+ if return_predicted_tokens
169
+ else 0, # always 1 if predicted tokens is enabled
170
+ n_cols=V,
171
+ n_non_ignore=total_n_non_ignore,
172
+ sum_non_ignore_weight=total_sum_non_ignore_ce_weight,
173
+ weight_sum=ce_weight_sum,
174
+ ignore_index=ignore_index,
175
+ lse_square_scale=lse_square_scale,
176
+ label_smoothing=label_smoothing,
177
+ reduction=reduction,
178
+ softcap=softcap,
179
+ RETURN_Z_LOSS=return_z_loss,
180
+ RETURN_TOKEN_ACCURACY=return_token_accuracy,
181
+ RETURN_PREDICTED_TOKENS=return_predicted_tokens,
182
+ HAS_WEIGHT=True if ce_weight is not None else False,
183
+ HAS_SOFTCAPPING=True if softcap is not None else False,
184
+ HAS_GRADIENTS=input_requires_grad,
185
+ BLOCK_SIZE=BLOCK_SIZE,
186
+ num_warps=32 if not is_hip() else 16,
187
+ )
188
 
189
  # Apply token scaling if requested
190
  if use_token_scaling:
 
249
  def fused_linear_cross_entropy_backward(grad_output, grad_input, grad_weight, grad_bias):
250
  # If cross entropy is the last layer, grad_output is 1.0. Skip the mul to save time
251
  if not torch.equal(grad_output, torch.tensor(1.0, device=grad_output.device)):
252
+ with device_context(grad_input.device):
253
+ # We use a Triton kernel instead of a PyTorch operation because modifying inputs in-place
254
+ # for gradient storage and backward multiple times causes anomalies with PyTorch but not with Triton.
255
+ BT, H = grad_input.shape
256
+ n_rows = BT
257
+ BLOCK_SIZE = min(MAX_FUSED_SIZE, triton.next_power_of_2(H))
 
 
 
 
 
 
 
 
 
 
 
 
 
258
 
259
  element_mul_kernel[(n_rows,)](
260
+ grad_input,
261
+ grad_input.stride(-2),
262
  grad_output,
263
  H,
264
  BLOCK_SIZE=BLOCK_SIZE,
265
  num_warps=32 if not is_hip() else 16,
266
  )
267
 
268
+ # handle grad_weight
269
+ if grad_weight is not None:
270
+ V, H = grad_weight.shape
271
+ n_rows = V
272
+
273
+ element_mul_kernel[(n_rows,)](
274
+ grad_weight,
275
+ grad_weight.stride(-2),
276
+ grad_output,
277
+ H,
278
+ BLOCK_SIZE=BLOCK_SIZE,
279
+ num_warps=32 if not is_hip() else 16,
280
+ )
281
+
282
+ if grad_bias is not None:
283
+ V = grad_bias.shape[0]
284
+ n_rows = V
285
+
286
+ element_mul_kernel[(n_rows,)](
287
+ grad_bias,
288
+ grad_bias.stride(-1),
289
+ grad_output,
290
+ 1,
291
+ BLOCK_SIZE=BLOCK_SIZE,
292
+ num_warps=32 if not is_hip() else 16,
293
+ )
294
  return grad_input, grad_weight, grad_bias
295
 
296
 
build/torch-rocm/geglu.py CHANGED
@@ -8,6 +8,8 @@ from .utils import calculate_settings
8
  from .utils import compare_version
9
  from .utils import ensure_contiguous
10
  from .utils import is_npu_available
 
 
11
 
12
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
13
  try:
@@ -94,15 +96,16 @@ def geglu_forward(a, b):
94
 
95
  BLOCK_SIZE, num_warps = calculate_settings(n_cols)
96
 
97
- _geglu_tanh_forward_kernel[(n_rows,)](
98
- a,
99
- b,
100
- c,
101
- c.stride(-2),
102
- n_cols=n_cols,
103
- BLOCK_SIZE=BLOCK_SIZE,
104
- num_warps=num_warps,
105
- )
 
106
  return a, b, c.view(*ori_shape)
107
 
108
 
@@ -114,15 +117,16 @@ def geglu_backward(a, b, dc):
114
 
115
  BLOCK_SIZE, num_warps = calculate_settings(n_cols)
116
 
117
- _geglu_tanh_backward_kernel[(n_rows,)](
118
- dc,
119
- a,
120
- b,
121
- dc.stride(-2),
122
- n_cols=n_cols,
123
- BLOCK_SIZE=BLOCK_SIZE,
124
- num_warps=num_warps,
125
- )
 
126
 
127
  return a.view(*ori_shape), b.view(*ori_shape)
128
 
 
8
  from .utils import compare_version
9
  from .utils import ensure_contiguous
10
  from .utils import is_npu_available
11
+ from .utils import device_context
12
+
13
 
14
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
15
  try:
 
96
 
97
  BLOCK_SIZE, num_warps = calculate_settings(n_cols)
98
 
99
+ with device_context(a.device):
100
+ _geglu_tanh_forward_kernel[(n_rows,)](
101
+ a,
102
+ b,
103
+ c,
104
+ c.stride(-2),
105
+ n_cols=n_cols,
106
+ BLOCK_SIZE=BLOCK_SIZE,
107
+ num_warps=num_warps,
108
+ )
109
  return a, b, c.view(*ori_shape)
110
 
111
 
 
117
 
118
  BLOCK_SIZE, num_warps = calculate_settings(n_cols)
119
 
120
+ with device_context(a.device):
121
+ _geglu_tanh_backward_kernel[(n_rows,)](
122
+ dc,
123
+ a,
124
+ b,
125
+ dc.stride(-2),
126
+ n_cols=n_cols,
127
+ BLOCK_SIZE=BLOCK_SIZE,
128
+ num_warps=num_warps,
129
+ )
130
 
131
  return a.view(*ori_shape), b.view(*ori_shape)
132
 
build/torch-rocm/group_norm.py CHANGED
@@ -8,6 +8,8 @@ from .utils import compare_version
8
  from .utils import ensure_contiguous
9
  from .utils import infer_device
10
  from .utils import is_npu_available
 
 
11
 
12
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
13
  try:
@@ -215,26 +217,27 @@ def group_norm_forward(X, num_channels, num_groups, W, B, eps):
215
  Mean = torch.zeros((batch_size, num_groups), dtype=X.dtype, device=X.device)
216
  RSTD = torch.zeros((batch_size, num_groups), dtype=X.dtype, device=X.device)
217
 
218
- _group_norm_forward_kernel[(batch_size, num_groups)](
219
- Y,
220
- Y.stride(0),
221
- Y.stride(1),
222
- X,
223
- X.stride(0),
224
- X.stride(1),
225
- Mean,
226
- Mean.stride(0),
227
- Mean.stride(1),
228
- RSTD,
229
- RSTD.stride(0),
230
- RSTD.stride(1),
231
- W,
232
- B,
233
- hidden_size,
234
- channels_per_group,
235
- eps,
236
- BLOCK_SIZE=BLOCK_SIZE,
237
- )
 
238
  # Return tensors in the original shape
239
  return Y.view(*shape), X.view(*shape), Mean, RSTD, BLOCK_SIZE
240
 
@@ -254,25 +257,26 @@ def group_norm_backward(dY, X, W, B, Mean, RSTD, num_channels, num_groups):
254
  DB = torch.zeros((num_channels), dtype=B.dtype, device=B.device)
255
  triton_dtype = tl.float32 if X.dtype == torch.float32 else tl.bfloat16
256
 
257
- BLOCK_SIZE = min(MAX_FUSED_SIZE, triton.next_power_of_2(hidden_size))
258
- _group_norm_backward_kernel[(batch_size, num_groups)](
259
- X,
260
- X.stride(0),
261
- X.stride(1),
262
- W,
263
- Mean,
264
- Mean.stride(0),
265
- Mean.stride(1),
266
- RSTD,
267
- DX,
268
- DW,
269
- DB,
270
- dY,
271
- hidden_size,
272
- channels_per_group,
273
- BLOCK_SIZE=BLOCK_SIZE,
274
- dtype=triton_dtype,
275
- )
 
276
 
277
  # Return tensors in the original shape
278
  return DX.view(*shape), DW, DB
 
8
  from .utils import ensure_contiguous
9
  from .utils import infer_device
10
  from .utils import is_npu_available
11
+ from .utils import device_context
12
+
13
 
14
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
15
  try:
 
217
  Mean = torch.zeros((batch_size, num_groups), dtype=X.dtype, device=X.device)
218
  RSTD = torch.zeros((batch_size, num_groups), dtype=X.dtype, device=X.device)
219
 
220
+ with device_context(X.device):
221
+ _group_norm_forward_kernel[(batch_size, num_groups)](
222
+ Y,
223
+ Y.stride(0),
224
+ Y.stride(1),
225
+ X,
226
+ X.stride(0),
227
+ X.stride(1),
228
+ Mean,
229
+ Mean.stride(0),
230
+ Mean.stride(1),
231
+ RSTD,
232
+ RSTD.stride(0),
233
+ RSTD.stride(1),
234
+ W,
235
+ B,
236
+ hidden_size,
237
+ channels_per_group,
238
+ eps,
239
+ BLOCK_SIZE=BLOCK_SIZE,
240
+ )
241
  # Return tensors in the original shape
242
  return Y.view(*shape), X.view(*shape), Mean, RSTD, BLOCK_SIZE
243
 
 
257
  DB = torch.zeros((num_channels), dtype=B.dtype, device=B.device)
258
  triton_dtype = tl.float32 if X.dtype == torch.float32 else tl.bfloat16
259
 
260
+ with device_context(X.device):
261
+ BLOCK_SIZE = min(MAX_FUSED_SIZE, triton.next_power_of_2(hidden_size))
262
+ _group_norm_backward_kernel[(batch_size, num_groups)](
263
+ X,
264
+ X.stride(0),
265
+ X.stride(1),
266
+ W,
267
+ Mean,
268
+ Mean.stride(0),
269
+ Mean.stride(1),
270
+ RSTD,
271
+ DX,
272
+ DW,
273
+ DB,
274
+ dY,
275
+ hidden_size,
276
+ channels_per_group,
277
+ BLOCK_SIZE=BLOCK_SIZE,
278
+ dtype=triton_dtype,
279
+ )
280
 
281
  # Return tensors in the original shape
282
  return DX.view(*shape), DW, DB
build/torch-rocm/jsd.py CHANGED
@@ -6,6 +6,7 @@ import triton.language as tl
6
 
7
  from .utils import ensure_contiguous
8
  from .utils import infer_device
 
9
 
10
 
11
  @triton.jit
@@ -109,23 +110,24 @@ def jsd_forward(_input, target, shift_labels, beta, ignore_index, has_label):
109
  else:
110
  n_non_ignore = BT
111
 
112
- _jsd_kernel[(n_rows,)](
113
- X_ptr=_input, # input in logspace, X = log Q
114
- X_stride=_input.stride(-2),
115
- Y_ptr=target, # ground truth in logspace, Y = log P
116
- Y_stride=target.stride(-2),
117
- loss_ptr=loss,
118
- loss_stride=loss.stride(-2),
119
- dX_ptr=dX,
120
- dX_stride=dX.stride(-2),
121
- label_ptr=(shift_labels if has_label else torch.empty(1, device=_input.device)), # dummy ptr if no label
122
- beta=beta,
123
- n_non_ignore=n_non_ignore,
124
- ignore_index=ignore_index,
125
- n_cols=V,
126
- BLOCK_SIZE=BLOCK_SIZE,
127
- HAS_LABEL=has_label,
128
- )
 
129
 
130
  loss = torch.sum(loss)
131
  return loss.to(_input.dtype), dX
 
6
 
7
  from .utils import ensure_contiguous
8
  from .utils import infer_device
9
+ from .utils import device_context
10
 
11
 
12
  @triton.jit
 
110
  else:
111
  n_non_ignore = BT
112
 
113
+ with device_context(_input.device):
114
+ _jsd_kernel[(n_rows,)](
115
+ X_ptr=_input, # input in logspace, X = log Q
116
+ X_stride=_input.stride(-2),
117
+ Y_ptr=target, # ground truth in logspace, Y = log P
118
+ Y_stride=target.stride(-2),
119
+ loss_ptr=loss,
120
+ loss_stride=loss.stride(-2),
121
+ dX_ptr=dX,
122
+ dX_stride=dX.stride(-2),
123
+ label_ptr=(shift_labels if has_label else torch.empty(1, device=_input.device)), # dummy ptr if no label
124
+ beta=beta,
125
+ n_non_ignore=n_non_ignore,
126
+ ignore_index=ignore_index,
127
+ n_cols=V,
128
+ BLOCK_SIZE=BLOCK_SIZE,
129
+ HAS_LABEL=has_label,
130
+ )
131
 
132
  loss = torch.sum(loss)
133
  return loss.to(_input.dtype), dX
build/torch-rocm/kl_div.py CHANGED
@@ -7,6 +7,7 @@ import triton.language as tl
7
  from .utils import ensure_contiguous
8
  from .utils import is_hip
9
  from .utils import infer_device
 
10
 
11
 
12
  def get_num_warps(BLOCK_SIZE):
@@ -130,20 +131,21 @@ def kldiv_forward_triton(y_pred, y_true, log_target, reduction, eps): # [BT, V]
130
  out_size = (BT, V) if reduction == _REDUCTION_MODE_NONE.value else (BT,)
131
  output_tensor = torch.zeros(out_size, device=y_pred.device, dtype=torch.float32)
132
 
133
- _kldiv_kernel_forward[grid](
134
- y_pred,
135
- y_pred.stride(0),
136
- y_true,
137
- y_true.stride(0),
138
- output_tensor,
139
- output_tensor.stride(0),
140
- V,
141
- eps=eps,
142
- BLOCK_SIZE=BLOCK_SIZE,
143
- num_warps=num_warps,
144
- log_target=log_target,
145
- reduction=reduction,
146
- )
 
147
 
148
  # calculated according to the reduction mode same as in Pytorch. In the later versions, `mean` will be changed to the same behavior as `batchmean`
149
  # https://pytorch.org/docs/stable/generated/torch.nn.KLDivLoss.html
@@ -165,17 +167,18 @@ def kldiv_backward_triton(target, grad_output, new_grads, log_target):
165
 
166
  grid = (BT,)
167
 
168
- # We store the gradients in-place in the input tensor
169
- _kldiv_kernel_backward[grid](
170
- target,
171
- target.stride(0),
172
- new_grads,
173
- new_grads.stride(0),
174
- V,
175
- BLOCK_SIZE=BLOCK_SIZE,
176
- num_warps=num_warps,
177
- log_target=log_target,
178
- )
 
179
 
180
  # If cross entropy is the last layer, grad_output is 1.0. Skip the mul then.
181
  if torch.equal(grad_output, torch.tensor(1.0, device=grad_output.device)):
 
7
  from .utils import ensure_contiguous
8
  from .utils import is_hip
9
  from .utils import infer_device
10
+ from .utils import device_context
11
 
12
 
13
  def get_num_warps(BLOCK_SIZE):
 
131
  out_size = (BT, V) if reduction == _REDUCTION_MODE_NONE.value else (BT,)
132
  output_tensor = torch.zeros(out_size, device=y_pred.device, dtype=torch.float32)
133
 
134
+ with device_context(y_pred.device):
135
+ _kldiv_kernel_forward[grid](
136
+ y_pred,
137
+ y_pred.stride(0),
138
+ y_true,
139
+ y_true.stride(0),
140
+ output_tensor,
141
+ output_tensor.stride(0),
142
+ V,
143
+ eps=eps,
144
+ BLOCK_SIZE=BLOCK_SIZE,
145
+ num_warps=num_warps,
146
+ log_target=log_target,
147
+ reduction=reduction,
148
+ )
149
 
150
  # calculated according to the reduction mode same as in Pytorch. In the later versions, `mean` will be changed to the same behavior as `batchmean`
151
  # https://pytorch.org/docs/stable/generated/torch.nn.KLDivLoss.html
 
167
 
168
  grid = (BT,)
169
 
170
+ with device_context(target.device):
171
+ # We store the gradients in-place in the input tensor
172
+ _kldiv_kernel_backward[grid](
173
+ target,
174
+ target.stride(0),
175
+ new_grads,
176
+ new_grads.stride(0),
177
+ V,
178
+ BLOCK_SIZE=BLOCK_SIZE,
179
+ num_warps=num_warps,
180
+ log_target=log_target,
181
+ )
182
 
183
  # If cross entropy is the last layer, grad_output is 1.0. Skip the mul then.
184
  if torch.equal(grad_output, torch.tensor(1.0, device=grad_output.device)):
build/torch-rocm/layer_norm.py CHANGED
@@ -11,6 +11,8 @@ from .utils import ensure_contiguous
11
  from .utils import get_npu_core_count
12
  from .utils import set_large_grf_mode
13
  from .utils import is_npu_available
 
 
14
 
15
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
16
  try:
@@ -202,26 +204,27 @@ def layer_norm_forward(X, W, B, eps):
202
  if X.device.type == "xpu":
203
  set_large_grf_mode(kernel_args)
204
 
205
- # Launch kernel with one thread block per row for optimal performance
206
- grid = (n_rows,)
207
- _layer_norm_forward_kernel[grid](
208
- Y,
209
- Y.stride(0),
210
- X,
211
- X.stride(0),
212
- W,
213
- W.stride(0),
214
- B,
215
- B.stride(0),
216
- Mean,
217
- Mean.stride(0),
218
- RSTD,
219
- RSTD.stride(0),
220
- n_cols,
221
- eps,
222
- BLOCK_SIZE=BLOCK_SIZE,
223
- num_warps=num_warps,
224
- **kernel_args,
 
225
  )
226
 
227
  return Y.view(*shape), X, Mean, RSTD, BLOCK_SIZE, num_warps
@@ -273,29 +276,30 @@ def layer_norm_backward(dY, X, W, B, Mean, RSTD):
273
  kernel_args.update({"num_warps": 32, "num_stages": 4})
274
  set_large_grf_mode(kernel_args)
275
 
276
- # Launch kernel with one thread block per row for optimal performance
277
- _layer_norm_backward_kernel[grid](
278
- X,
279
- X.stride(0),
280
- W,
281
- Mean,
282
- Mean.stride(0),
283
- RSTD,
284
- RSTD.stride(0),
285
- DX,
286
- DX.stride(0),
287
- _DW,
288
- _DW.stride(0),
289
- _DB,
290
- _DB.stride(0),
291
- dY,
292
- dY.stride(0),
293
- n_rows,
294
- n_cols,
295
- rows_per_program=rows_per_program,
296
- BLOCK_SIZE=BLOCK_SIZE,
297
- **kernel_args,
298
- )
 
299
 
300
  DX = DX.view(*shape)
301
  DW = _DW.sum(dim=0).to(W.dtype)
 
11
  from .utils import get_npu_core_count
12
  from .utils import set_large_grf_mode
13
  from .utils import is_npu_available
14
+ from .utils import device_context
15
+
16
 
17
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
18
  try:
 
204
  if X.device.type == "xpu":
205
  set_large_grf_mode(kernel_args)
206
 
207
+ with device_context(X.device):
208
+ # Launch kernel with one thread block per row for optimal performance
209
+ grid = (n_rows,)
210
+ _layer_norm_forward_kernel[grid](
211
+ Y,
212
+ Y.stride(0),
213
+ X,
214
+ X.stride(0),
215
+ W,
216
+ W.stride(0),
217
+ B,
218
+ B.stride(0),
219
+ Mean,
220
+ Mean.stride(0),
221
+ RSTD,
222
+ RSTD.stride(0),
223
+ n_cols,
224
+ eps,
225
+ BLOCK_SIZE=BLOCK_SIZE,
226
+ num_warps=num_warps,
227
+ **kernel_args,
228
  )
229
 
230
  return Y.view(*shape), X, Mean, RSTD, BLOCK_SIZE, num_warps
 
276
  kernel_args.update({"num_warps": 32, "num_stages": 4})
277
  set_large_grf_mode(kernel_args)
278
 
279
+ with device_context(X.device):
280
+ # Launch kernel with one thread block per row for optimal performance
281
+ _layer_norm_backward_kernel[grid](
282
+ X,
283
+ X.stride(0),
284
+ W,
285
+ Mean,
286
+ Mean.stride(0),
287
+ RSTD,
288
+ RSTD.stride(0),
289
+ DX,
290
+ DX.stride(0),
291
+ _DW,
292
+ _DW.stride(0),
293
+ _DB,
294
+ _DB.stride(0),
295
+ dY,
296
+ dY.stride(0),
297
+ n_rows,
298
+ n_cols,
299
+ rows_per_program=rows_per_program,
300
+ BLOCK_SIZE=BLOCK_SIZE,
301
+ **kernel_args,
302
+ )
303
 
304
  DX = DX.view(*shape)
305
  DW = _DW.sum(dim=0).to(W.dtype)
build/torch-rocm/layers.py CHANGED
@@ -1,360 +1,144 @@
1
  import inspect
2
  from dataclasses import dataclass
3
- from typing import Optional, Tuple
4
 
5
  import torch
6
  import torch.nn as nn
7
 
8
- from .cross_entropy import LigerCrossEntropyFunction
9
- from .dyt import LigerDyTFunction
10
  from .fused_linear_cross_entropy import LigerFusedLinearCrossEntropyFunction
11
  from .geglu import LigerGELUMulFunction
12
- from .group_norm import LigerGroupNormFunction
13
- from .jsd import LigerJSDFunction
14
- from .kl_div import LigerKLDivLossFunction
15
- from .layer_norm import LigerLayerNormFunction
16
- from .qwen2vl_mrope import LigerQwen2VLMRopeFunction
17
  from .rms_norm import LigerRMSNormFunction
18
  from .rope import LigerRopeFunction
19
  from .swiglu import LigerSiLUMulFunction
20
  from .tiled_mlp import apply_tiled_mlp
21
- from .tvd import LigerTVDLossFunction
22
 
23
 
24
  class LigerRMSNorm(nn.Module):
25
- def __init__(
26
- self,
27
- hidden_size: int,
28
- eps: float = 1e-6,
29
- offset: float = 0.0,
30
- casting_mode: str = "llama",
31
- init_fn: str = "ones",
32
- in_place: bool = True,
33
- row_mode: Optional[bool] = None,
34
- elementwise_affine: bool = True,
35
- ):
36
- super().__init__()
37
- assert init_fn in ("ones", "zeros"), f"init_fn must be 'ones' or 'zeros', got {init_fn}"
38
- self.hidden_size = hidden_size
39
- self.variance_epsilon = eps
40
- self.offset = offset
41
- self.casting_mode = casting_mode
42
- self.in_place = in_place
43
- self.row_mode = row_mode
44
- self.elementwise_affine = elementwise_affine
45
- if elementwise_affine:
46
- init = torch.ones(hidden_size) if init_fn == "ones" else torch.zeros(hidden_size)
47
- self.weight = nn.Parameter(init)
48
- else:
49
- self.register_parameter("weight", None)
50
 
51
- def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
52
- return LigerRMSNormFunction.apply(
53
- hidden_states,
54
- self.weight,
55
- self.variance_epsilon,
56
- self.offset,
57
- self.casting_mode,
58
- self.in_place,
59
- self.row_mode,
60
- )
61
-
62
- def extra_repr(self) -> str:
63
- return (
64
- f"{self.hidden_size}, eps={self.variance_epsilon}, offset={self.offset}, "
65
- f"in_place={self.in_place}, row_mode={self.row_mode}"
66
- )
67
-
68
-
69
- class LigerLayerNorm(nn.Module):
70
- def __init__(
71
- self,
72
- hidden_size: int,
73
- eps: float = 1e-6,
74
- bias: bool = False,
75
- init_fn: str = "ones",
76
- ):
77
- super().__init__()
78
- assert init_fn in ("ones", "zeros"), f"init_fn must be 'ones' or 'zeros', got {init_fn}"
79
- self.hidden_size = hidden_size
80
- self.variance_epsilon = eps
81
- self.weight = nn.Parameter(torch.ones(hidden_size) if init_fn == "ones" else torch.zeros(hidden_size))
82
- self.bias = nn.Parameter(torch.randn(hidden_size) if bias else torch.zeros(hidden_size))
83
 
84
  def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
85
- return LigerLayerNormFunction.apply(hidden_states, self.weight, self.bias, self.variance_epsilon)
86
-
87
- def extra_repr(self) -> str:
88
- return f"{self.hidden_size}, eps={self.variance_epsilon}"
89
-
90
-
91
- class LigerGroupNorm(nn.Module):
92
- def __init__(
93
- self,
94
- num_channels: int,
95
- num_groups: int,
96
- eps: float = 1e-6,
97
- bias: bool = False,
98
- init_fn: str = "ones",
99
- ):
100
- super().__init__()
101
- assert init_fn in ("ones", "zeros"), f"init_fn must be 'ones' or 'zeros', got {init_fn}"
102
- assert num_channels % num_groups == 0, (
103
- f"num_channels ({num_channels}) must be divisible by num_groups ({num_groups})"
104
- )
105
- self.num_channels = num_channels
106
- self.num_groups = num_groups
107
- self.variance_epsilon = eps
108
- self.weight = nn.Parameter(torch.ones(num_channels) if init_fn == "ones" else torch.zeros(num_channels))
109
- self.bias = nn.Parameter(torch.randn(num_channels) if bias else torch.zeros(num_channels))
110
-
111
- def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
112
- assert hidden_states.dim() >= 3, f"Input must have at least 3 dimensions, got {hidden_states.dim()}"
113
- assert hidden_states.size(1) == self.num_channels, (
114
- f"Input must have {self.num_channels} channels, got {hidden_states.size(1)}"
115
- )
116
- return LigerGroupNormFunction.apply(
117
  hidden_states,
118
  self.weight,
119
- self.bias,
120
- self.num_channels,
121
- self.num_groups,
122
  self.variance_epsilon,
123
- )
124
-
125
- def extra_repr(self) -> str:
126
- return f"num_channels={self.num_channels}, num_groups={self.num_groups}, eps={self.variance_epsilon}"
127
-
128
-
129
- class LigerDyT(nn.Module):
130
- def __init__(self, hidden_size: int, beta: bool = True, init_alpha: float = 0.5):
131
- super().__init__()
132
- self.hidden_size = hidden_size
133
- self.init_alpha = init_alpha
134
- self.alpha = nn.Parameter(torch.ones(1) * init_alpha)
135
- self.gamma = nn.Parameter(torch.ones(hidden_size))
136
- self.beta = nn.Parameter(torch.zeros(hidden_size)) if beta else None
137
-
138
- def forward(self, x: torch.Tensor) -> torch.Tensor:
139
- return LigerDyTFunction.apply(x, self.alpha, self.gamma, self.beta)
140
-
141
- def extra_repr(self) -> str:
142
- return f"{self.hidden_size}, init_alpha={self.init_alpha}, beta={self.beta is not None}"
143
-
144
-
145
- class LigerCrossEntropyLoss(nn.Module):
146
- def __init__(
147
- self,
148
- weight: Optional[torch.Tensor] = None,
149
- ignore_index: int = -100,
150
- lse_square_scale: float = 0.0,
151
- label_smoothing: float = 0.0,
152
- reduction: str = "mean",
153
- softcap: Optional[float] = None,
154
- ):
155
- super().__init__()
156
- assert 0.0 <= label_smoothing <= 1.0, f"label_smoothing must be in [0, 1], got {label_smoothing}"
157
- assert reduction in ("mean", "sum", "none"), f"reduction must be 'mean', 'sum', or 'none', got {reduction}"
158
- assert softcap is None or softcap > 0, f"softcap must be > 0 or None, got {softcap}"
159
- self.weight = weight
160
- self.ignore_index = ignore_index
161
- self.lse_square_scale = lse_square_scale
162
- self.label_smoothing = label_smoothing
163
- self.reduction = reduction
164
- self.softcap = softcap
165
-
166
- def forward(self, _input: torch.Tensor, target: torch.Tensor) -> torch.Tensor:
167
- loss, _, _, _ = LigerCrossEntropyFunction.apply(
168
- _input,
169
- target,
170
- self.weight,
171
- self.ignore_index,
172
- self.lse_square_scale,
173
- self.label_smoothing,
174
- self.reduction,
175
- self.softcap,
176
- False,
177
- False,
178
  False,
 
179
  )
180
- return loss
181
 
 
 
182
 
183
- class LigerFusedLinearCrossEntropyLoss(nn.Module):
184
- def __init__(
185
- self,
186
- ce_weight: Optional[torch.Tensor] = None,
187
- ignore_index: int = -100,
188
- lse_square_scale: float = 0.0,
189
- label_smoothing: float = 0.0,
190
- reduction: str = "mean",
191
- softcap: Optional[float] = None,
192
- accum_dtype: Optional[torch.dtype] = None,
193
- use_token_scaling: bool = False,
194
- ):
195
- super().__init__()
196
- assert 0.0 <= label_smoothing <= 1.0, f"label_smoothing must be in [0, 1], got {label_smoothing}"
197
- assert reduction in ("mean", "sum", "none"), f"reduction must be 'mean', 'sum', or 'none', got {reduction}"
198
- assert softcap is None or softcap > 0, f"softcap must be > 0 or None, got {softcap}"
199
- self.ce_weight = ce_weight
200
- self.ignore_index = ignore_index
201
- self.lse_square_scale = lse_square_scale
202
- self.label_smoothing = label_smoothing
203
- self.reduction = reduction
204
- self.softcap = softcap
205
- self.accum_dtype = accum_dtype
206
- self.use_token_scaling = use_token_scaling
207
 
208
- def forward(
209
- self,
210
- lin_weight: torch.Tensor,
211
- _input: torch.Tensor,
212
- target: torch.Tensor,
213
- bias: Optional[torch.Tensor] = None,
214
- ) -> torch.Tensor:
215
- loss, _, _, _ = LigerFusedLinearCrossEntropyFunction.apply(
216
- _input,
217
- lin_weight,
218
- target,
219
- bias,
220
- self.ce_weight,
221
- self.ignore_index,
222
- self.lse_square_scale,
223
- self.label_smoothing,
224
- self.reduction,
225
- self.softcap,
226
- False,
227
- self.accum_dtype,
228
- self.use_token_scaling,
229
- False,
230
- False,
231
- )
232
- return loss
233
 
 
234
 
235
- class LigerJSD(nn.Module):
236
- def __init__(self, beta: float = 0.5, ignore_index: int = -100):
237
- super().__init__()
238
- self.beta = beta
239
- self.ignore_index = ignore_index
240
 
241
- def forward(
242
- self,
243
- log_q: torch.Tensor,
244
- log_p: torch.Tensor,
245
- shift_labels: Optional[torch.Tensor] = None,
246
- ) -> torch.Tensor:
247
- return LigerJSDFunction.apply(log_q, log_p, shift_labels, self.beta, self.ignore_index)
248
-
249
-
250
- class LigerKLDIVLoss(nn.KLDivLoss):
251
- def __init__(self, eps: float = 1e-10, *args, **kwargs):
252
- super().__init__(*args, **kwargs)
253
- self.eps = eps
254
-
255
- def forward(self, y_pred: torch.Tensor, y_true: torch.Tensor) -> torch.Tensor:
256
- return LigerKLDivLossFunction.apply(y_pred, y_true, self.reduction, self.log_target, self.eps)
257
-
258
-
259
- class LigerTVDLoss(nn.Module):
260
- def __init__(self, reduction: str = "batchmean", ignore_index: int = -100):
261
- super().__init__()
262
- self.reduction = reduction
263
- self.ignore_index = ignore_index
264
 
265
- def forward(
266
- self,
267
- p: torch.Tensor,
268
- q: torch.Tensor,
269
- shift_labels: Optional[torch.Tensor] = None,
270
- ) -> torch.Tensor:
271
- return LigerTVDLossFunction.apply(p, q, shift_labels, self.reduction, self.ignore_index)
272
 
273
 
274
  class LigerSwiGLUMLP(nn.Module):
275
- """SwiGLU MLP block. ``config`` must expose ``hidden_size``, ``intermediate_size``,
276
- and ``hidden_act`` (must be ``silu`` or ``swish``)."""
277
-
278
- def __init__(self, config):
279
- super().__init__()
280
- if config.hidden_act not in ("silu", "swish"):
281
- raise ValueError(f"Activation function {config.hidden_act} not supported.")
282
- self.config = config
283
- self.hidden_size = config.hidden_size
284
- self.intermediate_size = config.intermediate_size
285
- self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
286
- self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
287
- self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
288
 
289
  def forward(self, x: torch.Tensor) -> torch.Tensor:
290
  return self.down_proj(LigerSiLUMulFunction.apply(self.gate_proj(x), self.up_proj(x)))
291
 
292
 
293
  class LigerGEGLUMLP(nn.Module):
294
- """GEGLU MLP block. ``config`` must expose ``hidden_size`` and ``intermediate_size``.
295
- Uses the tanh approximation of GELU (matches Gemma 1/1.1/2)."""
296
-
297
- def __init__(self, config):
298
- super().__init__()
299
- self.config = config
300
- self.hidden_size = config.hidden_size
301
- self.intermediate_size = config.intermediate_size
302
- self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
303
- self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
304
- self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
305
 
306
  def forward(self, x: torch.Tensor) -> torch.Tensor:
307
  return self.down_proj(LigerGELUMulFunction.apply(self.gate_proj(x), self.up_proj(x)))
308
 
309
 
310
- class LigerTiledGEGLUMLP(nn.Module):
311
  gate_proj: nn.Linear
312
  up_proj: nn.Linear
313
  down_proj: nn.Linear
314
- num_shards: int
315
 
316
- def _mlp_forward(self, module, x):
317
- """Internal MLP forward function for tiled computation."""
318
- gate = module.gate_proj(x)
319
- up = module.up_proj(x)
320
- return module.down_proj(LigerGELUMulFunction.apply(gate, up))
321
 
322
  def forward(self, x: torch.Tensor) -> torch.Tensor:
 
 
 
 
 
 
323
  compute_params = [p for p in self.parameters() if p.requires_grad]
324
 
325
  return apply_tiled_mlp(
326
- fn=self._mlp_forward,
327
  mlp_module=self,
328
  x=x,
329
- num_shards=self.num_shards,
330
  compute_params=compute_params,
331
  )
332
 
333
 
334
- class LigerTiledSwiGLUMLP(nn.Module):
335
  gate_proj: nn.Linear
336
  up_proj: nn.Linear
337
  down_proj: nn.Linear
338
- num_shards: int
339
 
340
- def _mlp_forward(self, module, x):
341
- """Internal MLP forward function for tiled computation."""
342
- gate = module.gate_proj(x)
343
- up = module.up_proj(x)
344
- return module.down_proj(LigerSiLUMulFunction.apply(gate, up))
345
 
346
  def forward(self, x: torch.Tensor) -> torch.Tensor:
 
 
 
 
 
 
347
  compute_params = [p for p in self.parameters() if p.requires_grad]
348
 
349
  return apply_tiled_mlp(
350
- fn=self._mlp_forward,
351
  mlp_module=self,
352
  x=x,
353
- num_shards=self.num_shards,
354
  compute_params=compute_params,
355
  )
356
 
357
 
 
 
 
 
 
 
 
 
 
 
 
358
  @dataclass
359
  class CrossEntropyOutput:
360
  loss: torch.Tensor
@@ -407,23 +191,33 @@ def liger_fused_linear_cross_entropy(
407
  )
408
 
409
 
 
 
 
 
410
  def LigerForCausalLMLoss(
411
- hidden_states: torch.Tensor,
412
- lm_head_weight: torch.Tensor,
413
  labels: torch.Tensor,
414
- hidden_size: int,
415
  num_items_in_batch: Optional[int] = None,
416
  ignore_index: int = -100,
417
  shift_labels: Optional[torch.Tensor] = None,
418
- final_logit_softcapping: Optional[float] = None,
419
- return_token_accuracy: bool = False,
420
- return_predicted_tokens: bool = False,
421
  **kwargs,
422
  ):
423
- """Drop-in replacement for ``transformers.loss.ForCausalLMLoss`` that fuses the
424
- final ``lm_head`` projection with the cross-entropy loss. Returns a scalar
425
- ``loss`` by default; returns a :class:`CrossEntropyOutput` when
426
- ``return_token_accuracy`` or ``return_predicted_tokens`` is set."""
 
 
 
 
 
 
 
427
  applicable_params = inspect.signature(liger_fused_linear_cross_entropy).parameters
428
  kwargs = {k: v for k, v in kwargs.items() if k in applicable_params}
429
 
@@ -435,80 +229,116 @@ def LigerForCausalLMLoss(
435
  shift_labels = shift_labels.view(-1).to(hidden_states.device)
436
 
437
  reduction = "sum" if num_items_in_batch is not None else "mean"
438
- result = liger_fused_linear_cross_entropy(
439
  hidden_states,
440
  lm_head_weight,
441
  shift_labels,
 
442
  reduction=reduction,
443
  ignore_index=ignore_index,
444
  softcap=final_logit_softcapping,
445
- return_token_accuracy=return_token_accuracy,
446
- return_predicted_tokens=return_predicted_tokens,
447
  **kwargs,
448
  )
449
 
450
- if isinstance(result, CrossEntropyOutput):
451
- loss = result.loss
452
- token_accuracy = result.token_accuracy
453
- predicted_tokens = result.predicted_tokens
454
- else:
455
- loss = result
456
- token_accuracy = None
457
- predicted_tokens = None
458
-
459
  if reduction == "sum":
460
  loss = loss / num_items_in_batch
461
 
462
- if return_token_accuracy or return_predicted_tokens:
463
- return CrossEntropyOutput(
464
- loss=loss,
465
- token_accuracy=token_accuracy,
466
- predicted_tokens=predicted_tokens,
467
- )
468
  return loss
469
 
470
 
471
- def liger_rotary_pos_emb(
472
- q: torch.Tensor,
473
- k: torch.Tensor,
474
- cos: torch.Tensor,
475
- sin: torch.Tensor,
476
- position_ids: Optional[torch.Tensor] = None,
477
- unsqueeze_dim: int = 1,
478
- ) -> Tuple[torch.Tensor, torch.Tensor]:
479
- """Apply standard rotary positional embedding to ``q`` and ``k``."""
480
- return LigerRopeFunction.apply(q, k, cos, sin, position_ids, unsqueeze_dim)
481
 
482
 
483
- def liger_multimodal_rotary_pos_emb(
484
- q: torch.Tensor,
485
- k: torch.Tensor,
486
- cos: torch.Tensor,
487
- sin: torch.Tensor,
488
- mrope_section,
489
- unsqueeze_dim: int = 1,
490
- ) -> Tuple[torch.Tensor, torch.Tensor]:
491
- """Apply Qwen2-VL multimodal rotary positional embedding (M-RoPE) to ``q`` and ``k``."""
492
- return LigerQwen2VLMRopeFunction.apply(q, k, cos, sin, mrope_section, unsqueeze_dim)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
493
 
494
 
495
  __all__ = [
496
  "LigerRMSNorm",
497
- "LigerLayerNorm",
498
- "LigerGroupNorm",
499
- "LigerDyT",
500
- "LigerCrossEntropyLoss",
501
- "LigerFusedLinearCrossEntropyLoss",
502
- "LigerJSD",
503
- "LigerKLDIVLoss",
504
- "LigerTVDLoss",
505
  "LigerSwiGLUMLP",
506
  "LigerGEGLUMLP",
507
- "LigerTiledGEGLUMLP",
508
  "LigerTiledSwiGLUMLP",
509
- "CrossEntropyOutput",
510
- "liger_fused_linear_cross_entropy",
511
- "LigerForCausalLMLoss",
512
  "liger_rotary_pos_emb",
513
- "liger_multimodal_rotary_pos_emb",
 
 
514
  ]
 
1
  import inspect
2
  from dataclasses import dataclass
3
+ from typing import Optional
4
 
5
  import torch
6
  import torch.nn as nn
7
 
 
 
8
  from .fused_linear_cross_entropy import LigerFusedLinearCrossEntropyFunction
9
  from .geglu import LigerGELUMulFunction
 
 
 
 
 
10
  from .rms_norm import LigerRMSNormFunction
11
  from .rope import LigerRopeFunction
12
  from .swiglu import LigerSiLUMulFunction
13
  from .tiled_mlp import apply_tiled_mlp
 
14
 
15
 
16
  class LigerRMSNorm(nn.Module):
17
+ weight: nn.Parameter
18
+ variance_epsilon: float
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ can_torch_compile = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
23
+ return LigerRMSNormFunction.apply(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  hidden_states,
25
  self.weight,
 
 
 
26
  self.variance_epsilon,
27
+ 0,
28
+ "llama",
29
+ # Not in place: dY can be shared with other branches (e.g. a residual add).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  False,
31
+ None,
32
  )
 
33
 
34
+ def extra_repr(self):
35
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ class LigerLinear(nn.Module):
39
+ weight: nn.Parameter
40
+ bias: nn.Parameter | None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ can_torch_compile = True
43
 
44
+ def forward(self, input: torch.Tensor) -> torch.Tensor:
45
+ def _forward(module, x):
46
+ return nn.functional.linear(x, module.weight, module.bias)
 
 
47
 
48
+ compute_params = [p for p in self.parameters() if p.requires_grad]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ return apply_tiled_mlp(
51
+ fn=_forward,
52
+ mlp_module=self,
53
+ x=input,
54
+ num_shards=None,
55
+ compute_params=compute_params,
56
+ )
57
 
58
 
59
  class LigerSwiGLUMLP(nn.Module):
60
+ gate_proj: nn.Linear
61
+ up_proj: nn.Linear
62
+ down_proj: nn.Linear
63
+
64
+ can_torch_compile = True
 
 
 
 
 
 
 
 
65
 
66
  def forward(self, x: torch.Tensor) -> torch.Tensor:
67
  return self.down_proj(LigerSiLUMulFunction.apply(self.gate_proj(x), self.up_proj(x)))
68
 
69
 
70
  class LigerGEGLUMLP(nn.Module):
71
+ gate_proj: nn.Linear
72
+ up_proj: nn.Linear
73
+ down_proj: nn.Linear
74
+
75
+ can_torch_compile = True
 
 
 
 
 
 
76
 
77
  def forward(self, x: torch.Tensor) -> torch.Tensor:
78
  return self.down_proj(LigerGELUMulFunction.apply(self.gate_proj(x), self.up_proj(x)))
79
 
80
 
81
+ class LigerTiledSwiGLUMLP(nn.Module):
82
  gate_proj: nn.Linear
83
  up_proj: nn.Linear
84
  down_proj: nn.Linear
 
85
 
86
+ can_torch_compile = True
 
 
 
 
87
 
88
  def forward(self, x: torch.Tensor) -> torch.Tensor:
89
+ def _mlp_forward(module, x):
90
+ """Internal MLP forward function for tiled computation."""
91
+ gate = module.gate_proj(x)
92
+ up = module.up_proj(x)
93
+ return module.down_proj(LigerSiLUMulFunction.apply(gate, up))
94
+
95
  compute_params = [p for p in self.parameters() if p.requires_grad]
96
 
97
  return apply_tiled_mlp(
98
+ fn=_mlp_forward,
99
  mlp_module=self,
100
  x=x,
101
+ num_shards=None,
102
  compute_params=compute_params,
103
  )
104
 
105
 
106
+ class LigerTiledGEGLUMLP(nn.Module):
107
  gate_proj: nn.Linear
108
  up_proj: nn.Linear
109
  down_proj: nn.Linear
 
110
 
111
+ can_torch_compile = True
 
 
 
 
112
 
113
  def forward(self, x: torch.Tensor) -> torch.Tensor:
114
+ def _mlp_forward(module, x):
115
+ """Internal MLP forward function for tiled computation."""
116
+ gate = module.gate_proj(x)
117
+ up = module.up_proj(x)
118
+ return module.down_proj(LigerGELUMulFunction.apply(gate, up))
119
+
120
  compute_params = [p for p in self.parameters() if p.requires_grad]
121
 
122
  return apply_tiled_mlp(
123
+ fn=_mlp_forward,
124
  mlp_module=self,
125
  x=x,
126
+ num_shards=None,
127
  compute_params=compute_params,
128
  )
129
 
130
 
131
+ def liger_rotary_pos_emb(
132
+ q: torch.Tensor,
133
+ k: torch.Tensor,
134
+ cos: torch.Tensor,
135
+ sin: torch.Tensor,
136
+ unsqueeze_dim: int = 1,
137
+ ) -> tuple[torch.Tensor, torch.Tensor]:
138
+ """Apply standard rotary positional embedding to ``q`` and ``k``."""
139
+ return LigerRopeFunction.apply(q, k, cos, sin, None, unsqueeze_dim)
140
+
141
+
142
  @dataclass
143
  class CrossEntropyOutput:
144
  loss: torch.Tensor
 
191
  )
192
 
193
 
194
+ # NOTE: We have this intentional graph break as we encounter issues such as IMAs and Cublas errors.
195
+ # We know that this is an optimized kernel already so there is less ways to
196
+ # fuse it either way; we rely on torch compile to go through the base model to optimize.
197
+ @torch.compiler.disable
198
  def LigerForCausalLMLoss(
199
+ logits: None, # to match transformers signature
 
200
  labels: torch.Tensor,
201
+ vocab_size: int, # to match transformers signature
202
  num_items_in_batch: Optional[int] = None,
203
  ignore_index: int = -100,
204
  shift_labels: Optional[torch.Tensor] = None,
205
+ hidden_states: torch.Tensor | None = None,
206
+ lm_head_weight: torch.Tensor | None = None,
207
+ lm_head_bias: torch.Tensor | None = None,
208
  **kwargs,
209
  ):
210
+ # To match signature we hide these behind the kwargs but we expect a few kwargs to exist
211
+ hidden_size = kwargs.pop("hidden_size", None)
212
+ final_logit_softcapping = kwargs.pop("final_logit_softcapping", None)
213
+
214
+ if hidden_size is None or hidden_states is None or lm_head_weight is None:
215
+ raise ValueError(
216
+ f"`LigerForCausalLMLoss` requires the LLM's weight (found `{lm_head_weight is not None}`),"
217
+ f"the last hidden state (found `{hidden_states is not None}`), and the `hidden_size`"
218
+ f"(found `{hidden_size is not None}`). Please make sure to pass the necessary kwargs."
219
+ )
220
+
221
  applicable_params = inspect.signature(liger_fused_linear_cross_entropy).parameters
222
  kwargs = {k: v for k, v in kwargs.items() if k in applicable_params}
223
 
 
229
  shift_labels = shift_labels.view(-1).to(hidden_states.device)
230
 
231
  reduction = "sum" if num_items_in_batch is not None else "mean"
232
+ loss = liger_fused_linear_cross_entropy(
233
  hidden_states,
234
  lm_head_weight,
235
  shift_labels,
236
+ bias=lm_head_bias,
237
  reduction=reduction,
238
  ignore_index=ignore_index,
239
  softcap=final_logit_softcapping,
240
+ return_token_accuracy=False,
241
+ return_predicted_tokens=False,
242
  **kwargs,
243
  )
244
 
 
 
 
 
 
 
 
 
 
245
  if reduction == "sum":
246
  loss = loss / num_items_in_batch
247
 
 
 
 
 
 
 
248
  return loss
249
 
250
 
251
+ # Add torch compile support for functions - in this case it's to allow this to be used
252
+ # but the function itself will not be compiled (see the note at the function)
253
+ liger_rotary_pos_emb.can_torch_compile = True
254
+ LigerForCausalLMLoss.can_torch_compile = True
 
 
 
 
 
 
255
 
256
 
257
+ class liger_rotary_pos_emb_layer(nn.Module):
258
+ can_torch_compile = True
259
+
260
+ def forward(
261
+ self,
262
+ q: torch.Tensor,
263
+ k: torch.Tensor,
264
+ cos: torch.Tensor,
265
+ sin: torch.Tensor,
266
+ unsqueeze_dim: int = 1,
267
+ ) -> tuple[torch.Tensor, torch.Tensor]:
268
+ """Apply standard rotary positional embedding to ``q`` and ``k``."""
269
+ return LigerRopeFunction.apply(q, k, cos, sin, None, unsqueeze_dim)
270
+
271
+
272
+ class LigerForCausalLMLossLayer(nn.Module):
273
+ can_torch_compile = True
274
+
275
+ # NOTE: We have this intentional graph break as we encounter issues such as IMAs and Cublas errors.
276
+ # We know that this is an optimized kernel already so there is less ways to
277
+ # fuse it either way; we rely on torch compile to go through the base model to optimize.
278
+ @torch.compiler.disable
279
+ def forward(
280
+ self,
281
+ logits: None, # to match transformers signature
282
+ labels: torch.Tensor,
283
+ vocab_size: int, # to match transformers signature
284
+ num_items_in_batch: Optional[int] = None,
285
+ ignore_index: int = -100,
286
+ shift_labels: Optional[torch.Tensor] = None,
287
+ hidden_states: torch.Tensor | None = None,
288
+ lm_head_weight: torch.Tensor | None = None,
289
+ lm_head_bias: torch.Tensor | None = None,
290
+ **kwargs,
291
+ ):
292
+ # To match signature we hide these behind the kwargs but we expect a few kwargs to exist
293
+ hidden_size = kwargs.pop("hidden_size", None)
294
+ final_logit_softcapping = kwargs.pop("final_logit_softcapping", None)
295
+
296
+ if hidden_size is None or hidden_states is None or lm_head_weight is None:
297
+ raise ValueError(
298
+ f"`LigerForCausalLMLoss` requires the LLM's weight (found `{lm_head_weight is not None}`),"
299
+ f"the last hidden state (found `{hidden_states is not None}`), and the `hidden_size`"
300
+ f"(found `{hidden_size is not None}`). Please make sure to pass the necessary kwargs."
301
+ )
302
+
303
+ applicable_params = inspect.signature(liger_fused_linear_cross_entropy).parameters
304
+ kwargs = {k: v for k, v in kwargs.items() if k in applicable_params}
305
+
306
+ if shift_labels is None:
307
+ labels = nn.functional.pad(labels, (0, 1), value=ignore_index)
308
+ shift_labels = labels[..., 1:].contiguous()
309
+
310
+ hidden_states = hidden_states.view(-1, hidden_size)
311
+ shift_labels = shift_labels.view(-1).to(hidden_states.device)
312
+
313
+ reduction = "sum" if num_items_in_batch is not None else "mean"
314
+ loss = liger_fused_linear_cross_entropy(
315
+ hidden_states,
316
+ lm_head_weight,
317
+ shift_labels,
318
+ bias=lm_head_bias,
319
+ reduction=reduction,
320
+ ignore_index=ignore_index,
321
+ softcap=final_logit_softcapping,
322
+ return_token_accuracy=False,
323
+ return_predicted_tokens=False,
324
+ **kwargs,
325
+ )
326
+
327
+ if reduction == "sum":
328
+ loss = loss / num_items_in_batch
329
+
330
+ return loss
331
 
332
 
333
  __all__ = [
334
  "LigerRMSNorm",
335
+ "LigerLinear",
 
 
 
 
 
 
 
336
  "LigerSwiGLUMLP",
337
  "LigerGEGLUMLP",
 
338
  "LigerTiledSwiGLUMLP",
339
+ "LigerTiledGEGLUMLP",
 
 
340
  "liger_rotary_pos_emb",
341
+ "liger_rotary_pos_emb_layer",
342
+ "LigerForCausalLMLoss",
343
+ "LigerForCausalLMLossLayer",
344
  ]
build/torch-rocm/liger_kernels/__init__.py DELETED
@@ -1,26 +0,0 @@
1
- import ctypes
2
- import importlib.util
3
- import sys
4
- from pathlib import Path
5
- from types import ModuleType
6
-
7
-
8
- def _import_from_path(file_path: Path) -> ModuleType:
9
- # We cannot use the module name as-is, after adding it to `sys.modules`,
10
- # it would also be used for other imports. So, we make a module name that
11
- # depends on the path for it to be unique using the hex-encoded hash of
12
- # the path.
13
- path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
- module_name = path_hash
15
- spec = importlib.util.spec_from_file_location(module_name, file_path)
16
- if spec is None:
17
- raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
- module = importlib.util.module_from_spec(spec)
19
- if module is None:
20
- raise ImportError(f"Cannot load module {module_name} from spec")
21
- sys.modules[module_name] = module
22
- spec.loader.exec_module(module) # type: ignore
23
- return module
24
-
25
-
26
- globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
build/torch-rocm/metadata.json CHANGED
@@ -1,10 +1,46 @@
1
  {
2
  "name": "liger-kernels",
3
- "id": "_liger_kernels_rocm_ab435e2",
4
- "version": 1,
 
5
  "license": "BSD-2-Clause",
6
  "python-depends": [],
 
7
  "backend": {
8
  "type": "rocm"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
  }
 
1
  {
2
  "name": "liger-kernels",
3
+ "id": "_liger_kernels_rocm_a5e3c9a",
4
+ "version": 4,
5
+ "kernels-minver": "0.14.0",
6
  "license": "BSD-2-Clause",
7
  "python-depends": [],
8
+ "kernel-depends": [],
9
  "backend": {
10
  "type": "rocm"
11
+ },
12
+ "digest": {
13
+ "algorithm": "sha256",
14
+ "files": {
15
+ "__init__.py": "DSZMiK0xOBiMb0JdCc2K9QH4Z6lV7L8D/fTowstf/og=",
16
+ "_ops.py": "bCtURpaJ/MUGhq9sttUuiQOZM4pbc8c6bvnj1pFhhTs=",
17
+ "cross_entropy.py": "N/GPXvZTWjsu2qlAC96kuFJ4XFI0c3Qff9YtOkqaQG0=",
18
+ "dyt.py": "Fa7TEHZqkfNKXaxSYQt8/MlnOUFo+WIUIkz6ZA2O/b8=",
19
+ "fused_linear_cross_entropy.py": "l21OYH+10ryswTwtuad+h7V6Xo/8zeSLoKDyn7ZCVxo=",
20
+ "geglu.py": "m1Y4vqkXPBdoSzxKOTi7SiU8NW85a2JW/2/2BQbgktg=",
21
+ "group_norm.py": "7EcdehRRoGaias7RiU5Qil+AYQ8ZClP7mJosl1Og8r4=",
22
+ "jsd.py": "yWhyIa06nzvlhcwGBQNSGrTv4bessgm4vrgqQEfNUMo=",
23
+ "kl_div.py": "nPN5Lb2NcIGWzk+RNxgFJ69GKyfPeRLg4ycCns7KO9U=",
24
+ "layer_norm.py": "+t987/DupvUHRaLK8s5V9W6ewHtFZIG5WJLD5kg0RjA=",
25
+ "layers.py": "o90FuFiP0vXzryK3lQG7NFWyNkfWtGyqUQ89gcL7Who=",
26
+ "qwen2vl_mrope.py": "uxztQJ0LlMEP4Zec/yjxVJa0/uOsB5XvjUN5rM37Rf4=",
27
+ "rms_norm.py": "LJfKK/kutmbztb17eC3a6OGAk39PLEAHa+hzzmcCjAA=",
28
+ "rope.py": "IdrugShnaNJJ9apTXlMEXMjZE0IpDZI7X23gIgYS3k4=",
29
+ "swiglu.py": "QSjLVgdF3a4rsPdI0B0VNTmA26M2F4Y9SSv4+303WkE=",
30
+ "tiled_mlp.py": "LYTCxF1DoPhcoUiIg8Q28x03+5vq1w/AKclZICc4T+Y=",
31
+ "tvd.py": "BEL3OibZ2tfGJRyycMTSUWah/6eDdLSV2jA7ZKcxE7s=",
32
+ "utils.py": "MXPc1rROeMsO7dZwR1HVLG2YHFgLvoUmNjNl+iad6x0="
33
+ }
34
+ },
35
+ "provenance": {
36
+ "kernel-builder": {
37
+ "version": "0.17.0-dev0",
38
+ "commit": "a7f0afdb29a6a3372b1d47180cc0c182454c5e3b",
39
+ "dirty": false
40
+ },
41
+ "kernel": {
42
+ "commit": "a5e3c9ae2b44550c966a5fd2109b8a224448ffe4",
43
+ "dirty": false
44
+ }
45
  }
46
  }
build/torch-rocm/metadata.json.sigstore ADDED
@@ -0,0 +1 @@
 
 
1
+ {"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial":{"certificate":{"rawBytes":"MIIHKzCCBrKgAwIBAgIUTYN/dKecYuFSy8iWylJxQLztS0kwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjYxMDA2MTUwNTMwWhcNMjYxMDA2MTUxNTMwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5whRctkwOyYT2myMamsaWQWb918sLTu9f+FAxenMOk8a357MBSH8nc6lhPPDU7KLxp/sItFJRW92l5LUOmd4FqOCBdEwggXNMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAfBgNVHSMEGDAWgBTf0+nPViQRlvmo2OkoVaLGLhhkPzBrBgNVHREBAf8EYTBfhl1odHRwczovL2dpdGh1Yi5jb20vaHVnZ2luZ2ZhY2Uva2VybmVscy1jb21tdW5pdHkvLmdpdGh1Yi93b3JrZmxvd3MvYnVpbGQueWFtbEByZWZzL2hlYWRzL21haW4wOQYKKwYBBAGDvzABAQQraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTAfBgorBgEEAYO/MAECBBF3b3JrZmxvd19kaXNwYXRjaDA2BgorBgEEAYO/MAEDBChhNWUzYzlhZTJiNDQ1NTBjOTY2YTVmZDIxMDliOGEyMjQ0NDhmZmU0MBMGCisGAQQBg78wAQQEBUJ1aWxkMCsGCisGAQQBg78wAQUEHWh1Z2dpbmdmYWNlL2tlcm5lbHMtY29tbXVuaXR5MB0GCisGAQQBg78wAQYED3JlZnMvaGVhZHMvbWFpbjA7BgorBgEEAYO/MAEIBC0MK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20wbQYKKwYBBAGDvzABCQRfDF1odHRwczovL2dpdGh1Yi5jb20vaHVnZ2luZ2ZhY2Uva2VybmVscy1jb21tdW5pdHkvLmdpdGh1Yi93b3JrZmxvd3MvYnVpbGQueWFtbEByZWZzL2hlYWRzL21haW4wOAYKKwYBBAGDvzABCgQqDChhNWUzYzlhZTJiNDQ1NTBjOTY2YTVmZDIxMDliOGEyMjQ0NDhmZmU0MBsGCisGAQQBg78wAQsEDQwLc2VsZi1ob3N0ZWQwQAYKKwYBBAGDvzABDAQyDDBodHRwczovL2dpdGh1Yi5jb20vaHVnZ2luZ2ZhY2Uva2VybmVscy1jb21tdW5pdHkwOAYKKwYBBAGDvzABDQQqDChhNWUzYzlhZTJiNDQ1NTBjOTY2YTVmZDIxMDliOGEyMjQ0NDhmZmU0MB8GCisGAQQBg78wAQ4EEQwPcmVmcy9oZWFkcy9tYWluMBoGCisGAQQBg78wAQ8EDAwKMTA3MTQ3NTUyOTAuBgorBgEEAYO/MAEQBCAMHmh0dHBzOi8vZ2l0aHViLmNvbS9odWdnaW5nZmFjZTAYBgorBgEEAYO/MAERBAoMCDI1NzIwNzQzMG0GCisGAQQBg78wARIEXwxdaHR0cHM6Ly9naXRodWIuY29tL2h1Z2dpbmdmYWNlL2tlcm5lbHMtY29tbXVuaXR5Ly5naXRodWIvd29ya2Zsb3dzL2J1aWxkLnlhbWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wARMEKgwoYTVlM2M5YWUyYjQ0NTUwYzk2NmE1ZmQyMTA5YjhhMjI0NDQ4ZmZlNDAhBgorBgEEAYO/MAEUBBMMEXdvcmtmbG93X2Rpc3BhdGNoMGQGCisGAQQBg78wARUEVgxUaHR0cHM6Ly9naXRodWIuY29tL2h1Z2dpbmdmYWNlL2tlcm5lbHMtY29tbXVuaXR5L2FjdGlvbnMvcnVucy8zNzQ4MzQzNzM3OC9hdHRlbXB0cy8xMBYGCisGAQQBg78wARYECAwGcHVibGljMEYGCisGAQQBg78wARgEOAw2cmVwbzpodWdnaW5nZmFjZS9rZXJuZWxzLWNvbW11bml0eTpyZWY6cmVmcy9oZWFkcy9tYWluMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGhEb+UyQAABAMARzBFAiBlpnWjAK1j/eAV1IoxifdKhfRT2Mmwlp03Ooy8L4u6qgIhAIvppJ7f0Nn0nGk9mNA2LTZg41wlq1TsrxkYNNRAeIOFMAoGCCqGSM49BAMDA2cAMGQCMHmzNS6irqP9TXZ5CmdzRvcDq/v40WYgtpttGwcN1ipTXjCoz/BfDU9Fzh5PRwPaVQIwUcO8s+UJWJOJOT/i6ZCmvUMFXbajPURMxwhLFniYEvO830KjFaP7lpPqIl45zjNY"}, "tlogEntries":[{"logIndex":"3111423604", "logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion":{"kind":"hashedrekord", "version":"0.0.1"}, "integratedTime":"1791299130", "inclusionPromise":{"signedEntryTimestamp":"MEYCIQC9Le9KJb7yZPMkwxn82LSWvVmgn7zbP+gNveNHzEjbUwIhAIJ81hNyxi+gyIzpTFstlTJDL4E+TjlB9EslRwpd4GgA"}, "inclusionProof":{"logIndex":"2989519342", "rootHash":"ZXKRZskZTAHxmvpU4Z+YqJgC534Dz86n1kkFy7LOVk8=", "treeSize":"2989519354", "hashes":["SLcAl9/bXfkZXL//RWNwKQidVBfTiCxNXkWAI8u2ZQQ=", "EnVECN/wbZz+gnOtscWBFAiI0Rb1lJiNy0KQonj3DmE=", "sjd5YgDCOcIQY6cN/eOufNOP1yNL981ZLbeZfku2I6U=", "mrGs7B4XcDynwbuRtph9W963YXTuA1PAK3X8yMxBSOM=", "bSw8mfeMy+OobhgMXa1U+QpCmLuo01XxVjT0hw+x7ew=", "hIhcjmKlXXWjqsIU927AphX6HWvoKqcx1cBmXctCyKo=", "MYhjnRbQvz/V0N3A/cPTBJbJ9hZW0nWOuGoVbVRzt2s=", "ymtg2bg2BTrQggg1pxCl9vaGF8BdLRBcr/sIfsN+WOc=", "0fmw4rqMbJrndCGwHEoKIxbr8PaNt4TRBnhTb0ygVtI=", "soci8BMAmEViF0iSvDe4Fr67aKooymgKvvmIeHpviec=", "uNYli6wjU0acRO+5zE2L4CKw5brwv/CVMDggUn4/ibA=", "/gAVm/mjy6BR4W9k2QfYflcuZtS4j8uS1FGmx5LRAUg=", "qLQ8+NTfJXVeQ4hnwzGZAfv08pDXZRJriV3XQZ3Lj5w=", "ewhVzfGoc5TIIeujB6CqXn5WyT2wQVElsw8KHXcxa44=", "x9rXqkSu8+Vm4yqD2XeAwn305JZ4ZykdOwcD90FjP8o=", "NlOclldmKPA1tMKIskqHAwuQDYHp31YwpK+OOMrMccc=", "qxzHanAzz57SDdmJe0B7bJK72NTIBbwEMGBBKvDOROw=", "xH/DCseLHr9eKoYT8qsORZK7zVdEGYWHuVtsVrD95wY="], "checkpoint":{"envelope":"rekor.sigstore.dev - 1193050959916656506\n2989519354\nZXKRZskZTAHxmvpU4Z+YqJgC534Dz86n1kkFy7LOVk8=\n\n— rekor.sigstore.dev wNI9ajBFAiB9QQ19qkO3m70dUooeo3ZXJ7SbT34FF0mfLey4DWQA7wIhAPWUVj5rm0NBQrNUUVs58lbU/XAGcryjx1hZAiwdSjZu\n"}}, "canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJmYjRkZjc3ZTBmMDliYjcxNmJlYzYzNDM0ZjEyMmY5YTdhNTExNDhkOTA5NGYxYzI3N2EyZGM2MjEzMWVlMmUxIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJQzR2L1JLdnZnaTBHYmpQYW00ZUxsaFJyUlJiREcvVkErbXJVeFlNL2FXSkFpQUh2dE9wVG1SdHhFNlBmMnBaeE40aHZUUjdqTi9QYTRwZ0pycEo2Y3UzOXc9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVaExla05EUW5KTFowRjNTVUpCWjBsVlZGbE9MMlJMWldOWmRVWlRlVGhwVjNsc1NuaFJUSHAwVXpCcmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFplRTFFUVRKTlZGVjNUbFJOZDFkb1kwNU5hbGw0VFVSQk1rMVVWWGhPVkUxM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVUxZDJoU1kzUnJkMDk1V1ZReWJYbE5ZVzF6WVZkUlYySTVNVGh6VEZSMU9XWXJSa0VLZUdWdVRVOXJPR0V6TlRkTlFsTklPRzVqTm14b1VGQkVWVGRMVEhod0wzTkpkRVpLVWxjNU1tdzFURlZQYldRMFJuRlBRMEprUlhkbloxaE9UVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXWkNaMDVXU0ZOTlJVZEVRVmRuUWxSbUNqQXJibEJXYVZGU2JIWnRiekpQYTI5V1lVeEhUR2hvYTFCNlFuSkNaMDVXU0ZKRlFrRm1PRVZaVkVKbWFHd3hiMlJJVW5kamVtOTJUREprY0dSSGFERUtXV2sxYW1JeU1IWmhTRlp1V2pKc2RWb3lXbWhaTWxWMllUSldlV0p0Vm5OamVURnFZakl4ZEdSWE5YQmtTR3QyVEcxa2NHUkhhREZaYVRrellqTktjZ3BhYlhoMlpETk5kbGx1Vm5CaVIxRjFaVmRHZEdKRlFubGFWMXA2VERKb2JGbFhVbnBNTWpGb1lWYzBkMDlSV1V0TGQxbENRa0ZIUkhaNlFVSkJVVkZ5Q21GSVVqQmpTRTAyVEhrNU1HSXlkR3hpYVRWb1dUTlNjR0l5TlhwTWJXUndaRWRvTVZsdVZucGFXRXBxWWpJMU1GcFhOVEJNYlU1MllsUkJaa0puYjNJS1FtZEZSVUZaVHk5TlFVVkRRa0pHTTJJelNuSmFiWGgyWkRFNWEyRllUbmRaV0ZKcVlVUkJNa0puYjNKQ1owVkZRVmxQTDAxQlJVUkNRMmhvVGxkVmVncFplbXhvV2xSS2FVNUVVVEZPVkVKcVQxUlpNbGxVVm0xYVJFbDRUVVJzYVU5SFJYbE5hbEV3VGtSb2JWcHRWVEJOUWsxSFEybHpSMEZSVVVKbk56aDNDa0ZSVVVWQ1ZVb3hZVmQ0YTAxRGMwZERhWE5IUVZGUlFtYzNPSGRCVVZWRlNGZG9NVm95WkhCaWJXUnRXVmRPYkV3eWRHeGpiVFZzWWtoTmRGa3lPWFFLWWxoV2RXRllValZOUWpCSFEybHpSMEZSVVVKbk56aDNRVkZaUlVRelNteGFiazEyWVVkV2FGcElUWFppVjBad1ltcEJOMEpuYjNKQ1owVkZRVmxQTHdwTlFVVkpRa013VFVzeWFEQmtTRUo2VDJrNGRtUkhPWEphVnpSMVdWZE9NR0ZYT1hWamVUVnVZVmhTYjJSWFNqRmpNbFo1V1RJNWRXUkhWblZrUXpWcUNtSXlNSGRpVVZsTFMzZFpRa0pCUjBSMmVrRkNRMUZTWmtSR01XOWtTRkozWTNwdmRrd3laSEJrUjJneFdXazFhbUl5TUhaaFNGWnVXakpzZFZveVdtZ0tXVEpWZG1FeVZubGliVlp6WTNreGFtSXlNWFJrVnpWd1pFaHJka3h0WkhCa1IyZ3hXV2s1TTJJelNuSmFiWGgyWkROTmRsbHVWbkJpUjFGMVpWZEdkQXBpUlVKNVdsZGFla3d5YUd4WlYxSjZUREl4YUdGWE5IZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1EyZFJjVVJEYUdoT1YxVjZXWHBzYUZwVVNtbE9SRkV4Q2s1VVFtcFBWRmt5V1ZSV2JWcEVTWGhOUkd4cFQwZEZlVTFxVVRCT1JHaHRXbTFWTUUxQ2MwZERhWE5IUVZGUlFtYzNPSGRCVVhORlJGRjNUR015Vm5NS1dta3hiMkl6VGpCYVYxRjNVVUZaUzB0M1dVSkNRVWRFZG5wQlFrUkJVWGxFUkVKdlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyWVVoV2JncGFNbXgxV2pKYWFGa3lWWFpoTWxaNVltMVdjMk41TVdwaU1qRjBaRmMxY0dSSWEzZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JGRlJjVVJEYUdoT1YxVjZDbGw2YkdoYVZFcHBUa1JSTVU1VVFtcFBWRmt5V1ZSV2JWcEVTWGhOUkd4cFQwZEZlVTFxVVRCT1JHaHRXbTFWTUUxQ09FZERhWE5IUVZGUlFtYzNPSGNLUVZFMFJVVlJkMUJqYlZadFkzazViMXBYUm10amVUbDBXVmRzZFUxQ2IwZERhWE5IUVZGUlFtYzNPSGRCVVRoRlJFRjNTMDFVUVROTlZGRXpUbFJWZVFwUFZFRjFRbWR2Y2tKblJVVkJXVTh2VFVGRlVVSkRRVTFJYldnd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemx2WkZka2JtRlhOVzVhYlVacUNscFVRVmxDWjI5eVFtZEZSVUZaVHk5TlFVVlNRa0Z2VFVORVNURk9la2wzVG5wUmVrMUhNRWREYVhOSFFWRlJRbWMzT0hkQlVrbEZXSGQ0WkdGSVVqQUtZMGhOTmt4NU9XNWhXRkp2WkZkSmRWa3lPWFJNTW1neFdqSmtjR0p0WkcxWlYwNXNUREowYkdOdE5XeGlTRTEwV1RJNWRHSllWblZoV0ZJMVRIazFiZ3BoV0ZKdlpGZEpkbVF5T1hsaE1scHpZak5rZWt3eVNqRmhWM2hyVEc1c2FHSlhlRUZqYlZadFkzazViMXBYUm10amVUbDBXVmRzZFUxRVowZERhWE5IQ2tGUlVVSm5OemgzUVZKTlJVdG5kMjlaVkZac1RUSk5OVmxYVlhsWmFsRXdUbFJWZDFsNmF6Sk9iVVV4V20xUmVVMVVRVFZaYW1ob1RXcEpNRTVFVVRRS1dtMWFiRTVFUVdoQ1oyOXlRbWRGUlVGWlR5OU5RVVZWUWtKTlRVVllaSFpqYlhSdFlrYzVNMWd5VW5Cak0wSm9aRWRPYjAxSFVVZERhWE5IUVZGUlFncG5OemgzUVZKVlJWWm5lRlZoU0ZJd1kwaE5Oa3g1T1c1aFdGSnZaRmRKZFZreU9YUk1NbWd4V2pKa2NHSnRaRzFaVjA1c1RESjBiR050Tld4aVNFMTBDbGt5T1hSaVdGWjFZVmhTTlV3eVJtcGtSMngyWW01TmRtTnVWblZqZVRoNlRucFJORTE2VVhwT2VrMHpUME01YUdSSVVteGlXRUl3WTNrNGVFMUNXVWNLUTJselIwRlJVVUpuTnpoM1FWSlpSVU5CZDBkalNGWnBZa2RzYWsxRldVZERhWE5IUVZGUlFtYzNPSGRCVW1kRlQwRjNNbU50Vm5kaWVuQnZaRmRrYmdwaFZ6VnVXbTFHYWxwVE9YSmFXRXAxV2xkNGVreFhUblppVnpFeFltMXNNR1ZVY0hsYVYxazJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOU1VkTENrSm5iM0pDWjBWRlFXUmFOVUZuVVVOQ1NIZEZaV2RDTkVGSVdVRXpWREIzWVhOaVNFVlVTbXBIVWpSamJWZGpNMEZ4U2t0WWNtcGxVRXN6TDJnMGNIa0taME00Y0Rkdk5FRkJRVWRvUldJclZYbFJRVUZDUVUxQlVucENSa0ZwUW14d2JsZHFRVXN4YWk5bFFWWXhTVzk0YVdaa1MyaG1VbFF5VFcxM2JIQXdNd3BQYjNrNFREUjFObkZuU1doQlNYWndjRW8zWmpCT2JqQnVSMnM1YlU1Qk1reFVXbWMwTVhkc2NURlVjM0o0YTFsT1RsSkJaVWxQUmsxQmIwZERRM0ZIQ2xOTk5EbENRVTFFUVRKalFVMUhVVU5OU0cxNlRsTTJhWEp4VURsVVdGbzFRMjFrZWxKMlkwUnhMM1kwTUZkWlozUndkSFJIZDJOT01XbHdWRmhxUTI4S2VpOUNaa1JWT1VaNmFEVlFVbmRRWVZaUlNYZFZZMDg0Y3l0VlNsZEtUMHBQVkM5cE5scERiWFpWVFVaWVltRnFVRlZTVFhoM2FFeEdibWxaUlhaUE9Bb3pNRXRxUm1GUU4yeHdVSEZKYkRRMWVtcE9XUW90TFMwdExVVk9SQ0JEUlZKVVNVWkpRMEZVUlMwdExTMHRDZz09In19fX0="}], "timestampVerificationData":{"rfc3161Timestamps":[{"signedTimestamp":"MIICyjADAgEAMIICwQYJKoZIhvcNAQcCoIICsjCCAq4CAQMxDTALBglghkgBZQMEAgEwgbgGCyqGSIb3DQEJEAEEoIGoBIGlMIGiAgEBBgkrBgEEAYO/MAIwMTANBglghkgBZQMEAgEFAAQg3tnb3BObAMoUcM46d2ZCs55BzE2LF3K4Xrnplje74HUCFQD/4d5EsY0f7z6gqFEA2jjeEebl9RgPMjAyNjEwMDYxNTA1MzBaMAMCAQGgMqQwMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhoAAxggHbMIIB1wIBATBRMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQCFDoTVC8MkGHuvMFDL8uKjosqI4sMMAsGCWCGSAFlAwQCAaCB/DAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI2MTAwNjE1MDUzMFowLwYJKoZIhvcNAQkEMSIEIE7VISON7ZDB9CszdIqpT7j3X3dUthRqMXD8+kp4maVXMIGOBgsqhkiG9w0BCRACLzF/MH0wezB5BCCF+Se8B6tiysO0Q1bBDvyBssaIP9p6uebYcNnROs0FtzBVMD2kOzA5MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxIDAeBgNVBAMTF3NpZ3N0b3JlLXRzYS1zZWxmc2lnbmVkAhQ6E1QvDJBh7rzBQy/Lio6LKiOLDDAKBggqhkjOPQQDAgRnMGUCMQCogfg7yTQQM24PKeQ4Kg9s3Kka7wrUcAdw4+UA4mftgZkz91jcAiHhTAve2sIBpnkCMAtig9g7oSsjJHtSeCohUkKNBB9PJ+Y7UX7fN7FIdVUyhwhW53fwl+rHJU2BVAD/Ug=="}]}}, "messageSignature":{"messageDigest":{"algorithm":"SHA2_256", "digest":"+033fg8Ju3Fr7GNDTxIvmnpRFI2QlPHCd6LcYhMe4uE="}, "signature":"MEQCIC4v/RKvvgi0GbjPam4eLlhRrRRbDG/VA+mrUxYM/aWJAiAHvtOpTmRtxE6Pf2pZxN4hvTR7jN/Pa4pgJrpJ6cu39w=="}}
build/torch-rocm/qwen2vl_mrope.py CHANGED
@@ -2,6 +2,8 @@ import torch
2
  import triton
3
  import triton.language as tl
4
 
 
 
5
 
6
  @triton.jit
7
  def _triton_qwen2vl_mrope(
@@ -128,24 +130,25 @@ def qwen2vl_mrope_forward(q, k, cos, sin, mrope_section):
128
  cos = cos.contiguous()
129
  sin = sin.contiguous()
130
 
131
- _triton_qwen2vl_mrope[(n_row,)](
132
- q,
133
- k,
134
- cos,
135
- sin,
136
- seq_len,
137
- batch_size,
138
- n_q_head,
139
- n_kv_head,
140
- head_dim,
141
- pad_n_q_head,
142
- pad_n_kv_head,
143
- pad_hd,
144
- mrope_section[0],
145
- mrope_section[1],
146
- BLOCK_SIZE=BLOCK_SIZE,
147
- BACKWARD_PASS=False,
148
- )
 
149
  return q.transpose(1, 2), k.transpose(1, 2), cos, sin
150
 
151
 
@@ -166,25 +169,26 @@ def qwen2vl_mrope_backward(dq, dk, cos, sin, mrope_section):
166
  dq = dq.contiguous()
167
  dk = dk.contiguous()
168
 
169
- # backward is similar to forward except swapping few ops
170
- _triton_qwen2vl_mrope[(n_row,)](
171
- dq,
172
- dk,
173
- cos,
174
- sin,
175
- seq_len,
176
- batch_size,
177
- n_q_head,
178
- n_kv_head,
179
- head_dim,
180
- pad_n_q_head,
181
- pad_n_kv_head,
182
- pad_hd,
183
- mrope_section[0],
184
- mrope_section[1],
185
- BLOCK_SIZE=BLOCK_SIZE,
186
- BACKWARD_PASS=True,
187
- )
 
188
  return dq.transpose(1, 2), dk.transpose(1, 2)
189
 
190
 
 
2
  import triton
3
  import triton.language as tl
4
 
5
+ from .utils import device_context
6
+
7
 
8
  @triton.jit
9
  def _triton_qwen2vl_mrope(
 
130
  cos = cos.contiguous()
131
  sin = sin.contiguous()
132
 
133
+ with device_context(q.device):
134
+ _triton_qwen2vl_mrope[(n_row,)](
135
+ q,
136
+ k,
137
+ cos,
138
+ sin,
139
+ seq_len,
140
+ batch_size,
141
+ n_q_head,
142
+ n_kv_head,
143
+ head_dim,
144
+ pad_n_q_head,
145
+ pad_n_kv_head,
146
+ pad_hd,
147
+ mrope_section[0],
148
+ mrope_section[1],
149
+ BLOCK_SIZE=BLOCK_SIZE,
150
+ BACKWARD_PASS=False,
151
+ )
152
  return q.transpose(1, 2), k.transpose(1, 2), cos, sin
153
 
154
 
 
169
  dq = dq.contiguous()
170
  dk = dk.contiguous()
171
 
172
+ with device_context(dq.device):
173
+ # backward is similar to forward except swapping few ops
174
+ _triton_qwen2vl_mrope[(n_row,)](
175
+ dq,
176
+ dk,
177
+ cos,
178
+ sin,
179
+ seq_len,
180
+ batch_size,
181
+ n_q_head,
182
+ n_kv_head,
183
+ head_dim,
184
+ pad_n_q_head,
185
+ pad_n_kv_head,
186
+ pad_hd,
187
+ mrope_section[0],
188
+ mrope_section[1],
189
+ BLOCK_SIZE=BLOCK_SIZE,
190
+ BACKWARD_PASS=True,
191
+ )
192
  return dq.transpose(1, 2), dk.transpose(1, 2)
193
 
194
 
build/torch-rocm/rms_norm.py CHANGED
@@ -24,6 +24,8 @@ from .utils import get_npu_core_count
24
  from .utils import set_large_grf_mode
25
  from .utils import torch_to_triton_dtype
26
  from .utils import is_npu_available
 
 
27
 
28
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
29
  try:
@@ -438,47 +440,49 @@ def rms_norm_forward(X, W, eps, offset, casting_mode, row_mode):
438
  kernel_args = {}
439
  if X.device.type == "xpu":
440
  set_large_grf_mode(kernel_args)
441
- if BLOCK_SIZE > 256 or n_rows < 4096 * 8 or row_mode:
442
- _rms_norm_forward_kernel[(n_rows,)](
443
- Y,
444
- Y.stride(0),
445
- X,
446
- X.stride(0),
447
- W,
448
- W.stride(0) if elementwise_affine else 0,
449
- RSTD,
450
- RSTD.stride(0),
451
- n_cols,
452
- eps,
453
- offset,
454
- casting_mode,
455
- elementwise_affine=elementwise_affine,
456
- BLOCK_SIZE=BLOCK_SIZE,
457
- num_warps=num_warps,
458
- **kernel_args, # XPU-specific optimization
459
- )
460
- else:
461
- BLOCK_ROW = 16
462
- kernel_args["BLOCK_ROW"] = BLOCK_ROW
463
- _block_rms_norm_forward_kernel[(triton.cdiv(n_rows, BLOCK_ROW),)](
464
- Y,
465
- Y.stride(0),
466
- X,
467
- X.stride(0),
468
- W,
469
- W.stride(0) if elementwise_affine else 0,
470
- RSTD,
471
- RSTD.stride(0),
472
- n_rows,
473
- n_cols,
474
- eps,
475
- offset,
476
- casting_mode,
477
- elementwise_affine=elementwise_affine,
478
- BLOCK_SIZE=BLOCK_SIZE,
479
- num_warps=num_warps,
480
- **kernel_args, # XPU-specific optimization
481
- )
 
 
482
  return Y.view(*shape), X, RSTD, BLOCK_SIZE, num_warps, casting_mode
483
 
484
 
@@ -519,57 +523,58 @@ def rms_norm_backward(dY, X, W, RSTD, offset, casting_mode, BLOCK_SIZE, num_warp
519
  if X.device.type == "xpu":
520
  set_large_grf_mode(kernel_args)
521
 
522
- if BLOCK_SIZE > 256 or n_rows < 4096 * 8 or row_mode:
523
- _rms_norm_backward_kernel[grid](
524
- dY,
525
- dY.stride(0),
526
- dX,
527
- dX.stride(0),
528
- X,
529
- X.stride(0),
530
- torch_to_triton_dtype[X.dtype],
531
- W,
532
- W.stride(0) if elementwise_affine else 0,
533
- RSTD,
534
- RSTD.stride(0),
535
- _dW,
536
- _dW.stride(0) if elementwise_affine else 0,
537
- n_rows,
538
- n_cols,
539
- offset,
540
- rows_per_program,
541
- casting_mode,
542
- elementwise_affine=elementwise_affine,
543
- BLOCK_SIZE=BLOCK_SIZE,
544
- num_warps=num_warps,
545
- **kernel_args, # XPU-specific optimization
546
- )
547
- else:
548
- BLOCK_ROW = 16
549
- kernel_args["BLOCK_ROW"] = BLOCK_ROW
550
- _block_rms_norm_backward_kernel[grid](
551
- dY,
552
- dY.stride(0),
553
- dX,
554
- dX.stride(0),
555
- X,
556
- X.stride(0),
557
- torch_to_triton_dtype[X.dtype],
558
- W,
559
- W.stride(0) if elementwise_affine else 0,
560
- RSTD,
561
- RSTD.stride(0),
562
- _dW,
563
- _dW.stride(0) if elementwise_affine else 0,
564
- n_rows,
565
- n_cols,
566
- offset,
567
- casting_mode,
568
- elementwise_affine=elementwise_affine,
569
- BLOCK_SIZE=BLOCK_SIZE,
570
- num_warps=num_warps,
571
- **kernel_args, # XPU-specific optimization
572
- )
 
573
  dX = dX.view(*shape)
574
 
575
  if elementwise_affine:
 
24
  from .utils import set_large_grf_mode
25
  from .utils import torch_to_triton_dtype
26
  from .utils import is_npu_available
27
+ from .utils import device_context
28
+
29
 
30
  if compare_version("triton", operator.ge, "3.0.0") and not is_npu_available():
31
  try:
 
440
  kernel_args = {}
441
  if X.device.type == "xpu":
442
  set_large_grf_mode(kernel_args)
443
+
444
+ with device_context(X.device):
445
+ if BLOCK_SIZE > 256 or n_rows < 4096 * 8 or row_mode:
446
+ _rms_norm_forward_kernel[(n_rows,)](
447
+ Y,
448
+ Y.stride(0),
449
+ X,
450
+ X.stride(0),
451
+ W,
452
+ W.stride(0) if elementwise_affine else 0,
453
+ RSTD,
454
+ RSTD.stride(0),
455
+ n_cols,
456
+ eps,
457
+ offset,
458
+ casting_mode,
459
+ elementwise_affine=elementwise_affine,
460
+ BLOCK_SIZE=BLOCK_SIZE,
461
+ num_warps=num_warps,
462
+ **kernel_args, # XPU-specific optimization
463
+ )
464
+ else:
465
+ BLOCK_ROW = 16
466
+ kernel_args["BLOCK_ROW"] = BLOCK_ROW
467
+ _block_rms_norm_forward_kernel[(triton.cdiv(n_rows, BLOCK_ROW),)](
468
+ Y,
469
+ Y.stride(0),
470
+ X,
471
+ X.stride(0),
472
+ W,
473
+ W.stride(0) if elementwise_affine else 0,
474
+ RSTD,
475
+ RSTD.stride(0),
476
+ n_rows,
477
+ n_cols,
478
+ eps,
479
+ offset,
480
+ casting_mode,
481
+ elementwise_affine=elementwise_affine,
482
+ BLOCK_SIZE=BLOCK_SIZE,
483
+ num_warps=num_warps,
484
+ **kernel_args, # XPU-specific optimization
485
+ )
486
  return Y.view(*shape), X, RSTD, BLOCK_SIZE, num_warps, casting_mode
487
 
488
 
 
523
  if X.device.type == "xpu":
524
  set_large_grf_mode(kernel_args)
525
 
526
+ with device_context(X.device):
527
+ if BLOCK_SIZE > 256 or n_rows < 4096 * 8 or row_mode:
528
+ _rms_norm_backward_kernel[grid](
529
+ dY,
530
+ dY.stride(0),
531
+ dX,
532
+ dX.stride(0),
533
+ X,
534
+ X.stride(0),
535
+ torch_to_triton_dtype[X.dtype],
536
+ W,
537
+ W.stride(0) if elementwise_affine else 0,
538
+ RSTD,
539
+ RSTD.stride(0),
540
+ _dW,
541
+ _dW.stride(0) if elementwise_affine else 0,
542
+ n_rows,
543
+ n_cols,
544
+ offset,
545
+ rows_per_program,
546
+ casting_mode,
547
+ elementwise_affine=elementwise_affine,
548
+ BLOCK_SIZE=BLOCK_SIZE,
549
+ num_warps=num_warps,
550
+ **kernel_args, # XPU-specific optimization
551
+ )
552
+ else:
553
+ BLOCK_ROW = 16
554
+ kernel_args["BLOCK_ROW"] = BLOCK_ROW
555
+ _block_rms_norm_backward_kernel[grid](
556
+ dY,
557
+ dY.stride(0),
558
+ dX,
559
+ dX.stride(0),
560
+ X,
561
+ X.stride(0),
562
+ torch_to_triton_dtype[X.dtype],
563
+ W,
564
+ W.stride(0) if elementwise_affine else 0,
565
+ RSTD,
566
+ RSTD.stride(0),
567
+ _dW,
568
+ _dW.stride(0) if elementwise_affine else 0,
569
+ n_rows,
570
+ n_cols,
571
+ offset,
572
+ casting_mode,
573
+ elementwise_affine=elementwise_affine,
574
+ BLOCK_SIZE=BLOCK_SIZE,
575
+ num_warps=num_warps,
576
+ **kernel_args, # XPU-specific optimization
577
+ )
578
  dX = dX.view(*shape)
579
 
580
  if elementwise_affine:
build/torch-rocm/rope.py CHANGED
@@ -2,6 +2,8 @@ import torch
2
  import triton
3
  import triton.language as tl
4
 
 
 
5
 
6
  @triton.jit
7
  def _triton_rope(
@@ -134,27 +136,28 @@ def rope_forward(q, k, cos, sin):
134
  sin = sin.contiguous()
135
  cos_batch_size = cos.shape[0]
136
 
137
- _triton_rope[(n_row,)](
138
- q,
139
- q.stride(1),
140
- k,
141
- k.stride(1),
142
- cos,
143
- cos.stride(-2),
144
- sin,
145
- sin.stride(-2),
146
- seq_len,
147
- batch_size,
148
- cos_batch_size,
149
- n_q_head,
150
- n_kv_head,
151
- head_dim,
152
- pad_n_q_head,
153
- pad_n_kv_head,
154
- pad_hd,
155
- BLOCK_SIZE=BLOCK_SIZE,
156
- BACKWARD_PASS=False,
157
- )
 
158
  return q.transpose(1, 2), k.transpose(1, 2), cos, sin
159
 
160
 
@@ -176,28 +179,29 @@ def rope_backward(dq, dk, cos, sin):
176
  dq = dq.contiguous()
177
  dk = dk.contiguous()
178
 
179
- # backward is similar to forward except swapping few ops
180
- _triton_rope[(n_row,)](
181
- dq,
182
- dq.stride(1),
183
- dk,
184
- dk.stride(1),
185
- cos,
186
- cos.stride(-2),
187
- sin,
188
- sin.stride(-2),
189
- seq_len,
190
- batch_size,
191
- cos_batch_size,
192
- n_q_head,
193
- n_kv_head,
194
- head_dim,
195
- pad_n_q_head,
196
- pad_n_kv_head,
197
- pad_hd,
198
- BLOCK_SIZE=BLOCK_SIZE,
199
- BACKWARD_PASS=True,
200
- )
 
201
  return dq.transpose(1, 2), dk.transpose(1, 2)
202
 
203
 
 
2
  import triton
3
  import triton.language as tl
4
 
5
+ from .utils import device_context
6
+
7
 
8
  @triton.jit
9
  def _triton_rope(
 
136
  sin = sin.contiguous()
137
  cos_batch_size = cos.shape[0]
138
 
139
+ with device_context(q.device):
140
+ _triton_rope[(n_row,)](
141
+ q,
142
+ q.stride(1),
143
+ k,
144
+ k.stride(1),
145
+ cos,
146
+ cos.stride(-2),
147
+ sin,
148
+ sin.stride(-2),
149
+ seq_len,
150
+ batch_size,
151
+ cos_batch_size,
152
+ n_q_head,
153
+ n_kv_head,
154
+ head_dim,
155
+ pad_n_q_head,
156
+ pad_n_kv_head,
157
+ pad_hd,
158
+ BLOCK_SIZE=BLOCK_SIZE,
159
+ BACKWARD_PASS=False,
160
+ )
161
  return q.transpose(1, 2), k.transpose(1, 2), cos, sin
162
 
163
 
 
179
  dq = dq.contiguous()
180
  dk = dk.contiguous()
181
 
182
+ with device_context(dq.device):
183
+ # backward is similar to forward except swapping few ops
184
+ _triton_rope[(n_row,)](
185
+ dq,
186
+ dq.stride(1),
187
+ dk,
188
+ dk.stride(1),
189
+ cos,
190
+ cos.stride(-2),
191
+ sin,
192
+ sin.stride(-2),
193
+ seq_len,
194
+ batch_size,
195
+ cos_batch_size,
196
+ n_q_head,
197
+ n_kv_head,
198
+ head_dim,
199
+ pad_n_q_head,
200
+ pad_n_kv_head,
201
+ pad_hd,
202
+ BLOCK_SIZE=BLOCK_SIZE,
203
+ BACKWARD_PASS=True,
204
+ )
205
  return dq.transpose(1, 2), dk.transpose(1, 2)
206
 
207
 
build/torch-rocm/swiglu.py CHANGED
@@ -4,6 +4,7 @@ import triton.language as tl
4
 
5
  from .utils import calculate_settings
6
  from .utils import ensure_contiguous
 
7
 
8
 
9
  @triton.jit
@@ -73,16 +74,17 @@ def swiglu_forward(a, b, gate_multiplier: float = 1.0):
73
 
74
  BLOCK_SIZE, num_warps = calculate_settings(n_cols)
75
 
76
- _swiglu_forward_kernel[(n_rows,)](
77
- a,
78
- b,
79
- c,
80
- c.stride(-2),
81
- float(gate_multiplier),
82
- n_cols=n_cols,
83
- BLOCK_SIZE=BLOCK_SIZE,
84
- num_warps=num_warps,
85
- )
 
86
  return a, b, c.view(*ori_shape)
87
 
88
 
@@ -94,16 +96,17 @@ def swiglu_backward(a, b, dc, gate_multiplier: float = 1.0):
94
 
95
  BLOCK_SIZE, num_warps = calculate_settings(n_cols)
96
 
97
- _swiglu_backward_kernel[(n_rows,)](
98
- dc,
99
- a,
100
- b,
101
- dc.stride(-2),
102
- float(gate_multiplier),
103
- n_cols=n_cols,
104
- BLOCK_SIZE=BLOCK_SIZE,
105
- num_warps=num_warps,
106
- )
 
107
  return a.view(*ori_shape), b.view(*ori_shape)
108
 
109
 
 
4
 
5
  from .utils import calculate_settings
6
  from .utils import ensure_contiguous
7
+ from .utils import device_context
8
 
9
 
10
  @triton.jit
 
74
 
75
  BLOCK_SIZE, num_warps = calculate_settings(n_cols)
76
 
77
+ with device_context(a.device):
78
+ _swiglu_forward_kernel[(n_rows,)](
79
+ a,
80
+ b,
81
+ c,
82
+ c.stride(-2),
83
+ float(gate_multiplier),
84
+ n_cols=n_cols,
85
+ BLOCK_SIZE=BLOCK_SIZE,
86
+ num_warps=num_warps,
87
+ )
88
  return a, b, c.view(*ori_shape)
89
 
90
 
 
96
 
97
  BLOCK_SIZE, num_warps = calculate_settings(n_cols)
98
 
99
+ with device_context(a.device):
100
+ _swiglu_backward_kernel[(n_rows,)](
101
+ dc,
102
+ a,
103
+ b,
104
+ dc.stride(-2),
105
+ float(gate_multiplier),
106
+ n_cols=n_cols,
107
+ BLOCK_SIZE=BLOCK_SIZE,
108
+ num_warps=num_warps,
109
+ )
110
  return a.view(*ori_shape), b.view(*ori_shape)
111
 
112
 
build/torch-rocm/tiled_mlp.py CHANGED
@@ -5,10 +5,32 @@ from typing import List
5
  from typing import Optional
6
 
7
  import torch
 
8
 
9
  from .utils import ensure_contiguous
10
 
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  class LigerTiledMLPFunction(torch.autograd.Function):
13
  """
14
  Based on DeepSpeed's TiledMLP:
@@ -40,10 +62,15 @@ class LigerTiledMLPFunction(torch.autograd.Function):
40
  x: torch.Tensor,
41
  shards: int,
42
  compute_params: Optional[List[torch.nn.Parameter]] = None,
 
43
  ) -> torch.Tensor:
44
  ctx.fn = fn
45
  ctx.mlp_module = mlp_module
46
  ctx.shards = shards
 
 
 
 
47
  ctx.save_for_backward(x)
48
 
49
  # x.shape could be [bs, seqlen, hidden_size] or [seqlen, hidden_size] (moe experts)
@@ -61,22 +88,38 @@ class LigerTiledMLPFunction(torch.autograd.Function):
61
  (x,) = ctx.saved_tensors
62
  mlp_module = ctx.mlp_module
63
  shards = ctx.shards
 
 
 
 
64
 
65
  x_requires_grad = x.requires_grad
66
  x = x.detach()
67
  # detach() unsets x.requires_grad, so restore it
68
  x.requires_grad_(x_requires_grad)
69
 
70
- # x.shape could be [bs, seqlen, hidden_size] or [seqlen, hidden_size] (moe experts)
71
- hidden_size = x.shape[-1]
 
72
  x_shape_orig = x.shape
73
 
74
  # flatten bs+seqlen to avoid having stride issues when narrowing into seqlen w/ bs>1
75
- x = x.view(-1, hidden_size)
76
- incoming_grad = grads[0].view(-1, hidden_size)
 
 
77
  x_grad = torch.zeros_like(x)
78
 
79
  x_shards = list(torch.chunk(x, chunks=shards, dim=0))
 
 
 
 
 
 
 
 
 
80
 
81
  for i, x_shard in enumerate(x_shards):
82
  x_shard.requires_grad_(x_requires_grad)
@@ -85,17 +128,44 @@ class LigerTiledMLPFunction(torch.autograd.Function):
85
  shard_step = x_shards[i].shape[0]
86
  shard_offset = i * x_shards[0].shape[0]
87
 
88
- x_shard.grad = x_grad.narrow(0, shard_offset, shard_step).view_as(x_shard)
89
- incoming_grad_shard = incoming_grad.narrow(0, shard_offset, shard_step).view_as(x_shard)
90
-
91
- with torch.enable_grad():
92
- output = fn(mlp_module, x_shard)
93
- torch.autograd.backward(output, incoming_grad_shard)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  # unflatten
96
  x_grad = x_grad.view(x_shape_orig)
97
 
98
- return (None, None, x_grad, None, None)
99
 
100
 
101
  def apply_tiled_mlp(
@@ -114,9 +184,6 @@ def apply_tiled_mlp(
114
  x: the input tensor with shape [bs, seqlen, hidden_size] or [seqlen, hidden_size]
115
  num_shards: number of shards to use. If None, automatically calculated as ceil(seqlen / hidden_size)
116
  compute_params: list of parameters for DeepSpeed ZeRO optimization
117
-
118
- Returns:
119
- output tensor with the same shape as input
120
  """
121
  if num_shards is None:
122
  # x.shape could be [bs, seqlen, hidden_size] or [seqlen, hidden_size]
@@ -127,10 +194,20 @@ def apply_tiled_mlp(
127
  # Ensure num_shards is at least 1
128
  num_shards = max(1, num_shards)
129
 
 
 
 
 
 
 
 
 
130
  return LigerTiledMLPFunction.apply(
131
  fn,
132
  mlp_module,
133
  x,
134
  num_shards,
135
  compute_params,
 
 
136
  )
 
5
  from typing import Optional
6
 
7
  import torch
8
+ import torch.distributed as dist
9
 
10
  from .utils import ensure_contiguous
11
 
12
 
13
+ def _autograd_input_params(
14
+ compute_params: Optional[List[torch.nn.Parameter]],
15
+ ) -> List[torch.nn.Parameter]:
16
+ """The weights to pass to the autograd Function as explicit inputs.
17
+
18
+ Doing so makes autograd accumulate each weight once, at the end of the backward, instead of once
19
+ per shard. DDP registers one hook per parameter and marks it ready on every firing, so the
20
+ per-shard accumulation would trip "Expected to mark a variable ready only once".
21
+
22
+ Returns an empty list under ZeRO-3: partitioned weights are 0-sized placeholders outside their
23
+ owning module's forward, so autograd would record ``(0,)`` as the expected gradient shape and the
24
+ recompute would fail. Those stay on the accumulate-into-``.grad`` path, where the reduction is
25
+ deferred to the last shard via ``ds_grad_is_ready``.
26
+ """
27
+ if not compute_params:
28
+ return []
29
+ if any(hasattr(p, "ds_id") for p in compute_params):
30
+ return []
31
+ return [p for p in compute_params if p.requires_grad]
32
+
33
+
34
  class LigerTiledMLPFunction(torch.autograd.Function):
35
  """
36
  Based on DeepSpeed's TiledMLP:
 
62
  x: torch.Tensor,
63
  shards: int,
64
  compute_params: Optional[List[torch.nn.Parameter]] = None,
65
+ *params: torch.Tensor,
66
  ) -> torch.Tensor:
67
  ctx.fn = fn
68
  ctx.mlp_module = mlp_module
69
  ctx.shards = shards
70
+ ctx.compute_params = compute_params
71
+ # `params` arrives via ensure_contiguous, which may hand us copies; resolve the originals so
72
+ # torch.autograd.grad differentiates the tensors the recompute actually uses.
73
+ ctx.grad_params = _autograd_input_params(compute_params)
74
  ctx.save_for_backward(x)
75
 
76
  # x.shape could be [bs, seqlen, hidden_size] or [seqlen, hidden_size] (moe experts)
 
88
  (x,) = ctx.saved_tensors
89
  mlp_module = ctx.mlp_module
90
  shards = ctx.shards
91
+ compute_params = ctx.compute_params
92
+ grad_params = ctx.grad_params
93
+
94
+ grad_output = grads[0]
95
 
96
  x_requires_grad = x.requires_grad
97
  x = x.detach()
98
  # detach() unsets x.requires_grad, so restore it
99
  x.requires_grad_(x_requires_grad)
100
 
101
+ # x.shape could be [bs, seqlen, in_features] or [seqlen, in_features] (moe experts)
102
+ in_features = x.shape[-1]
103
+ out_features = grad_output.shape[-1]
104
  x_shape_orig = x.shape
105
 
106
  # flatten bs+seqlen to avoid having stride issues when narrowing into seqlen w/ bs>1
107
+ # NOTE: input and output feature dimensions may differ, e.g.
108
+ # Linear(in_features, out_features), so flatten x and grad_output with their own last dims.
109
+ x = x.view(-1, in_features)
110
+ incoming_grad = grad_output.view(-1, out_features)
111
  x_grad = torch.zeros_like(x)
112
 
113
  x_shards = list(torch.chunk(x, chunks=shards, dim=0))
114
+ incoming_grad_shards = list(torch.chunk(incoming_grad, chunks=shards, dim=0))
115
+
116
+ # ZeRO-3 partitioned parameters carry a ds_id; collect them once so the per-shard loop only
117
+ # flips the ready flag. Parameters on other backends have no ds_id and are left untouched.
118
+ ds_params = [p for p in compute_params if hasattr(p, "ds_id")] if compute_params else []
119
+
120
+ # Summed over shards and returned as this Function's gradients, so autograd accumulates each
121
+ # weight exactly once. Empty under ZeRO-3, which keeps the per-shard accumulation below.
122
+ param_grads = [None] * len(grad_params)
123
 
124
  for i, x_shard in enumerate(x_shards):
125
  x_shard.requires_grad_(x_requires_grad)
 
128
  shard_step = x_shards[i].shape[0]
129
  shard_offset = i * x_shards[0].shape[0]
130
 
131
+ incoming_grad_shard = incoming_grad_shards[i]
132
+
133
+ if grad_params:
134
+ with torch.enable_grad():
135
+ output = fn(mlp_module, x_shard)
136
+ inputs = ([x_shard] if x_requires_grad else []) + grad_params
137
+ # torch.autograd.grad returns the gradients instead of accumulating into .grad, so no
138
+ # AccumulateGrad node fires here and DDP's per-parameter hook stays untouched
139
+ shard_grads = torch.autograd.grad(
140
+ outputs=output,
141
+ inputs=inputs,
142
+ grad_outputs=incoming_grad_shard,
143
+ allow_unused=True,
144
+ )
145
+ if x_requires_grad:
146
+ x_grad.narrow(0, shard_offset, shard_step).copy_(shard_grads[0])
147
+ shard_grads = shard_grads[1:]
148
+ for j, shard_grad in enumerate(shard_grads):
149
+ if shard_grad is None:
150
+ continue
151
+ # the first shard's gradient is freshly allocated, so accumulate into it in place
152
+ param_grads[j] = shard_grad if param_grads[j] is None else param_grads[j].add_(shard_grad)
153
+ else:
154
+ x_shard.grad = x_grad.narrow(0, shard_offset, shard_step).view_as(x_shard)
155
+
156
+ # Defer DeepSpeed's reduction until the last shard has accumulated into param.grad; the flag
157
+ # is read by ZeRO's hook during each shard's backward, so it must be set per shard.
158
+ for param in ds_params:
159
+ param.ds_grad_is_ready = i + 1 == len(x_shards)
160
+
161
+ with torch.enable_grad():
162
+ output = fn(mlp_module, x_shard)
163
+ torch.autograd.backward(output, incoming_grad_shard)
164
 
165
  # unflatten
166
  x_grad = x_grad.view(x_shape_orig)
167
 
168
+ return (None, None, x_grad, None, None, *param_grads)
169
 
170
 
171
  def apply_tiled_mlp(
 
184
  x: the input tensor with shape [bs, seqlen, hidden_size] or [seqlen, hidden_size]
185
  num_shards: number of shards to use. If None, automatically calculated as ceil(seqlen / hidden_size)
186
  compute_params: list of parameters for DeepSpeed ZeRO optimization
 
 
 
187
  """
188
  if num_shards is None:
189
  # x.shape could be [bs, seqlen, hidden_size] or [seqlen, hidden_size]
 
194
  # Ensure num_shards is at least 1
195
  num_shards = max(1, num_shards)
196
 
197
+ # All ranks must run the same number of shards: a sharded-parameter backend (DeepSpeed ZeRO-3, FSDP)
198
+ # gathers weights inside each shard's recompute, so a rank that runs fewer shards stops participating
199
+ # in those collectives and deadlocks the others. Harmonize on the per-rank maximum.
200
+ if dist.is_available() and dist.is_initialized() and dist.get_world_size() > 1:
201
+ num_shards_tensor = torch.tensor(num_shards, device=x.device)
202
+ dist.all_reduce(num_shards_tensor, op=dist.ReduceOp.MAX)
203
+ num_shards = int(num_shards_tensor.item())
204
+
205
  return LigerTiledMLPFunction.apply(
206
  fn,
207
  mlp_module,
208
  x,
209
  num_shards,
210
  compute_params,
211
+ # passed as explicit Function inputs so autograd accumulates each weight once per backward
212
+ *_autograd_input_params(compute_params),
213
  )
build/torch-rocm/tvd.py CHANGED
@@ -6,6 +6,7 @@ import triton
6
  import triton.language as tl
7
 
8
  from .utils import ensure_contiguous
 
9
 
10
  MAX_FUSED_SIZE = 65536 // 4
11
 
@@ -124,24 +125,25 @@ def tv_distance_forward_triton(p, q, shift_labels, reduction, ignore_index, has_
124
  else:
125
  scale = 1.0
126
 
127
- _tv_distance_kernel[grid](
128
- p,
129
- p.stride(0),
130
- q,
131
- q.stride(0),
132
- output_tensor,
133
- output_tensor.stride(0),
134
- grads,
135
- grads.stride(0),
136
- shift_labels if has_label else torch.empty(1, device=p.device),
137
- ignore_index,
138
- V,
139
- scale,
140
- BLOCK_SIZE=BLOCK_SIZE,
141
- HAS_LABEL=has_label,
142
- num_warps=num_warps,
143
- reduction=reduction,
144
- )
 
145
 
146
  # Loss and gradients are already scaled inside the kernel — no separate division needed
147
  if reduction in (_REDUCTION_MODE_BATCHMEAN.value, _REDUCTION_MODE_MEAN.value):
 
6
  import triton.language as tl
7
 
8
  from .utils import ensure_contiguous
9
+ from .utils import device_context
10
 
11
  MAX_FUSED_SIZE = 65536 // 4
12
 
 
125
  else:
126
  scale = 1.0
127
 
128
+ with device_context(p.device):
129
+ _tv_distance_kernel[grid](
130
+ p,
131
+ p.stride(0),
132
+ q,
133
+ q.stride(0),
134
+ output_tensor,
135
+ output_tensor.stride(0),
136
+ grads,
137
+ grads.stride(0),
138
+ shift_labels if has_label else torch.empty(1, device=p.device),
139
+ ignore_index,
140
+ V,
141
+ scale,
142
+ BLOCK_SIZE=BLOCK_SIZE,
143
+ HAS_LABEL=has_label,
144
+ num_warps=num_warps,
145
+ reduction=reduction,
146
+ )
147
 
148
  # Loss and gradients are already scaled inside the kernel — no separate division needed
149
  if reduction in (_REDUCTION_MODE_BATCHMEAN.value, _REDUCTION_MODE_MEAN.value):
build/torch-rocm/utils.py CHANGED
@@ -21,6 +21,7 @@ import triton
21
  import triton.language as tl
22
 
23
  from packaging.version import Version
 
24
 
25
 
26
  def is_npu_available() -> bool:
@@ -174,3 +175,14 @@ def set_large_grf_mode(kernel_args: dict):
174
  else:
175
  # API was changed in https://github.com/intel/intel-xpu-backend-for-triton/pull/5430
176
  kernel_args["grf_mode"] = "large"
 
 
 
 
 
 
 
 
 
 
 
 
21
  import triton.language as tl
22
 
23
  from packaging.version import Version
24
+ from contextlib import contextmanager
25
 
26
 
27
  def is_npu_available() -> bool:
 
175
  else:
176
  # API was changed in https://github.com/intel/intel-xpu-backend-for-triton/pull/5430
177
  kernel_args["grf_mode"] = "large"
178
+
179
+ @contextmanager
180
+ def device_context(device: torch.device):
181
+ """Context manager that sets the active device for any backend (cuda, xpu, etc.)."""
182
+ backend = getattr(torch, device.type, None)
183
+ # Skipped while compiling: torch 2.14 regression, https://github.com/pytorch/pytorch/issues/199919
184
+ if not torch.compiler.is_compiling() and backend is not None and hasattr(backend, "device"):
185
+ with backend.device(device):
186
+ yield
187
+ else:
188
+ yield