marcsun13 HF Staff commited on
Commit
97231ed
·
verified ·
1 Parent(s): 2c20074

GGUF kernels: dequantize + fused gemv over packed blocks

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +6 -0
  2. .gitignore +4 -0
  3. SKILL.md +162 -0
  4. build.toml +1 -0
  5. build/torch210-cxx11-cu126-x86_64-linux/metadata.json +0 -4
  6. build/torch210-cxx11-cu128-x86_64-linux/metadata.json +0 -4
  7. build/torch210-cxx11-cu130-x86_64-linux/metadata.json +0 -4
  8. build/{torch210-cxx11-cu126-x86_64-linux → torch211-cxx11-cu126-x86_64-linux}/__init__.py +0 -0
  9. build/{torch210-cxx11-cu126-x86_64-linux/_gguf_kernels_20260805124229.abi3.so → torch211-cxx11-cu126-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so} +2 -2
  10. build/{torch210-cxx11-cu128-x86_64-linux → torch211-cxx11-cu126-x86_64-linux}/_ops.py +3 -3
  11. build/{torch210-cxx11-cu128-x86_64-linux → torch211-cxx11-cu126-x86_64-linux}/gguf_kernels/__init__.py +2 -2
  12. build/torch211-cxx11-cu126-x86_64-linux/metadata.json +17 -0
  13. build/{torch210-cxx11-cu128-x86_64-linux → torch211-cxx11-cu128-x86_64-linux}/__init__.py +0 -0
  14. build/{torch210-cxx11-cu128-x86_64-linux/_gguf_kernels_20260805124229.abi3.so → torch211-cxx11-cu128-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so} +2 -2
  15. build/{torch210-cxx11-cu126-x86_64-linux → torch211-cxx11-cu128-x86_64-linux}/_ops.py +3 -3
  16. build/{torch210-cxx11-cu130-x86_64-linux → torch211-cxx11-cu128-x86_64-linux}/gguf_kernels/__init__.py +2 -2
  17. build/torch211-cxx11-cu128-x86_64-linux/metadata.json +19 -0
  18. build/{torch210-cxx11-cu130-x86_64-linux → torch211-cxx11-cu130-x86_64-linux}/__init__.py +0 -0
  19. build/{torch210-cxx11-cu130-x86_64-linux/_gguf_kernels_20260805124229.abi3.so → torch211-cxx11-cu130-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so} +2 -2
  20. build/{torch210-cxx11-cu130-x86_64-linux → torch211-cxx11-cu130-x86_64-linux}/_ops.py +3 -3
  21. build/{torch210-cxx11-cu126-x86_64-linux → torch211-cxx11-cu130-x86_64-linux}/gguf_kernels/__init__.py +2 -2
  22. build/torch211-cxx11-cu130-x86_64-linux/metadata.json +19 -0
  23. build/{torch28-cxx11-cu126-x86_64-linux → torch212-cxx11-cu126-x86_64-linux}/__init__.py +0 -0
  24. build/{torch28-cxx11-cu126-x86_64-linux/_gguf_kernels_20260805124229.abi3.so → torch212-cxx11-cu126-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so} +2 -2
  25. build/{torch28-cxx11-cu126-x86_64-linux → torch212-cxx11-cu126-x86_64-linux}/_ops.py +3 -3
  26. build/{torch28-cxx11-cu126-x86_64-linux → torch212-cxx11-cu126-x86_64-linux}/gguf_kernels/__init__.py +2 -2
  27. build/torch212-cxx11-cu126-x86_64-linux/metadata.json +17 -0
  28. build/{torch28-cxx11-cu128-x86_64-linux → torch212-cxx11-cu130-x86_64-linux}/__init__.py +0 -0
  29. build/torch212-cxx11-cu130-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so +3 -0
  30. build/torch212-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  31. build/torch212-cxx11-cu130-x86_64-linux/gguf_kernels/__init__.py +26 -0
  32. build/torch212-cxx11-cu130-x86_64-linux/metadata.json +19 -0
  33. build/{torch28-cxx11-cu129-x86_64-linux → torch212-cxx11-cu132-x86_64-linux}/__init__.py +0 -0
  34. build/torch212-cxx11-cu132-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so +3 -0
  35. build/torch212-cxx11-cu132-x86_64-linux/_ops.py +9 -0
  36. build/torch212-cxx11-cu132-x86_64-linux/gguf_kernels/__init__.py +26 -0
  37. build/torch212-cxx11-cu132-x86_64-linux/metadata.json +19 -0
  38. build/torch28-cxx11-cu126-x86_64-linux/metadata.json +0 -4
  39. build/torch28-cxx11-cu128-x86_64-linux/_gguf_kernels_20260805124229.abi3.so +0 -3
  40. build/torch28-cxx11-cu128-x86_64-linux/_ops.py +0 -9
  41. build/torch28-cxx11-cu128-x86_64-linux/gguf_kernels/__init__.py +0 -26
  42. build/torch28-cxx11-cu128-x86_64-linux/metadata.json +0 -4
  43. build/torch28-cxx11-cu129-x86_64-linux/_gguf_kernels_20260805124229.abi3.so +0 -3
  44. build/torch28-cxx11-cu129-x86_64-linux/_ops.py +0 -9
  45. build/torch28-cxx11-cu129-x86_64-linux/gguf_kernels/__init__.py +0 -26
  46. build/torch28-cxx11-cu129-x86_64-linux/metadata.json +0 -4
  47. build/torch29-cxx11-cu126-x86_64-linux/__init__.py +0 -55
  48. build/torch29-cxx11-cu126-x86_64-linux/_gguf_kernels_20260805124229.abi3.so +0 -3
  49. build/torch29-cxx11-cu126-x86_64-linux/_ops.py +0 -9
  50. build/torch29-cxx11-cu126-x86_64-linux/gguf_kernels/__init__.py +0 -26
