Upload 3 files
Browse files- q3_k.py +13 -8
- q4_0.py +9 -10
- spectral.py +82 -0
q3_k.py
CHANGED
|
@@ -50,11 +50,11 @@ except ImportError: # pragma: no cover
|
|
| 50 |
|
| 51 |
from .anneal import thermal_refine_q3_k, thermal_refine_q3_k_cuda
|
| 52 |
from .config import HPCConfig
|
| 53 |
-
from .cuda_backend import cuda_is_available
|
| 54 |
from .factored import MULTS_D
|
| 55 |
from .fp16 import from_fp16_bits, nearest_int, to_fp16_bits
|
| 56 |
from .sieve import sieve_measure_chain, subblock_chain_edges
|
| 57 |
-
from .spectral import pin_dc_codes_uniform
|
| 58 |
from .viterbi import robust_temperature
|
| 59 |
|
| 60 |
QK3_K = 256
|
|
@@ -851,17 +851,22 @@ def _quantize_q3_k_hpc_cuda(
|
|
| 851 |
d16, sc, code = _fit_q3_k_blocks_cuda(X_f32, W_f32, sub_scales, dev, cfg)
|
| 852 |
|
| 853 |
# Zero-DC Pin (deterministic code-flip exchange within pin_budget):
|
|
|
|
| 854 |
if cfg.pin_dc:
|
| 855 |
-
|
| 856 |
-
|
| 857 |
-
|
| 858 |
-
|
| 859 |
-
|
|
|
|
|
|
|
| 860 |
Q3_CODE_MIN,
|
| 861 |
Q3_CODE_MAX,
|
| 862 |
budget_frac=float(cfg.pin_budget),
|
| 863 |
)
|
| 864 |
-
code =
|
|
|
|
|
|
|
| 865 |
|
| 866 |
hmask, qs = _pack_q3_k_codes(code)
|
| 867 |
scales = _pack_q3_k_scales(sc)
|
|
|
|
| 50 |
|
| 51 |
from .anneal import thermal_refine_q3_k, thermal_refine_q3_k_cuda
|
| 52 |
from .config import HPCConfig
|
| 53 |
+
from .cuda_backend import _from_fp16_bits_t, cuda_is_available
|
| 54 |
from .factored import MULTS_D
|
| 55 |
from .fp16 import from_fp16_bits, nearest_int, to_fp16_bits
|
| 56 |
from .sieve import sieve_measure_chain, subblock_chain_edges
|
| 57 |
+
from .spectral import pin_dc_codes_uniform, pin_dc_codes_uniform_cuda
|
| 58 |
from .viterbi import robust_temperature
|
| 59 |
|
| 60 |
QK3_K = 256
|
|
|
|
| 851 |
d16, sc, code = _fit_q3_k_blocks_cuda(X_f32, W_f32, sub_scales, dev, cfg)
|
| 852 |
|
| 853 |
# Zero-DC Pin (deterministic code-flip exchange within pin_budget):
|
| 854 |
+
# Runs fully on the GPU — d from the fp16 bits, unit-grid = sc repeated.
|
| 855 |
if cfg.pin_dc:
|
| 856 |
+
d_pin = _from_fp16_bits_t(torch.from_numpy(d16).to(dev))
|
| 857 |
+
sc_gpu = torch.from_numpy(sc.astype(np.float32)).to(dev)
|
| 858 |
+
codes_gpu, _ = pin_dc_codes_uniform_cuda(
|
| 859 |
+
torch.from_numpy(X_f32).to(dev),
|
| 860 |
+
d_pin,
|
| 861 |
+
torch.from_numpy(code.reshape(B, QK3_K).astype(np.int64)).to(dev),
|
| 862 |
+
sc_gpu.repeat_interleave(Q3_K_SUBBLOCK, dim=1),
|
| 863 |
Q3_CODE_MIN,
|
| 864 |
Q3_CODE_MAX,
|
| 865 |
budget_frac=float(cfg.pin_budget),
|
| 866 |
)
|
| 867 |
+
code = codes_gpu.cpu().numpy().reshape(
|
| 868 |
+
B, Q3_K_N_SUBBLOCKS, Q3_K_SUBBLOCK
|
| 869 |
+
).astype(np.int16)
|
| 870 |
|
| 871 |
hmask, qs = _pack_q3_k_codes(code)
|
| 872 |
scales = _pack_q3_k_scales(sc)
|
q4_0.py
CHANGED
|
@@ -41,7 +41,7 @@ from .cuda_backend import cuda_is_available
|
|
| 41 |
from .factored import CAND_TO_QUHIT, MULTS_D
|
| 42 |
from .fp16 import from_fp16_bits, nearest_int, to_fp16_bits
|
| 43 |
from .sieve import sieve_measure_chain, subblock_chain_edges
|
| 44 |
-
from .spectral import pin_dc_codes_uniform
|
| 45 |
from .viterbi import robust_temperature
|
| 46 |
|
| 47 |
QK4_0 = 32
|
|
@@ -416,19 +416,18 @@ def _quantize_q4_0_hpc_cuda(
|
|
| 416 |
|
| 417 |
# 5c. Zero-DC Pin (deterministic code-flip exchange within pin_budget):
|
| 418 |
# Unsigned codes u in [0, 15], zero-point 8 — pass (X + 8d) so the
|
| 419 |
-
# pin's model residual equals the true dequant error.
|
|
|
|
| 420 |
if cfg.pin_dc:
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
np.ones((X_np.shape[0], QK4_0)),
|
| 427 |
0,
|
| 428 |
15,
|
| 429 |
budget_frac=float(cfg.pin_budget),
|
| 430 |
-
)
|
| 431 |
-
best_q = torch.from_numpy(q_np).to(dev)
|
| 432 |
|
| 433 |
best_q_u8 = best_q.to(torch.uint8)
|
| 434 |
deq_fin = best_d[:, None] * (best_q_u8.to(torch.float32) - 8.0)
|
|
|
|
| 41 |
from .factored import CAND_TO_QUHIT, MULTS_D
|
| 42 |
from .fp16 import from_fp16_bits, nearest_int, to_fp16_bits
|
| 43 |
from .sieve import sieve_measure_chain, subblock_chain_edges
|
| 44 |
+
from .spectral import pin_dc_codes_uniform, pin_dc_codes_uniform_cuda
|
| 45 |
from .viterbi import robust_temperature
|
| 46 |
|
| 47 |
QK4_0 = 32
|
|
|
|
| 416 |
|
| 417 |
# 5c. Zero-DC Pin (deterministic code-flip exchange within pin_budget):
|
| 418 |
# Unsigned codes u in [0, 15], zero-point 8 — pass (X + 8d) so the
|
| 419 |
+
# pin's model residual equals the true dequant error. Runs fully on
|
| 420 |
+
# the GPU.
|
| 421 |
if cfg.pin_dc:
|
| 422 |
+
best_q, _ = pin_dc_codes_uniform_cuda(
|
| 423 |
+
X + 8.0 * best_d[:, None].float(),
|
| 424 |
+
best_d,
|
| 425 |
+
best_q.to(torch.int64),
|
| 426 |
+
torch.ones_like(X),
|
|
|
|
| 427 |
0,
|
| 428 |
15,
|
| 429 |
budget_frac=float(cfg.pin_budget),
|
| 430 |
+
)
|
|
|
|
| 431 |
|
| 432 |
best_q_u8 = best_q.to(torch.uint8)
|
| 433 |
deq_fin = best_d[:, None] * (best_q_u8.to(torch.float32) - 8.0)
|
spectral.py
CHANGED
|
@@ -315,3 +315,85 @@ def pin_dc_codes_uniform(
|
|
| 315 |
touched[bi] = True
|
| 316 |
|
| 317 |
return codes, int(np.sum(touched))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 315 |
touched[bi] = True
|
| 316 |
|
| 317 |
return codes, int(np.sum(touched))
|
| 318 |
+
|
| 319 |
+
|
| 320 |
+
def pin_dc_codes_uniform_cuda(
|
| 321 |
+
x: "torch.Tensor",
|
| 322 |
+
d: "torch.Tensor",
|
| 323 |
+
codes: "torch.Tensor",
|
| 324 |
+
unit: "torch.Tensor",
|
| 325 |
+
lo: int,
|
| 326 |
+
hi: int,
|
| 327 |
+
budget_frac: float = 0.05,
|
| 328 |
+
max_rounds: int = 96,
|
| 329 |
+
) -> tuple["torch.Tensor", int]:
|
| 330 |
+
"""GPU port of :func:`pin_dc_codes_uniform` (same greedy exchange).
|
| 331 |
+
|
| 332 |
+
``x``/``d``/``codes``/``unit`` all live on one CUDA device; ``codes`` is
|
| 333 |
+
int64 and is updated in place (returned tensor is the same object).
|
| 334 |
+
Float32 throughout — matches the CUDA pipeline's precision, and the
|
| 335 |
+
exchange is self-correcting (any round that slightly mis-ranks a flip
|
| 336 |
+
simply loses one candidate, the residual still never regresses SSE
|
| 337 |
+
beyond ``budget_frac`` of the block's starting SSE).
|
| 338 |
+
"""
|
| 339 |
+
import torch
|
| 340 |
+
|
| 341 |
+
if budget_frac <= 0.0 or codes.shape[0] == 0:
|
| 342 |
+
return codes, 0
|
| 343 |
+
X = x.float()
|
| 344 |
+
B, n = X.shape
|
| 345 |
+
dev = X.device
|
| 346 |
+
if codes.dtype != torch.int64:
|
| 347 |
+
codes = codes.to(torch.int64)
|
| 348 |
+
d = d.to(dev).float()
|
| 349 |
+
if unit.dim() == 1 and unit.numel() == n:
|
| 350 |
+
unit = unit[None, :]
|
| 351 |
+
unit = unit.to(dev).float()
|
| 352 |
+
if unit.shape[0] == 1 and B != 1:
|
| 353 |
+
unit = unit.expand(B, n)
|
| 354 |
+
|
| 355 |
+
d_col = d[:, None]
|
| 356 |
+
e = X - d_col * codes.float() * unit
|
| 357 |
+
dc = e.sum(dim=1)
|
| 358 |
+
sse0 = (e * e).sum(dim=1)
|
| 359 |
+
cap = sse0 * float(budget_frac)
|
| 360 |
+
spent = torch.zeros(B, device=dev)
|
| 361 |
+
rows = torch.arange(B, device=dev)
|
| 362 |
+
tol = d.abs() * 0.5
|
| 363 |
+
touched = 0
|
| 364 |
+
|
| 365 |
+
for _ in range(max_rounds):
|
| 366 |
+
want_cost = torch.full((B,), float("inf"), device=dev)
|
| 367 |
+
want_pos = torch.full((B,), -1, dtype=torch.int64, device=dev)
|
| 368 |
+
want_dir = torch.zeros(B, dtype=torch.int64, device=dev)
|
| 369 |
+
for direction in (1, -1):
|
| 370 |
+
sel = (codes < hi) if direction == 1 else (codes > lo)
|
| 371 |
+
de = sel.float() * (float(direction) * unit * -d_col)
|
| 372 |
+
dE = 2.0 * e * de + de * de
|
| 373 |
+
valid = sel & (dc[:, None] * de < 0.0)
|
| 374 |
+
ratio = torch.where(valid, dE.abs() / de.abs().clamp_min(1.0e-30), torch.inf)
|
| 375 |
+
pmin = ratio.argmin(dim=1)
|
| 376 |
+
rmin = ratio[rows, pmin]
|
| 377 |
+
cmin = dE[rows, pmin]
|
| 378 |
+
take = torch.isfinite(rmin) & (rmin < want_cost)
|
| 379 |
+
want_cost = torch.where(take, cmin, want_cost)
|
| 380 |
+
want_pos = torch.where(take, pmin, want_pos)
|
| 381 |
+
want_dir = torch.where(take, torch.full_like(want_dir, direction), want_dir)
|
| 382 |
+
want = (
|
| 383 |
+
(dc.abs() > tol)
|
| 384 |
+
& (want_pos >= 0)
|
| 385 |
+
& (spent + want_cost <= cap)
|
| 386 |
+
)
|
| 387 |
+
if not bool(want.any()):
|
| 388 |
+
break
|
| 389 |
+
bi = want.nonzero(as_tuple=False).squeeze(1)
|
| 390 |
+
pos = want_pos[bi]
|
| 391 |
+
dirv = want_dir[bi]
|
| 392 |
+
de = -d[bi] * dirv.float() * unit[bi, pos]
|
| 393 |
+
spent[bi] += 2.0 * e[bi, pos] * de + de * de
|
| 394 |
+
e[bi, pos] += de
|
| 395 |
+
codes[bi, pos] += dirv
|
| 396 |
+
dc[bi] += de
|
| 397 |
+
touched += int(bi.numel())
|
| 398 |
+
|
| 399 |
+
return codes, touched
|