Skip to content

Commit 2907c53

Browse files
authored
Split transformer engine benchmark suite (#2677)
1 parent abb5e6e commit 2907c53

8 files changed

Lines changed: 271 additions & 160 deletions

benchmark/performance_utils.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,67 @@ def get_input_iter(self, cur_dtype) -> Generator:
580580
yield inp,
581581

582582

583+
class TexGluBenchmark(Benchmark):
584+
DEFAULT_METRICS = DEFAULT_METRICS[:] + ["tflops"]
585+
# Triton grid_y is capped at 65535, BLOCK_SIZE_H=64 -> last dim <= 8388480.
586+
MAX_LAST_DIM = 2 * 64 * 65535
587+
588+
def set_more_shapes(self):
589+
# Last dim must be even for GLU operations to split
590+
special_shapes_2d = [[1024, 2**i] for i in range(1, 20, 4)]
591+
sp_shapes_3d = [[64, 64, 2**i] for i in range(1, 15, 4)]
592+
593+
return special_shapes_2d + sp_shapes_3d
594+
595+
def init_user_config(self):
596+
super().init_user_config()
597+
supported = []
598+
for shape in self.shapes:
599+
last_dim = shape[-1]
600+
if last_dim % 2 != 0:
601+
continue
602+
if last_dim > self.MAX_LAST_DIM:
603+
continue
604+
supported.append(shape)
605+
if not supported:
606+
pytest.skip(
607+
"No geglu shapes satisfy the constraints of FlagGems implementation."
608+
)
609+
self.shapes = supported
610+
611+
612+
class TexGluForwardBenchmark(TexGluBenchmark):
613+
def get_input_iter(self, dtype):
614+
for shape in self.shapes:
615+
x = generate_tensor_input(shape, dtype, self.device)
616+
# TE GLU APIs typically accept (input, quantizer).
617+
yield (x, None)
618+
619+
def get_tflops(self, op, *args, **kwargs):
620+
# args[0] is the input tensor x
621+
shape = list(args[0].shape)
622+
return torch.tensor(shape).prod().item()
623+
624+
625+
class TexGluBackwardBenchmark(TexGluBenchmark):
626+
def get_input_iter(self, dtype):
627+
for shape in self.shapes:
628+
inp = generate_tensor_input(shape, dtype, self.device)
629+
630+
out_shape = list(shape)
631+
out_shape[-1] = out_shape[-1] // 2
632+
633+
grad_out = torch.randn(out_shape, dtype=dtype, device=self.device)
634+
635+
yield grad_out, inp, None
636+
637+
def get_tflops(self, op, *args, **kwargs):
638+
# args[1] is the original input tensor 'inp'
639+
inp_shape = list(args[1].shape)
640+
# Proxy FLOPs estimate: forward + backward cost roughly approximated
641+
return torch.tensor(inp_shape).prod().item() * 2
642+
643+
583644
def generate_tensor_input(shape, dtype, device):
584645
if dtype in FLOAT_DTYPES:
585646
return torch.randn(shape, dtype=dtype, device=device)

benchmark/test_dgeglu.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import pytest
2+
3+
import flag_gems
4+
from benchmark.attri_util import FLOAT_DTYPES
5+
from benchmark.performance_utils import TexGluBackwardBenchmark
6+
7+
# Note: Importing transformer_engine (especially in some versions like py 3.10) may automatically
8+
# configure the Root Logger (adding handlers). This may cause subsequent `logging.basicConfig`
9+
# calls (used by FlagGems benchmark) to be ignored/no-op, leading to missing result log files.
10+
# See: https://github.com/NVIDIA/TransformerEngine/issues/1065
11+
try:
12+
from transformer_engine.pytorch import cpp_extensions as tex
13+
14+
TE_OP = getattr(tex, "dgeglu")
15+
TE_AVAILABLE = True
16+
GEMS_OP = getattr(flag_gems, "dgeglu")
17+
except ImportError:
18+
TE_AVAILABLE = False
19+
TE_OP = None
20+
GEMS_OP = None
21+
22+
23+
@pytest.mark.dgeglu
24+
@pytest.mark.skipif(not TE_AVAILABLE, reason="TransformerEngine not installed")
25+
@pytest.mark.skipif(TE_OP is None, reason="'dgeglu' not found in TransformerEngine")
26+
@pytest.mark.skipif(GEMS_OP is None, reason="'dgeglu' not found in FlagGems")
27+
def test_dgeglu():
28+
bench = TexGluBackwardBenchmark(
29+
op_name="dgeglu",
30+
torch_op=TE_OP,
31+
gems_op=GEMS_OP,
32+
dtypes=FLOAT_DTYPES,
33+
# TODO(Qiming): Is this flag correct?
34+
is_backward=False,
35+
)
36+
bench.run()

benchmark/test_dreglu.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import pytest
2+
3+
import flag_gems
4+
from benchmark.attri_util import FLOAT_DTYPES
5+
from benchmark.performance_utils import TexGluBackwardBenchmark
6+
7+
# Note: Importing transformer_engine (especially in some versions like py 3.10) may automatically
8+
# configure the Root Logger (adding handlers). This may cause subsequent `logging.basicConfig`
9+
# calls (used by FlagGems benchmark) to be ignored/no-op, leading to missing result log files.
10+
# See: https://github.com/NVIDIA/TransformerEngine/issues/1065
11+
try:
12+
from transformer_engine.pytorch import cpp_extensions as tex
13+
14+
TE_OP = getattr(tex, "dreglu")
15+
TE_AVAILABLE = True
16+
GEMS_OP = getattr(flag_gems, "dreglu")
17+
except ImportError:
18+
TE_AVAILABLE = False
19+
TE_OP = None
20+
GEMS_OP = None
21+
22+
23+
@pytest.mark.dreglu
24+
@pytest.mark.skipif(not TE_AVAILABLE, reason="TransformerEngine not installed")
25+
@pytest.mark.skipif(TE_OP is None, reason="'dreglu' not found in TransformerEngine")
26+
@pytest.mark.skipif(GEMS_OP is None, reason="'dreglu' not found in FlagGems")
27+
def test_dreglu():
28+
bench = TexGluBackwardBenchmark(
29+
op_name="dreglu",
30+
torch_op=TE_OP,
31+
gems_op=GEMS_OP,
32+
dtypes=FLOAT_DTYPES,
33+
# TODO(Qiming): Is this flag correct?
34+
is_backward=False,
35+
)
36+
bench.run()

benchmark/test_dswiglu.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import pytest
2+
3+
import flag_gems
4+
from benchmark.attri_util import FLOAT_DTYPES
5+
from benchmark.performance_utils import TexGluBackwardBenchmark
6+
7+
# Note: Importing transformer_engine (especially in some versions like py 3.10) may automatically
8+
# configure the Root Logger (adding handlers). This may cause subsequent `logging.basicConfig`
9+
# calls (used by FlagGems benchmark) to be ignored/no-op, leading to missing result log files.
10+
# See: https://github.com/NVIDIA/TransformerEngine/issues/1065
11+
try:
12+
from transformer_engine.pytorch import cpp_extensions as tex
13+
14+
TE_OP = getattr(tex, "dswiglu")
15+
TE_AVAILABLE = True
16+
GEMS_OP = getattr(flag_gems, "dswiglu")
17+
except ImportError:
18+
TE_AVAILABLE = False
19+
TE_OP = None
20+
GEMS_OP = None
21+
22+
23+
@pytest.mark.dswiglu
24+
@pytest.mark.skipif(not TE_AVAILABLE, reason="TransformerEngine not installed")
25+
@pytest.mark.skipif(TE_OP is None, reason="'dswiglu' not found in TransformerEngine")
26+
@pytest.mark.skipif(GEMS_OP is None, reason="'dswiglu' not found in FlagGems")
27+
def test_swigglu():
28+
bench = TexGluBackwardBenchmark(
29+
op_name="dswiglu",
30+
torch_op=TE_OP,
31+
gems_op=GEMS_OP,
32+
dtypes=FLOAT_DTYPES,
33+
# TODO(Qiming): Is this flag correct?
34+
is_backward=False,
35+
)
36+
bench.run()

benchmark/test_geglu.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
3+
import flag_gems
4+
from benchmark.attri_util import FLOAT_DTYPES
5+
from benchmark.performance_utils import TexGluForwardBenchmark
6+
7+
# Note: Importing transformer_engine (especially in some versions like py 3.10) may automatically
8+
# configure the Root Logger (adding handlers). This may cause subsequent `logging.basicConfig`
9+
# calls (used by FlagGems benchmark) to be ignored/no-op, leading to missing result log files.
10+
# See: https://github.com/NVIDIA/TransformerEngine/issues/1065
11+
try:
12+
from transformer_engine.pytorch import cpp_extensions as tex
13+
14+
TE_OP = getattr(tex, "geglu")
15+
TE_AVAILABLE = True
16+
GEMS_OP = getattr(flag_gems, "geglu")
17+
except ImportError:
18+
TE_AVAILABLE = False
19+
TE_OP = None
20+
GEMS_OP = None
21+
22+
23+
@pytest.mark.geglu
24+
@pytest.mark.skipif(not TE_AVAILABLE, reason="TransformerEngine not installed")
25+
@pytest.mark.skipif(TE_OP is None, reason="'geglu' not found in TransformerEngine")
26+
@pytest.mark.skipif(GEMS_OP is None, reason="'geglu' not found in FlagGems")
27+
def test_geglu():
28+
bench = TexGluForwardBenchmark(
29+
op_name="geglu",
30+
torch_op=TE_OP,
31+
gems_op=GEMS_OP,
32+
dtypes=FLOAT_DTYPES,
33+
)
34+
bench.run()

benchmark/test_reglu.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
3+
import flag_gems
4+
from benchmark.attri_util import FLOAT_DTYPES
5+
from benchmark.performance_utils import TexGluForwardBenchmark
6+
7+
# Note: Importing transformer_engine (especially in some versions like py 3.10) may automatically
8+
# configure the Root Logger (adding handlers). This may cause subsequent `logging.basicConfig`
9+
# calls (used by FlagGems benchmark) to be ignored/no-op, leading to missing result log files.
10+
# See: https://github.com/NVIDIA/TransformerEngine/issues/1065
11+
try:
12+
from transformer_engine.pytorch import cpp_extensions as tex
13+
14+
TE_OP = getattr(tex, "reglu")
15+
TE_AVAILABLE = True
16+
GEMS_OP = getattr(flag_gems, "reglu")
17+
except ImportError:
18+
TE_AVAILABLE = False
19+
TE_OP = None
20+
GEMS_OP = None
21+
22+
23+
@pytest.mark.reglu
24+
@pytest.mark.skipif(not TE_AVAILABLE, reason="TransformerEngine not installed")
25+
@pytest.mark.skipif(TE_OP is None, reason="'reglu' not found in TransformerEngine")
26+
@pytest.mark.skipif(GEMS_OP is None, reason="'reglu' not found in FlagGems")
27+
def test_reglu():
28+
bench = TexGluForwardBenchmark(
29+
op_name="reglu",
30+
torch_op=TE_OP,
31+
gems_op=GEMS_OP,
32+
dtypes=FLOAT_DTYPES,
33+
)
34+
bench.run()

benchmark/test_swiglu.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
3+
import flag_gems
4+
from benchmark.attri_util import FLOAT_DTYPES
5+
from benchmark.performance_utils import TexGluForwardBenchmark
6+
7+
# Note: Importing transformer_engine (especially in some versions like py 3.10) may automatically
8+
# configure the Root Logger (adding handlers). This may cause subsequent `logging.basicConfig`
9+
# calls (used by FlagGems benchmark) to be ignored/no-op, leading to missing result log files.
10+
# See: https://github.com/NVIDIA/TransformerEngine/issues/1065
11+
try:
12+
from transformer_engine.pytorch import cpp_extensions as tex
13+
14+
TE_OP = getattr(tex, "swiglu")
15+
TE_AVAILABLE = True
16+
GEMS_OP = getattr(flag_gems, "swiglu")
17+
except ImportError:
18+
TE_AVAILABLE = False
19+
TE_OP = None
20+
GEMS_OP = None
21+
22+
23+
@pytest.mark.swiglu
24+
@pytest.mark.skipif(not TE_AVAILABLE, reason="TransformerEngine not installed")
25+
@pytest.mark.skipif(TE_OP is None, reason="'swilu' not found in TransformerEngine")
26+
@pytest.mark.skipif(GEMS_OP is None, reason="'swiglu' not found in FlagGems")
27+
def test_swiglu():
28+
bench = TexGluForwardBenchmark(
29+
op_name="swiglu",
30+
torch_op=TE_OP,
31+
gems_op=GEMS_OP,
32+
dtypes=FLOAT_DTYPES,
33+
)
34+
bench.run()

0 commit comments

Comments
 (0)