.gitattributes CHANGED
@@ -42,3 +42,9 @@ build/torch28-cxx11-cu129-x86_64-linux/_gguf_kernels_20260805124229.abi3.so filt
42
  build/torch29-cxx11-cu126-x86_64-linux/_gguf_kernels_20260805124229.abi3.so filter=lfs diff=lfs merge=lfs -text
43
  build/torch29-cxx11-cu128-x86_64-linux/_gguf_kernels_20260805124229.abi3.so filter=lfs diff=lfs merge=lfs -text
44
  build/torch29-cxx11-cu130-x86_64-linux/_gguf_kernels_20260805124229.abi3.so filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
42
  build/torch29-cxx11-cu126-x86_64-linux/_gguf_kernels_20260805124229.abi3.so filter=lfs diff=lfs merge=lfs -text
43
  build/torch29-cxx11-cu128-x86_64-linux/_gguf_kernels_20260805124229.abi3.so filter=lfs diff=lfs merge=lfs -text
44
  build/torch29-cxx11-cu130-x86_64-linux/_gguf_kernels_20260805124229.abi3.so filter=lfs diff=lfs merge=lfs -text
45
+ build/torch211-cxx11-cu126-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so filter=lfs diff=lfs merge=lfs -text
46
+ build/torch211-cxx11-cu128-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so filter=lfs diff=lfs merge=lfs -text
47
+ build/torch211-cxx11-cu130-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so filter=lfs diff=lfs merge=lfs -text
48
+ build/torch212-cxx11-cu126-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so filter=lfs diff=lfs merge=lfs -text
49
+ build/torch212-cxx11-cu130-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so filter=lfs diff=lfs merge=lfs -text
50
+ build/torch212-cxx11-cu132-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ build/
2
+ ci-out/
3
+ result
4
+ __pycache__/
SKILL.md ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: build-kernels
3
+ description: Build a CUDA/Metal kernel into a Hub `kernels` repo with kernel-builder, and load it from transformers. Covers the layout, the build.toml traps, running the builder without nix (podman), and what the Hub and the `kernels` client each require. Use when packaging a kernel, debugging a kernel-builder build, or when `get_kernel` fails to load one.
4
+ ---
5
+
6
+ # Building kernels for the Hub
7
+
8
+ Learned by packaging llama.cpp's GGUF kernels as `marcsun13/gguf-kernels`. The official guide covers
9
+ the happy path; this is what actually bit me, in the order it bit me.
10
+
11
+ ## 1. Layout
12
+
13
+ ```
14
+ my-kernel/
15
+ ├── build.toml # the only build config you write
16
+ ├── flake.nix # nix entry point
17
+ ├── my_kernel_cuda/*.cu # one directory per backend
18
+ ├── torch-ext/
19
+ │ ├── torch_binding.h # the entry points, same signature for every backend
20
+ │ ├── torch_binding.cpp # schema + per-backend registration
21
+ │ └── my_kernel/__init__.py # the Python API (hyphens in the name become underscores)
22
+ └── tests/test_my_kernel.py
23
+ ```
24
+
25
+ **One schema, one implementation per backend.** Do not split the registration per backend — declare
26
+ the ops once and pick the implementation with the macros the builder defines:
27
+
28
+ ```cpp
29
+ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
30
+ ops.def("my_op(Tensor x) -> Tensor");
31
+ #if defined(CUDA_KERNEL) || defined(ROCM_KERNEL)
32
+ ops.impl("my_op", torch::kCUDA, &my_op);
33
+ #elif defined(METAL_KERNEL)
34
+ ops.impl("my_op", torch::kMPS, &my_op);
35
+ #endif
36
+ }
37
+ REGISTER_EXTENSION(TORCH_EXTENSION_NAME)
38
+ ```
39
+
40
+ Adding a backend is then a `[kernel.*]` section and a directory. Nothing else moves, and callers
41
+ dispatch on the tensor's device as usual.
42
+
43
+ ## 2. build.toml traps
44
+
45
+ - **Every file must be listed in `src`, headers included.** The builder stages only what is listed,
46
+ so an unlisted `.cuh` fails as "No such file or directory" even with the right `include` dirs.
47
+ - **`include` needs `torch-ext`** if a backend source includes `torch_binding.h`.
48
+ - **A vendored `.cu` you `#include` must be renamed** (e.g. `mmvq.cu` → `mmvq-impl.cuh`). Anything
49
+ ending in `.cu` in `src` is compiled as its own translation unit. Watch for collisions when
50
+ renaming: upstream often ships both `foo.cu` and `foo.cuh`, and clobbering the header gives a
51
+ baffling "#include nested depth 200 exceeds maximum" — the file now includes itself.
52
+ - **Undo torch's half/bf16 flags** for ggml-style code:
53
+ `-U__CUDA_NO_HALF_OPERATORS__`, `-U__CUDA_NO_BFLOAT16_CONVERSIONS__` and friends.
54
+ - `cuda-capabilities` are intersected with what each variant's CUDA toolkit supports, so listing
55
+ `12.0` is harmless on an older toolkit — it is silently dropped.
56
+
57
+ ## 3. Which builder, and why it decides everything
58
+
59
+ Use `github:huggingface/kernels` (the old `kernel-builder` repo is stale) with
60
+ `lib.genKernelFlakeOutputs`. **Pin it to the same version as the `kernels` client you load with**,
61
+ because the builder version decides two things at once:
62
+
63
+ | | |
64
+ | --- | --- |
65
+ | which torch variants exist | `v0.15.2` → torch 2.11/2.12; `main` → 2.12/2.13 |
66
+ | the `metadata.json` format | older builders omit `name`, and a current client refuses to load that |
67
+
68
+ A mismatch surfaces as `Cannot parse metadata from ...: missing field 'name'`, or as a build with no
69
+ variant your interpreter can import. Check what came out before debugging anything else:
70
+
71
+ ```bash
72
+ ls build/ && head -6 build/*/metadata.json
73
+ ```
74
+
75
+ The builder also wants **a git repo with a clean tree** — otherwise it refuses to build
76
+ ("non-reproducible"), and uncommitted changes leave the artifact id ending in `_dirty`.
77
+
78
+ ## 4. Running the builder without nix (podman)
79
+
80
+ The docker image works under rootless podman with two adjustments:
81
+
82
+ ```bash
83
+ export XDG_RUNTIME_DIR=/tmp/podman-run && mkdir -p $XDG_RUNTIME_DIR # else podman won't start
84
+ podman run --rm --privileged \
85
+ --mount type=bind,source=$PWD,target=/kernelcode -w /kernelcode \
86
+ --entrypoint bash ghcr.io/huggingface/kernel-builder:main \
87
+ -c "nix run .#build-and-copy -L --max-jobs 4 --cores 16"
88
+ ```
89
+
90
+ **`--privileged` is required.** Without it nix's unpack phase dies on
91
+ `cp: setting permissions for 'source': Operation not permitted` — rootless podman lacks the
92
+ capability for that chmod. `--option sandbox false` and `NIX_REMOTE=` do not help; don't bother.
93
+
94
+ - `nix run .#build-and-copy` → every variant, into `build/`. Budget ~150 s per variant.
95
+ - `nix build .#ci` → this system's variant only, into `result/`. Note **`nix run .#ci` fails**: it is
96
+ a package, not an app.
97
+
98
+ ## 5. Python side
99
+
100
+ `_ops.py` is generated. Use relative imports only, and put the `torch.compile` fakes in the kernel —
101
+ they belong with the op, not with the caller:
102
+
103
+ ```python
104
+ from ._ops import add_op_namespace_prefix, ops
105
+
106
+ def my_op(x): return ops.my_op(x)
107
+
108
+ @torch.library.register_fake(add_op_namespace_prefix("my_op"))
109
+ def _(x): return x.new_empty(...)
110
+ ```
111
+
112
+ Publish the kernel's own limits as constants (max rows, supported type ids). Callers should read
113
+ capabilities from the kernel instead of hardcoding them — a second backend will differ.
114
+
115
+ Test against a built variant by putting it on the path, and assert the graph does not break:
116
+
117
+ ```bash
118
+ PYTHONPATH=build/torch211-cxx11-cu128-x86_64-linux pytest tests/ -q
119
+ ```
120
+
121
+ ```python
122
+ compiled = torch.compile(lambda x: my_op(x), fullgraph=True) # fails loudly if the fake is wrong
123
+ ```
124
+
125
+ Prefer a reference implementation that is already installed over writing one. For GGUF,
126
+ `gguf.quants.dequantize` unpacks every quant type and accepts *any* byte pattern, so random bytes
127
+ make a complete test with no checkpoint and no quantizer — just mask the fp16 scale fields so a
128
+ random pattern cannot produce inf/nan (clearing bit 6 of every odd byte does it).
129
+
130
+ ## 6. Publishing, and what the client demands
131
+
132
+ Upload `build/` plus `README.md` (with `tags: [kernel]`), and keep the sources in the repo so it stays
133
+ reproducible. Then, in increasing order of surprise:
134
+
135
+ 1. **Tag a version.** `get_kernel` refuses an unpinned repo: "A kernel version or revision must be
136
+ specified". Create a `v<major>.<minor>.<patch>` tag, load with `version=<major>`.
137
+ 2. **Trust.** `get_kernel` loads unattended only from a publisher the Hub marks as a trusted kernel
138
+ publisher (e.g. `kernels-community`). A personal repo needs `trust_remote_code=True`, i.e. the
139
+ caller opting into running downloaded code — so a library should not pass it silently.
140
+ 3. **Indexing.** The client resolves through `https://huggingface.co/api/kernels/<repo>/...`, which
141
+ 401s for a repo the Hub has not indexed as a kernel. A correct repo can still be unfetchable;
142
+ `kernels-community` repos work, so compare against one before suspecting your own build.
143
+
144
+ Test without the Hub at all:
145
+
146
+ ```bash
147
+ LOCAL_KERNELS="user/my-kernel=/path/to/my-kernel" python -c \
148
+ "from kernels import get_kernel; print(get_kernel('user/my-kernel', version=1))"
149
+ ```
150
+
151
+ ## 7. Loading from transformers
152
+
153
+ Resolve once, keep the ops in module-level globals, call them as plain functions:
154
+
155
+ ```python
156
+ module = get_kernel(repo, version=1)
157
+ _MY_OP = module.my_op # NOT self.kernel.my_op
158
+ ```
159
+
160
+ Reaching an op through an attribute on an object makes dynamo graph-break at every call, which costs
161
+ more than the kernel saves — the same reason the fakes matter. Treat "no kernel" as a normal outcome:
162
+ return `None`, log why, and fall back to the dense path.
build.toml CHANGED
@@ -8,6 +8,7 @@
8
  [general]
