seedpack 0.1.0__py3-none-any.whl

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.
Files changed (47) hide show
  1. seedpack/__init__.py +6 -0
  2. seedpack/__main__.py +3 -0
  3. seedpack/bf16codec.py +103 -0
  4. seedpack/bf16v2.py +421 -0
  5. seedpack/bundle.py +36 -0
  6. seedpack/cli.py +413 -0
  7. seedpack/codecs_gguf.py +344 -0
  8. seedpack/container.py +106 -0
  9. seedpack/ggml/LICENSE +21 -0
  10. seedpack/ggml/build.sh +14 -0
  11. seedpack/ggml/export.c +10 -0
  12. seedpack/ggml/ggml-alloc.h +87 -0
  13. seedpack/ggml/ggml-backend.h +463 -0
  14. seedpack/ggml/ggml-common.h +1911 -0
  15. seedpack/ggml/ggml-cpu/ggml-cpu-impl.h +540 -0
  16. seedpack/ggml/ggml-cpu.h +152 -0
  17. seedpack/ggml/ggml-impl.h +795 -0
  18. seedpack/ggml/ggml-quants.c +5639 -0
  19. seedpack/ggml/ggml-quants.h +115 -0
  20. seedpack/ggml/ggml.h +3049 -0
  21. seedpack/ggml/gguf.h +211 -0
  22. seedpack/ggml/iqtables.npz +0 -0
  23. seedpack/ggml/stubs.c +29 -0
  24. seedpack/ggml/variants/ggml-quants.pre-f95b0d9539.c +5667 -0
  25. seedpack/gguf_reader.py +121 -0
  26. seedpack/gpu2.py +874 -0
  27. seedpack/gpu3.py +639 -0
  28. seedpack/gpu_bf16.py +530 -0
  29. seedpack/gpu_codec.py +353 -0
  30. seedpack/gpuquant.py +416 -0
  31. seedpack/ptxfix.py +78 -0
  32. seedpack/qr.py +735 -0
  33. seedpack/rans.py +164 -0
  34. seedpack/refcodec.py +314 -0
  35. seedpack/repo.py +597 -0
  36. seedpack/repo2.py +160 -0
  37. seedpack/repo3.py +931 -0
  38. seedpack/requant.py +117 -0
  39. seedpack/seed.py +160 -0
  40. seedpack-0.1.0.dist-info/METADATA +111 -0
  41. seedpack-0.1.0.dist-info/RECORD +47 -0
  42. seedpack-0.1.0.dist-info/WHEEL +5 -0
  43. seedpack-0.1.0.dist-info/entry_points.txt +2 -0
  44. seedpack-0.1.0.dist-info/licenses/LICENSE +202 -0
  45. seedpack-0.1.0.dist-info/licenses/NOTICE +6 -0
  46. seedpack-0.1.0.dist-info/licenses/seedpack/ggml/LICENSE +21 -0
  47. seedpack-0.1.0.dist-info/top_level.txt +1 -0
