Download offload/dspark/native/reference.py from ProprietaryLegal/dsv41-offload: direct link, hf CLI and curl.
- Browser
- Download file 6.86 kB
-
https://huggingface.co/ProprietaryLegal/dsv41-offload/resolve/main/offload/dspark/native/reference.py
- Command line
-
hf download hf://ProprietaryLegal/dsv41-offload/offload/dspark/native/reference.py
-
curl -L -o reference.py https://huggingface.co/ProprietaryLegal/dsv41-offload/resolve/main/offload/dspark/native/reference.py
6.86 kB
| """Reference ops with the OFFICIAL 1017 semantics (inference/model.py + kernel.py @ 1bae0e10), device-agnostic torch. | |
| These are the oracles for N1's loader / integration and for the KX kernels (NATIVE.md "Kernel contract"). They are | |
| written for clarity and exactness, not speed. Accumulation: ``acc="f64"`` sums exact products in float64 and rounds | |
| once (the real-number result rounded to the output dtype: the best any kernel can do); ``acc="blocked"`` is the | |
| official kernels' order: each 32-wide K block summed (float64, then fp32, standing in for the MMA's fp32 block sum), | |
| scaled, and accumulated in fp32 block by block (kernel.fp8_gemm / fp4_gemm C_local_accum). A correct kernel lands | |
| within fp32 summation-order noise of both; anything further is a bug. | |
| Rounding points the official model has and every native path must keep (NATIVE.md): | |
| * every FP8/FP4 linear quantizes its input with act_qdq (per 32, power-of-two scale, e4m3) and returns bf16; | |
| * Expert: gate = bf16(w1 x).float(), up = bf16(w3 x).float(); up clamped to [-10, 10], gate to <= 10; | |
| h = silu(gate) * up (fp32), h = route_w * h (fp32), bf16(h) -> act_qdq -> w2 -> bf16 per expert; | |
| * MoE: y = 0 (fp32); experts in ASCENDING expert id: y[rows] += bf16 expert output; y += bf16 shared output; | |
| out = bf16(y); | |
| * Gate: scores = fp32(x) @ fp32(W)^T (no TF32) -> sqrt(softplus); top-3 of (scores + bias) with the fp32 bias; | |
| weights = scores at those ids / (sum + 1e-20) * 1.5 (bias only selects). | |
| """ | |
| from __future__ import annotations | |
| import torch | |
| import torch.nn.functional as Fn | |
| from . import formats as F | |
| SWIGLU_LIMIT = 10.0 | |
| ROUTE_SCALE = 1.5 | |
| TOPK = 3 | |
| def _matmul_acc(a: torch.Tensor, w: torch.Tensor, sa: torch.Tensor | None, sw: torch.Tensor | None, acc: str | |
| ) -> torch.Tensor: | |
| """sum_k a[m,k] * w[n,k] with optional per-32 scales already folded (sa/sw None) or blocked (acc='blocked': | |
| a, w are CODES, sa [M, K/32], sw [N, K/32] the per-block scales). Returns fp32 [M, N].""" | |
| if acc == "f64": | |
| return (a.double() @ w.double().t()).float() | |
| if acc != "blocked": | |
| raise ValueError(acc) | |
| M, K = a.shape | |
| N = w.shape[0] | |
| nb = K // F.BLOCK | |
| ab = a.double().view(M, nb, F.BLOCK) | |
| wb = w.double().view(N, nb, F.BLOCK) | |
| out = torch.zeros(M, N, dtype=torch.float32, device=a.device) | |
| for b in range(nb): | |
| part = (ab[:, b] @ wb[:, b].t()).float() # exact block sum, rounded to fp32 | |
| if sa is not None: | |
| part = part * sa[:, b:b + 1] * sw[:, b].unsqueeze(0) # (C * sa) * sb, powers of two: exact | |
| out += part | |
| return out | |
| def linear_fp4(x: torch.Tensor, w_packed: torch.Tensor, w_scale: torch.Tensor, acc: str = "f64") -> torch.Tensor: | |
| """model.linear for a float4_e2m1fn_x2 weight: act_quant(x) then fp4_gemm; bf16 [M, N].""" | |
| shape = x.shape | |
| x2 = x.reshape(-1, shape[-1]) | |
| if acc == "blocked": | |
| q, s = F.act_quant(x2) | |
| codes = F._fp4_lut(x.device)[F.fp4_codes(w_packed).long()] | |
| y = _matmul_acc(q, codes, s, F.e8m0_to_f32(w_scale), acc) | |
| else: | |
| y = _matmul_acc(F.act_qdq(x2).float(), F.decode_fp4(w_packed, w_scale), None, None, acc) | |
| return y.to(torch.bfloat16).view(*shape[:-1], -1) | |
| def linear_fp8(x: torch.Tensor, w_u8: torch.Tensor, w_scale: torch.Tensor, acc: str = "f64", | |
| rows: tuple[int, int] | None = None, cols: tuple[int, int] | None = None) -> torch.Tensor: | |
| """model.linear for a float8_e4m3fn weight (32x32 E8M0 blocks): act_quant(x) then fp8_gemm; bf16 [M, N]. | |
| ``rows`` / ``cols``: the window of the full tensor ``w_u8`` holds (w_scale is always the full tensor's).""" | |
| shape = x.shape | |
| x2 = x.reshape(-1, shape[-1]) | |
| if acc == "blocked": | |
| q, s = F.act_quant(x2) | |
| r0 = rows[0] if rows else 0 | |
| c0 = cols[0] if cols else 0 | |
| N, K = w_u8.shape | |
| sw = F.e8m0_to_f32(w_scale)[r0 // 32:(r0 + N + 31) // 32, c0 // 32:(c0 + K + 31) // 32] | |
| sw = sw.repeat_interleave(32, 0)[:N] | |
| y = _matmul_acc(q, F.e4m3_codes_to_f32(w_u8), s, sw, acc) | |
| else: | |
| y = _matmul_acc(F.act_qdq(x2).float(), F.decode_fp8_block(w_u8, w_scale, rows, cols), None, None, acc) | |
| return y.to(torch.bfloat16).view(*shape[:-1], -1) | |
| def linear_bf16(x: torch.Tensor, w: torch.Tensor, acc: str = "f64") -> torch.Tensor: | |
| """F.linear(x, w) for bf16 x, w: fp32 accumulation, bf16 out.""" | |
| shape = x.shape | |
| y = _matmul_acc(x.reshape(-1, shape[-1]).float(), w.float(), None, None, "f64" if acc == "blocked" else acc) | |
| return y.to(torch.bfloat16).view(*shape[:-1], -1) | |
| def swiglu(g16: torch.Tensor, u16: torch.Tensor, route_w: torch.Tensor | None, limit: float = SWIGLU_LIMIT | |
| ) -> torch.Tensor: | |
| """Expert.forward between w1/w3 and w2: bf16 in (the linears' outputs), bf16 out (x.to(dtype)).""" | |
| gate = g16.float() | |
| up = u16.float() | |
| if limit > 0: | |
| up = torch.clamp(up, min=-limit, max=limit) | |
| gate = torch.clamp(gate, max=limit) | |
| h = Fn.silu(gate) * up | |
| if route_w is not None: | |
| h = route_w * h | |
| return h.to(torch.bfloat16) | |
| def expert(x: torch.Tensor, w1, s1, w3, s3, w2, s2, route_w: torch.Tensor | None, fmt: str = "fp4", | |
| acc: str = "f64") -> torch.Tensor: | |
| """One official Expert on rows x (bf16 [M, 5120]); route_w fp32 [M, 1] or None (shared expert). bf16 out.""" | |
| lin = linear_fp4 if fmt == "fp4" else linear_fp8 | |
| h = swiglu(lin(x, w1, s1, acc), lin(x, w3, s3, acc), route_w) | |
| return lin(h, w2, s2, acc) | |
| def gate(x: torch.Tensor, gate_w: torch.Tensor, bias: torch.Tensor, topk: int = TOPK, | |
| route_scale: float = ROUTE_SCALE) -> tuple[torch.Tensor, torch.Tensor]: | |
| """Gate.forward (text tokens): (weights fp32 [T, k], indices int64 [T, k]).""" | |
| scores = (x.float().double() @ gate_w.float().double().t()).float() # F.linear fp32, no TF32 | |
| scores = Fn.softplus(scores).sqrt() | |
| idx = (scores + bias.float()).topk(topk, dim=-1)[1] | |
| w = scores.gather(1, idx) | |
| if topk > 1: | |
| w = w / (w.sum(dim=-1, keepdim=True) + 1e-20) | |
| return w * route_scale, idx | |
| def moe(x: torch.Tensor, gate_w: torch.Tensor, bias: torch.Tensor, get_expert, shared: tuple, acc: str = "f64" | |
| ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]: | |
| """MoE.forward, world_size 1. get_expert(e) -> (w1, s1, w3, s3, w2, s2) packed FP4; shared = the FP8 shared | |
| expert's (w1, s1, w3, s3, w2, s2). Returns (bf16 out [T, 5120], weights, indices).""" | |
| w, idx = gate(x, gate_w, bias) | |
| y = torch.zeros(x.shape, dtype=torch.float32, device=x.device) | |
| for e in sorted(set(idx.flatten().tolist())): | |
| rows, slot = torch.where(idx == e) | |
| y[rows] += expert(x[rows], *get_expert(e), w[rows, slot, None], "fp4", acc).float() | |
| y += expert(x, *shared, None, "fp8", acc).float() | |
| return y.to(x.dtype), w, idx | |