dispatch ggml's f32 gemv for unquantized weights
Browse files- build/torch212-metal-aarch64-darwin/_ggml_quantization_metal_9534e0b_dirty.abi3.so +0 -3
- build/torch212-metal-aarch64-darwin/_ops.py +3 -3
- build/torch212-metal-aarch64-darwin/metadata.json +4 -4
- build/torch213-metal-aarch64-darwin/_ggml_quantization_metal_9534e0b_dirty.abi3.so +0 -3
- build/torch213-metal-aarch64-darwin/_ops.py +3 -3
- build/torch213-metal-aarch64-darwin/metadata.json +4 -4
- gguf_metal/ggml_dispatch.mm +30 -5
build/torch212-metal-aarch64-darwin/_ggml_quantization_metal_9534e0b_dirty.abi3.so
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:5cfbd7846fed56165a528fdb29d0c3245bfd8a3d3f45c659232ffc92592b3f57
|
| 3 |
-
size 3347472
|
|
|
|
|
|
|
|
|
|
|
|
build/torch212-metal-aarch64-darwin/_ops.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
| 1 |
import torch
|
| 2 |
-
from . import
|
| 3 |
-
ops = torch.ops.
|
| 4 |
|
| 5 |
def add_op_namespace_prefix(op_name: str):
|
| 6 |
"""
|
| 7 |
Prefix op by namespace.
|
| 8 |
"""
|
| 9 |
-
return f"
|
|
|
|
| 1 |
import torch
|
| 2 |
+
from . import _ggml_quantization_metal_e1c26fb_dirty
|
| 3 |
+
ops = torch.ops._ggml_quantization_metal_e1c26fb_dirty
|
| 4 |
|
| 5 |
def add_op_namespace_prefix(op_name: str):
|
| 6 |
"""
|
| 7 |
Prefix op by namespace.
|
| 8 |
"""
|
| 9 |
+
return f"_ggml_quantization_metal_e1c26fb_dirty::{op_name}"
|
build/torch212-metal-aarch64-darwin/metadata.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
{
|
| 2 |
"name": "ggml-quantization",
|
| 3 |
-
"id": "
|
| 4 |
"version": 1,
|
| 5 |
"license": "MIT",
|
| 6 |
"python-depends": [],
|
|
@@ -11,8 +11,8 @@
|
|
| 11 |
"algorithm": "sha256",
|
| 12 |
"files": {
|
| 13 |
"__init__.py": "iPXgZXBgY3CzpNUSjmCovMVNPLBol1KBaNoTzkXp5mM=",
|
| 14 |
-
"
|
| 15 |
-
"_ops.py": "
|
| 16 |
}
|
| 17 |
},
|
| 18 |
"provenance": {
|
|
@@ -22,7 +22,7 @@
|
|
| 22 |
"dirty": false
|
| 23 |
},
|
| 24 |
"kernel": {
|
| 25 |
-
"sha": "
|
| 26 |
"dirty": true
|
| 27 |
}
|
| 28 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"name": "ggml-quantization",
|
| 3 |
+
"id": "_ggml_quantization_metal_e1c26fb_dirty",
|
| 4 |
"version": 1,
|
| 5 |
"license": "MIT",
|
| 6 |
"python-depends": [],
|
|
|
|
| 11 |
"algorithm": "sha256",
|
| 12 |
"files": {
|
| 13 |
"__init__.py": "iPXgZXBgY3CzpNUSjmCovMVNPLBol1KBaNoTzkXp5mM=",
|
| 14 |
+
"_ggml_quantization_metal_e1c26fb_dirty.abi3.so": "h8e+W6XgHY6Nq5KUfmDnI9LZUxHexKjA/O2yuwuFzko=",
|
| 15 |
+
"_ops.py": "Z1v1Vem/A3QJA8XQki0lB8D80aXJJ+Zsma16emhbRNw="
|
| 16 |
}
|
| 17 |
},
|
| 18 |
"provenance": {
|
|
|
|
| 22 |
"dirty": false
|
| 23 |
},
|
| 24 |
"kernel": {
|
| 25 |
+
"sha": "e1c26fbaad0bd4b9ef9a3c48435942a4bc560f0a",
|
| 26 |
"dirty": true
|
| 27 |
}
|
| 28 |
}
|
build/torch213-metal-aarch64-darwin/_ggml_quantization_metal_9534e0b_dirty.abi3.so
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:deae8683c779e9477721573ac7f0b3abccccd11aebef0a49c27d4ae7a8cd7f91
|
| 3 |
-
size 3347472
|
|
|
|
|
|
|
|
|
|
|
|
build/torch213-metal-aarch64-darwin/_ops.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
| 1 |
import torch
|
| 2 |
-
from . import
|
| 3 |
-
ops = torch.ops.
|
| 4 |
|
| 5 |
def add_op_namespace_prefix(op_name: str):
|
| 6 |
"""
|
| 7 |
Prefix op by namespace.
|
| 8 |
"""
|
| 9 |
-
return f"
|
|
|
|
| 1 |
import torch
|
| 2 |
+
from . import _ggml_quantization_metal_e1c26fb_dirty
|
| 3 |
+
ops = torch.ops._ggml_quantization_metal_e1c26fb_dirty
|
| 4 |
|
| 5 |
def add_op_namespace_prefix(op_name: str):
|
| 6 |
"""
|
| 7 |
Prefix op by namespace.
|
| 8 |
"""
|
| 9 |
+
return f"_ggml_quantization_metal_e1c26fb_dirty::{op_name}"
|
build/torch213-metal-aarch64-darwin/metadata.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
{
|
| 2 |
"name": "ggml-quantization",
|
| 3 |
-
"id": "
|
| 4 |
"version": 1,
|
| 5 |
"license": "MIT",
|
| 6 |
"python-depends": [],
|
|
@@ -11,8 +11,8 @@
|
|
| 11 |
"algorithm": "sha256",
|
| 12 |
"files": {
|
| 13 |
"__init__.py": "iPXgZXBgY3CzpNUSjmCovMVNPLBol1KBaNoTzkXp5mM=",
|
| 14 |
-
"
|
| 15 |
-
"_ops.py": "
|
| 16 |
}
|
| 17 |
},
|
| 18 |
"provenance": {
|
|
@@ -22,7 +22,7 @@
|
|
| 22 |
"dirty": false
|
| 23 |
},
|
| 24 |
"kernel": {
|
| 25 |
-
"sha": "
|
| 26 |
"dirty": true
|
| 27 |
}
|
| 28 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"name": "ggml-quantization",
|
| 3 |
+
"id": "_ggml_quantization_metal_e1c26fb_dirty",
|
| 4 |
"version": 1,
|
| 5 |
"license": "MIT",
|
| 6 |
"python-depends": [],
|
|
|
|
| 11 |
"algorithm": "sha256",
|
| 12 |
"files": {
|
| 13 |
"__init__.py": "iPXgZXBgY3CzpNUSjmCovMVNPLBol1KBaNoTzkXp5mM=",
|
| 14 |
+
"_ggml_quantization_metal_e1c26fb_dirty.abi3.so": "51EmqssYeOEoRK/C2bQHIY5tLWmK0Rp7GKMboo4w0u4=",
|
| 15 |
+
"_ops.py": "Z1v1Vem/A3QJA8XQki0lB8D80aXJJ+Zsma16emhbRNw="
|
| 16 |
}
|
| 17 |
},
|
| 18 |
"provenance": {
|
|
|
|
| 22 |
"dirty": false
|
| 23 |
},
|
| 24 |
"kernel": {
|
| 25 |
+
"sha": "e1c26fbaad0bd4b9ef9a3c48435942a4bc560f0a",
|
| 26 |
"dirty": true
|
| 27 |
}
|
| 28 |
}
|
gguf_metal/ggml_dispatch.mm
CHANGED
|
@@ -29,7 +29,7 @@
|
|
| 29 |
namespace {
|
| 30 |
|
| 31 |
// ggml type ids, matching ggml.h
|
| 32 |
-
enum { GGML_Q4_0 = 2, GGML_Q4_1 = 3, GGML_Q5_0 = 6, GGML_Q5_1 = 7, GGML_Q8_0 = 8,
|
| 33 |
GGML_Q2_K = 10, GGML_Q3_K = 11, GGML_Q4_K = 12, GGML_Q5_K = 13, GGML_Q6_K = 14,
|
| 34 |
GGML_IQ2_XXS = 16, GGML_IQ2_XS = 17, GGML_IQ3_XXS = 18, GGML_IQ1_S = 19,
|
| 35 |
GGML_IQ4_NL = 20, GGML_IQ3_S = 21, GGML_IQ2_S = 22, GGML_IQ4_XS = 23,
|
|
@@ -59,6 +59,10 @@ struct TypeInfo {
|
|
| 59 |
// which upstream's Metal backend has no kernel for. Block sizes are ggml's GGML_QUANT_SIZES.
|
| 60 |
const std::unordered_map<int, TypeInfo> &type_table() {
|
| 61 |
static const std::unordered_map<int, TypeInfo> table = {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
// legacy quants
|
| 63 |
{GGML_Q4_0, {"q4_0", 32, 18, N_SG_Q4_0, N_R0_Q4_0, false, 0}},
|
| 64 |
{GGML_Q4_1, {"q4_1", 32, 20, N_SG_Q4_1, N_R0_Q4_1, false, 0}},
|
|
@@ -86,6 +90,26 @@ const std::unordered_map<int, TypeInfo> &type_table() {
|
|
| 86 |
return table;
|
| 87 |
}
|
| 88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
const TypeInfo *lookup(int ggml_type) {
|
| 90 |
auto it = type_table().find(ggml_type);
|
| 91 |
return it == type_table().end() ? nullptr : &it->second;
|
|
@@ -202,9 +226,10 @@ extern "C" int gguf_metal_mul_mat(void *blocks, size_t blocks_off, void *x, size
|
|
| 202 |
|
| 203 |
if (M <= 8) {
|
| 204 |
// gemv: one token (or a handful), the decode path
|
| 205 |
-
const
|
|
|
|
| 206 |
char fn[128];
|
| 207 |
-
snprintf(fn, sizeof(fn), "kernel_mul_mv_%s_f32", info->name);
|
| 208 |
std::string key = std::string(fn) + "_nsg=" + std::to_string(nsg);
|
| 209 |
|
| 210 |
MTLFunctionConstantValues *cv = [MTLFunctionConstantValues new];
|
|
@@ -232,8 +257,8 @@ extern "C" int gguf_metal_mul_mat(void *blocks, size_t blocks_off, void *x, size
|
|
| 232 |
[enc setBuffer:b_blocks offset:blocks_off atIndex:1];
|
| 233 |
[enc setBuffer:b_x offset:x_off atIndex:2];
|
| 234 |
[enc setBuffer:b_out offset:out_off atIndex:3];
|
| 235 |
-
if (
|
| 236 |
-
[enc setThreadgroupMemoryLength:
|
| 237 |
}
|
| 238 |
const NSUInteger gx = info->mv_reduce_across_sgs ? (N + nr0 - 1) / nr0
|
| 239 |
: (N + nr0 * nsg - 1) / (nr0 * nsg);
|
|
|
|
| 29 |
namespace {
|
| 30 |
|
| 31 |
// ggml type ids, matching ggml.h
|
| 32 |
+
enum { GGML_F32 = 0, GGML_Q4_0 = 2, GGML_Q4_1 = 3, GGML_Q5_0 = 6, GGML_Q5_1 = 7, GGML_Q8_0 = 8,
|
| 33 |
GGML_Q2_K = 10, GGML_Q3_K = 11, GGML_Q4_K = 12, GGML_Q5_K = 13, GGML_Q6_K = 14,
|
| 34 |
GGML_IQ2_XXS = 16, GGML_IQ2_XS = 17, GGML_IQ3_XXS = 18, GGML_IQ1_S = 19,
|
| 35 |
GGML_IQ4_NL = 20, GGML_IQ3_S = 21, GGML_IQ2_S = 22, GGML_IQ4_XS = 23,
|
|
|
|
| 59 |
// which upstream's Metal backend has no kernel for. Block sizes are ggml's GGML_QUANT_SIZES.
|
| 60 |
const std::unordered_map<int, TypeInfo> &type_table() {
|
| 61 |
static const std::unordered_map<int, TypeInfo> table = {
|
| 62 |
+
// A dense f32 weight, which a GGUF stores unquantized: the norms, the router, and any tensor
|
| 63 |
+
// llama.cpp declined to quantize. Upstream picks this kernel's grid from the row length rather
|
| 64 |
+
// than from a table, so the nsg/nr0/smem below are placeholders that `mv_params` overrides.
|
| 65 |
+
{GGML_F32, {"f32", 1, 4, 1, 2, true, 0}},
|
| 66 |
// legacy quants
|
| 67 |
{GGML_Q4_0, {"q4_0", 32, 18, N_SG_Q4_0, N_R0_Q4_0, false, 0}},
|
| 68 |
{GGML_Q4_1, {"q4_1", 32, 20, N_SG_Q4_1, N_R0_Q4_1, false, 0}},
|
|
|
|
| 90 |
return table;
|
| 91 |
}
|
| 92 |
|
| 93 |
+
// What `ggml_metal_library_get_pipeline_mul_mv` decides inline for the dense types, where the grid
|
| 94 |
+
// follows the row length instead of a per-type constant. Quantized types keep their table values.
|
| 95 |
+
struct MvParams {
|
| 96 |
+
int nsg;
|
| 97 |
+
int nr0;
|
| 98 |
+
size_t smem;
|
| 99 |
+
const char *suffix;
|
| 100 |
+
};
|
| 101 |
+
|
| 102 |
+
MvParams mv_params(const TypeInfo *info, int64_t K) {
|
| 103 |
+
if (info->block_elems != 1) {
|
| 104 |
+
return {info->mv_nsg, info->mv_nr0, info->mv_smem, ""};
|
| 105 |
+
}
|
| 106 |
+
if (K < 32) {
|
| 107 |
+
return {1, 32, 0, "_short"};
|
| 108 |
+
}
|
| 109 |
+
const int nsg = (int)MIN((int64_t)4, (K + 127) / 128);
|
| 110 |
+
return {nsg, 2, 32 * sizeof(float) * 2, (K % 4 == 0) ? "_4" : ""};
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
const TypeInfo *lookup(int ggml_type) {
|
| 114 |
auto it = type_table().find(ggml_type);
|
| 115 |
return it == type_table().end() ? nullptr : &it->second;
|
|
|
|
| 226 |
|
| 227 |
if (M <= 8) {
|
| 228 |
// gemv: one token (or a handful), the decode path
|
| 229 |
+
const MvParams mv = mv_params(info, K);
|
| 230 |
+
const int nsg = mv.nsg, nr0 = mv.nr0;
|
| 231 |
char fn[128];
|
| 232 |
+
snprintf(fn, sizeof(fn), "kernel_mul_mv_%s_f32%s", info->name, mv.suffix);
|
| 233 |
std::string key = std::string(fn) + "_nsg=" + std::to_string(nsg);
|
| 234 |
|
| 235 |
MTLFunctionConstantValues *cv = [MTLFunctionConstantValues new];
|
|
|
|
| 257 |
[enc setBuffer:b_blocks offset:blocks_off atIndex:1];
|
| 258 |
[enc setBuffer:b_x offset:x_off atIndex:2];
|
| 259 |
[enc setBuffer:b_out offset:out_off atIndex:3];
|
| 260 |
+
if (mv.smem) {
|
| 261 |
+
[enc setThreadgroupMemoryLength:mv.smem atIndex:0];
|
| 262 |
}
|
| 263 |
const NSUInteger gx = info->mv_reduce_across_sgs ? (N + nr0 - 1) / nr0
|
| 264 |
: (N + nr0 * nsg - 1) / (nr0 * nsg);
|