9
  name = "gguf-kernels"
10
  version = 1
 
11
  backends = ["cuda"]
12
 
13
  [torch]
 
8
  [general]
9
  name = "gguf-kernels"
10
  version = 1
11
+ license = "MIT"
12
  backends = ["cuda"]
13
 
14
  [torch]
build/torch210-cxx11-cu126-x86_64-linux/metadata.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "version": 1,
3
- "python-depends": []
4
- }
 
 
 
 
 
build/torch210-cxx11-cu128-x86_64-linux/metadata.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "version": 1,
3
- "python-depends": []
4
- }
 
 
 
 
 
build/torch210-cxx11-cu130-x86_64-linux/metadata.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "version": 1,
3
- "python-depends": []
4
- }
 
 
 
 
 
build/{torch210-cxx11-cu126-x86_64-linux → torch211-cxx11-cu126-x86_64-linux}/__init__.py RENAMED
File without changes
build/{torch210-cxx11-cu126-x86_64-linux/_gguf_kernels_20260805124229.abi3.so → torch211-cxx11-cu126-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:deef7081403683a708ba874d97321243281a1b6e9e1f23ae06c930f06459f3b1
3
- size 26692640
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4bc09a45aabd708b54f9ce83b5ec9627ed185826b64aeb2b5673f46cad4c508e
3
+ size 24799632
build/{torch210-cxx11-cu128-x86_64-linux → torch211-cxx11-cu126-x86_64-linux}/_ops.py RENAMED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _gguf_kernels_20260805124229
3
- ops = torch.ops._gguf_kernels_20260805124229
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_gguf_kernels_20260805124229::{op_name}"
 
1
  import torch
2
+ from . import _gguf_kernels_cuda_e4e2164
3
+ ops = torch.ops._gguf_kernels_cuda_e4e2164
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_gguf_kernels_cuda_e4e2164::{op_name}"
build/{torch210-cxx11-cu128-x86_64-linux → torch211-cxx11-cu126-x86_64-linux}/gguf_kernels/__init__.py RENAMED
@@ -1,10 +1,10 @@
1
  import ctypes
 
2
  import sys
3
-
4
- import importlib
5
  from pathlib import Path
6
  from types import ModuleType
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
 
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
build/torch211-cxx11-cu126-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "gguf-kernels",
3
+ "id": "_gguf_kernels_cuda_e4e2164",
4
+ "version": 1,
5
+ "license": "MIT",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "7.5",
11
+ "8.0",
12
+ "8.6",
13
+ "8.9",
14
+ "9.0"
15
+ ]
16
+ }
17
+ }
build/{torch210-cxx11-cu128-x86_64-linux → torch211-cxx11-cu128-x86_64-linux}/__init__.py RENAMED
File without changes
build/{torch210-cxx11-cu128-x86_64-linux/_gguf_kernels_20260805124229.abi3.so → torch211-cxx11-cu128-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:b6cba7d21629a2a2269bd06de30ace18b373266c7e74e75e11f093cc27eec066
3
- size 39064328
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b71394062f24b9601e17ee704b313494487bbe77b8d20f54adbfd52665d9f300
3
+ size 37124624
build/{torch210-cxx11-cu126-x86_64-linux → torch211-cxx11-cu128-x86_64-linux}/_ops.py RENAMED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _gguf_kernels_20260805124229
3
- ops = torch.ops._gguf_kernels_20260805124229
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_gguf_kernels_20260805124229::{op_name}"
 
1
  import torch
2
+ from . import _gguf_kernels_cuda_e4e2164
3
+ ops = torch.ops._gguf_kernels_cuda_e4e2164
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_gguf_kernels_cuda_e4e2164::{op_name}"
build/{torch210-cxx11-cu130-x86_64-linux → torch211-cxx11-cu128-x86_64-linux}/gguf_kernels/__init__.py RENAMED
@@ -1,10 +1,10 @@
1
  import ctypes
 
2
  import sys
3
-
4
- import importlib
5
  from pathlib import Path
6
  from types import ModuleType
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
 
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
build/torch211-cxx11-cu128-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "gguf-kernels",
3
+ "id": "_gguf_kernels_cuda_e4e2164",
4
+ "version": 1,
5
+ "license": "MIT",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "7.5",
13
+ "8.0",
14
+ "8.6",
15
+ "8.9",
16
+ "9.0"
17
+ ]
18
+ }
19
+ }
build/{torch210-cxx11-cu130-x86_64-linux → torch211-cxx11-cu130-x86_64-linux}/__init__.py RENAMED
File without changes
build/{torch210-cxx11-cu130-x86_64-linux/_gguf_kernels_20260805124229.abi3.so → torch211-cxx11-cu130-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:b4e935328add4b20b3761b3ab018967f2b61030491865b841c455e6a25702e4e
3
- size 39318224
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5b19aec224f81561100e3133d414393779bacfabf2c703040e64b95fe0b69cef
3
+ size 37378504
build/{torch210-cxx11-cu130-x86_64-linux → torch211-cxx11-cu130-x86_64-linux}/_ops.py RENAMED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _gguf_kernels_20260805124229
3
- ops = torch.ops._gguf_kernels_20260805124229
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_gguf_kernels_20260805124229::{op_name}"
 
1
  import torch
2
+ from . import _gguf_kernels_cuda_e4e2164
3
+ ops = torch.ops._gguf_kernels_cuda_e4e2164
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_gguf_kernels_cuda_e4e2164::{op_name}"
build/{torch210-cxx11-cu126-x86_64-linux → torch211-cxx11-cu130-x86_64-linux}/gguf_kernels/__init__.py RENAMED
@@ -1,10 +1,10 @@
1
  import ctypes
 
2
  import sys
3
-
4
- import importlib
5
  from pathlib import Path
6
  from types import ModuleType
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
 
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
build/torch211-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "gguf-kernels",
3
+ "id": "_gguf_kernels_cuda_e4e2164",
4
+ "version": 1,
5
+ "license": "MIT",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "7.5",
13
+ "8.0",
14
+ "8.6",
15
+ "8.9",
16
+ "9.0"
17
+ ]
18
+ }
19
+ }
build/{torch28-cxx11-cu126-x86_64-linux → torch212-cxx11-cu126-x86_64-linux}/__init__.py RENAMED
File without changes
build/{torch28-cxx11-cu126-x86_64-linux/_gguf_kernels_20260805124229.abi3.so → torch212-cxx11-cu126-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:6708d42e7390b3a6fe316852e3857716defd991e5861031c8d04a1e7b4e0260f
3
- size 26686512
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0176cb70a486d747de1e4b4aa785760580e7b4dc8afc9efc897621d5fd307639
3
+ size 24805280
build/{torch28-cxx11-cu126-x86_64-linux → torch212-cxx11-cu126-x86_64-linux}/_ops.py RENAMED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _gguf_kernels_20260805124229
3
- ops = torch.ops._gguf_kernels_20260805124229
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_gguf_kernels_20260805124229::{op_name}"
 
1
  import torch
2
+ from . import _gguf_kernels_cuda_e4e2164
3
+ ops = torch.ops._gguf_kernels_cuda_e4e2164
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_gguf_kernels_cuda_e4e2164::{op_name}"
build/{torch28-cxx11-cu126-x86_64-linux → torch212-cxx11-cu126-x86_64-linux}/gguf_kernels/__init__.py RENAMED
@@ -1,10 +1,10 @@
1
  import ctypes
 
2
  import sys
3
-
4
- import importlib
5
  from pathlib import Path
6
  from types import ModuleType
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
 
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
build/torch212-cxx11-cu126-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "gguf-kernels",
3
+ "id": "_gguf_kernels_cuda_e4e2164",
4
+ "version": 1,
5
+ "license": "MIT",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "7.5",
11
+ "8.0",
12
+ "8.6",
13
+ "8.9",
14
+ "9.0"
15
+ ]
16
+ }
17
+ }
build/{torch28-cxx11-cu128-x86_64-linux → torch212-cxx11-cu130-x86_64-linux}/__init__.py RENAMED
File without changes
build/torch212-cxx11-cu130-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4d7e366d102d2194c5df8ab2b96f2c741e4738798e4ce913c5f980eefe0f96d4
3
+ size 37380240
build/torch212-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _gguf_kernels_cuda_e4e2164
3
+ ops = torch.ops._gguf_kernels_cuda_e4e2164
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_gguf_kernels_cuda_e4e2164::{op_name}"
build/torch212-cxx11-cu130-x86_64-linux/gguf_kernels/__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/torch212-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "gguf-kernels",
3
+ "id": "_gguf_kernels_cuda_e4e2164",
4
+ "version": 1,
5
+ "license": "MIT",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "7.5",
13
+ "8.0",
14
+ "8.6",
15
+ "8.9",
16
+ "9.0"
17
+ ]
18
+ }
19
+ }
build/{torch28-cxx11-cu129-x86_64-linux → torch212-cxx11-cu132-x86_64-linux}/__init__.py RENAMED
File without changes
build/torch212-cxx11-cu132-x86_64-linux/_gguf_kernels_cuda_e4e2164.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:998f0c3e2e8a77d5e7dbd43ed817a98d46f519e1bcd626cd58d6365d2666edb4
3
+ size 37398744
build/torch212-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _gguf_kernels_cuda_e4e2164
3
+ ops = torch.ops._gguf_kernels_cuda_e4e2164
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_gguf_kernels_cuda_e4e2164::{op_name}"
build/torch212-cxx11-cu132-x86_64-linux/gguf_kernels/__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/torch212-cxx11-cu132-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "gguf-kernels",
3
+ "id": "_gguf_kernels_cuda_e4e2164",
4
+ "version": 1,
5
+ "license": "MIT",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "7.5",
13
+ "8.0",
14
+ "8.6",
15
+ "8.9",
16
+ "9.0"
17
+ ]
18
+ }
19
+ }
build/torch28-cxx11-cu126-x86_64-linux/metadata.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "version": 1,
3
- "python-depends": []
4
- }
 
 
 
 
 