seedpack/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ """SeedPack: lossless GPU archiver for GGUF model repositories.
2
+
3
+ The quants of a repository are re-derived on the GPU from its most precise model (the seed) with
4
+ a bit-exact port of llama.cpp's quantisers; only what differs is stored. Command line: `seedpack`.
5
+ """
6
+ __version__ = "0.1.0"
seedpack/__main__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main()
seedpack/bf16codec.py ADDED
@@ -0,0 +1,103 @@
1
+ """Method 22: lossless BF16 GGUF codec (no reference model).
2
+
3
+ A bf16 weight = sign(1) | exponent(8) | mantissa(7). Trained weights use ~2.6 of the 8
4
+ exponent bits (the DFloat11 / ZipNN observation); on top of that this codec models
5
+ * exponent | predicted exponent (rank-1 variance model: row factor + column factor,
6
+ quarter-octave side info per row and per column)
7
+ * mantissa | exponent - predicted exponent (density slope inside an octave)
8
+ * sign | column mean-bias class
9
+ Each stream is coded with static rANS, tables per tensor. Everything outside 2-D bf16
10
+ tensors (header, norms, padding) goes through the tokenizer-aware header codec.
11
+ """
12
+ import json
13
+ import struct
14
+
15
+ import numpy as np
16
+
17
+ from . import rans
18
+ from .codecs_gguf import pack, unpack, zstd_c, zstd_d
19
+ from .gguf_reader import GGUF, GGML_BF16
20
+ from .gpu2 import header_pairs_c, header_pairs_d, xz_chunks_c, xz_chunks_d, rest_of
21
+
22
+
23
+ def _contexts(rfi, cfi, ex=None):
24
+ pred4 = rfi[:, None].astype(np.int32) + cfi[None, :].astype(np.int32) # log2 sigma in 1/4 octave
25
+ eb = np.clip((pred4 + 4 * 27) // 2, 0, 127).astype(np.int16) # half-octave bins
26
+ if ex is None:
27
+ return eb, pred4
28
+ rel = np.clip(ex.astype(np.int32) - (pred4 + 508) // 4 + 8, 0, 15).astype(np.int16)
29
+ return eb, rel
30
+
31
+
32
+ class M22BF16:
33
+ name = "M22 BF16: exponent/mantissa/sign context rANS"
34
+
35
+ def compress(self, data):
36
+ g = GGUF.from_bytes(data)
37
+ ts = sorted((t for t in g.tensors if t.type == GGML_BF16 and len(t.shape) == 2), key=lambda t: t.offset)
38
+ layout = {"size": len(data), "t": [[t.offset, t.nbytes, t.shape[0], "bf16"] for t in ts]}
39
+ bufs, tabs, side = [], [], []
40
+ for t in ts:
41
+ rowlen = t.shape[0]
42
+ u = np.frombuffer(data, np.uint16, t.nbytes // 2, t.offset).reshape(-1, rowlen)
43
+ w = (u.astype(np.uint32) << 16).view(np.float32)
44
+ rf = np.log2(np.sqrt((w.astype(np.float64) ** 2).mean(1)) + 1e-30)
45
+ cf = np.log2(np.sqrt(((w / np.exp2(rf)[:, None]).astype(np.float64) ** 2).mean(0)) + 1e-30)
46
+ rfi = np.clip(np.rint(rf * 4), -32768, 32767).astype(np.int16)
47
+ cfi = np.clip(np.rint(cf * 4), -32768, 32767).astype(np.int16)
48
+ bias = (w / np.exp2(rf)[:, None]).mean(0) / np.exp2(cfi / 4.0)
49
+ sc = np.clip(np.floor(bias * 16) + 8, 0, 15).astype(np.int16)
50
+ ex = ((u >> 7) & 255).astype(np.uint8); man = (u & 127).astype(np.uint8); sg = (u >> 15).astype(np.uint8)
51
+ eb, rel = _contexts(rfi, cfi, ex)
52
+ sctx = np.broadcast_to(sc[None, :], u.shape)
53
+ for sym, ctx, nctx in ((ex, eb, 128), (man, rel, 16), (sg, sctx, 16)):
54
+ sym = sym.ravel(); ctx = np.ascontiguousarray(ctx.ravel())
55
+ f = rans.build_freqs(sym, ctx, nctx)
56
+ tabs.append(f); bufs.append(rans.encode(sym, ctx, f))
57
+ side.append(rfi.tobytes() + cfi.tobytes() + sc.astype(np.int8).tobytes())
58
+ h = header_pairs_c(data, g, layout)
59
+ rest = b"P" + h if h is not None else b"X" + xz_chunks_c(rest_of(data, layout))
60
+ ch = {
61
+ "layout": zstd_c(json.dumps(layout).encode()),
62
+ "side": zstd_c(b"".join(side), 19),
63
+ "tables": zstd_c(b"".join(f.astype(np.uint16).tobytes() for f in tabs), 19),
64
+ "streams": b"".join(struct.pack("<Q", len(b)) + b for b in bufs),
65
+ "rest": rest,
66
+ }
67
+ return pack(ch)
68
+
69
+ def decompress(self, buf):
70
+ ch = unpack(buf)
71
+ layout = json.loads(zstd_d(ch["layout"]))
72
+ side = zstd_d(ch["side"]); tabs = np.frombuffer(zstd_d(ch["tables"]), np.uint16)
73
+ sbuf, spos, tpos, dpos = ch["streams"], 0, 0, 0
74
+ r = ch["rest"]
75
+ rest = header_pairs_d(r[1:]) if r[:1] == b"P" else xz_chunks_d(r[1:])
76
+ out = np.empty(layout["size"], np.uint8)
77
+ pos = rpos = 0
78
+
79
+ def next_stream():
80
+ nonlocal spos
81
+ (ln,) = struct.unpack_from("<Q", sbuf, spos); spos += 8
82
+ b = sbuf[spos:spos + ln]; spos += ln
83
+ return b
84
+
85
+ for off, nbytes, rowlen, _ in layout["t"]:
86
+ n = nbytes // 2; nrows = n // rowlen
87
+ rfi = np.frombuffer(side, np.int16, nrows, dpos); dpos += 2 * nrows
88
+ cfi = np.frombuffer(side, np.int16, rowlen, dpos); dpos += 2 * rowlen
89
+ sc = np.frombuffer(side, np.int8, rowlen, dpos).astype(np.int16); dpos += rowlen
90
+ res = []
91
+ for nctx in (128, 16, 16):
92
+ res.append(tabs[tpos:tpos + nctx * 256].reshape(nctx, 256)); tpos += nctx * 256
93
+ eb, pred4 = _contexts(rfi, cfi)
94
+ ex = rans.decode(next_stream(), eb.ravel(), res[0]).reshape(nrows, rowlen)
95
+ _, rel = _contexts(rfi, cfi, ex)
96
+ man = rans.decode(next_stream(), np.ascontiguousarray(rel.ravel()), res[1]).reshape(nrows, rowlen)
97
+ sg = rans.decode(next_stream(), np.ascontiguousarray(np.broadcast_to(sc[None, :], (nrows, rowlen)).ravel()), res[2])
98
+ u = (sg.reshape(nrows, rowlen).astype(np.uint16) << 15) | (ex.astype(np.uint16) << 7) | man.astype(np.uint16)
99
+ gap = off - pos
100
+ out[pos:off] = np.frombuffer(rest, np.uint8, gap, rpos); rpos += gap
101
+ out[off:off + nbytes] = u.view(np.uint8).ravel(); pos = off + nbytes
102
+ out[pos:] = np.frombuffer(rest, np.uint8, len(rest) - rpos, rpos)
103
+ return out
seedpack/bf16v2.py ADDED
@@ -0,0 +1,421 @@
1
+ """R2: BF16 GGUF codec v2 (candidate successor of M24).
2
+
3
+ Changes against M24 (src/gpu_bf16.py):
4
+ * 1/8-octave variance side info (rfi/cfi = rint(8*log2 rms)) instead of 1/4 octave;
5
+ exponent context = predicted log2 sigma in 1/8 octave (512 ctx), mantissa context =
6
+ exponent - prediction in 1/8 octave (128 ctx), sign context = column bias class (16 ctx);
7
+ * frequency tables are SHARED by all tensors of the same role (blk.*.ffn_up, ...), which makes
8
+ the finer contexts affordable (table cost ~0.06 MB instead of ~0.3 MB for M24's coarser ones);
9
+ * exact duplicate rows (e.g. untrained token embeddings) are coded once + a row map;
10
+ * bounded GPU memory: tensors are processed in groups of <= group_bytes; the file is kept
11
+ on the GPU between the histogram and the encode pass only when it fits `budget` bytes.
12
+ Exactness: contexts are pure integer functions of side info stored in the archive.
13
+ """
14
+ import json, os, re, sys, struct
15
+ from concurrent.futures import ThreadPoolExecutor
16
+
17
+ import cupy as cp
18
+ import numpy as np
19
+
20
+
21
+ from .codecs_gguf import pack, unpack, zstd_c, zstd_d
22
+ from .gguf_reader import GGUF, GGML_BF16
23
+ from .gpu2 import normalize_gpu, cum_of, store_tables, load_tables, Timer, GPU2
24
+ PB = 15 # probability resolution (M24: 12); +0.25 MB gain, see pb_study.py
25
+ from .gpu_bf16 import M24BF16GPU
26
+
27
+ SEG = 16384
28
+ K = 8 # side info resolution: 1/K octave
29
+ NE, NM, NS = 512, 128, 16
30
+ TPT = NE + NM + NS # tables per role group
31
+
32
+ KERNELS = r"""
33
+ #define PB %(PB)d
34
+ #define PSCALE (1u << PB)
35
+ #define RANS_L (1u << 23)
36
+
37
+ struct TB { long long doff; int rowlen, rowbase, colbase, tab, rmap, pad; };
38
+ struct SG { int t; int n; long long i0; };
39
+
40
+ #define PUT(tab, s) { \
41
+ int tt_ = remap[tab]; unsigned int s_ = (s); \
42
+ unsigned int f_ = freq[tt_ * 256 + s_], c_ = cum[tt_ * 257 + s_]; \
43
+ unsigned int xm_ = ((RANS_L >> PB) << 8) * f_; \
44
+ while (x >= xm_) { *--ptr = (unsigned char)(x & 0xff); x >>= 8; } \
45
+ x = ((x / f_) << PB) + (x % f_) + c_; }
46
+
47
+ #define GET(tab, out) { \
48
+ int tt_ = remap[tab]; unsigned int slot_ = x & (PSCALE - 1); \
49
+ int s_ = lut[(size_t)tt_ * PSCALE + slot_]; \
50
+ x = freq[tt_ * 256 + s_] * (x >> PB) + slot_ - cum[tt_ * 257 + s_]; \
51
+ while (x < RANS_L) x = (x << 8) | *ptr++; \
52
+ out = s_; }
53
+
54
+ __device__ __forceinline__ int clampi(int v, int lo, int hi) { return v < lo ? lo : (v > hi ? hi : v); }
55
+
56
+ // compact row rc -> original row
57
+ #define OROW(rc) (T.rmap >= 0 ? rowmap[T.rmap + (rc)] : (rc))
58
+ #define CTX \
59
+ int pred = rfi[T.rowbase + orow] + cfi[T.colbase + j]; \
60
+ int pe = clampi(pred + 256, 0, 511);
61
+ #define MCTX int rl = clampi(8 * ex - pred - 1016 + 64, 0, 127);
62
+
63
+ extern "C" __global__ void v2_hist(const unsigned char* dev, const TB* tb, const SG* sg, int nseg,
64
+ const short* rfi, const short* cfi, const signed char* scl, const int* rowmap,
65
+ unsigned int* counts) {
66
+ int s = blockIdx.x * blockDim.x + threadIdx.x;
67
+ if (s >= nseg) return;
68
+ TB T = tb[sg[s].t];
69
+ const unsigned short* W = (const unsigned short*)(dev + T.doff);
70
+ int rc = (int)(sg[s].i0 / T.rowlen), j = (int)(sg[s].i0 % T.rowlen);
71
+ int orow = OROW(rc);
72
+ const unsigned short* w = W + (size_t)orow * T.rowlen;
73
+ for (int k = 0; k < sg[s].n; k++) {
74
+ unsigned int u = w[j];
75
+ int ex = (u >> 7) & 255, man = u & 127, sgn = u >> 15;
76
+ CTX MCTX
77
+ atomicAdd(&counts[(size_t)(T.tab + pe) * 256 + ex], 1u);
78
+ atomicAdd(&counts[(size_t)(T.tab + 512 + rl) * 256 + man], 1u);
79
+ atomicAdd(&counts[(size_t)(T.tab + 640 + scl[T.colbase + j]) * 256 + sgn], 1u);
80
+ if (++j == T.rowlen) { j = 0; rc++; if (k + 1 < sg[s].n) { orow = OROW(rc); w = W + (size_t)orow * T.rowlen; } }
81
+ }
82
+ }
83
+
84
+ extern "C" __global__ void v2_enc(const unsigned char* dev, const TB* tb, const SG* sg, int nseg,
85
+ const short* rfi, const short* cfi, const signed char* scl, const int* rowmap,
86
+ const int* remap, const unsigned short* freq, const unsigned int* cum,
87
+ unsigned char* out, size_t cap, unsigned int* out_len) {
88
+ int s = blockIdx.x * blockDim.x + threadIdx.x;
89
+ if (s >= nseg) return;
90
+ TB T = tb[sg[s].t];
91
+ const unsigned short* W = (const unsigned short*)(dev + T.doff);
92
+ long long last = sg[s].i0 + sg[s].n - 1;
93
+ int rc = (int)(last / T.rowlen), j = (int)(last % T.rowlen);
94
+ int orow = OROW(rc);
95
+ const unsigned short* w = W + (size_t)orow * T.rowlen;
96
+ unsigned char* start = out + (size_t)s * cap;
97
+ unsigned char* end = start + cap; unsigned char* ptr = end;
98
+ unsigned int x = RANS_L;
99
+ for (int k = sg[s].n - 1; k >= 0; k--) {
100
+ unsigned int u = w[j];
101
+ int ex = (u >> 7) & 255, man = u & 127, sgn = u >> 15;
102
+ CTX MCTX
103
+ PUT(T.tab + 640 + scl[T.colbase + j], sgn);
104
+ PUT(T.tab + 512 + rl, man);
105
+ PUT(T.tab + pe, ex);
106
+ if (ptr - start < 64) { out_len[s] = 0xffffffffu; return; }
107
+ if (--j < 0) { j = T.rowlen - 1; rc--; if (k > 0) { orow = OROW(rc); w = W + (size_t)orow * T.rowlen; } }
108
+ }
109
+ for (int i = 0; i < 4; i++) { *--ptr = (unsigned char)(x & 0xff); x >>= 8; }
110
+ out_len[s] = (unsigned int)(end - ptr);
111
+ }
112
+
113
+ extern "C" __global__ void v2_dec(const unsigned char* in, const unsigned long long* in_off,
114
+ unsigned char* dev, const TB* tb, const SG* sg, int nseg,
115
+ const short* rfi, const short* cfi, const signed char* scl, const int* rowmap,
116
+ const int* remap, const unsigned short* freq, const unsigned int* cum,
117
+ const unsigned char* lut) {
118
+ int s = blockIdx.x * blockDim.x + threadIdx.x;
119
+ if (s >= nseg) return;
120
+ TB T = tb[sg[s].t];
121
+ unsigned short* W = (unsigned short*)(dev + T.doff);
122
+ int rc = (int)(sg[s].i0 / T.rowlen), j = (int)(sg[s].i0 % T.rowlen);
123
+ int orow = OROW(rc);
124
+ unsigned short* w = W + (size_t)orow * T.rowlen;
125
+ const unsigned char* ptr = in + in_off[s]; unsigned int x = 0;
126
+ for (int i = 0; i < 4; i++) x = (x << 8) | *ptr++;
127
+ for (int k = 0; k < sg[s].n; k++) {
128
+ int ex, man, sgn;
129
+ CTX
130
+ GET(T.tab + pe, ex);
131
+ MCTX
132
+ GET(T.tab + 512 + rl, man);
133
+ GET(T.tab + 640 + scl[T.colbase + j], sgn);
134
+ w[j] = (unsigned short)((sgn << 15) | (ex << 7) | man);
135
+ if (++j == T.rowlen) { j = 0; rc++; if (k + 1 < sg[s].n) { orow = OROW(rc); w = W + (size_t)orow * T.rowlen; } }
136
+ }
137
+ }
138
+
139
+ extern "C" __global__ void build_lut(const unsigned int* cum, int ntab, unsigned char* lut) {
140
+ int tb = blockIdx.x;
141
+ if (tb >= ntab) return;
142
+ for (int sym = threadIdx.x; sym < 256; sym += blockDim.x)
143
+ for (unsigned int i = cum[tb * 257 + sym]; i < cum[tb * 257 + sym + 1]; i++)
144
+ lut[(size_t)tb * PSCALE + i] = (unsigned char)sym;
145
+ }
146
+
147
+ // 64-bit row fingerprints for duplicate-row detection
148
+ extern "C" __global__ void row_hash(const unsigned short* w, int nrows, int rowlen, unsigned long long* h) {
149
+ int r = blockIdx.x * blockDim.x + threadIdx.x;
150
+ if (r >= nrows) return;
151
+ unsigned long long a = 1469598103934665603ull;
152
+ const unsigned short* p = w + (size_t)r * rowlen;
153
+ for (int j = 0; j < rowlen; j++) { a ^= p[j]; a *= 1099511628211ull; a ^= a >> 29; }
154
+ h[r] = a;
155
+ }
156
+ """.replace("%(PB)d", str(PB))
157
+
158
+ TB_DT = np.dtype([("doff", "<i8"), ("rowlen", "<i4"), ("rowbase", "<i4"), ("colbase", "<i4"), ("tab", "<i4"), ("rmap", "<i4"), ("pad", "<i4")])
159
+ SG_DT = np.dtype([("t", "<i4"), ("n", "<i4"), ("i0", "<i8")])
160
+ _mod = None
161
+ _g2 = GPU2()
162
+
163
+
164
+ def kern(name):
165
+ global _mod
166
+ if _mod is None:
167
+ _mod = cp.RawModule(code=KERNELS, options=("-std=c++17",))
168
+ return _mod.get_function(name)
169
+
170
+
171
+ def role(name):
172
+ return re.sub(r"blk\.\d+\.", "", name)
173
+
174
+
175
+ class BF16v2:
176
+ name = "R2 BF16 v2: 1/8-octave contexts, role-shared tables, row dedup, bounded GPU memory"
177
+
178
+ def __init__(self, budget=2_000_000_000, group_bytes=400 << 20, dedup=True):
179
+ self.budget, self.group_bytes, self.dedup = budget, group_bytes, dedup
180
+ self.timing = {}
181
+
182
+ # ---------------------------------------------------------------- layout
183
+ @staticmethod
184
+ def _layout(g, size):
185
+ ts = sorted((t for t in g.tensors if t.type == GGML_BF16 and len(t.shape) == 2), key=lambda t: t.offset)
186
+ roles = []
187
+ for t in ts:
188
+ if role(t.name) not in roles:
189
+ roles.append(role(t.name))
190
+ return {"size": size, "t": [[t.offset, t.nbytes, t.shape[0], "bf16"] for t in ts],
191
+ "role": [roles.index(role(t.name)) for t in ts], "nroles": len(roles)}
192
+
193
+ def _groups(self, layout):
194
+ gs, cur, cb = [], [], 0
195
+ for i, (off, nb, rl, _) in enumerate(layout["t"]):
196
+ if cur and cb + nb > self.group_bytes:
197
+ gs.append(cur); cur, cb = [], 0
198
+ cur.append(i); cb += nb
199
+ if cur:
200
+ gs.append(cur)
201
+ return gs
202
+
203
+ @staticmethod
204
+ def _bases(layout):
205
+ rb, cb, rowbase, colbase = [], [], 0, 0
206
+ for off, nb, rl, _ in layout["t"]:
207
+ rb.append(rowbase); cb.append(colbase)
208
+ rowbase += nb // 2 // rl; colbase += rl
209
+ return rb, cb, rowbase, colbase
210
+
211
+ def _plan(self, layout, gi, grp, nrows_c, rmap_off):
212
+ """descriptors for one group: TB array (device offsets relative to the group buffer), segments"""
213
+ rb, cb, _, _ = self._bases(layout)
214
+ tb = np.zeros(len(grp), TB_DT); segs = []
215
+ a = layout["t"][grp[0]][0]
216
+ for k, i in enumerate(grp):
217
+ off, nb, rl, _ = layout["t"][i]
218
+ tb[k] = (off - a, rl, rb[i], cb[i], layout["role"][i] * TPT, rmap_off.get(i, -1), 0)
219
+ n = nrows_c[i] * rl
220
+ for i0 in range(0, n, SEG):
221
+ segs.append((k, min(SEG, n - i0), i0))
222
+ return tb, np.array(segs, SG_DT)
223
+
224
+ # ---------------------------------------------------------------- compression
225
+ def _stats(self, dev, rl):
226
+ """side info for one tensor in row chunks: rfi (rows), cfi, scl (cols)"""
227
+ u = dev.view(cp.uint16).reshape(-1, rl)
228
+ nr = u.shape[0]; step = max(1, (16 << 20) // rl)
229
+ rf = cp.empty(nr, cp.float64)
230
+ for r0 in range(0, nr, step):
231
+ w = (u[r0:r0 + step].astype(cp.uint32) << 16).view(cp.float32)
232
+ rf[r0:r0 + step] = cp.log2(cp.sqrt((w * w).mean(1, dtype=cp.float64)) + 1e-30)
233
+ rfa = cp.exp2(rf).astype(cp.float32)
234
+ s2 = cp.zeros(rl, cp.float64); s1 = cp.zeros(rl, cp.float64)
235
+ for r0 in range(0, nr, step):
236
+ w = (u[r0:r0 + step].astype(cp.uint32) << 16).view(cp.float32) / rfa[r0:r0 + step, None]
237
+ s2 += (w * w).sum(0, dtype=cp.float64); s1 += w.sum(0, dtype=cp.float64)
238
+ cf = cp.log2(cp.sqrt(s2 / nr) + 1e-30)
239
+ rfi = cp.clip(cp.rint(rf * K), -32768, 32767).astype(cp.int16)
240
+ cfi = cp.clip(cp.rint(cf * K), -32768, 32767).astype(cp.int16)
241
+ bias = (s1 / nr) / cp.exp2(cfi.astype(cp.float64) / K)
242
+ scl = cp.clip(cp.floor(bias * 16) + 8, 0, 15).astype(cp.int8)
243
+ return rfi, cfi, scl
244
+
245
+ def _dups(self, dev, rl, host):
246
+ """exact duplicate rows -> (keep rows (sorted), [(dup row, source row)])"""
247
+ u = dev.view(cp.uint16).reshape(-1, rl)
248
+ nr = u.shape[0]
249
+ h = cp.empty(nr, cp.uint64)
250
+ kern("row_hash")(((nr + 127) // 128,), (128,), (u, np.int32(nr), np.int32(rl), h))
251
+ h = h.get()
252
+ order = np.argsort(h, kind="stable")
253
+ hs = h[order]
254
+ same = np.flatnonzero(hs[1:] == hs[:-1])
255
+ if len(same) == 0:
256
+ return None, []
257
+ hu = host.reshape(-1, rl)
258
+ pairs, isdup = [], np.zeros(nr, bool)
259
+ first = {}
260
+ for k in np.unique(np.concatenate([same, same + 1])):
261
+ r = int(order[k]); key = int(hs[k])
262
+ cands = first.setdefault(key, [])
263
+ src = next((c for c in cands if np.array_equal(hu[c], hu[r])), None)
264
+ if src is None:
265
+ cands.append(r)
266
+ else:
267
+ pairs.append((r, src)); isdup[r] = True
268
+ if not pairs:
269
+ return None, []
270
+ return np.flatnonzero(~isdup).astype(np.int32), sorted(pairs)
271
+
272
+ def compress(self, data):
273
+ ev = Timer()
274
+ g = GGUF.from_bytes(data)
275
+ layout = self._layout(g, len(data))
276
+ hdr_job = ThreadPoolExecutor(1).submit(M24BF16GPU._header_c, data, g, layout)
277
+ host = np.frombuffer(data, np.uint8)
278
+ groups = self._groups(layout)
279
+ resident = sum(nb for _, nb, _, _ in layout["t"]) + 2 * self.group_bytes < self.budget
280
+ nt = len(layout["t"])
281
+ rfi_l, cfi_l, scl_l = [None] * nt, [None] * nt, [None] * nt
282
+ nrows_c, rowmaps, dup_pairs = {}, {}, {}
283
+ counts = cp.zeros((layout["nroles"] * TPT, 256), cp.uint32)
284
+ devs, plans = {}, {}
285
+ rmap_all = []
286
+ ev("parse")
287
+ # pass 1: statistics, duplicate rows, histograms
288
+ for gi, grp in enumerate(groups):
289
+ a, b = layout["t"][grp[0]][0], layout["t"][grp[-1]][0] + layout["t"][grp[-1]][1]
290
+ dev = cp.asarray(host[a:b])
291
+ rmap_off = {}
292
+ for i in grp:
293
+ off, nb, rl, _ = layout["t"][i]
294
+ d = dev[off - a:off - a + nb]
295
+ rfi_l[i], cfi_l[i], scl_l[i] = self._stats(d, rl)
296
+ keep, pairs = self._dups(d, rl, host[off:off + nb].view(np.uint16)) if self.dedup else (None, [])
297
+ nrows_c[i] = nb // 2 // rl if keep is None else len(keep)
298
+ if keep is not None:
299
+ rmap_off[i] = sum(len(x) for x in rmap_all); rmap_all.append(keep)
300
+ dup_pairs[i] = pairs
301
+ rowmaps[gi] = rmap_off
302
+ plans[gi] = self._plan(layout, gi, grp, nrows_c, rmap_off)
303
+ if gi == 0:
304
+ pass
305
+ devs[gi] = (dev, a) if resident else (None, a)
306
+ rfi = cp.concatenate(rfi_l); cfi = cp.concatenate(cfi_l); scl = cp.concatenate(scl_l)
307
+ rowmap = cp.asarray(np.concatenate(rmap_all)) if rmap_all else cp.zeros(1, cp.int32)
308
+ ev("statistics + dedup")
309
+ for gi, grp in enumerate(groups):
310
+ dev, a = devs[gi]
311
+ if dev is None:
312
+ b = layout["t"][grp[-1]][0] + layout["t"][grp[-1]][1]; dev = cp.asarray(host[a:b])
313
+ tb, sg = plans[gi]
314
+ kern("v2_hist")(((len(sg) + 63) // 64,), (64,),
315
+ (dev, cp.asarray(tb.view(np.uint8)), cp.asarray(sg.view(np.uint8)), np.int32(len(sg)),
316
+ rfi, cfi, scl, rowmap, counts))
317
+ ev("histogram")
318
+ self.last_counts = counts.get()
319
+ freq, used = normalize_gpu(counts, 1 << PB)
320
+ remap = cp.full(counts.shape[0], -1, cp.int32); remap[used] = cp.arange(len(used), dtype=cp.int32)
321
+ cum = cum_of(freq)
322
+ streams, lens_all = [], []
323
+ cap = SEG * 2 + 1024
324
+ for gi, grp in enumerate(groups):
325
+ dev, a = devs[gi]
326
+ if dev is None:
327
+ b = layout["t"][grp[-1]][0] + layout["t"][grp[-1]][1]; dev = cp.asarray(host[a:b])
328
+ tb, sg = plans[gi]
329
+ out = cp.empty(len(sg) * cap, cp.uint8); out_len = cp.zeros(len(sg), cp.uint32)
330
+ kern("v2_enc")(((len(sg) + 63) // 64,), (64,),
331
+ (dev, cp.asarray(tb.view(np.uint8)), cp.asarray(sg.view(np.uint8)), np.int32(len(sg)),
332
+ rfi, cfi, scl, rowmap, remap, freq, cum, out, np.uint64(cap), out_len))
333
+ lens = out_len.get()
334
+ if (lens == 0xffffffff).any():
335
+ raise RuntimeError("rANS segment overflow")
336
+ offs = cp.zeros(len(sg) + 1, cp.uint64); offs[1:] = cp.cumsum(out_len.astype(cp.uint64))
337
+ dst = cp.empty(int(offs[-1]), cp.uint8)
338
+ _g2.kern("gather")((len(sg),), (256,), (out, np.uint64(cap), out_len, offs, np.int32(len(sg)), dst))
339
+ streams.append(dst.get().tobytes()); lens_all.append(lens)
340
+ del out, dst
341
+ devs[gi] = None
342
+ ev("encode")
343
+ dups = [[i, r, s] for i, ps in dup_pairs.items() for r, s in ps]
344
+ meta = dict(layout=layout, dups=dups, nrows_c=[nrows_c[i] for i in range(nt)])
345
+ ch = {
346
+ "meta": zstd_c(json.dumps(meta).encode()),
347
+ "side": zstd_c(rfi.get().tobytes() + cfi.get().tobytes() + scl.get().tobytes(), 19),
348
+ "tables": store_tables(freq, used),
349
+ "lens": zstd_c(np.concatenate(lens_all).astype(np.uint32).tobytes()),
350
+ "stream": b"".join(streams),
351
+ "rest": hdr_job.result(),
352
+ }
353
+ ev("header")
354
+ self.timing["compress"] = ev.parts
355
+ return pack(ch)
356
+
357
+ # ---------------------------------------------------------------- decompression
358
+ def decompress(self, buf):
359
+ ev = Timer()
360
+ ch = unpack(buf)
361
+ meta = json.loads(zstd_d(ch["meta"]))
362
+ layout = meta["layout"]; nt = len(layout["t"])
363
+ hdr_job = ThreadPoolExecutor(1).submit(M24BF16GPU._header_d, ch["rest"])
364
+ _, _, nrow, ncol = self._bases(layout)
365
+ side = zstd_d(ch["side"])
366
+ rfi = cp.asarray(np.frombuffer(side, np.int16, nrow, 0))
367
+ cfi = cp.asarray(np.frombuffer(side, np.int16, ncol, 2 * nrow))
368
+ scl = cp.asarray(np.frombuffer(side, np.int8, ncol, 2 * nrow + 2 * ncol))
369
+ freq_h, used_h = load_tables(ch["tables"])
370
+ freq = cp.asarray(freq_h); cum = cum_of(freq)
371
+ lut = cp.empty((len(freq_h), 1 << PB), cp.uint8)
372
+ kern("build_lut")((len(freq_h),), (256,), (cum, np.int32(len(freq_h)), lut))
373
+ remap = cp.full(layout["nroles"] * TPT, -1, cp.int32); remap[cp.asarray(used_h)] = cp.arange(len(used_h), dtype=cp.int32)
374
+ lens = np.frombuffer(zstd_d(ch["lens"]), np.uint32)
375
+ nrows_c = {i: n for i, n in enumerate(meta["nrows_c"])}
376
+ dups = {}
377
+ for i, r, s in meta["dups"]:
378
+ dups.setdefault(i, []).append((r, s))
379
+ # row maps (same construction order as the encoder)
380
+ rmap_all, rmap_off_t = [], {}
381
+ for i in range(nt):
382
+ if i in dups:
383
+ rl = layout["t"][i][2]; nr = layout["t"][i][1] // 2 // rl
384
+ isdup = np.zeros(nr, bool); isdup[[r for r, _ in dups[i]]] = True
385
+ rmap_off_t[i] = sum(len(x) for x in rmap_all); rmap_all.append(np.flatnonzero(~isdup).astype(np.int32))
386
+ rowmap = cp.asarray(np.concatenate(rmap_all)) if rmap_all else cp.zeros(1, cp.int32)
387
+ out = np.empty(layout["size"], np.uint8)
388
+ stream_h = np.frombuffer(ch["stream"], np.uint8)
389
+ ev("unpack")
390
+ spos, lpos = 0, 0
391
+ for gi, grp in enumerate(self._groups(layout)):
392
+ rmap_off = {i: rmap_off_t[i] for i in grp if i in rmap_off_t}
393
+ tb, sg = self._plan(layout, gi, grp, nrows_c, rmap_off)
394
+ gl = lens[lpos:lpos + len(sg)]; lpos += len(sg)
395
+ nbytes = int(gl.sum(dtype=np.uint64))
396
+ offs = np.zeros(len(sg), np.uint64); offs[1:] = np.cumsum(gl.astype(np.uint64))[:-1]
397
+ a = layout["t"][grp[0]][0]; b = layout["t"][grp[-1]][0] + layout["t"][grp[-1]][1]
398
+ dev = cp.empty(b - a, cp.uint8)
399
+ kern("v2_dec")(((len(sg) + 63) // 64,), (64,),
400
+ (cp.asarray(stream_h[spos:spos + nbytes]), cp.asarray(offs), dev,
401
+ cp.asarray(tb.view(np.uint8)), cp.asarray(sg.view(np.uint8)), np.int32(len(sg)),
402
+ rfi, cfi, scl, rowmap, remap, freq, cum, lut))
403
+ spos += nbytes
404
+ for i in grp:
405
+ if i in dups:
406
+ off, nb, rl, _ = layout["t"][i]
407
+ u = dev[off - a:off - a + nb].view(cp.uint16).reshape(-1, rl)
408
+ d = np.array(dups[i], np.int64)
409
+ u[cp.asarray(d[:, 0])] = u[cp.asarray(d[:, 1])]
410
+ dev.get(out=out[a:b])
411
+ del dev
412
+ ev("decode + download")
413
+ rest = np.frombuffer(hdr_job.result(), np.uint8)
414
+ pos = rpos = 0
415
+ for off, nbytes, _, _ in layout["t"]:
416
+ gap = off - pos
417
+ out[pos:off] = rest[rpos:rpos + gap]; rpos += gap; pos = off + nbytes
418
+ out[pos:] = rest[rpos:]
419
+ ev("header")
420
+ self.timing["decompress"] = ev.parts
421
+ return out
seedpack/bundle.py ADDED
@@ -0,0 +1,36 @@
1
+ """Method 23: self-contained archive of a model *repository* (several files of one model).
2
+
3
+ The BF16 original is coded with M22; every quantised file of the same model is then coded
4
+ relative to the BF16 weights that are already inside the same archive (refcodec predictor:
5
+ re-quantise + context-coded correction). The receiver needs nothing but the archive.
6
+ """
7
+ import struct
8
+
9
+ from .codecs_gguf import pack, unpack
10
+ from .bf16codec import M22BF16
11
+ from .gguf_reader import GGUF
12
+ from .refcodec import RefCodec, sha
13
+
14
+
15
+ class _InArchiveRef(RefCodec):
16
+ def __init__(self, ref_bytes):
17
+ super().__init__([])
18
+ self._refs = [(GGUF.from_bytes(ref_bytes), sha(ref_bytes))]
19
+
20
+
21
+ class M23Bundle:
22
+ name = "M23 model-repo bundle: BF16 (M22) + quants coded against it"
23
+
24
+ def compress_files(self, base: bytes, others: list) -> bytes:
25
+ ch = {"base": M22BF16().compress(base)}
26
+ rc = _InArchiveRef(base)
27
+ for i, d in enumerate(others):
28
+ ch[f"q{i}"] = rc.compress(d)
29
+ return pack(ch)
30
+
31
+ def decompress_files(self, buf: bytes):
32
+ ch = unpack(buf)
33
+ base = M22BF16().decompress(ch["base"]).tobytes()
34
+ rc = _InArchiveRef(base)
35
+ others = [rc.decompress(ch[k]) for k in sorted(k for k in ch if k.startswith("q"))]
36
+ return base, others