Kernels:
Trusted publisher
Uploaded using `kernel-builder`.
Browse files- build/torch-rocm/__init__.py +8 -2
- build/torch-rocm/_ops.py +8 -2
- build/torch-rocm/cross_entropy.py +54 -50
- build/torch-rocm/dyt.py +16 -12
- build/torch-rocm/fused_linear_cross_entropy.py +72 -69
- build/torch-rocm/geglu.py +22 -18
- build/torch-rocm/group_norm.py +43 -39
- build/torch-rocm/jsd.py +19 -17
- build/torch-rocm/kl_div.py +28 -25
- build/torch-rocm/layer_norm.py +47 -43
- build/torch-rocm/layers.py +174 -344
- build/torch-rocm/liger_kernels/__init__.py +0 -26
- build/torch-rocm/metadata.json +38 -2
- build/torch-rocm/metadata.json.sigstore +1 -0
- build/torch-rocm/qwen2vl_mrope.py +41 -37
- build/torch-rocm/rms_norm.py +97 -92
- build/torch-rocm/rope.py +47 -43
- build/torch-rocm/swiglu.py +23 -20
- build/torch-rocm/tiled_mlp.py +91 -14
- build/torch-rocm/tvd.py +20 -18
- build/torch-rocm/utils.py +12 -0
build/torch-rocm/__init__.py
CHANGED
|
@@ -1,4 +1,10 @@
|
|
| 1 |
from . import layers
|
| 2 |
-
from .layers import
|
| 3 |
|
| 4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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, "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 = "
|
| 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 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
|
| 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 |
-
|
| 441 |
-
|
| 442 |
-
|
| 443 |
-
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
| 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 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 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 |
-
|
| 143 |
-
|
|
|
|
| 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 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 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 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 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 |
-
|
| 272 |
-
|
| 273 |
grad_output,
|
| 274 |
H,
|
| 275 |
BLOCK_SIZE=BLOCK_SIZE,
|
| 276 |
num_warps=32 if not is_hip() else 16,
|
| 277 |
)
|
| 278 |
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 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 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 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 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 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 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 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 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 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 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 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 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 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 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 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 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
|
|
|
| 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 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 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
|
| 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 |
-
|
| 26 |
-
|
| 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 |
-
|
| 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
|
| 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 |
-
|
| 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 |
-
|
| 209 |
-
|
| 210 |
-
|
| 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 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
self.beta = beta
|
| 239 |
-
self.ignore_index = ignore_index
|
| 240 |
|
| 241 |
-
|
| 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 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
|
| 273 |
|
| 274 |
class LigerSwiGLUMLP(nn.Module):
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 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 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 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
|
| 311 |
gate_proj: nn.Linear
|
| 312 |
up_proj: nn.Linear
|
| 313 |
down_proj: nn.Linear
|
| 314 |
-
num_shards: int
|
| 315 |
|
| 316 |
-
|
| 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=
|
| 327 |
mlp_module=self,
|
| 328 |
x=x,
|
| 329 |
-
num_shards=
|
| 330 |
compute_params=compute_params,
|
| 331 |
)
|
| 332 |
|
| 333 |
|
| 334 |
-
class
|
| 335 |
gate_proj: nn.Linear
|
| 336 |
up_proj: nn.Linear
|
| 337 |
down_proj: nn.Linear
|
| 338 |
-
num_shards: int
|
| 339 |
|
| 340 |
-
|
| 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=
|
| 351 |
mlp_module=self,
|
| 352 |
x=x,
|
| 353 |
-
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 |
-
|
| 412 |
-
lm_head_weight: torch.Tensor,
|
| 413 |
labels: torch.Tensor,
|
| 414 |
-
|
| 415 |
num_items_in_batch: Optional[int] = None,
|
| 416 |
ignore_index: int = -100,
|
| 417 |
shift_labels: Optional[torch.Tensor] = None,
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
**kwargs,
|
| 422 |
):
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 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=
|
| 446 |
-
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 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 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 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 493 |
|
| 494 |
|
| 495 |
__all__ = [
|
| 496 |
"LigerRMSNorm",
|
| 497 |
-
"
|
| 498 |
-
"LigerGroupNorm",
|
| 499 |
-
"LigerDyT",
|
| 500 |
-
"LigerCrossEntropyLoss",
|
| 501 |
-
"LigerFusedLinearCrossEntropyLoss",
|
| 502 |
-
"LigerJSD",
|
| 503 |
-
"LigerKLDIVLoss",
|
| 504 |
-
"LigerTVDLoss",
|
| 505 |
"LigerSwiGLUMLP",
|
| 506 |
"LigerGEGLUMLP",
|
| 507 |
-
"LigerTiledGEGLUMLP",
|
| 508 |
"LigerTiledSwiGLUMLP",
|
| 509 |
-
"
|
| 510 |
-
"liger_fused_linear_cross_entropy",
|
| 511 |
-
"LigerForCausalLMLoss",
|
| 512 |
"liger_rotary_pos_emb",
|
| 513 |
-
"
|
|
|
|
|
|
|
| 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": "
|
| 4 |
-
"version":
|
|
|
|
| 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 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 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 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 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 |
-
|
| 442 |
-
|
| 443 |
-
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
| 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 |
-
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
|
| 549 |
-
|
| 550 |
-
|
| 551 |
-
|
| 552 |
-
|
| 553 |
-
|
| 554 |
-
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
|
| 565 |
-
|
| 566 |
-
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 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 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 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 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 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 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 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 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 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,
|
| 71 |
-
|
|
|
|
| 72 |
x_shape_orig = x.shape
|
| 73 |
|
| 74 |
# flatten bs+seqlen to avoid having stride issues when narrowing into seqlen w/ bs>1
|
| 75 |
-
|
| 76 |
-
|
|
|
|
|
|
|
| 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 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 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
|