tileops 0.0.1.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tileops-0.0.1.dev0/LICENSE +21 -0
- tileops-0.0.1.dev0/PKG-INFO +82 -0
- tileops-0.0.1.dev0/README.md +65 -0
- tileops-0.0.1.dev0/pyproject.toml +70 -0
- tileops-0.0.1.dev0/setup.cfg +4 -0
- tileops-0.0.1.dev0/setup.py +33 -0
- tileops-0.0.1.dev0/tests/test_bitnet.py +34 -0
- tileops-0.0.1.dev0/tests/test_blocksparse_attention.py +55 -0
- tileops-0.0.1.dev0/tests/test_gqa.py +49 -0
- tileops-0.0.1.dev0/tests/test_gqa_decode.py +42 -0
- tileops-0.0.1.dev0/tests/test_linear_attn_fused_chunk.py +23 -0
- tileops-0.0.1.dev0/tests/test_linear_attn_fused_recurrent.py +23 -0
- tileops-0.0.1.dev0/tests/test_mamba_chunk_scan.py +71 -0
- tileops-0.0.1.dev0/tests/test_mamba_chunk_state.py +64 -0
- tileops-0.0.1.dev0/tests/test_mha.py +24 -0
- tileops-0.0.1.dev0/tests/test_mha_decode.py +23 -0
- tileops-0.0.1.dev0/tests/test_mla.py +39 -0
- tileops-0.0.1.dev0/tileops.egg-info/PKG-INFO +82 -0
- tileops-0.0.1.dev0/tileops.egg-info/SOURCES.txt +21 -0
- tileops-0.0.1.dev0/tileops.egg-info/dependency_links.txt +1 -0
- tileops-0.0.1.dev0/tileops.egg-info/requires.txt +2 -0
- tileops-0.0.1.dev0/tileops.egg-info/top_level.txt +1 -0
- tileops-0.0.1.dev0/top/__init__.py +18 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Tile-AI.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tileops
|
|
3
|
+
Version: 0.0.1.dev0
|
|
4
|
+
Summary: TileOPs kernels for efficient inference
|
|
5
|
+
Author: Tile-AI
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/tile-ai/tileops
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/tile-ai/tileops/issues
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: torch
|
|
15
|
+
Requires-Dist: tilelang
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# TileOPs (TOP)
|
|
19
|
+
|
|
20
|
+
**TileOPs (TOP)** is a high-performance machine learning operator collections built to run on the [TileLang](https://github.com/tile-ai/tilelang) backend. It offers efficient, modular, and composable implementations optimized for AI workloads.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## 📦 Installation
|
|
26
|
+
|
|
27
|
+
### Requirements
|
|
28
|
+
|
|
29
|
+
- Python 3.8+
|
|
30
|
+
- PyTorch >= 2.1
|
|
31
|
+
- [TileLang](https://github.com/tilelang/tilelang)
|
|
32
|
+
- Triton (optional, for selected fast kernels)
|
|
33
|
+
|
|
34
|
+
### Install (editable mode for development)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/tile-ai/TileOPs
|
|
38
|
+
cd TileOPs
|
|
39
|
+
git submodule update --init --recursive
|
|
40
|
+
pip install -e .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 🚀 Quick Usage
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import torch
|
|
47
|
+
import top
|
|
48
|
+
from top import MLAKernel
|
|
49
|
+
|
|
50
|
+
device = "cuda"
|
|
51
|
+
dtype = torch.float16
|
|
52
|
+
|
|
53
|
+
batch = 128
|
|
54
|
+
heads = 64
|
|
55
|
+
kv_heads = 1
|
|
56
|
+
kv_ctx = 8192
|
|
57
|
+
dim = 512
|
|
58
|
+
pe_dim = 64
|
|
59
|
+
|
|
60
|
+
# Query input: [batch, heads, dim]
|
|
61
|
+
q = torch.randn(batch, heads, dim, device=device, dtype=dtype)
|
|
62
|
+
|
|
63
|
+
# Query positional encoding: [batch, heads, pe_dim]
|
|
64
|
+
q_pe = torch.randn(batch, heads, pe_dim, device=device, dtype=dtype)
|
|
65
|
+
|
|
66
|
+
# KV cache input: [batch, kv_ctx, kv_heads, dim]
|
|
67
|
+
kv = torch.randn(batch, kv_ctx, kv_heads, dim, device=device, dtype=dtype)
|
|
68
|
+
|
|
69
|
+
# KV positional encoding: [batch, kv_ctx, kv_heads, pe_dim]
|
|
70
|
+
k_pe = torch.randn(batch, kv_ctx, kv_heads, pe_dim, device=device, dtype=dtype)
|
|
71
|
+
|
|
72
|
+
# Use MLA kernel
|
|
73
|
+
block_N = 64
|
|
74
|
+
block_H = 64
|
|
75
|
+
num_split = 1
|
|
76
|
+
|
|
77
|
+
mla = MLAKernel(batch, heads, kv_heads, kv_ctx, dim, pe_dim, block_N, block_H, num_split)
|
|
78
|
+
|
|
79
|
+
out = mla(q, q_pe, kv, k_pe)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Acknowledgments
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# TileOPs (TOP)
|
|
2
|
+
|
|
3
|
+
**TileOPs (TOP)** is a high-performance machine learning operator collections built to run on the [TileLang](https://github.com/tile-ai/tilelang) backend. It offers efficient, modular, and composable implementations optimized for AI workloads.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## 📦 Installation
|
|
9
|
+
|
|
10
|
+
### Requirements
|
|
11
|
+
|
|
12
|
+
- Python 3.8+
|
|
13
|
+
- PyTorch >= 2.1
|
|
14
|
+
- [TileLang](https://github.com/tilelang/tilelang)
|
|
15
|
+
- Triton (optional, for selected fast kernels)
|
|
16
|
+
|
|
17
|
+
### Install (editable mode for development)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
git clone https://github.com/tile-ai/TileOPs
|
|
21
|
+
cd TileOPs
|
|
22
|
+
git submodule update --init --recursive
|
|
23
|
+
pip install -e .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 🚀 Quick Usage
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
import torch
|
|
30
|
+
import top
|
|
31
|
+
from top import MLAKernel
|
|
32
|
+
|
|
33
|
+
device = "cuda"
|
|
34
|
+
dtype = torch.float16
|
|
35
|
+
|
|
36
|
+
batch = 128
|
|
37
|
+
heads = 64
|
|
38
|
+
kv_heads = 1
|
|
39
|
+
kv_ctx = 8192
|
|
40
|
+
dim = 512
|
|
41
|
+
pe_dim = 64
|
|
42
|
+
|
|
43
|
+
# Query input: [batch, heads, dim]
|
|
44
|
+
q = torch.randn(batch, heads, dim, device=device, dtype=dtype)
|
|
45
|
+
|
|
46
|
+
# Query positional encoding: [batch, heads, pe_dim]
|
|
47
|
+
q_pe = torch.randn(batch, heads, pe_dim, device=device, dtype=dtype)
|
|
48
|
+
|
|
49
|
+
# KV cache input: [batch, kv_ctx, kv_heads, dim]
|
|
50
|
+
kv = torch.randn(batch, kv_ctx, kv_heads, dim, device=device, dtype=dtype)
|
|
51
|
+
|
|
52
|
+
# KV positional encoding: [batch, kv_ctx, kv_heads, pe_dim]
|
|
53
|
+
k_pe = torch.randn(batch, kv_ctx, kv_heads, pe_dim, device=device, dtype=dtype)
|
|
54
|
+
|
|
55
|
+
# Use MLA kernel
|
|
56
|
+
block_N = 64
|
|
57
|
+
block_H = 64
|
|
58
|
+
num_split = 1
|
|
59
|
+
|
|
60
|
+
mla = MLAKernel(batch, heads, kv_heads, kv_ctx, dim, pe_dim, block_N, block_H, num_split)
|
|
61
|
+
|
|
62
|
+
out = mla(q, q_pe, kv, k_pe)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Acknowledgments
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "tileops"
|
|
3
|
+
version = "0.0.1.dev0"
|
|
4
|
+
description = "TileOPs kernels for efficient inference"
|
|
5
|
+
authors = [{ name="Tile-AI" }]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
requires-python = ">=3.8"
|
|
8
|
+
license = "MIT"
|
|
9
|
+
dependencies = ["torch", "tilelang"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Programming Language :: Python :: 3"
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[build-system]
|
|
16
|
+
requires = ["setuptools", "wheel"]
|
|
17
|
+
build-backend = "setuptools.build_meta"
|
|
18
|
+
|
|
19
|
+
[tool.yapf]
|
|
20
|
+
based_on_style = "yapf"
|
|
21
|
+
column_limit = 100
|
|
22
|
+
indent_width = 4
|
|
23
|
+
|
|
24
|
+
[tool.codespell]
|
|
25
|
+
ignore-words-list = "nd, te, ist, LOD, offen, NotIn, HSA"
|
|
26
|
+
skip = [
|
|
27
|
+
"build",
|
|
28
|
+
"3rdparty",
|
|
29
|
+
"dist",
|
|
30
|
+
".venv"
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[tool.setuptools]
|
|
34
|
+
packages = ["top"]
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
"Homepage" = "https://github.com/tile-ai/tileops"
|
|
38
|
+
"Bug Tracker" = "https://github.com/tile-ai/tileops/issues"
|
|
39
|
+
|
|
40
|
+
[tool.ruff.lint]
|
|
41
|
+
select = [
|
|
42
|
+
# pycodestyle
|
|
43
|
+
"E",
|
|
44
|
+
# Pyflakes
|
|
45
|
+
"F",
|
|
46
|
+
# pyupgrade
|
|
47
|
+
# "UP",
|
|
48
|
+
# flake8-bugbear
|
|
49
|
+
"B",
|
|
50
|
+
# flake8-simplify
|
|
51
|
+
"SIM",
|
|
52
|
+
# isort
|
|
53
|
+
# "I",
|
|
54
|
+
]
|
|
55
|
+
ignore = [
|
|
56
|
+
# Module level import not at top of file
|
|
57
|
+
"E402",
|
|
58
|
+
# star imports
|
|
59
|
+
"F405", "F403",
|
|
60
|
+
# ambiguous name
|
|
61
|
+
"E741",
|
|
62
|
+
# line too long
|
|
63
|
+
"E501",
|
|
64
|
+
# key in dict.keys()
|
|
65
|
+
"SIM118",
|
|
66
|
+
# memory leaks
|
|
67
|
+
"B019",
|
|
68
|
+
# No such file or directory
|
|
69
|
+
"E902",
|
|
70
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import subprocess
|
|
5
|
+
from setuptools import setup, find_packages
|
|
6
|
+
from setuptools.command.install import install
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CustomInstall(install):
|
|
10
|
+
|
|
11
|
+
def run(self):
|
|
12
|
+
# Step 1: Install system dependencies (optional, warning: requires sudo)
|
|
13
|
+
# print("Installing system dependencies for TileLang...")
|
|
14
|
+
# subprocess.run(["sudo", "apt-get", "update"])
|
|
15
|
+
# subprocess.run([
|
|
16
|
+
# "sudo", "apt-get", "install", "-y", "python3-setuptools", "gcc",
|
|
17
|
+
# "libtinfo-dev", "zlib1g-dev", "build-essential", "cmake",
|
|
18
|
+
# "libedit-dev", "libxml2-dev"
|
|
19
|
+
# ])
|
|
20
|
+
|
|
21
|
+
# Step 2: Install TileLang via pip from local path
|
|
22
|
+
# print("Installing TileLang from submodule...")
|
|
23
|
+
# subprocess.run(["pip", "install", "-e", "3rdparty/tilelang"])
|
|
24
|
+
|
|
25
|
+
# Continue normal installation
|
|
26
|
+
install.run(self)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
setup(name="top",
|
|
30
|
+
version="0.1.0",
|
|
31
|
+
packages=find_packages(),
|
|
32
|
+
install_requires=["torch", "tilelang"],
|
|
33
|
+
cmdclass={'install': CustomInstall})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import torch
|
|
3
|
+
from top import Bitnet_158_int8xint2_kernel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
parser = argparse.ArgumentParser()
|
|
8
|
+
parser.add_argument('--M', type=int, default=1, help='')
|
|
9
|
+
parser.add_argument('--N', type=int, default=256, help='')
|
|
10
|
+
parser.add_argument('--K', type=int, default=256, help='')
|
|
11
|
+
parser.add_argument('--in_dtype', type=str, default="int8", help='')
|
|
12
|
+
parser.add_argument('--out_dtype', type=str, default="int32", help='')
|
|
13
|
+
parser.add_argument('--accum_dtype', type=str, default="int32", help='')
|
|
14
|
+
parser.add_argument('--fast_decoding', type=bool, default=True, help='')
|
|
15
|
+
|
|
16
|
+
args = parser.parse_args()
|
|
17
|
+
M, N, K, in_dtype, out_dtype, accum_dtype, fast_decoding = args.M, args.N, args.K, args.in_dtype, args.out_dtype, args.accum_dtype, args.fast_decoding
|
|
18
|
+
|
|
19
|
+
A = torch.randint(0, 4, (M, K), device="cuda", dtype=getattr(torch, in_dtype))
|
|
20
|
+
B = torch.randint(0, 2, (N, K), device="cuda", dtype=getattr(torch, in_dtype))
|
|
21
|
+
C = torch.zeros(M, N, device="cuda", dtype=getattr(torch, accum_dtype))
|
|
22
|
+
|
|
23
|
+
bitnet_158_int8xint2 = Bitnet_158_int8xint2_kernel(
|
|
24
|
+
M, N, K, in_dtype, out_dtype, accum_dtype, fast_decoding)
|
|
25
|
+
C1 = bitnet_158_int8xint2.prefill(A, B, C)
|
|
26
|
+
C2 = bitnet_158_int8xint2.decode(A, B, C)
|
|
27
|
+
print(C1)
|
|
28
|
+
print(C2)
|
|
29
|
+
bitnet_158_int8xint2.check(A, B, C, "prefill")
|
|
30
|
+
bitnet_158_int8xint2.check(A, B, C, "decode")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
main()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import torch
|
|
6
|
+
from top import BlockSparseAttentionKernel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
parser = argparse.ArgumentParser()
|
|
11
|
+
parser.add_argument('--batch', type=int, default=8, help='batch size')
|
|
12
|
+
parser.add_argument('--h', type=int, default=32, help='Number of heads')
|
|
13
|
+
parser.add_argument('--n_ctx', type=int, default=1024, help='Context size')
|
|
14
|
+
parser.add_argument('--d_head_qk', type=int, default=128, help='Head dimension for Q/K')
|
|
15
|
+
parser.add_argument('--d_head_v', type=int, default=64, help='Head dimension for V')
|
|
16
|
+
parser.add_argument('--causal', action='store_true', help='Causal flag')
|
|
17
|
+
parser.add_argument('--groups', type=int, default=16, help='groups')
|
|
18
|
+
args = parser.parse_args()
|
|
19
|
+
BATCH, H, N_CTX, D_HEAD_QK, D_HEAD_V, groups, causal = args.batch, args.h, args.n_ctx, args.d_head_qk, args.d_head_v, args.groups, args.causal
|
|
20
|
+
|
|
21
|
+
BLOCK_M = 128
|
|
22
|
+
BLOCK_N = 64
|
|
23
|
+
Q = (
|
|
24
|
+
torch.empty(BATCH, N_CTX, H, D_HEAD_QK, dtype=torch.half,
|
|
25
|
+
device="cuda").normal_().requires_grad_())
|
|
26
|
+
|
|
27
|
+
head_kv = H // groups
|
|
28
|
+
K = (
|
|
29
|
+
torch.empty(BATCH, N_CTX, head_kv, D_HEAD_QK, dtype=torch.half,
|
|
30
|
+
device="cuda").normal_().requires_grad_())
|
|
31
|
+
V = (
|
|
32
|
+
torch.empty(BATCH, N_CTX, head_kv, D_HEAD_V, dtype=torch.half,
|
|
33
|
+
device="cuda").normal_().requires_grad_())
|
|
34
|
+
dO = (
|
|
35
|
+
torch.empty(BATCH, N_CTX, H, D_HEAD_V, dtype=torch.half,
|
|
36
|
+
device="cuda").normal_().requires_grad_())
|
|
37
|
+
|
|
38
|
+
M_BLOCKS = N_CTX // BLOCK_M
|
|
39
|
+
N_BLOCKS = N_CTX // BLOCK_N
|
|
40
|
+
|
|
41
|
+
block_mask = torch.randint(
|
|
42
|
+
low=0, high=2, size=(BATCH, H, M_BLOCKS, N_BLOCKS), dtype=torch.bool, device="cuda")
|
|
43
|
+
|
|
44
|
+
attention = BlockSparseAttentionKernel(
|
|
45
|
+
BATCH, H, N_CTX, D_HEAD_QK, D_HEAD_V, BLOCK_M, BLOCK_N, causal=causal, groups=groups)
|
|
46
|
+
|
|
47
|
+
o = attention.backward(Q, K, V, dO, block_mask)
|
|
48
|
+
print(o)
|
|
49
|
+
|
|
50
|
+
attention.check(Q, K, V, dO, block_mask)
|
|
51
|
+
attention.profile(Q, K, V, dO, block_mask)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if __name__ == "__main__":
|
|
55
|
+
main()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import torch
|
|
6
|
+
from top import GQAKernel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
parser = argparse.ArgumentParser()
|
|
11
|
+
parser.add_argument('--batch', type=int, default=8, help='batch size')
|
|
12
|
+
parser.add_argument('--h', type=int, default=32, help='Number of heads')
|
|
13
|
+
parser.add_argument('--n_ctx', type=int, default=1024, help='Context size')
|
|
14
|
+
parser.add_argument('--d_head_qk', type=int, default=128, help='Head dimension for Q/K')
|
|
15
|
+
parser.add_argument('--d_head_v', type=int, default=64, help='Head dimension for V')
|
|
16
|
+
parser.add_argument('--causal', type=bool, default=False, help='Casual flag')
|
|
17
|
+
parser.add_argument('--groups', type=int, default=16, help='groups')
|
|
18
|
+
args = parser.parse_args()
|
|
19
|
+
BATCH, H, N_CTX, D_HEAD_QK, D_HEAD_V, groups, causal = args.batch, args.h, args.n_ctx, args.d_head_qk, args.d_head_v, args.groups, args.causal
|
|
20
|
+
|
|
21
|
+
BLOCK_M = 128
|
|
22
|
+
BLOCK_N = 64
|
|
23
|
+
# q = torch.randn(batch, heads, dim, device='cuda', dtype=torch.float16)
|
|
24
|
+
Q = (
|
|
25
|
+
torch.empty(BATCH, N_CTX, H, D_HEAD_QK, dtype=torch.half,
|
|
26
|
+
device="cuda").normal_().requires_grad_())
|
|
27
|
+
|
|
28
|
+
head_kv = H // groups
|
|
29
|
+
K = (
|
|
30
|
+
torch.empty(BATCH, N_CTX, head_kv, D_HEAD_QK, dtype=torch.half,
|
|
31
|
+
device="cuda").normal_().requires_grad_())
|
|
32
|
+
V = (
|
|
33
|
+
torch.empty(BATCH, N_CTX, head_kv, D_HEAD_V, dtype=torch.half,
|
|
34
|
+
device="cuda").normal_().requires_grad_())
|
|
35
|
+
dO = (
|
|
36
|
+
torch.empty(BATCH, N_CTX, H, D_HEAD_V, dtype=torch.half,
|
|
37
|
+
device="cuda").normal_().requires_grad_())
|
|
38
|
+
|
|
39
|
+
gqa = GQAKernel(
|
|
40
|
+
BATCH, H, N_CTX, D_HEAD_QK, D_HEAD_V, BLOCK_M, BLOCK_N, causal=causal, groups=groups)
|
|
41
|
+
o = gqa.backward(Q, K, V, dO)
|
|
42
|
+
print(o)
|
|
43
|
+
latency = gqa.profile()
|
|
44
|
+
print(f"Latency: {latency:.4f} ms")
|
|
45
|
+
gqa.check(Q, K, V, dO)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if __name__ == "__main__":
|
|
49
|
+
main()
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import torch
|
|
3
|
+
from top import GQADecodeKernel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
parser = argparse.ArgumentParser()
|
|
8
|
+
parser.add_argument('--batch', type=int, default=1, help='batch size')
|
|
9
|
+
parser.add_argument('--heads', type=int, default=32, help='heads')
|
|
10
|
+
parser.add_argument('--groups', type=int, default=8, help='groups')
|
|
11
|
+
parser.add_argument('--kv_seqlen', type=int, default=8192, help='kv sequence length')
|
|
12
|
+
parser.add_argument('--dim', type=int, default=128, help='dim')
|
|
13
|
+
parser.add_argument('--num_split', type=int, default=8, help='num_split')
|
|
14
|
+
parser.add_argument('--tune', action='store_true', help='tune configs')
|
|
15
|
+
args = parser.parse_args()
|
|
16
|
+
batch, heads, groups, kv_seqlen, dim, num_split, tune = args.batch, args.heads, args.groups, args.kv_seqlen, args.dim, args.num_split, args.tune
|
|
17
|
+
|
|
18
|
+
BLOCK_N = 128
|
|
19
|
+
BLOCK_H = 64
|
|
20
|
+
threads = 128
|
|
21
|
+
|
|
22
|
+
Q = torch.randn(batch, heads, dim, device="cuda", dtype=torch.float16)
|
|
23
|
+
K = torch.randn(batch, kv_seqlen, groups, dim, device="cuda", dtype=torch.float16)
|
|
24
|
+
V = torch.randn(batch, kv_seqlen, groups, dim, device="cuda", dtype=torch.float16)
|
|
25
|
+
|
|
26
|
+
gqa_decode = GQADecodeKernel(batch, heads, kv_seqlen, dim, BLOCK_N, BLOCK_H, threads, num_split,
|
|
27
|
+
groups)
|
|
28
|
+
if tune:
|
|
29
|
+
gqa_decode.autotune()
|
|
30
|
+
o = gqa_decode.decode(Q, K, V)
|
|
31
|
+
print(o)
|
|
32
|
+
|
|
33
|
+
gqa_decode.profile()
|
|
34
|
+
|
|
35
|
+
gqa_decode.check(Q, K, V)
|
|
36
|
+
|
|
37
|
+
gqa_decode.autotune()
|
|
38
|
+
gqa_decode.profile()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
main()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
from top import LinearAttentionFusedChunkKernel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_fused_chunk(B, S, H, D):
|
|
9
|
+
kernel = LinearAttentionFusedChunkKernel(B, S, H, D)
|
|
10
|
+
kernel.check()
|
|
11
|
+
kernel.profile()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
parser = argparse.ArgumentParser()
|
|
16
|
+
parser.add_argument('--batch', type=int, default=8, help='batch size')
|
|
17
|
+
parser.add_argument('--seq_len', type=int, default=2048, help='sequence length')
|
|
18
|
+
parser.add_argument('--heads', type=int, default=32, help='num heads')
|
|
19
|
+
parser.add_argument('--dim', type=int, default=256, help='head dim')
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
B, S, H, D = args.batch, args.seq_len, args.heads, args.dim
|
|
22
|
+
|
|
23
|
+
test_fused_chunk(B, S, H, D)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
from top import LinearAttentionFusedRecurrentKernel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_fused_recurrent(B, S, H, D):
|
|
9
|
+
kernel = LinearAttentionFusedRecurrentKernel(B, S, H, D)
|
|
10
|
+
kernel.check()
|
|
11
|
+
kernel.profile()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
parser = argparse.ArgumentParser()
|
|
16
|
+
parser.add_argument('--batch', type=int, default=8, help='batch size')
|
|
17
|
+
parser.add_argument('--seq_len', type=int, default=2048, help='sequence length')
|
|
18
|
+
parser.add_argument('--heads', type=int, default=32, help='num heads')
|
|
19
|
+
parser.add_argument('--dim', type=int, default=256, help='head dim')
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
B, S, H, D = args.batch, args.seq_len, args.heads, args.dim
|
|
22
|
+
|
|
23
|
+
test_fused_recurrent(B, S, H, D)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import torch
|
|
6
|
+
from top import MambaChunkScanKernel
|
|
7
|
+
import math
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
parser = argparse.ArgumentParser()
|
|
12
|
+
parser.add_argument('--batch', type=int, default=8, help='batch size')
|
|
13
|
+
parser.add_argument('--heads', type=int, default=80, help='heads')
|
|
14
|
+
parser.add_argument('--groups', type=int, default=1, help='groups')
|
|
15
|
+
parser.add_argument('--seq_len', type=int, default=4096, help='sequence length')
|
|
16
|
+
parser.add_argument('--chunk_size', type=int, default=256, help='chunk size')
|
|
17
|
+
parser.add_argument('--dim', type=int, default=64, help='dim')
|
|
18
|
+
parser.add_argument('--dstate', type=int, default=128, help='dstate')
|
|
19
|
+
parser.add_argument('--tune', action='store_true', help='tune configs')
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
BATCH, HEADS, GROUPS, SEQ_LEN, CHUNK_SIZE, DIM, DSTATE = args.batch, args.heads, args.groups, args.seq_len, args.chunk_size, args.dim, args.dstate
|
|
22
|
+
NCHUNKS = math.ceil(SEQ_LEN / CHUNK_SIZE)
|
|
23
|
+
|
|
24
|
+
cb = torch.empty((BATCH, NCHUNKS, GROUPS, CHUNK_SIZE, CHUNK_SIZE),
|
|
25
|
+
dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
26
|
+
x = torch.empty((BATCH, SEQ_LEN, HEADS, DIM), dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
27
|
+
dt = torch.empty((BATCH, HEADS, NCHUNKS, CHUNK_SIZE),
|
|
28
|
+
dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
29
|
+
dA_cumsum = torch.empty((BATCH, HEADS, NCHUNKS, CHUNK_SIZE),
|
|
30
|
+
dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
31
|
+
C = torch.empty((BATCH, SEQ_LEN, GROUPS, DSTATE), dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
32
|
+
prev_states = torch.empty((BATCH, NCHUNKS, HEADS, DIM, DSTATE),
|
|
33
|
+
dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
34
|
+
D = torch.empty((HEADS,), dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
35
|
+
|
|
36
|
+
if args.tune:
|
|
37
|
+
mamba_chunk_scan = MambaChunkScanKernel(
|
|
38
|
+
BATCH, HEADS, GROUPS, SEQ_LEN, CHUNK_SIZE, DIM, DSTATE, tune=True)
|
|
39
|
+
|
|
40
|
+
else:
|
|
41
|
+
block_M = 64
|
|
42
|
+
block_N = 64
|
|
43
|
+
block_K = 64
|
|
44
|
+
block_Dstate = 128
|
|
45
|
+
num_stages = 2
|
|
46
|
+
threads = 128
|
|
47
|
+
|
|
48
|
+
mamba_chunk_scan = MambaChunkScanKernel(
|
|
49
|
+
BATCH,
|
|
50
|
+
HEADS,
|
|
51
|
+
GROUPS,
|
|
52
|
+
SEQ_LEN,
|
|
53
|
+
CHUNK_SIZE,
|
|
54
|
+
DIM,
|
|
55
|
+
DSTATE,
|
|
56
|
+
block_M=block_M,
|
|
57
|
+
block_N=block_N,
|
|
58
|
+
block_K=block_K,
|
|
59
|
+
block_Dstate=block_Dstate,
|
|
60
|
+
num_stages=num_stages,
|
|
61
|
+
threads=threads)
|
|
62
|
+
|
|
63
|
+
o = mamba_chunk_scan(cb, x, dt, dA_cumsum, C, prev_states, D)
|
|
64
|
+
print(o)
|
|
65
|
+
latency = mamba_chunk_scan.profile()
|
|
66
|
+
print(f"Latency: {latency:.4f} ms")
|
|
67
|
+
mamba_chunk_scan.check(cb, x, dt, dA_cumsum, C, prev_states, D)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
main()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import torch
|
|
6
|
+
from top import MambaChunkStateKernel
|
|
7
|
+
import math
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
parser = argparse.ArgumentParser()
|
|
12
|
+
parser.add_argument('--batch', type=int, default=8, help='batch size')
|
|
13
|
+
parser.add_argument('--heads', type=int, default=80, help='heads')
|
|
14
|
+
parser.add_argument('--groups', type=int, default=1, help='groups')
|
|
15
|
+
parser.add_argument('--seq_len', type=int, default=4096, help='sequence length')
|
|
16
|
+
parser.add_argument('--chunk_size', type=int, default=256, help='chunk size')
|
|
17
|
+
parser.add_argument('--dim', type=int, default=64, help='dim')
|
|
18
|
+
parser.add_argument('--dstate', type=int, default=128, help='dstate')
|
|
19
|
+
parser.add_argument('--tune', action='store_true', help='tune configs')
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
BATCH, HEADS, GROUPS, SEQ_LEN, CHUNK_SIZE, DIM, DSTATE = args.batch, args.heads, args.groups, args.seq_len, args.chunk_size, args.dim, args.dstate
|
|
22
|
+
NCHUNKS = math.ceil(SEQ_LEN / CHUNK_SIZE)
|
|
23
|
+
|
|
24
|
+
B = torch.empty((BATCH, SEQ_LEN, GROUPS, DSTATE), dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
25
|
+
x = torch.empty((BATCH, SEQ_LEN, HEADS, DIM), dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
26
|
+
dt = torch.empty((BATCH, HEADS, NCHUNKS, CHUNK_SIZE),
|
|
27
|
+
dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
28
|
+
dA_cumsum = torch.empty((BATCH, HEADS, NCHUNKS, CHUNK_SIZE),
|
|
29
|
+
dtype=torch.half).cuda().normal_(-1.0, 1.0)
|
|
30
|
+
|
|
31
|
+
if args.tune:
|
|
32
|
+
mamba_chunk_state = MambaChunkStateKernel(
|
|
33
|
+
BATCH, HEADS, GROUPS, SEQ_LEN, CHUNK_SIZE, DIM, DSTATE, tune=True)
|
|
34
|
+
|
|
35
|
+
else:
|
|
36
|
+
block_M = 64
|
|
37
|
+
block_N = 128
|
|
38
|
+
block_K = 64
|
|
39
|
+
num_stages = 4
|
|
40
|
+
threads = 128
|
|
41
|
+
|
|
42
|
+
mamba_chunk_state = MambaChunkStateKernel(
|
|
43
|
+
BATCH,
|
|
44
|
+
HEADS,
|
|
45
|
+
GROUPS,
|
|
46
|
+
SEQ_LEN,
|
|
47
|
+
CHUNK_SIZE,
|
|
48
|
+
DIM,
|
|
49
|
+
DSTATE,
|
|
50
|
+
block_M=block_M,
|
|
51
|
+
block_N=block_N,
|
|
52
|
+
block_K=block_K,
|
|
53
|
+
num_stages=num_stages,
|
|
54
|
+
threads=threads)
|
|
55
|
+
|
|
56
|
+
o = mamba_chunk_state(B, x, dt, dA_cumsum)
|
|
57
|
+
print(o)
|
|
58
|
+
latency = mamba_chunk_state.profile()
|
|
59
|
+
print(f"Latency: {latency:.4f} ms")
|
|
60
|
+
mamba_chunk_state.check(B, x, dt, dA_cumsum)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if __name__ == "__main__":
|
|
64
|
+
main()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
from top import MHAKernel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_mha_kernel(B, S, H, D, causal):
|
|
9
|
+
kernel = MHAKernel(B, H, S, D, causal)
|
|
10
|
+
kernel.check()
|
|
11
|
+
kernel.profile()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
parser = argparse.ArgumentParser()
|
|
16
|
+
parser.add_argument('--batch', type=int, default=8, help='batch size')
|
|
17
|
+
parser.add_argument('--seq_len', type=int, default=1024, help='sequence length')
|
|
18
|
+
parser.add_argument('--heads', type=int, default=32, help='num heads')
|
|
19
|
+
parser.add_argument('--dim', type=int, default=64, help='head dim')
|
|
20
|
+
parser.add_argument('--causal', action='store_true', default=False, help='causal attention')
|
|
21
|
+
args = parser.parse_args()
|
|
22
|
+
B, S, H, D, causal = args.batch, args.seq_len, args.heads, args.dim, args.causal
|
|
23
|
+
|
|
24
|
+
test_mha_kernel(B, S, H, D, causal)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
from top import MHADecodeKernel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_mha_decode_kernel(B, S, H, D):
|
|
9
|
+
kernel = MHADecodeKernel(B, H, S, D)
|
|
10
|
+
kernel.check()
|
|
11
|
+
kernel.profile()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
parser = argparse.ArgumentParser()
|
|
16
|
+
parser.add_argument('--batch', type=int, default=1, help='batch size')
|
|
17
|
+
parser.add_argument('--seqlen_kv', type=int, default=8192, help='sequence length')
|
|
18
|
+
parser.add_argument('--heads', type=int, default=32, help='num heads')
|
|
19
|
+
parser.add_argument('--dim', type=int, default=128, help='head dim')
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
B, S, H, D = args.batch, args.seqlen_kv, args.heads, args.dim
|
|
22
|
+
|
|
23
|
+
test_mha_decode_kernel(B, S, H, D)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import torch
|
|
6
|
+
from top import MLAKernel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
parser = argparse.ArgumentParser()
|
|
11
|
+
parser.add_argument('--batch', type=int, default=128, help='batch size')
|
|
12
|
+
parser.add_argument('--heads', type=int, default=128, help='q heads number')
|
|
13
|
+
parser.add_argument('--kv_heads', type=int, default=1, help='kv heads number')
|
|
14
|
+
parser.add_argument('--kv_ctx', type=int, default=4096, help='kv context length')
|
|
15
|
+
parser.add_argument('--dim', type=int, default=256, help='head dim')
|
|
16
|
+
parser.add_argument('--pe_dim', type=int, default=64, help='pe head dim')
|
|
17
|
+
args = parser.parse_args()
|
|
18
|
+
batch, heads, kv_heads, kv_ctx, dim, pe_dim = args.batch, args.heads, args.kv_heads, args.kv_ctx, args.dim, args.pe_dim
|
|
19
|
+
|
|
20
|
+
BLOCK_N = 32
|
|
21
|
+
BLOCK_H = 32
|
|
22
|
+
num_split = 1
|
|
23
|
+
|
|
24
|
+
mla = MLAKernel(batch, heads, kv_heads, kv_ctx, dim, pe_dim, BLOCK_N, BLOCK_H, num_split)
|
|
25
|
+
|
|
26
|
+
q = torch.randn(batch, heads, dim, device='cuda', dtype=torch.float16)
|
|
27
|
+
q_pe = torch.randn(batch, heads, pe_dim, device='cuda', dtype=torch.float16)
|
|
28
|
+
kv = torch.randn(batch, kv_ctx, kv_heads, dim, device='cuda', dtype=torch.float16)
|
|
29
|
+
k_pe = torch.randn(batch, kv_ctx, kv_heads, pe_dim, device='cuda', dtype=torch.float16)
|
|
30
|
+
|
|
31
|
+
o = mla(q, q_pe, kv, k_pe)
|
|
32
|
+
print(o)
|
|
33
|
+
latency = mla.profile()
|
|
34
|
+
print(f"Latency: {latency:.4f} ms")
|
|
35
|
+
mla.check(q, q_pe, kv, k_pe)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
main()
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tileops
|
|
3
|
+
Version: 0.0.1.dev0
|
|
4
|
+
Summary: TileOPs kernels for efficient inference
|
|
5
|
+
Author: Tile-AI
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/tile-ai/tileops
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/tile-ai/tileops/issues
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: torch
|
|
15
|
+
Requires-Dist: tilelang
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# TileOPs (TOP)
|
|
19
|
+
|
|
20
|
+
**TileOPs (TOP)** is a high-performance machine learning operator collections built to run on the [TileLang](https://github.com/tile-ai/tilelang) backend. It offers efficient, modular, and composable implementations optimized for AI workloads.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## 📦 Installation
|
|
26
|
+
|
|
27
|
+
### Requirements
|
|
28
|
+
|
|
29
|
+
- Python 3.8+
|
|
30
|
+
- PyTorch >= 2.1
|
|
31
|
+
- [TileLang](https://github.com/tilelang/tilelang)
|
|
32
|
+
- Triton (optional, for selected fast kernels)
|
|
33
|
+
|
|
34
|
+
### Install (editable mode for development)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/tile-ai/TileOPs
|
|
38
|
+
cd TileOPs
|
|
39
|
+
git submodule update --init --recursive
|
|
40
|
+
pip install -e .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 🚀 Quick Usage
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import torch
|
|
47
|
+
import top
|
|
48
|
+
from top import MLAKernel
|
|
49
|
+
|
|
50
|
+
device = "cuda"
|
|
51
|
+
dtype = torch.float16
|
|
52
|
+
|
|
53
|
+
batch = 128
|
|
54
|
+
heads = 64
|
|
55
|
+
kv_heads = 1
|
|
56
|
+
kv_ctx = 8192
|
|
57
|
+
dim = 512
|
|
58
|
+
pe_dim = 64
|
|
59
|
+
|
|
60
|
+
# Query input: [batch, heads, dim]
|
|
61
|
+
q = torch.randn(batch, heads, dim, device=device, dtype=dtype)
|
|
62
|
+
|
|
63
|
+
# Query positional encoding: [batch, heads, pe_dim]
|
|
64
|
+
q_pe = torch.randn(batch, heads, pe_dim, device=device, dtype=dtype)
|
|
65
|
+
|
|
66
|
+
# KV cache input: [batch, kv_ctx, kv_heads, dim]
|
|
67
|
+
kv = torch.randn(batch, kv_ctx, kv_heads, dim, device=device, dtype=dtype)
|
|
68
|
+
|
|
69
|
+
# KV positional encoding: [batch, kv_ctx, kv_heads, pe_dim]
|
|
70
|
+
k_pe = torch.randn(batch, kv_ctx, kv_heads, pe_dim, device=device, dtype=dtype)
|
|
71
|
+
|
|
72
|
+
# Use MLA kernel
|
|
73
|
+
block_N = 64
|
|
74
|
+
block_H = 64
|
|
75
|
+
num_split = 1
|
|
76
|
+
|
|
77
|
+
mla = MLAKernel(batch, heads, kv_heads, kv_ctx, dim, pe_dim, block_N, block_H, num_split)
|
|
78
|
+
|
|
79
|
+
out = mla(q, q_pe, kv, k_pe)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Acknowledgments
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
tests/test_bitnet.py
|
|
6
|
+
tests/test_blocksparse_attention.py
|
|
7
|
+
tests/test_gqa.py
|
|
8
|
+
tests/test_gqa_decode.py
|
|
9
|
+
tests/test_linear_attn_fused_chunk.py
|
|
10
|
+
tests/test_linear_attn_fused_recurrent.py
|
|
11
|
+
tests/test_mamba_chunk_scan.py
|
|
12
|
+
tests/test_mamba_chunk_state.py
|
|
13
|
+
tests/test_mha.py
|
|
14
|
+
tests/test_mha_decode.py
|
|
15
|
+
tests/test_mla.py
|
|
16
|
+
tileops.egg-info/PKG-INFO
|
|
17
|
+
tileops.egg-info/SOURCES.txt
|
|
18
|
+
tileops.egg-info/dependency_links.txt
|
|
19
|
+
tileops.egg-info/requires.txt
|
|
20
|
+
tileops.egg-info/top_level.txt
|
|
21
|
+
top/__init__.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
top
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright (c) Tile-AI.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
from .kernel.mha import MHAKernel, MHADecodeKernel
|
|
5
|
+
from .kernel.mla import MLAKernel
|
|
6
|
+
from .kernel.gqa import GQAKernel, GQADecodeKernel
|
|
7
|
+
from .kernel.mamba_chunk_scan import MambaChunkScanKernel
|
|
8
|
+
from .kernel.mamba_chunk_state import MambaChunkStateKernel
|
|
9
|
+
from .kernel.blocksparse_attention import BlockSparseAttentionKernel
|
|
10
|
+
from .kernel.linear_attention.linear_attn import LinearAttentionFusedChunkKernel, LinearAttentionFusedRecurrentKernel
|
|
11
|
+
from .kernel.bitnet import Bitnet_158_int8xint2_kernel
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"MHAKernel", "MHADecodeKernel", "MLAKernel", "GQAKernel", "GQADecodeKernel",
|
|
15
|
+
"MambaChunkScanKernel", "MambaChunkStateKernel", "BlockSparseAttentionKernel",
|
|
16
|
+
"LinearAttentionFusedChunkKernel", "LinearAttentionFusedRecurrentKernel",
|
|
17
|
+
"Bitnet_158_int8xint2_kernel"
|
|
18
|
+
]
|