Skip to content

Commit 9c18d75

Browse files
authored
Merge branch 'flagos-ai:main' into main
2 parents f601ad9 + ebcfadc commit 9c18d75

55 files changed

Lines changed: 3647 additions & 143 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

transformer_engine/__init__.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,35 @@
1010
from importlib import metadata
1111
import transformer_engine.common
1212

13+
import torch
14+
15+
# Public, simple global (kept for backward compatibility).
16+
TE_DEVICE_TYPE = "cuda"
17+
TE_PLATFORM = torch.cuda
18+
19+
# Apply MUSA (VENDOR) Patches, such as torch.cuda.device -> torch.musa.device
20+
try:
21+
from .plugin.core.backends.vendor.musa.patches import apply_patch as _musa_apply_patch
22+
23+
_musa_apply_patch()
24+
except Exception as e:
25+
pass
26+
27+
28+
def te_device_type(default: str = "cuda") -> str:
29+
try:
30+
return TE_DEVICE_TYPE
31+
except Exception:
32+
return default
33+
34+
35+
def te_platform(default=torch.cuda):
36+
try:
37+
return TE_PLATFORM
38+
except Exception:
39+
return default
40+
41+
1342
try:
1443
from . import pytorch
1544
except ImportError:

transformer_engine/debug/features/fake_quant.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515

