liangsu9988 commited on
Commit
63ffb0f
·
verified ·
1 Parent(s): c768b0c

Promote latest kernel artifacts to main

Browse files
README.md CHANGED
@@ -1,9 +1,47 @@
1
- # flashrt/fp8-kv-attention
 
 
 
 
 
 
 
 
 
2
 
3
- This repository is a compatibility mirror for older `kernels` clients
4
- that resolve repositories through the default Hugging Face model repo API.
5
 
6
- Canonical Kernel Hub repo: https://huggingface.co/kernels/flashrt/fp8-kv-attention
7
 
8
- Do not edit this mirror by hand. It is generated from the Kernel Hub
9
- `vN` branches and contains the same `build/**` artifacts.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ tags:
4
+ - cuda
5
+ - flashrt
6
+ - attention
7
+ - fp8
8
+ - kv-cache
9
+ - transformers
10
+ ---
11
 
12
+ # FlashRT FP8 KV Attention
 
13
 
14
+ Native CUDA XQA attention for BF16 queries over FP8 E4M3 paged K/V cache.
15
 
16
+ ## Available Functions
17
+
18
+ - `xqa_bf16_fp8kv`
19
+ - `causal_spec_mask`
20
+ - `default_page_table`
21
+ - `allocate_workspace`
22
+
23
+ ## Scope
24
+
25
+ v2 supports validated production decode/verify profiles:
26
+
27
+ - BF16 Q/O
28
+ - FP8 E4M3 K/V cache
29
+ - Q/KV/head-dim `24/4/256`, `32/8/128`, `32/16/128`, and `16/8/128`
30
+ - page size `128`
31
+ - speculative/decode `q_seq <= 32`
32
+
33
+ This is not a generic FlashAttention replacement. It is the direct FP8-KV XQA
34
+ decode/verify kernel used to keep long-context transformer runtimes off BF16
35
+ KV cache bandwidth.
36
+
37
+ ## Minimal Usage
38
+
39
+ ```python
40
+ from kernels import get_kernel
41
+
42
+ attn = get_kernel("flashrt/fp8-kv-attention", version=2, trust_remote_code=True)
43
+ out = attn.xqa_bf16_fp8kv(q_bf16, k_cache_fp8, v_cache_fp8)
44
+ ```
45
+
46
+ Pass explicit `page_table`, `seq_lens`, `mask`, `out`, `semaphores`, and
47
+ `scratch` tensors for CUDA Graph/static-buffer runtimes.
build/torch213-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FlashRT BF16-Q + FP8-KV XQA attention kernels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ PAGE_SIZE = 128
13
+ SUPPORTED_CONFIGS = (
14
+ (24, 4, 256),
15
+ (16, 2, 256),
16
+ (32, 8, 128),
17
+ (32, 16, 128),
18
+ (16, 8, 128),
19
+ )
20
+
21
+
22
+ @torch.library.register_fake(add_op_namespace_prefix("xqa_bf16_fp8kv"))
23
+ def _xqa_bf16_fp8kv_fake(
24
+ q: torch.Tensor,
25
+ k_cache: torch.Tensor,
26
+ v_cache: torch.Tensor,
27
+ page_table: torch.Tensor,
28
+ seq_lens: torch.Tensor,
29
+ mask: torch.Tensor,
30
+ out: torch.Tensor,
31
+ semaphores: torch.Tensor,
32
+ scratch: torch.Tensor,
33
+ max_seq_len: int = 0,
34
+ q_scale: float = 1.0,
35
+ kv_scale: float = 1.0,
36
+ enable_pdl: bool = True,
37
+ sm_count: int = 0,
38
+ k_stride_page: int = 0,
39
+ k_stride_token: int = 0,
40
+ k_stride_head: int = 0,
41
+ ) -> None:
42
+ if q.dim() == 3:
43
+ q_seq = q.shape[0]
44
+ q_heads, head_dim = q.shape[1:]
45
+ elif q.dim() == 5:
46
+ q_seq = q.shape[2]
47
+ if q.shape[:2] != (1, 1):
48
+ raise RuntimeError("rank-5 q must begin with (1,1)")
49
+ q_heads, head_dim = q.shape[3:]
50
+ else:
51
+ raise RuntimeError("q must have rank 3 or 5")
52
+ if out.shape != q.shape:
53
+ raise RuntimeError("q/out shape mismatch")
54
+ if k_cache.dim() != 4 or k_cache.shape[1] != PAGE_SIZE or k_cache.shape[3] != head_dim:
55
+ raise RuntimeError("k_cache shape does not match q")
56
+ if v_cache.shape != k_cache.shape:
57
+ raise RuntimeError("v_cache shape mismatch")
58
+ config = (q_heads, k_cache.shape[2], head_dim)
59
+ if config not in SUPPORTED_CONFIGS:
60
+ raise RuntimeError(f"unsupported XQA configuration: {config}")
61
+ if mask.numel() < q_seq * ((q_seq + 31) // 32):
62
+ raise RuntimeError("mask is too small")
63
+ return None
64
+
65
+
66
+ def causal_spec_mask(q_seq: int, *, device: torch.device | str = "cuda", dtype: torch.dtype = torch.int32) -> torch.Tensor:
67
+ """Return the packed lower-triangular mask expected by the XQA kernel."""
68
+
69
+ q_seq = int(q_seq)
70
+ words = (q_seq + 31) // 32
71
+ rows = torch.zeros((q_seq, words), dtype=torch.int32)
72
+ for i in range(q_seq):
73
+ upto = i + 1
74
+ full = upto // 32
75
+ rem = upto % 32
76
+ if full:
77
+ rows[i, :full] = -1
78
+ if rem:
79
+ rows[i, full] = (1 << rem) - 1
80
+ return rows.to(device=device, dtype=dtype)
81
+
82
+
83
+ def default_page_table(num_pages: int, *, device: torch.device | str = "cuda") -> torch.Tensor:
84
+ """Return a contiguous one-batch page table."""
85
+
86
+ return torch.arange(int(num_pages), device=device, dtype=torch.int32).view(1, int(num_pages))
87
+
88
+
89
+ def allocate_workspace(
90
+ *,
91
+ q_seq: int,
92
+ num_q_heads: int = 24,
93
+ num_kv_heads: int = 4,
94
+ device: torch.device | str = "cuda",
95
+ scratch_mb: int = 256,
96
+ ) -> tuple[torch.Tensor, torch.Tensor]:
97
+ """Allocate semaphores and scratch tensors for static-buffer runtimes."""
98
+
99
+ if num_q_heads % num_kv_heads:
100
+ raise ValueError("num_q_heads must be divisible by num_kv_heads")
101
+ sem_count = num_kv_heads * (
102
+ ((int(q_seq) * (num_q_heads // num_kv_heads)) + 31) // 32
103
+ )
104
+ semaphores = torch.zeros(max(256, sem_count), device=device, dtype=torch.int32)
105
+ scratch = torch.empty(max(1, int(scratch_mb)) << 20, device=device, dtype=torch.uint8)
106
+ return semaphores, scratch
107
+
108
+
109
+ def xqa_bf16_fp8kv(
110
+ q: torch.Tensor,
111
+ k_cache: torch.Tensor,
112
+ v_cache: torch.Tensor,
113
+ page_table: Optional[torch.Tensor] = None,
114
+ seq_lens: Optional[torch.Tensor] = None,
115
+ mask: Optional[torch.Tensor] = None,
116
+ *,
117
+ out: Optional[torch.Tensor] = None,
118
+ semaphores: Optional[torch.Tensor] = None,
119
+ scratch: Optional[torch.Tensor] = None,
120
+ max_seq_len: int = 0,
121
+ q_scale: float = 1.0,
122
+ kv_scale: float = 1.0,
123
+ enable_pdl: bool = True,
124
+ sm_count: int = 0,
125
+ k_stride_page: int = 0,
126
+ k_stride_token: int = 0,
127
+ k_stride_head: int = 0,
128
+ ) -> torch.Tensor:
129
+ """Run a validated BF16-query / FP8-KV paged XQA configuration."""
130
+
131
+ if out is None:
132
+ out = torch.empty_like(q)
133
+ if page_table is None:
134
+ page_table = default_page_table(k_cache.shape[0], device=q.device)
135
+ if seq_lens is None:
136
+ seq_lens = torch.tensor([[k_cache.shape[0] * PAGE_SIZE]], device=q.device, dtype=torch.int32)
137
+ if mask is None:
138
+ q_seq = q.shape[0] if q.dim() == 3 else q.shape[2]
139
+ mask = causal_spec_mask(int(q_seq), device=q.device, dtype=torch.int32)
140
+ if semaphores is None or scratch is None:
141
+ q_seq = q.shape[0] if q.dim() == 3 else q.shape[2]
142
+ q_heads = q.shape[1] if q.dim() == 3 else q.shape[3]
143
+ semaphores_new, scratch_new = allocate_workspace(
144
+ q_seq=int(q_seq),
145
+ num_q_heads=int(q_heads),
146
+ num_kv_heads=int(k_cache.shape[2]),
147
+ device=q.device,
148
+ )
149
+ if semaphores is None:
150
+ semaphores = semaphores_new
151
+ if scratch is None:
152
+ scratch = scratch_new
153
+ ops.xqa_bf16_fp8kv(
154
+ q,
155
+ k_cache,
156
+ v_cache,
157
+ page_table,
158
+ seq_lens,
159
+ mask,
160
+ out,
161
+ semaphores,
162
+ scratch,
163
+ int(max_seq_len),
164
+ float(q_scale),
165
+ float(kv_scale),
166
+ bool(enable_pdl),
167
+ int(sm_count),
168
+ int(k_stride_page),
169
+ int(k_stride_token),
170
+ int(k_stride_head),
171
+ )
172
+ return out
173
+
174
+
175
+ __all__ = [
176
+ "PAGE_SIZE",
177
+ "SUPPORTED_CONFIGS",
178
+ "allocate_workspace",
179
+ "causal_spec_mask",
180
+ "default_page_table",
181
+ "xqa_bf16_fp8kv",
182
+ ]
build/torch213-cxx11-cu130-x86_64-linux/_fp8_kv_attention_cuda_e18d34b.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aae85d678394d5fdddff7080650fd159540df72e7d7c239ebf7c33adbb90432a
3
+ size 1174056
build/torch213-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _fp8_kv_attention_cuda_e18d34b
3
+ ops = torch.ops._fp8_kv_attention_cuda_e18d34b
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_fp8_kv_attention_cuda_e18d34b::{op_name}"
build/torch213-cxx11-cu130-x86_64-linux/fp8_kv_attention/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/torch213-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "fp8-kv-attention",
3
+ "id": "_fp8_kv_attention_cuda_e18d34b",
4
+ "version": 3,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0",
11
+ "12.0"
12
+ ]
13
+ },
14
+ "digest": {
15
+ "algorithm": "sha256",
16
+ "files": {
17
+ "__init__.py": "+u58XepDIAhYF7g3KZSoRhkN/PInROHfZilcN7Th+nc=",
18
+ "_fp8_kv_attention_cuda_e18d34b.abi3.so": "quhdZ4OU1f3d/3CAZQ/RWVQN9y59fCOev3wzrbuQQyo=",
19
+ "_ops.py": "RDYB4/Nm3ZFmR0Z0Hooh/I/f8g7lJ02RDZxkt+SUp7E=",
20
+ "fp8_kv_attention/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
21
+ }
22
+ },
23
+ "provenance": {
24
+ "kernel-builder": {
25
+ "version": "0.17.0-dev0",
26
+ "sha": "b39ca23f1b36383df00b27b3ffe1276cd5dbea85",
27
+ "dirty": false
28
+ },
29
+ "kernel": {
30
+ "sha": "e18d34b116c127d0c976303a3e05c78ec47760d1",
31
+ "dirty": false
32
+ }
33
+ }
34
+ }
build/torch213-cxx11-cu132-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FlashRT BF16-Q + FP8-KV XQA attention kernels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ PAGE_SIZE = 128
13
+ SUPPORTED_CONFIGS = (
14
+ (24, 4, 256),
15
+ (16, 2, 256),
16
+ (32, 8, 128),
17
+ (32, 16, 128),
18
+ (16, 8, 128),
19
+ )
20
+
21
+
22
+ @torch.library.register_fake(add_op_namespace_prefix("xqa_bf16_fp8kv"))
23
+ def _xqa_bf16_fp8kv_fake(
24
+ q: torch.Tensor,
25
+ k_cache: torch.Tensor,
26
+ v_cache: torch.Tensor,
27
+ page_table: torch.Tensor,
28
+ seq_lens: torch.Tensor,
29
+ mask: torch.Tensor,
30
+ out: torch.Tensor,
31
+ semaphores: torch.Tensor,
32
+ scratch: torch.Tensor,
33
+ max_seq_len: int = 0,
34
+ q_scale: float = 1.0,
35
+ kv_scale: float = 1.0,
36
+ enable_pdl: bool = True,
37
+ sm_count: int = 0,
38
+ k_stride_page: int = 0,
39
+ k_stride_token: int = 0,
40
+ k_stride_head: int = 0,
41
+ ) -> None:
42
+ if q.dim() == 3:
43
+ q_seq = q.shape[0]
44
+ q_heads, head_dim = q.shape[1:]
45
+ elif q.dim() == 5:
46
+ q_seq = q.shape[2]
47
+ if q.shape[:2] != (1, 1):
48
+ raise RuntimeError("rank-5 q must begin with (1,1)")
49
+ q_heads, head_dim = q.shape[3:]
50
+ else:
51
+ raise RuntimeError("q must have rank 3 or 5")
52
+ if out.shape != q.shape:
53
+ raise RuntimeError("q/out shape mismatch")
54
+ if k_cache.dim() != 4 or k_cache.shape[1] != PAGE_SIZE or k_cache.shape[3] != head_dim:
55
+ raise RuntimeError("k_cache shape does not match q")
56
+ if v_cache.shape != k_cache.shape:
57
+ raise RuntimeError("v_cache shape mismatch")
58
+ config = (q_heads, k_cache.shape[2], head_dim)
59
+ if config not in SUPPORTED_CONFIGS:
60
+ raise RuntimeError(f"unsupported XQA configuration: {config}")
61
+ if mask.numel() < q_seq * ((q_seq + 31) // 32):
62
+ raise RuntimeError("mask is too small")
63
+ return None
64
+
65
+
66
+ def causal_spec_mask(q_seq: int, *, device: torch.device | str = "cuda", dtype: torch.dtype = torch.int32) -> torch.Tensor:
67
+ """Return the packed lower-triangular mask expected by the XQA kernel."""
68
+
69
+ q_seq = int(q_seq)
70
+ words = (q_seq + 31) // 32
71
+ rows = torch.zeros((q_seq, words), dtype=torch.int32)
72
+ for i in range(q_seq):
73
+ upto = i + 1
74
+ full = upto // 32
75
+ rem = upto % 32
76
+ if full:
77
+ rows[i, :full] = -1
78
+ if rem:
79
+ rows[i, full] = (1 << rem) - 1
80
+ return rows.to(device=device, dtype=dtype)
81
+
82
+
83
+ def default_page_table(num_pages: int, *, device: torch.device | str = "cuda") -> torch.Tensor:
84
+ """Return a contiguous one-batch page table."""
85
+
86
+ return torch.arange(int(num_pages), device=device, dtype=torch.int32).view(1, int(num_pages))
87
+
88
+
89
+ def allocate_workspace(
90
+ *,
91
+ q_seq: int,
92
+ num_q_heads: int = 24,
93
+ num_kv_heads: int = 4,
94
+ device: torch.device | str = "cuda",
95
+ scratch_mb: int = 256,
96
+ ) -> tuple[torch.Tensor, torch.Tensor]:
97
+ """Allocate semaphores and scratch tensors for static-buffer runtimes."""
98
+
99
+ if num_q_heads % num_kv_heads:
100
+ raise ValueError("num_q_heads must be divisible by num_kv_heads")
101
+ sem_count = num_kv_heads * (
102
+ ((int(q_seq) * (num_q_heads // num_kv_heads)) + 31) // 32
103
+ )
104
+ semaphores = torch.zeros(max(256, sem_count), device=device, dtype=torch.int32)
105
+ scratch = torch.empty(max(1, int(scratch_mb)) << 20, device=device, dtype=torch.uint8)
106
+ return semaphores, scratch
107
+
108
+
109
+ def xqa_bf16_fp8kv(
110
+ q: torch.Tensor,
111
+ k_cache: torch.Tensor,
112
+ v_cache: torch.Tensor,
113
+ page_table: Optional[torch.Tensor] = None,
114
+ seq_lens: Optional[torch.Tensor] = None,
115
+ mask: Optional[torch.Tensor] = None,
116
+ *,
117
+ out: Optional[torch.Tensor] = None,
118
+ semaphores: Optional[torch.Tensor] = None,
119
+ scratch: Optional[torch.Tensor] = None,
120
+ max_seq_len: int = 0,
121
+ q_scale: float = 1.0,
122
+ kv_scale: float = 1.0,
123
+ enable_pdl: bool = True,
124
+ sm_count: int = 0,
125
+ k_stride_page: int = 0,
126
+ k_stride_token: int = 0,
127
+ k_stride_head: int = 0,
128
+ ) -> torch.Tensor:
129
+ """Run a validated BF16-query / FP8-KV paged XQA configuration."""
130
+
131
+ if out is None:
132
+ out = torch.empty_like(q)
133
+ if page_table is None:
134
+ page_table = default_page_table(k_cache.shape[0], device=q.device)
135
+ if seq_lens is None:
136
+ seq_lens = torch.tensor([[k_cache.shape[0] * PAGE_SIZE]], device=q.device, dtype=torch.int32)
137
+ if mask is None:
138
+ q_seq = q.shape[0] if q.dim() == 3 else q.shape[2]
139
+ mask = causal_spec_mask(int(q_seq), device=q.device, dtype=torch.int32)
140
+ if semaphores is None or scratch is None:
141
+ q_seq = q.shape[0] if q.dim() == 3 else q.shape[2]
142
+ q_heads = q.shape[1] if q.dim() == 3 else q.shape[3]
143
+ semaphores_new, scratch_new = allocate_workspace(
144
+ q_seq=int(q_seq),
145
+ num_q_heads=int(q_heads),
146
+ num_kv_heads=int(k_cache.shape[2]),
147
+ device=q.device,
148
+ )
149
+ if semaphores is None:
150
+ semaphores = semaphores_new
151
+ if scratch is None:
152
+ scratch = scratch_new
153
+ ops.xqa_bf16_fp8kv(
154
+ q,
155
+ k_cache,
156
+ v_cache,
157
+ page_table,
158
+ seq_lens,
159
+ mask,
160
+ out,
161
+ semaphores,
162
+ scratch,
163
+ int(max_seq_len),
164
+ float(q_scale),
165
+ float(kv_scale),
166
+ bool(enable_pdl),
167
+ int(sm_count),
168
+ int(k_stride_page),
169
+ int(k_stride_token),
170
+ int(k_stride_head),
171
+ )
172
+ return out
173
+
174
+
175
+ __all__ = [
176
+ "PAGE_SIZE",
177
+ "SUPPORTED_CONFIGS",
178
+ "allocate_workspace",
179
+ "causal_spec_mask",
180
+ "default_page_table",
181
+ "xqa_bf16_fp8kv",
182
+ ]
build/torch213-cxx11-cu132-x86_64-linux/_fp8_kv_attention_cuda_e18d34b.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8c44af999396e63a7725238b69c9ff5b3bf9ca9818c9f46d4e7c4aac4b16c27b
3
+ size 1174056
build/torch213-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _fp8_kv_attention_cuda_e18d34b
3
+ ops = torch.ops._fp8_kv_attention_cuda_e18d34b
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_fp8_kv_attention_cuda_e18d34b::{op_name}"
build/torch213-cxx11-cu132-x86_64-linux/fp8_kv_attention/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/torch213-cxx11-cu132-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "fp8-kv-attention",
3
+ "id": "_fp8_kv_attention_cuda_e18d34b",
4
+ "version": 3,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0",
11
+ "12.0"
12
+ ]
13
+ },
14
+ "digest": {
15
+ "algorithm": "sha256",
16
+ "files": {
17
+ "__init__.py": "+u58XepDIAhYF7g3KZSoRhkN/PInROHfZilcN7Th+nc=",
18
+ "_fp8_kv_attention_cuda_e18d34b.abi3.so": "jESvmZOW5jp3JSOLacn/Wzv5ypgYyfRtTnxKrEsWwns=",
19
+ "_ops.py": "RDYB4/Nm3ZFmR0Z0Hooh/I/f8g7lJ02RDZxkt+SUp7E=",
20
+ "fp8_kv_attention/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
21
+ }
22
+ },
23
+ "provenance": {
24
+ "kernel-builder": {
25
+ "version": "0.17.0-dev0",
26
+ "sha": "b39ca23f1b36383df00b27b3ffe1276cd5dbea85",
27
+ "dirty": false
28
+ },
29
+ "kernel": {
30
+ "sha": "e18d34b116c127d0c976303a3e05c78ec47760d1",
31
+ "dirty": false
32
+ }
33
+ }
34
+ }