build/torch28-cxx11-cu128-x86_64-linux/_gguf_kernels_20260805124229.abi3.so DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:964ea6025655311cfebe2fb58eca589ace6d208222d793134a48925309ccf910
3
- size 39054016
 
 
 
 
build/torch28-cxx11-cu128-x86_64-linux/_ops.py DELETED
@@ -1,9 +0,0 @@
1
- import torch
2
- from . import _gguf_kernels_20260805124229
3
- ops = torch.ops._gguf_kernels_20260805124229
4
-
5
- def add_op_namespace_prefix(op_name: str):
6
- """
7
- Prefix op by namespace.
8
- """
9
- return f"_gguf_kernels_20260805124229::{op_name}"
 
 
 
 
 
 
 
 
 
 
build/torch28-cxx11-cu128-x86_64-linux/gguf_kernels/__init__.py DELETED
@@ -1,26 +0,0 @@
1
- import ctypes
2
- import sys
3
-
4
- import importlib
5
- from pathlib import Path
6
- from types import ModuleType
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/torch28-cxx11-cu128-x86_64-linux/metadata.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "version": 1,
3
- "python-depends": []
4
- }
 
 
 
 
 
build/torch28-cxx11-cu129-x86_64-linux/_gguf_kernels_20260805124229.abi3.so DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:51b5f28bd29d9373e0a9a5046e7314af5061350b340646ab98dfa391fd4f8670
3
- size 38993592
 
 
 
 
build/torch28-cxx11-cu129-x86_64-linux/_ops.py DELETED
@@ -1,9 +0,0 @@
1
- import torch
2
- from . import _gguf_kernels_20260805124229
3
- ops = torch.ops._gguf_kernels_20260805124229
4
-
5
- def add_op_namespace_prefix(op_name: str):
6
- """
7
- Prefix op by namespace.
8
- """
9
- return f"_gguf_kernels_20260805124229::{op_name}"
 
 
 
 
 
 
 
 
 
 
build/torch28-cxx11-cu129-x86_64-linux/gguf_kernels/__init__.py DELETED
@@ -1,26 +0,0 @@
1
- import ctypes
2
- import sys
3
-
4
- import importlib
5
- from pathlib import Path
6
- from types import ModuleType
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/torch28-cxx11-cu129-x86_64-linux/metadata.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "version": 1,
3
- "python-depends": []
4
- }
 
 
 
 
 