1616
import transformer_engine_torch as tex
17+
from transformer_engine import te_device_type
1718
from transformer_engine.debug.features.api import TEConfigAPIMapper
1819
from transformer_engine.common.recipe import Format
1920
from transformer_engine.pytorch.tensor import Quantizer
@@ -30,7 +31,9 @@ def fake_quantize(tensor: torch.Tensor, fp8_format: tex.DType, out=None):
3031
torch.float16,
3132
torch.bfloat16,
3233
), "[NVTORCH INSPECT ERROR] Unsupported tensor type."
33-
assert tensor.is_cuda, "[NVTORCH INSPECT ERROR] Must be a GPU tensor."
34+
assert (
35+
tensor.device.type == te_device_type()
36+
), f"[NVTORCH INSPECT ERROR] Must be a {te_device_type()} tensor."
3437
assert fp8_format in {
3538
"FP8E4M3",
3639
"FP8E5M2",

transformer_engine/debug/features/log_fp8_tensor_stats.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from nvdlfw_inspect.debug_features.log_tensor_stats import LogTensorStats as BaseLogTensorStats
1515
from nvdlfw_inspect.registry import Registry, api_method
1616

17+
from transformer_engine import te_device_type
1718
from transformer_engine.debug.features.utils.stats_buffer import STATS_BUFFERS
1819
from transformer_engine.pytorch.tensor import Quantizer, QuantizedTensor
1920
from transformer_engine.pytorch.tensor.float8_tensor import (
@@ -47,7 +48,10 @@ def _get_new_quantizer(recipe_name, fp8_dtype):
4748
return Float8BlockQuantizer(fp8_dtype=fp8_dtype, rowwise=True, columnwise=True)
4849
if recipe_name == "fp8_current_scaling":
4950
return Float8CurrentScalingQuantizer(
50-
fp8_dtype=fp8_dtype, device=torch.device("cuda"), rowwise=True, columnwise=True
51+
fp8_dtype=fp8_dtype,
52+
device=torch.device(te_device_type()),
53+
rowwise=True,
54+
columnwise=True,
5155
)
5256
if recipe_name == "mxfp8":
5357
return MXFP8Quantizer(fp8_dtype=fp8_dtype, rowwise=True, columnwise=True)

transformer_engine/debug/features/per_tensor_scaling.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
import nvdlfw_inspect.api as debug_api
1212
from nvdlfw_inspect.registry import Registry, api_method
1313

14+
1415
import transformer_engine_torch as tex
16+
from transformer_engine import te_device_type
1517
from transformer_engine.pytorch.tensor import Quantizer
1618
from transformer_engine.pytorch.tensor.float8_tensor import (
1719
Float8Tensor,
@@ -33,7 +35,9 @@ def per_tensor_cast(
3335
torch.float16,
3436
torch.bfloat16,
3537
), "[NVTORCH INSPECT ERROR] Unsupported tensor type for per tensor current scaling"
36-
assert tensor.is_cuda, "[NVTORCH INSPECT ERROR] Must be a GPU tensor."
38+
assert (
39+
tensor.device.type == te_device_type()
40+
), f"[NVTORCH INSPECT ERROR] Must be a {te_device_type()} tensor."
3741
assert fp8_dtype in {
3842
tex.DType.kFloat8E4M3,
3943
tex.DType.kFloat8E5M2,

transformer_engine/debug/features/utils/stats_buffer.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from nvdlfw_inspect.utils import gather_along_first_dim
1717
from nvdlfw_inspect.logging import MetricLogger
1818

19+
from transformer_engine import te_device_type
1920
from transformer_engine.debug.features.utils.stats_computation import (
2021
STATS,
2122
DEPENDENCIES,
@@ -41,14 +42,14 @@ def __init__(self, layer_name, tensor_name, stats, reduction_group, reduce_withi
4142
for stat in stats:
4243
self.stats_to_compute = self.stats_to_compute | DEPENDENCIES[stat]
4344

44-
self._buffer = torch.zeros(len(STATS), dtype=torch.float32).cuda()
45+
self._buffer = torch.zeros(len(STATS), dtype=torch.float32).to(te_device_type())
4546
self._new_buffer = self._buffer.clone()
4647
self._tmp_buffer = self._buffer.clone()
4748

4849
# in case of data parallelism it is possible that layer will not be run on one node
4950
# modified is set to True if node is run
5051
# we do not take not run nodes into account
51-
self.modified = torch.tensor([False], dtype=torch.bool).cuda()
52+
self.modified = torch.tensor([False], dtype=torch.bool).to(te_device_type())
5253
self.iteration = None
5354
self.skip_reduction = False
5455

transformer_engine/plugin/core/backends/flagos/attention/dot_product_attention/backends.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from packaging.version import Version as PkgVersion
1010

1111
import torch
12+
from transformer_engine import te_device_type
1213
from transformer_engine.pytorch.utils import (
1314
get_device_compute_capability,
1415
)
@@ -283,8 +284,10 @@ def _forward_impl(
283284
for x in [query_layer, key_layer, value_layer]
284285
), "FLAttention only supports FP16 and BF16 data types, or Float8Tensors."
285286
assert (
286-
query_layer.is_cuda and key_layer.is_cuda and value_layer.is_cuda
287-
), "FLAttention only supports CUDA tensors."
287+
query_layer.device.type == te_device_type()
288+
and key_layer.device.type == te_device_type()
289+
and value_layer.device.type == te_device_type()
290+
), f"FLAttention only supports {te_device_type()} tensors."
288291
assert qkv_layout in QKVLayouts, f"FLAttention does not support qkv_layout = {qkv_layout}!"
289292

290293
cp_size = 1

transformer_engine/plugin/core/backends/flagos/flagos.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
multi_tensor_adam_param_remainder_fl,
1818
multi_tensor_l2_norm_fl,
1919
generic_gemm_fl,
20+
scaled_masked_softmax_forward_fl,
21+
scaled_masked_softmax_backward_fl,
22+
te_general_grouped_gemm_fl,
2023
)
2124

2225

@@ -116,6 +119,46 @@ def generic_gemm(
116119
beta,
117120
)
118121

122+
def te_general_grouped_gemm(
123+
self,
124+
A: List[Any],
125+
transa: bool,
126+
B: List[Any],
127+
transb: bool,
128+
D: Optional[List[torch.Tensor]],
129+
D_type: DType,
130+
m_splits: List[int],
131+
bias: List[torch.Tensor],
132+
bias_type: DType,
133+
single_output: bool,
134+
pre_gelu_out: List[torch.Tensor],
135+
grad: bool,
136+
workspace: List[torch.Tensor],
137+
workspaceSizes: int,
138+
accumulate: bool,
139+
use_split_accumulator: bool,
140+
math_sm_count: int,
141+
) -> Optional[List[torch.Tensor]]:
142+
return te_general_grouped_gemm_fl(
143+
A,
144+
transa,
145+
B,
146+
transb,
147+
D,
148+
D_type,
149+
m_splits,
150+
bias,
151+
bias_type,
152+
single_output,
153+
pre_gelu_out,
154+
grad,
155+
workspace,
156+
workspaceSizes,
157+
accumulate,
158+
use_split_accumulator,
159+
math_sm_count,
160+
)
161+
119162
# Other granular functions
120163
def rmsnorm_fwd(
121164
self,
@@ -160,6 +203,23 @@ def rmsnorm_bwd(
160203
def get_fused_attn_backend(self, *args, **kwargs) -> int:
161204
return NVTE_Fused_Attn_Backend.NVTE_No_Backend
162205

206+
# Softmax functions
207+
def scaled_masked_softmax_forward(
208+
self,
209+
input: torch.Tensor,
210+
mask: torch.Tensor,
211+
scale_factor: Union[float, torch.Tensor],
212+
) -> torch.Tensor:
213+
return scaled_masked_softmax_forward_fl(input, mask, scale_factor)
214+
215+
def scaled_masked_softmax_backward(
216+
self,
217+
output_grad_: torch.Tensor,
218+
softmax_results_: torch.Tensor,
219+
scale_factor: float,
220+
) -> torch.Tensor:
221+
return scaled_masked_softmax_backward_fl(output_grad_, softmax_results_, scale_factor)
222+
163223
# multi-tensor functions
164224
def multi_tensor_scale(
165225
self,
@@ -243,7 +303,7 @@ def get_cudnn_version(self) -> int:
243303
return 90000
244304

245305
def get_num_cublas_streams(self) -> int:
246-
return 0
306+
return 4 # keep consistent with transformer_engine/common/util/multi_stream.cpp, get_num_compute_streams()
247307

248308
############## class func #################################
249309
def get_flash_attention_class(self):

transformer_engine/plugin/core/backends/flagos/impl/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
from .rmsnorm import *
77
from .fused_adam import *
88
from .multi_tensor import *
9+
from .softmax import *

transformer_engine/plugin/core/backends/flagos/impl/gemm.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
__all__ = [
1212
"generic_gemm_fl",
13+
"te_general_grouped_gemm_fl",
1314
]
1415

1516
_DTYPE_TO_TORCH = {
@@ -115,3 +116,107 @@ def generic_gemm_fl(
115116
return D, bias_grad, gelu_input, extra_output_ret
116117
else:
117118
return out1, bias_grad, gelu_input, extra_output_ret
119+
120+
121+
# This function can represent both forward and backward computations.
122+
# When grad is False (forward computation), the 'bias' is bias;
123+
# When grad is True (backward computation/gradient calculation), the 'bias' is grad_bias;
124+
def te_general_grouped_gemm_fl(
125+
B: List[torch.Tensor],
126+
transb: bool,
127+
A: List[torch.Tensor],
128+
transa: bool,
129+
D: Optional[List[torch.Tensor]],
130+
D_type: Any,
131+
m_splits: List[int],
132+
bias: List[torch.Tensor], # bias or grad_bias
133+
bias_type: Any,
134+
single_output: bool,
135+
pre_gelu_out: List[torch.Tensor],
136+
grad: bool,
137+
workspace: List[torch.Tensor],
138+
workspaceSize: int,
139+
accumulate: bool,
140+
use_split_accumulator: bool,
141+
math_sm_count: int,
142+
) -> Optional[List[torch.Tensor]]:
143+
if single_output and D is None:
144+
raise ValueError("not implemented, D should be allocated for single output case.")
145+
146+
num_gemms = len(A)
147+
if D is None:
148+
D = []
149+
for i in range(num_gemms):
150+
m = A[i].shape[1] if transa else A[i].shape[0]
151+
n = B[i].shape[0] if transb else B[i].shape[1]
152+
D.append(torch.empty((m, n), dtype=D[i].dtype, device=A[0].device))
153+
154+
temp_D = []
155+
for i in range(num_gemms):
156+
# Handle the special case of zero-element inputs
157+
if A[i].numel() == 0 or B[i].numel() == 0:
158+
if not single_output:
159+
if D[i].numel() != 0 and not accumulate:
160+
flag_gems.copy_(D[i], flag_gems.zeros(D[i].shape))
161+
else:
162+
out = flag_gems.zeros((A[i].shape[0], B[i].shape[1]))
163+
if grad and len(bias) > i and bias[i] is not None and bias[i].numel() != 0:
164+
flag_gems.copy_(bias[i], flag_gems.zeros(bias[i].shape))
165+
if (
166+
len(pre_gelu_out) > i
167+
and pre_gelu_out[i] is not None
168+
and pre_gelu_out[i].numel() != 0
169+
):
170+
flag_gems.copy_(pre_gelu_out[i], flag_gems.zeros(pre_gelu_out[i].shape))
171+
continue
172+
173+
a = A[i].t() if transa else A[i]
174+
b = B[i].t() if transb else B[i]
175+
# Determine presence of epilogue tensors
176+
has_bias = len(bias) > i and bias[i] is not None and bias[i].numel() > 0
177+
has_pre_gelu = (
178+
len(pre_gelu_out) > i and pre_gelu_out[i] is not None and pre_gelu_out[i].numel() > 0
179+
)
180+
181+
# Forward Pass calculation
182+
if not grad:
183+
if has_bias:
184+
# Fused matrix multiplication and bias addition
185+
out = flag_gems.addmm(bias[i], a, b)
186+
else:
187+
out = flag_gems.mm(a, b)
188+
189+
# Apply GELU epilogue if pre_gelu_out is provided
190+
if has_pre_gelu:
191+
flag_gems.copy_(pre_gelu_out[i], out)
192+
out = flag_gems.gelu(out)
193+
else:
194+
out = flag_gems.mm(a, b)
195+
196+
# Apply dGELU epilogue if requested
197+
if has_pre_gelu:
198+
out = flag_gems.gelu_backward(out, pre_gelu_out[i])
199+
200+
# Compute bias gradients if requested
201+
if has_bias:
202+
bias_grad = flag_gems.sum_dim(out, dim=[0])
203+
if accumulate:
204+
flag_gems.add_(bias[i], bias_grad)
205+
else:
206+
flag_gems.copy_(bias[i], bias_grad)
207+
208+
if not single_output:
209+
# Store output
210+
if accumulate:
211+
flag_gems.add_(D[i], out.to(D[i].dtype))
212+
else:
213+
flag_gems.copy_(D[i], out.to(D[i].dtype))
214+
else:
215+
temp_D.append(out.to(D[0].dtype))
216+
217+
if single_output:
218+
if temp_D:
219+
temp = flag_gems.cat(temp_D, dim=0)
220+
flag_gems.copy_(D[0], temp)
221+
222+
return bias

0 commit comments

Comments
 (0)