kernels 0.4.3__tar.gz → 0.4.4__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.
- {kernels-0.4.3/src/kernels.egg-info → kernels-0.4.4}/PKG-INFO +12 -1
- {kernels-0.4.3 → kernels-0.4.4}/README.md +11 -0
- {kernels-0.4.3 → kernels-0.4.4}/pyproject.toml +1 -1
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels/__init__.py +2 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels/layer.py +14 -9
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels/utils.py +24 -1
- {kernels-0.4.3 → kernels-0.4.4/src/kernels.egg-info}/PKG-INFO +12 -1
- {kernels-0.4.3 → kernels-0.4.4}/tests/test_basic.py +17 -1
- {kernels-0.4.3 → kernels-0.4.4}/tests/test_layer.py +72 -0
- {kernels-0.4.3 → kernels-0.4.4}/LICENSE +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/setup.cfg +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels/cli.py +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels/compat.py +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels/lockfile.py +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels.egg-info/SOURCES.txt +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels.egg-info/dependency_links.txt +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels.egg-info/entry_points.txt +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels.egg-info/requires.txt +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/src/kernels.egg-info/top_level.txt +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/tests/test_benchmarks.py +0 -0
- {kernels-0.4.3 → kernels-0.4.4}/tests/test_kernel_locking.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: kernels
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: Download compute kernels
|
|
5
5
|
Author-email: OlivierDehaene <olivier@huggingface.co>, Daniel de Kok <daniel@huggingface.co>, David Holtz <david@huggingface.co>, Nicolas Patry <nicolas@huggingface.co>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -15,6 +15,17 @@ Requires-Dist: torch; extra == "torch"
|
|
|
15
15
|
|
|
16
16
|
# kernels
|
|
17
17
|
|
|
18
|
+
<div align="center">
|
|
19
|
+
<img src="https://github.com/user-attachments/assets/64a652f3-0cd3-4829-b3c1-df13f7933569" width="450" height="450" alt="kernel-builder logo">
|
|
20
|
+
<p align="center">
|
|
21
|
+
<a href="https://pypi.org/project/kernels"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/kernels"></a>
|
|
22
|
+
<a href="https://github.com/huggingface/kernels/tags"><img alt="GitHub tag" src="https://img.shields.io/github/v/tag/huggingface/kernels"></a>
|
|
23
|
+
<a href="https://github.com/huggingface/kernels/actions/workflows/docker-build-push.yaml"><img alt="Test kernels" src="https://img.shields.io/github/actions/workflow/status/huggingface/kernels/test.yml?label=test"></a>
|
|
24
|
+
|
|
25
|
+
</p>
|
|
26
|
+
</div>
|
|
27
|
+
<hr/>
|
|
28
|
+
|
|
18
29
|
The Kernel Hub allows Python libraries and applications to load compute
|
|
19
30
|
kernels directly from the [Hub](https://hf.co/). To support this kind
|
|
20
31
|
of dynamic loading, Hub kernels differ from traditional Python kernel
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# kernels
|
|
2
2
|
|
|
3
|
+
<div align="center">
|
|
4
|
+
<img src="https://github.com/user-attachments/assets/64a652f3-0cd3-4829-b3c1-df13f7933569" width="450" height="450" alt="kernel-builder logo">
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://pypi.org/project/kernels"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/kernels"></a>
|
|
7
|
+
<a href="https://github.com/huggingface/kernels/tags"><img alt="GitHub tag" src="https://img.shields.io/github/v/tag/huggingface/kernels"></a>
|
|
8
|
+
<a href="https://github.com/huggingface/kernels/actions/workflows/docker-build-push.yaml"><img alt="Test kernels" src="https://img.shields.io/github/actions/workflow/status/huggingface/kernels/test.yml?label=test"></a>
|
|
9
|
+
|
|
10
|
+
</p>
|
|
11
|
+
</div>
|
|
12
|
+
<hr/>
|
|
13
|
+
|
|
3
14
|
The Kernel Hub allows Python libraries and applications to load compute
|
|
4
15
|
kernels directly from the [Hub](https://hf.co/). To support this kind
|
|
5
16
|
of dynamic loading, Hub kernels differ from traditional Python kernel
|
|
@@ -9,6 +9,7 @@ from kernels.layer import (
|
|
|
9
9
|
from kernels.utils import (
|
|
10
10
|
get_kernel,
|
|
11
11
|
get_locked_kernel,
|
|
12
|
+
has_kernel,
|
|
12
13
|
install_kernel,
|
|
13
14
|
load_kernel,
|
|
14
15
|
)
|
|
@@ -16,6 +17,7 @@ from kernels.utils import (
|
|
|
16
17
|
__all__ = [
|
|
17
18
|
"get_kernel",
|
|
18
19
|
"get_locked_kernel",
|
|
20
|
+
"has_kernel",
|
|
19
21
|
"load_kernel",
|
|
20
22
|
"install_kernel",
|
|
21
23
|
"use_kernel_forward_from_hub",
|
|
@@ -4,7 +4,7 @@ import warnings
|
|
|
4
4
|
from contextvars import ContextVar
|
|
5
5
|
from copy import deepcopy
|
|
6
6
|
from dataclasses import dataclass, field
|
|
7
|
-
from typing import TYPE_CHECKING,
|
|
7
|
+
from typing import TYPE_CHECKING, Dict, Union
|
|
8
8
|
|
|
9
9
|
from .utils import get_kernel
|
|
10
10
|
|
|
@@ -131,12 +131,13 @@ def replace_kernel_forward_from_hub(cls, layer_name: str, *, use_fallback: bool
|
|
|
131
131
|
|
|
132
132
|
fallback_forward = cls.forward
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
cached_layer: Dict[LayerRepository, nn.Module] = {}
|
|
135
135
|
|
|
136
136
|
def forward(self, x, *args, **kwargs):
|
|
137
137
|
if _DISABLE_KERNEL_MAPPING:
|
|
138
138
|
return fallback_forward(self, x, *args, **kwargs)
|
|
139
139
|
|
|
140
|
+
needs_backward = self.training
|
|
140
141
|
kernel = _KERNEL_MAPPING.get().get(layer_name)
|
|
141
142
|
if kernel is None:
|
|
142
143
|
warnings.warn(
|
|
@@ -162,9 +163,11 @@ def replace_kernel_forward_from_hub(cls, layer_name: str, *, use_fallback: bool
|
|
|
162
163
|
return fallback_forward(self, x, *args, **kwargs)
|
|
163
164
|
|
|
164
165
|
# Short-circuit if we already loaded the layer.
|
|
165
|
-
|
|
166
|
-
if
|
|
167
|
-
|
|
166
|
+
layer = cached_layer.get(repo, None)
|
|
167
|
+
if layer is not None:
|
|
168
|
+
if needs_backward and not getattr(layer, "has_backward", True):
|
|
169
|
+
return fallback_forward(self, x, *args, **kwargs)
|
|
170
|
+
return layer.forward(self, x, *args, **kwargs)
|
|
168
171
|
|
|
169
172
|
layer = _get_kernel_layer(
|
|
170
173
|
repo_id=repo.repo_id,
|
|
@@ -180,10 +183,11 @@ def replace_kernel_forward_from_hub(cls, layer_name: str, *, use_fallback: bool
|
|
|
180
183
|
finally:
|
|
181
184
|
cls.forward = orig_forward
|
|
182
185
|
|
|
183
|
-
|
|
184
|
-
cached_forward[repo] = layer_forward
|
|
186
|
+
cached_layer[repo] = layer
|
|
185
187
|
|
|
186
|
-
|
|
188
|
+
if needs_backward and not getattr(layer, "has_backward", True):
|
|
189
|
+
return fallback_forward(self, x, *args, **kwargs)
|
|
190
|
+
return layer.forward(self, x, *args, **kwargs)
|
|
187
191
|
|
|
188
192
|
cls.forward = forward
|
|
189
193
|
|
|
@@ -240,7 +244,8 @@ def _validate_layer(*, check_cls, cls):
|
|
|
240
244
|
# ... or predefined member variables.
|
|
241
245
|
torch_module_members = {name for name, _ in inspect.getmembers(nn.Module)}
|
|
242
246
|
cls_members = {name for name, _ in inspect.getmembers(cls)}
|
|
243
|
-
|
|
247
|
+
difference = cls_members - torch_module_members
|
|
248
|
+
if difference != set() and difference != {"has_backward"}:
|
|
244
249
|
raise TypeError("Layer must not contain additional members.")
|
|
245
250
|
|
|
246
251
|
# Check whether the forward signatures are similar.
|
|
@@ -13,7 +13,7 @@ from pathlib import Path
|
|
|
13
13
|
from types import ModuleType
|
|
14
14
|
from typing import Dict, List, Optional, Tuple
|
|
15
15
|
|
|
16
|
-
from huggingface_hub import snapshot_download
|
|
16
|
+
from huggingface_hub import file_exists, snapshot_download
|
|
17
17
|
from packaging.version import parse
|
|
18
18
|
|
|
19
19
|
from kernels.lockfile import KernelLock, VariantLock
|
|
@@ -161,6 +161,29 @@ def get_kernel(repo_id: str, revision: str = "main") -> ModuleType:
|
|
|
161
161
|
return import_from_path(package_name, package_path / package_name / "__init__.py")
|
|
162
162
|
|
|
163
163
|
|
|
164
|
+
def has_kernel(repo_id: str, revision: str = "main") -> bool:
|
|
165
|
+
"""
|
|
166
|
+
Check whether a kernel build exists for the current environment
|
|
167
|
+
(Torch version and compute framework).
|
|
168
|
+
"""
|
|
169
|
+
package_name = package_name_from_repo_id(repo_id)
|
|
170
|
+
variant = build_variant()
|
|
171
|
+
universal_variant = universal_build_variant()
|
|
172
|
+
|
|
173
|
+
if file_exists(
|
|
174
|
+
repo_id,
|
|
175
|
+
revision=revision,
|
|
176
|
+
filename=f"build/{universal_variant}/{package_name}/__init__.py",
|
|
177
|
+
):
|
|
178
|
+
return True
|
|
179
|
+
|
|
180
|
+
return file_exists(
|
|
181
|
+
repo_id,
|
|
182
|
+
revision=revision,
|
|
183
|
+
filename=f"build/{variant}/{package_name}/__init__.py",
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
164
187
|
def load_kernel(repo_id: str, *, lockfile: Optional[Path] = None) -> ModuleType:
|
|
165
188
|
"""
|
|
166
189
|
Get a pre-downloaded, locked kernel.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: kernels
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: Download compute kernels
|
|
5
5
|
Author-email: OlivierDehaene <olivier@huggingface.co>, Daniel de Kok <daniel@huggingface.co>, David Holtz <david@huggingface.co>, Nicolas Patry <nicolas@huggingface.co>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -15,6 +15,17 @@ Requires-Dist: torch; extra == "torch"
|
|
|
15
15
|
|
|
16
16
|
# kernels
|
|
17
17
|
|
|
18
|
+
<div align="center">
|
|
19
|
+
<img src="https://github.com/user-attachments/assets/64a652f3-0cd3-4829-b3c1-df13f7933569" width="450" height="450" alt="kernel-builder logo">
|
|
20
|
+
<p align="center">
|
|
21
|
+
<a href="https://pypi.org/project/kernels"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/kernels"></a>
|
|
22
|
+
<a href="https://github.com/huggingface/kernels/tags"><img alt="GitHub tag" src="https://img.shields.io/github/v/tag/huggingface/kernels"></a>
|
|
23
|
+
<a href="https://github.com/huggingface/kernels/actions/workflows/docker-build-push.yaml"><img alt="Test kernels" src="https://img.shields.io/github/actions/workflow/status/huggingface/kernels/test.yml?label=test"></a>
|
|
24
|
+
|
|
25
|
+
</p>
|
|
26
|
+
</div>
|
|
27
|
+
<hr/>
|
|
28
|
+
|
|
18
29
|
The Kernel Hub allows Python libraries and applications to load compute
|
|
19
30
|
kernels directly from the [Hub](https://hf.co/). To support this kind
|
|
20
31
|
of dynamic loading, Hub kernels differ from traditional Python kernel
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
import torch
|
|
3
3
|
|
|
4
|
-
from kernels import get_kernel
|
|
4
|
+
from kernels import get_kernel, has_kernel
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
@pytest.fixture
|
|
@@ -36,6 +36,22 @@ def test_gelu_fast(kernel, device):
|
|
|
36
36
|
assert torch.allclose(y, expected)
|
|
37
37
|
|
|
38
38
|
|
|
39
|
+
@pytest.mark.parametrize(
|
|
40
|
+
"kernel_exists",
|
|
41
|
+
[
|
|
42
|
+
("kernels-community/activation", "main", True),
|
|
43
|
+
("kernels-community/triton-layer-norm", "main", True),
|
|
44
|
+
# Repo only contains Torch 2.4 kernels (and we don't
|
|
45
|
+
# support/test against this version).
|
|
46
|
+
("kernels-test/only-torch-2.4", "main", False),
|
|
47
|
+
("google-bert/bert-base-uncased", "87565a309", False),
|
|
48
|
+
],
|
|
49
|
+
)
|
|
50
|
+
def test_has_kernel(kernel_exists):
|
|
51
|
+
repo_id, revision, kernel = kernel_exists
|
|
52
|
+
assert has_kernel(repo_id, revision=revision) == kernel
|
|
53
|
+
|
|
54
|
+
|
|
39
55
|
def test_universal_kernel(universal_kernel):
|
|
40
56
|
torch.manual_seed(0)
|
|
41
57
|
A = torch.randint(-10, 10, (64, 128), dtype=torch.int8, device="cuda")
|
|
@@ -203,3 +203,75 @@ def test_validate_kernel_layer():
|
|
|
203
203
|
|
|
204
204
|
with pytest.raises(TypeError, match="different kind of arguments"):
|
|
205
205
|
_validate_layer(cls=BadLayer4, check_cls=SiluAndMul)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def test_fallback_used_when_training():
|
|
209
|
+
@use_kernel_forward_from_hub("Linear")
|
|
210
|
+
class TorchLinear(nn.Linear):
|
|
211
|
+
def __init__(self, *args, **kwargs):
|
|
212
|
+
super().__init__(*args, **kwargs)
|
|
213
|
+
# Used to check that we called hub kernel.
|
|
214
|
+
self.n_calls = 0
|
|
215
|
+
|
|
216
|
+
def forward(self, input: torch.Tensor) -> torch.Tensor:
|
|
217
|
+
self.n_calls += 1
|
|
218
|
+
return super().forward(input)
|
|
219
|
+
|
|
220
|
+
linear = TorchLinear(32, 32).to("cuda")
|
|
221
|
+
|
|
222
|
+
with use_kernel_mapping(
|
|
223
|
+
{
|
|
224
|
+
"Linear": {
|
|
225
|
+
Device(type="cuda"): LayerRepository(
|
|
226
|
+
repo_id="kernels-test/backward-marker-test",
|
|
227
|
+
layer_name="LinearImplicitBackward",
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
):
|
|
232
|
+
linear.train()
|
|
233
|
+
X = torch.randn(10, 32, device="cuda")
|
|
234
|
+
linear(X)
|
|
235
|
+
assert linear.n_calls == 0
|
|
236
|
+
|
|
237
|
+
linear.eval()
|
|
238
|
+
linear(X)
|
|
239
|
+
assert linear.n_calls == 0
|
|
240
|
+
|
|
241
|
+
with use_kernel_mapping(
|
|
242
|
+
{
|
|
243
|
+
"Linear": {
|
|
244
|
+
Device(type="cuda"): LayerRepository(
|
|
245
|
+
repo_id="kernels-test/backward-marker-test",
|
|
246
|
+
layer_name="LinearBackward",
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
):
|
|
251
|
+
linear.train()
|
|
252
|
+
X = torch.randn(10, 32, device="cuda")
|
|
253
|
+
linear(X)
|
|
254
|
+
assert linear.n_calls == 0
|
|
255
|
+
|
|
256
|
+
linear.eval()
|
|
257
|
+
linear(X)
|
|
258
|
+
assert linear.n_calls == 0
|
|
259
|
+
|
|
260
|
+
with use_kernel_mapping(
|
|
261
|
+
{
|
|
262
|
+
"Linear": {
|
|
263
|
+
Device(type="cuda"): LayerRepository(
|
|
264
|
+
repo_id="kernels-test/backward-marker-test",
|
|
265
|
+
layer_name="LinearNoBackward",
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
):
|
|
270
|
+
linear.train()
|
|
271
|
+
X = torch.randn(10, 32, device="cuda")
|
|
272
|
+
linear(X)
|
|
273
|
+
assert linear.n_calls == 1
|
|
274
|
+
|
|
275
|
+
linear.eval()
|
|
276
|
+
linear(X)
|
|
277
|
+
assert linear.n_calls == 1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|