Upload slimshard.py
Browse files- slimshard.py +306 -0
slimshard.py
CHANGED
|
@@ -941,6 +941,312 @@ def _run_generic_transformer_forward(
|
|
| 941 |
return outputs
|
| 942 |
|
| 943 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 944 |
def _synthesize_embed_tokens_checkfree(
|
| 945 |
f_handle,
|
| 946 |
present: set[str],
|
|
|
|
| 941 |
return outputs
|
| 942 |
|
| 943 |
|
| 944 |
+
_FP4_LUT_CPU = [0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 0.0, -0.5, -1.0, -1.5, -2.0, -3.0, -4.0, -6.0]
|
| 945 |
+
|
| 946 |
+
|
| 947 |
+
def _ds4_dequant_fp8_32x32(w_fp8: "torch.Tensor", s_u8: "torch.Tensor") -> "torch.Tensor":
|
| 948 |
+
out_d, in_d = w_fp8.shape
|
| 949 |
+
s = torch.exp2(s_u8.view(torch.uint8).float() - 127.0)
|
| 950 |
+
b0, b1 = s.shape
|
| 951 |
+
g0, g1 = out_d // b0, in_d // b1
|
| 952 |
+
return (w_fp8.float().view(b0, g0, b1, g1) * s[:, None, :, None]).reshape(out_d, in_d)
|
| 953 |
+
|
| 954 |
+
|
| 955 |
+
def _ds4_dequant_fp4_1x32(w_i8: "torch.Tensor", s_u8: "torch.Tensor", lut: "torch.Tensor") -> "torch.Tensor":
|
| 956 |
+
out_d, half_in = w_i8.shape
|
| 957 |
+
in_d = half_in * 2
|
| 958 |
+
u = w_i8.view(torch.uint8)
|
| 959 |
+
low = (u & 0x0F).long()
|
| 960 |
+
high = ((u >> 4) & 0x0F).long()
|
| 961 |
+
vals = torch.stack([lut[low], lut[high]], dim=-1).reshape(out_d, in_d // 32, 32)
|
| 962 |
+
s = torch.exp2(s_u8.view(torch.uint8).float() - 127.0).unsqueeze(-1)
|
| 963 |
+
return (vals * s).reshape(out_d, in_d)
|
| 964 |
+
|
| 965 |
+
|
| 966 |
+
def _ds4_hc_mixes(
|
| 967 |
+
x: "torch.Tensor",
|
| 968 |
+
hc_fn: "torch.Tensor",
|
| 969 |
+
hc_scale: "torch.Tensor",
|
| 970 |
+
hc_base: "torch.Tensor",
|
| 971 |
+
hc_mult: int = 4,
|
| 972 |
+
sinkhorn_iters: int = 20,
|
| 973 |
+
norm_eps: float = 1.0e-20,
|
| 974 |
+
hc_eps: float = 1.0e-6,
|
| 975 |
+
) -> tuple["torch.Tensor", "torch.Tensor", "torch.Tensor"]:
|
| 976 |
+
xf = x.flatten(2).float()
|
| 977 |
+
rsqrt = torch.rsqrt(xf.square().mean(-1, keepdim=True) + norm_eps)
|
| 978 |
+
mixes = F.linear(xf, hc_fn.float()) * rsqrt
|
| 979 |
+
s0, s1, s2 = hc_scale.float()[0], hc_scale.float()[1], hc_scale.float()[2]
|
| 980 |
+
b_f = hc_base.float()
|
| 981 |
+
pre = torch.sigmoid(mixes[..., :hc_mult] * s0 + b_f[:hc_mult]) + hc_eps
|
| 982 |
+
post = 2.0 * torch.sigmoid(mixes[..., hc_mult : 2 * hc_mult] * s1 + b_f[hc_mult : 2 * hc_mult])
|
| 983 |
+
comb = (mixes[..., 2 * hc_mult :] * s2 + b_f[2 * hc_mult :]).reshape(*mixes.shape[:-1], hc_mult, hc_mult)
|
| 984 |
+
comb = torch.softmax(comb, dim=-1) + hc_eps
|
| 985 |
+
comb = comb / (comb.sum(dim=-2, keepdim=True) + hc_eps)
|
| 986 |
+
for _ in range(sinkhorn_iters - 1):
|
| 987 |
+
comb = comb / (comb.sum(dim=-1, keepdim=True) + hc_eps)
|
| 988 |
+
comb = comb / (comb.sum(dim=-2, keepdim=True) + hc_eps)
|
| 989 |
+
return pre, post, comb
|
| 990 |
+
|
| 991 |
+
|
| 992 |
+
def _ds4_apply_rope(x: "torch.Tensor", freqs_cis: "torch.Tensor", inverse: bool = False) -> "torch.Tensor":
|
| 993 |
+
rd = freqs_cis.shape[-1] * 2
|
| 994 |
+
tail = x[..., -rd:].float().unflatten(-1, (-1, 2))
|
| 995 |
+
c = torch.view_as_complex(tail)
|
| 996 |
+
fc = freqs_cis.conj() if inverse else freqs_cis
|
| 997 |
+
if x.ndim == 3:
|
| 998 |
+
fc = fc.view(1, x.size(1), -1)
|
| 999 |
+
else:
|
| 1000 |
+
fc = fc.view(1, x.size(1), 1, -1)
|
| 1001 |
+
rot = torch.view_as_real(c * fc).flatten(-2).to(x.dtype)
|
| 1002 |
+
if rd == x.shape[-1]:
|
| 1003 |
+
return rot
|
| 1004 |
+
return torch.cat([x[..., :-rd], rot], dim=-1)
|
| 1005 |
+
|
| 1006 |
+
|
| 1007 |
+
def _run_deepseek_v41_forward(
|
| 1008 |
+
read_fn,
|
| 1009 |
+
has_key_fn,
|
| 1010 |
+
token_seqs: list[list[int]],
|
| 1011 |
+
coords: np.ndarray | None,
|
| 1012 |
+
basis_in: "torch.Tensor | None",
|
| 1013 |
+
scale_in: float,
|
| 1014 |
+
arch: dict,
|
| 1015 |
+
dev: "torch.device",
|
| 1016 |
+
) -> list["torch.Tensor"]:
|
| 1017 |
+
"""Execute DeepSeek-V4.1 causal forward pass (4-stream Sinkhorn HC + MLA + FP4/FP8 MoE)."""
|
| 1018 |
+
num_layers = int(arch.get("num_hidden_layers", 40))
|
| 1019 |
+
dim = int(arch.get("hidden_size", 5120))
|
| 1020 |
+
eps = float(arch.get("rms_norm_eps", 1.0e-20))
|
| 1021 |
+
hc_mult = int(arch.get("hc_mult", 4))
|
| 1022 |
+
hc_iters = int(arch.get("hc_sinkhorn_iters", 20))
|
| 1023 |
+
hc_eps = float(arch.get("hc_eps", 1.0e-6))
|
| 1024 |
+
n_heads = int(arch.get("num_attention_heads", 64))
|
| 1025 |
+
head_dim = int(arch.get("head_dim", 512))
|
| 1026 |
+
rope_dim = int(arch.get("qk_rope_head_dim", 64))
|
| 1027 |
+
o_groups = int(arch.get("o_groups", 8))
|
| 1028 |
+
o_lora_rank = int(arch.get("o_lora_rank", 1024))
|
| 1029 |
+
top_k = int(arch.get("num_experts_per_tok", arch.get("num_experts_per_token", 6)))
|
| 1030 |
+
route_scale = float(arch.get("routed_scaling_factor", 1.5))
|
| 1031 |
+
swiglu_limit = float(arch.get("swiglu_limit", 10.0))
|
| 1032 |
+
rope_theta = float(arch.get("rope_theta", 10000.0))
|
| 1033 |
+
softmax_scale = head_dim ** -0.5
|
| 1034 |
+
|
| 1035 |
+
lut = torch.tensor(_FP4_LUT_CPU, dtype=torch.float32, device=dev)
|
| 1036 |
+
max_t = max(len(s) for s in token_seqs)
|
| 1037 |
+
freqs = 1.0 / (rope_theta ** (torch.arange(0, rope_dim, 2, dtype=torch.float32, device=dev) / rope_dim))
|
| 1038 |
+
freqs_cis_all = torch.polar(torch.ones((max_t, rope_dim // 2), device=dev), torch.outer(torch.arange(max_t, device=dev, dtype=torch.float32), freqs))
|
| 1039 |
+
|
| 1040 |
+
streams = []
|
| 1041 |
+
pre_mixes = []
|
| 1042 |
+
if coords is not None and basis_in is not None:
|
| 1043 |
+
for seq in token_seqs:
|
| 1044 |
+
c_seq = torch.from_numpy(coords[seq]).to(dev, dtype=torch.float32)
|
| 1045 |
+
inp = (c_seq @ basis_in * scale_in).to(torch.bfloat16).unsqueeze(0)
|
| 1046 |
+
h0 = inp.unsqueeze(2).repeat(1, 1, hc_mult, 1)
|
| 1047 |
+
pm = torch.zeros(1, len(seq), hc_mult, dtype=torch.float32, device=dev)
|
| 1048 |
+
pm[:, :, 0] = 1.0
|
| 1049 |
+
streams.append(h0)
|
| 1050 |
+
pre_mixes.append(pm)
|
| 1051 |
+
else:
|
| 1052 |
+
emb_w = read_fn("embed.weight")
|
| 1053 |
+
for seq in token_seqs:
|
| 1054 |
+
ids_t = torch.tensor([seq], dtype=torch.long, device=dev)
|
| 1055 |
+
inp = F.embedding(ids_t, emb_w).to(torch.bfloat16)
|
| 1056 |
+
h0 = inp.unsqueeze(2).repeat(1, 1, hc_mult, 1)
|
| 1057 |
+
pm = torch.zeros(1, len(seq), hc_mult, dtype=torch.float32, device=dev)
|
| 1058 |
+
pm[:, :, 0] = 1.0
|
| 1059 |
+
streams.append(h0)
|
| 1060 |
+
pre_mixes.append(pm)
|
| 1061 |
+
del emb_w
|
| 1062 |
+
|
| 1063 |
+
# Cache layer weights if multiple layers are identical (e.g. single-shard anchor recovery)
|
| 1064 |
+
cached_layer_ signature = None
|
| 1065 |
+
cached_layer_data = None
|
| 1066 |
+
|
| 1067 |
+
for lidx in range(num_layers):
|
| 1068 |
+
lp = f"layers.{lidx}"
|
| 1069 |
+
if not has_key_fn(f"{lp}.attn_norm.weight"):
|
| 1070 |
+
lp = f"model.layers.{lidx}"
|
| 1071 |
+
w_anorm = read_fn(f"{lp}.attn_norm.weight")
|
| 1072 |
+
w_fnorm = read_fn(f"{lp}.ffn_norm.weight")
|
| 1073 |
+
hc_afn = read_fn(f"{lp}.hc_attn_fn")
|
| 1074 |
+
hc_asc = read_fn(f"{lp}.hc_attn_scale")
|
| 1075 |
+
hc_ab = read_fn(f"{lp}.hc_attn_base")
|
| 1076 |
+
hc_ffn = read_fn(f"{lp}.hc_ffn_fn")
|
| 1077 |
+
hc_fsc = read_fn(f"{lp}.hc_ffn_scale")
|
| 1078 |
+
hc_fb = read_fn(f"{lp}.hc_ffn_base")
|
| 1079 |
+
|
| 1080 |
+
sig = float(hc_ab.float().sum().item())
|
| 1081 |
+
if cached_layer_data is not None and cached_layer_signature == sig:
|
| 1082 |
+
wq_a, wq_b, wkv, wo_a, wo_b, q_norm_w, kv_norm_w, attn_sink, sw1, sw2, sw3, gw, gb = cached_layer_data
|
| 1083 |
+
else:
|
| 1084 |
+
wq_a = _ds4_dequant_fp8_32x32(read_fn(f"{lp}.attn.wq_a.weight"), read_fn(f"{lp}.attn.wq_a.scale")).to(torch.bfloat16)
|
| 1085 |
+
wq_b = _ds4_dequant_fp8_32x32(read_fn(f"{lp}.attn.wq_b.weight"), read_fn(f"{lp}.attn.wq_b.scale")).to(torch.bfloat16)
|
| 1086 |
+
wkv = _ds4_dequant_fp8_32x32(read_fn(f"{lp}.attn.wkv.weight"), read_fn(f"{lp}.attn.wkv.scale")).to(torch.bfloat16)
|
| 1087 |
+
wo_a = _ds4_dequant_fp8_32x32(read_fn(f"{lp}.attn.wo_a.weight"), read_fn(f"{lp}.attn.wo_a.scale")).to(torch.bfloat16)
|
| 1088 |
+
wo_b = _ds4_dequant_fp8_32x32(read_fn(f"{lp}.attn.wo_b.weight"), read_fn(f"{lp}.attn.wo_b.scale")).to(torch.bfloat16)
|
| 1089 |
+
q_norm_w = read_fn(f"{lp}.attn.q_norm.weight")
|
| 1090 |
+
kv_norm_w = read_fn(f"{lp}.attn.kv_norm.weight")
|
| 1091 |
+
attn_sink = read_fn(f"{lp}.attn.attn_sink").float()
|
| 1092 |
+
sw1 = _ds4_dequant_fp8_32x32(read_fn(f"{lp}.ffn.shared_experts.w1.weight"), read_fn(f"{lp}.ffn.shared_experts.w1.scale")).to(torch.bfloat16)
|
| 1093 |
+
sw2 = _ds4_dequant_fp8_32x32(read_fn(f"{lp}.ffn.shared_experts.w2.weight"), read_fn(f"{lp}.ffn.shared_experts.w2.scale")).to(torch.bfloat16)
|
| 1094 |
+
sw3 = _ds4_dequant_fp8_32x32(read_fn(f"{lp}.ffn.shared_experts.w3.weight"), read_fn(f"{lp}.ffn.shared_experts.w3.scale")).to(torch.bfloat16)
|
| 1095 |
+
gw = read_fn(f"{lp}.ffn.gate.weight").float()
|
| 1096 |
+
gb = read_fn(f"{lp}.ffn.gate.bias").float()
|
| 1097 |
+
cached_layer_signature = sig
|
| 1098 |
+
cached_layer_data = (wq_a, wq_b, wkv, wo_a, wo_b, q_norm_w, kv_norm_w, attn_sink, sw1, sw2, sw3, gw, gb)
|
| 1099 |
+
|
| 1100 |
+
n_routed_eff = gw.shape[0]
|
| 1101 |
+
top_k_eff = min(top_k, n_routed_eff)
|
| 1102 |
+
wo_a_grouped = wo_a.view(o_groups, o_lora_rank, -1)
|
| 1103 |
+
|
| 1104 |
+
in_ffn_list = []
|
| 1105 |
+
ffn_meta = []
|
| 1106 |
+
|
| 1107 |
+
for s_idx, h in enumerate(streams):
|
| 1108 |
+
B, T, _, _ = h.shape
|
| 1109 |
+
fc = freqs_cis_all[:T]
|
| 1110 |
+
residual = h
|
| 1111 |
+
attn_pre, attn_post, attn_comb = _ds4_hc_mixes(h, hc_afn, hc_asc, hc_ab, hc_mult, hc_iters, eps, hc_eps)
|
| 1112 |
+
x = torch.sum(pre_mixes[s_idx].unsqueeze(-1) * h.float(), dim=2).to(torch.bfloat16)
|
| 1113 |
+
x = _rms_norm_torch(x, w_anorm, eps)
|
| 1114 |
+
|
| 1115 |
+
qr = _rms_norm_torch(F.linear(x, wq_a), q_norm_w, eps)
|
| 1116 |
+
q = F.linear(qr, wq_b).view(B, T, n_heads, head_dim)
|
| 1117 |
+
q = _ds4_apply_rope(q, fc, inverse=False)
|
| 1118 |
+
kv = _rms_norm_torch(F.linear(x, wkv), kv_norm_w, eps)
|
| 1119 |
+
kv = _ds4_apply_rope(kv, fc, inverse=False)
|
| 1120 |
+
|
| 1121 |
+
# Causal attention with attn_sink
|
| 1122 |
+
scores = torch.einsum("bthd,bsd->bhts", q.float(), kv.float()) * softmax_scale
|
| 1123 |
+
if T > 1:
|
| 1124 |
+
causal_mask = torch.triu(torch.ones((T, T), dtype=torch.bool, device=dev), diagonal=1)
|
| 1125 |
+
scores = scores.masked_fill(causal_mask[None, None, :, :], -1.0e30)
|
| 1126 |
+
s_max = torch.maximum(scores.amax(dim=-1, keepdim=True), attn_sink.view(1, n_heads, 1, 1))
|
| 1127 |
+
exp_s = torch.exp(scores - s_max)
|
| 1128 |
+
denom = exp_s.sum(dim=-1, keepdim=True) + torch.exp(attn_sink.view(1, n_heads, 1, 1) - s_max)
|
| 1129 |
+
probs_a = (exp_s / denom).to(torch.bfloat16)
|
| 1130 |
+
o = torch.einsum("bhts,bsd->bthd", probs_a, kv)
|
| 1131 |
+
o = _ds4_apply_rope(o, fc, inverse=True)
|
| 1132 |
+
o_grp = o.reshape(B, T, o_groups, -1)
|
| 1133 |
+
o_proj = torch.einsum("bsgd,grd->bsgr", o_grp, wo_a_grouped).flatten(2)
|
| 1134 |
+
attn_out = F.linear(o_proj, wo_b)
|
| 1135 |
+
|
| 1136 |
+
h = (attn_post.unsqueeze(-1) * attn_out.float().unsqueeze(-2) + torch.sum(attn_comb.unsqueeze(-1) * residual.float().unsqueeze(-2), dim=2)).to(torch.bfloat16)
|
| 1137 |
+
residual2 = h
|
| 1138 |
+
ffn_pre, ffn_post, ffn_comb = _ds4_hc_mixes(h, hc_ffn, hc_fsc, hc_fb, hc_mult, hc_iters, eps, hc_eps)
|
| 1139 |
+
x_ffn = _rms_norm_torch(torch.sum(attn_pre.unsqueeze(-1) * h.float(), dim=2).to(torch.bfloat16), w_fnorm, eps)
|
| 1140 |
+
in_ffn_list.append(x_ffn.reshape(B * T, dim))
|
| 1141 |
+
ffn_meta.append((s_idx, B, T, residual2, ffn_pre, ffn_post, ffn_comb))
|
| 1142 |
+
|
| 1143 |
+
flat_all = torch.cat(in_ffn_list, dim=0)
|
| 1144 |
+
g_scores = F.softplus(F.linear(flat_all.float(), gw)).sqrt()
|
| 1145 |
+
_, top_idx = (g_scores + gb).topk(top_k_eff, dim=-1)
|
| 1146 |
+
top_w = g_scores.gather(1, top_idx)
|
| 1147 |
+
top_w = (top_w / (top_w.sum(dim=-1, keepdim=True) + 1.0e-20)) * route_scale
|
| 1148 |
+
|
| 1149 |
+
y_all = torch.zeros_like(flat_all, dtype=torch.float32)
|
| 1150 |
+
hit = torch.bincount(top_idx.flatten(), minlength=n_routed_eff)
|
| 1151 |
+
for eidx in hit.nonzero().flatten().tolist():
|
| 1152 |
+
erows, eslot = torch.where(top_idx == eidx)
|
| 1153 |
+
xe = flat_all.index_select(0, erows)
|
| 1154 |
+
ep = f"{lp}.ffn.experts.{eidx}"
|
| 1155 |
+
ew1 = _ds4_dequant_fp4_1x32(read_fn(f"{ep}.w1.weight"), read_fn(f"{ep}.w1.scale"), lut).to(torch.bfloat16)
|
| 1156 |
+
ew2 = _ds4_dequant_fp4_1x32(read_fn(f"{ep}.w2.weight"), read_fn(f"{ep}.w2.scale"), lut).to(torch.bfloat16)
|
| 1157 |
+
ew3 = _ds4_dequant_fp4_1x32(read_fn(f"{ep}.w3.weight"), read_fn(f"{ep}.w3.scale"), lut).to(torch.bfloat16)
|
| 1158 |
+
egate = F.linear(xe, ew1).float().clamp(max=swiglu_limit)
|
| 1159 |
+
eup = F.linear(xe, ew3).float().clamp(min=-swiglu_limit, max=swiglu_limit)
|
| 1160 |
+
eact = (F.silu(egate) * eup) * top_w[erows, eslot, None]
|
| 1161 |
+
y_all.index_add_(0, erows, F.linear(eact.to(torch.bfloat16), ew2).float())
|
| 1162 |
+
|
| 1163 |
+
sgate = F.linear(flat_all, sw1).float().clamp(max=swiglu_limit)
|
| 1164 |
+
sup = F.linear(flat_all, sw3).float().clamp(min=-swiglu_limit, max=swiglu_limit)
|
| 1165 |
+
y_all = y_all + F.linear((F.silu(sgate) * sup).to(torch.bfloat16), sw2).float()
|
| 1166 |
+
|
| 1167 |
+
off = 0
|
| 1168 |
+
for s_idx, B, T, residual2, ffn_pre, ffn_post, ffn_comb in ffn_meta:
|
| 1169 |
+
nt = B * T
|
| 1170 |
+
fout = y_all[off : off + nt].reshape(B, T, dim)
|
| 1171 |
+
off += nt
|
| 1172 |
+
h_next = (ffn_post.unsqueeze(-1) * fout.unsqueeze(-2) + torch.sum(ffn_comb.unsqueeze(-1) * residual2.float().unsqueeze(-2), dim=2)).to(torch.bfloat16)
|
| 1173 |
+
streams[s_idx] = h_next
|
| 1174 |
+
pre_mixes[s_idx] = ffn_pre
|
| 1175 |
+
|
| 1176 |
+
norm_key = next((k for k in ("norm.weight", "model.norm.weight") if has_key_fn(k)), None)
|
| 1177 |
+
w_final = read_fn(norm_key) if norm_key else torch.ones(dim, dtype=torch.bfloat16, device=dev)
|
| 1178 |
+
if w_final.numel() != dim:
|
| 1179 |
+
w_final = torch.ones(dim, dtype=torch.bfloat16, device=dev)
|
| 1180 |
+
outputs = []
|
| 1181 |
+
for s_idx, h in enumerate(streams):
|
| 1182 |
+
h_col = torch.sum(pre_mixes[s_idx].unsqueeze(-1) * h.float(), dim=2).to(torch.bfloat16)
|
| 1183 |
+
out_h = _rms_norm_torch(h_col, w_final, eps)
|
| 1184 |
+
outputs.append(out_h[0].float())
|
| 1185 |
+
return outputs
|
| 1186 |
+
|
| 1187 |
+
|
| 1188 |
+
def run_deepseek_v41_generate(
|
| 1189 |
+
safetensors_path: str | Path,
|
| 1190 |
+
config_path: str | Path,
|
| 1191 |
+
tokenizer_dir: str | Path,
|
| 1192 |
+
prompt: str = "hello",
|
| 1193 |
+
max_new_tokens: int = 16,
|
| 1194 |
+
use_chat_template: bool = False,
|
| 1195 |
+
device: str = "auto",
|
| 1196 |
+
) -> tuple[str, list[int]]:
|
| 1197 |
+
"""Run autoregressive greedy generation on a recovered DeepSeek-V4.1 safetensors model."""
|
| 1198 |
+
from transformers import AutoTokenizer
|
| 1199 |
+
|
| 1200 |
+
tok = AutoTokenizer.from_pretrained(str(tokenizer_dir), trust_remote_code=True, local_files_only=True)
|
| 1201 |
+
raw_cfg = json.loads(Path(config_path).read_text())
|
| 1202 |
+
arch = _normalize_arch_config(raw_cfg)
|
| 1203 |
+
dev = torch.device("cuda:0" if (device in ("auto", "cuda") and torch.cuda.is_available()) else "cpu")
|
| 1204 |
+
|
| 1205 |
+
if use_chat_template and getattr(tok, "chat_template", None):
|
| 1206 |
+
ids = tok.apply_chat_template(
|
| 1207 |
+
[{"role": "user", "content": prompt}],
|
| 1208 |
+
add_generation_prompt=True,
|
| 1209 |
+
tokenize=True,
|
| 1210 |
+
)
|
| 1211 |
+
if isinstance(ids, dict):
|
| 1212 |
+
ids = ids["input_ids"]
|
| 1213 |
+
else:
|
| 1214 |
+
ids = tok.encode(prompt, add_special_tokens=False)
|
| 1215 |
+
if not ids:
|
| 1216 |
+
ids = [0]
|
| 1217 |
+
|
| 1218 |
+
prompt_len = len(ids)
|
| 1219 |
+
cur_ids = list(ids)
|
| 1220 |
+
eos_id = tok.eos_token_id if tok.eos_token_id is not None else int(arch.get("eos_token_id", 1))
|
| 1221 |
+
im_end_id = tok.convert_tokens_to_ids("<|im_end|>") if "<|im_end|>" in tok.get_vocab() else -1
|
| 1222 |
+
|
| 1223 |
+
with safe_open(str(safetensors_path), framework="pt", device="cpu") as sf:
|
| 1224 |
+
keys_set = set(sf.keys())
|
| 1225 |
+
head_key = next((k for k in _HEAD_NAMES if k in keys_set), "head.weight")
|
| 1226 |
+
head_w = sf.get_tensor(head_key).to(dev, dtype=torch.bfloat16)
|
| 1227 |
+
|
| 1228 |
+
def read_fn(k: str) -> "torch.Tensor":
|
| 1229 |
+
return sf.get_tensor(k).to(dev, non_blocking=True)
|
| 1230 |
+
|
| 1231 |
+
def has_key_fn(k: str) -> bool:
|
| 1232 |
+
return k in keys_set
|
| 1233 |
+
|
| 1234 |
+
with torch.no_grad():
|
| 1235 |
+
for _ in range(max_new_tokens):
|
| 1236 |
+
h_outs = _run_deepseek_v41_forward(
|
| 1237 |
+
read_fn, has_key_fn, [cur_ids], None, None, 1.0, arch, dev
|
| 1238 |
+
)
|
| 1239 |
+
last_h = h_outs[0][-1].to(torch.bfloat16)
|
| 1240 |
+
logits = F.linear(last_h, head_w).float()
|
| 1241 |
+
next_id = int(torch.argmax(logits).item())
|
| 1242 |
+
cur_ids.append(next_id)
|
| 1243 |
+
if next_id in (eos_id, im_end_id):
|
| 1244 |
+
break
|
| 1245 |
+
|
| 1246 |
+
text = tok.decode(cur_ids[prompt_len:] if use_chat_template else cur_ids, skip_special_tokens=False)
|
| 1247 |
+
return text, cur_ids
|
| 1248 |
+
|
| 1249 |
+
|
| 1250 |
def _synthesize_embed_tokens_checkfree(
|
| 1251 |
f_handle,
|
| 1252 |
present: set[str],
|