build/torch29-cxx11-cu126-x86_64-linux/__init__.py DELETED
@@ -1,55 +0,0 @@
1
- """Compute directly on the packed blocks of a GGUF checkpoint.
2
-
3
- A GGUF weight is stored as blocks of 32 or 256 values sharing a scale. These kernels read that
4
- layout as it is, so a quantized model can be loaded and run without ever materializing a dense
5
- copy — which is the whole memory saving.
6
-
7
- Ported from llama.cpp's ggml-cuda; `vendor/UPSTREAM` pins the revision. The ops are named for what
8
- they do rather than for a backend: each backend registers its own implementation of the same
9
- schema, so calls dispatch on the tensor's device.
10
- """
11
-
12
- import torch
13
-
14
- from ._ops import add_op_namespace_prefix, ops
15
-
16
-
17
- __all__ = ["GEMV_TYPES", "MAX_GEMV_ROWS", "dequantize", "mul_mat_vec"]
18
-
19
- # Upstream's MMVQ_MAX_BATCH_SIZE: `mul_mat_vec` has no implementation beyond this many rows, so a
20
- # caller with more (prefill) dequantizes and uses an ordinary matmul.
21
- MAX_GEMV_ROWS = 8
22
-
23
- # ggml type ids `mul_mat_vec` implements: Q4_0/Q4_1/Q5_0/Q5_1/Q8_0, the K quants, and the IQ quants.
24
- # `dequantize` covers more, so check this one before choosing the fused path.
25
- GEMV_TYPES = frozenset({2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 29, 39, 40, 41, 42})
26
-
27
-
28
- def dequantize(
29
- blocks: torch.Tensor, ggml_type: int, rows: int, cols: int, dtype: torch.dtype
30
- ) -> torch.Tensor:
31
- """`(rows, bytes_per_row)` uint8 blocks -> `(rows, cols)` values of `dtype`."""
32
- return ops.dequantize(blocks, ggml_type, rows, cols, dtype)
33
-
34
-
35
- def mul_mat_vec(
36
- blocks: torch.Tensor, x: torch.Tensor, ggml_type: int, out_features: int
37
- ) -> torch.Tensor:
38
- """Fused dequantize-gemv: `x @ blocks.T` without unpacking `blocks`.
39
-
40
- `x` is `(rows, in_features)` and `rows` must be at most `MAX_GEMV_ROWS`. The result is f32
41
- whatever `x`'s dtype was, since the kernel writes an f32 destination; cast it at the call site,
42
- where the cast can be fused into whatever consumes it.
43
- """
44
- return ops.mul_mat_vec(blocks, x, ggml_type, out_features)
45
-
46
-
47
- # Without these, torch.compile cannot trace the ops and breaks the graph at every call.
48
- @torch.library.register_fake(add_op_namespace_prefix("dequantize"))
49
- def _dequantize_fake(blocks, ggml_type, rows, cols, dtype):
50
- return blocks.new_empty((rows, cols), dtype=dtype)
51
-
52
-
53
- @torch.library.register_fake(add_op_namespace_prefix("mul_mat_vec"))
54
- def _mul_mat_vec_fake(blocks, x, ggml_type, out_features):
55
- return x.new_empty((x.shape[0], out_features), dtype=torch.float32)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
build/torch29-cxx11-cu126-x86_64-linux/_gguf_kernels_20260805124229.abi3.so DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:d7435e6aeaab83f149782dd9d4dd926012315c0e9162b2a141dcbc961da18ea9
3
- size 26690648
 
 
 
 
build/torch29-cxx11-cu126-x86_64-linux/_ops.py DELETED
@@ -1,9 +0,0 @@
1
- import torch
2
- from . import _gguf_kernels_20260805124229
3
- ops = torch.ops._gguf_kernels_20260805124229
4
-
5
- def add_op_namespace_prefix(op_name: str):
6
- """
7
- Prefix op by namespace.
8
- """
9
- return f"_gguf_kernels_20260805124229::{op_name}"
 
 
 
 
 
 
 
 
 
 
build/torch29-cxx11-cu126-x86_64-linux/gguf_kernels/__init__.py DELETED
@@ -1,26 +0,0 @@
1
- import ctypes
2
- import sys
3
-
4
- import importlib
5
- from pathlib import Path
6
- from types import ModuleType
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")))