DS tweaks
Browse files- slimshard.py +162 -164
slimshard.py
CHANGED
|
@@ -3051,40 +3051,10 @@ def export_safetensors_to_gguf(
|
|
| 3051 |
gname = f"blk.{lidx}.{mapped_proj}"
|
| 3052 |
work_items.append(("experts", (lidx, proj), members, gname))
|
| 3053 |
|
| 3054 |
-
#
|
| 3055 |
-
|
| 3056 |
-
|
| 3057 |
-
|
| 3058 |
-
payload_cache: dict[tuple, tuple[int, tuple[int, ...], int, int]] = {}
|
| 3059 |
-
stats = {"tensors": 0, "q2_k": 0, "q4_0": 0, "bf16": 0, "f32": 0}
|
| 3060 |
-
|
| 3061 |
-
if is_dsv4:
|
| 3062 |
-
last_l = max(int(arch.get("num_hidden_layers", 40)) - 1, 0)
|
| 3063 |
-
fn_k = f"layers.{last_l}.hc_ffn_fn"
|
| 3064 |
-
bs_k = f"layers.{last_l}.hc_ffn_base"
|
| 3065 |
-
sc_k = f"layers.{last_l}.hc_ffn_scale"
|
| 3066 |
-
if fn_k in keys_set and bs_k in keys_set and sc_k in keys_set:
|
| 3067 |
-
fn_t = f.get_tensor(fn_k).float()[:hc_mult].contiguous()
|
| 3068 |
-
bs_t = f.get_tensor(bs_k).float()[:hc_mult].contiguous()
|
| 3069 |
-
sc_t = f.get_tensor(sc_k).float()[:1].contiguous()
|
| 3070 |
-
for g_hc_name, hc_t in (
|
| 3071 |
-
("output_hc_fn.weight", fn_t),
|
| 3072 |
-
("output_hc_base.weight", bs_t),
|
| 3073 |
-
("output_hc_scale.weight", sc_t),
|
| 3074 |
-
):
|
| 3075 |
-
pad = _gguf_align(data_offset) - data_offset
|
| 3076 |
-
if pad > 0:
|
| 3077 |
-
tmp_data.write(b"\x00" * pad)
|
| 3078 |
-
data_offset += pad
|
| 3079 |
-
raw_hc = hc_t.cpu().numpy().astype("<f4").tobytes()
|
| 3080 |
-
gguf_tensors.append((g_hc_name, tuple(reversed(hc_t.shape)), _GGML_F32, data_offset))
|
| 3081 |
-
tmp_data.write(raw_hc)
|
| 3082 |
-
data_offset += len(raw_hc)
|
| 3083 |
-
stats["tensors"] += 1
|
| 3084 |
-
stats["f32"] += 1
|
| 3085 |
-
tmp_data.flush()
|
| 3086 |
-
|
| 3087 |
-
total_items = len(work_items)
|
| 3088 |
|
| 3089 |
def _dequant_single_to_f32_torch(w_key: str, s_key: str | None) -> "torch.Tensor":
|
| 3090 |
wt = f.get_tensor(w_key).to(dev)
|
|
@@ -3113,7 +3083,6 @@ def export_safetensors_to_gguf(
|
|
| 3113 |
if not is_emb and row_w % QK_K == 0 and n_el % QK_K == 0:
|
| 3114 |
return "Q2_K"
|
| 3115 |
return "BF16"
|
| 3116 |
-
# mixed
|
| 3117 |
if is_emb:
|
| 3118 |
return "Q4_0" if (row_w % QK4_0 == 0 and n_el % QK4_0 == 0) else "BF16"
|
| 3119 |
if row_w % QK_K == 0 and n_el % QK_K == 0:
|
|
@@ -3122,6 +3091,18 @@ def export_safetensors_to_gguf(
|
|
| 3122 |
return "Q4_0"
|
| 3123 |
return "BF16"
|
| 3124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3125 |
def _encode_tensor_f32(t_f32: "torch.Tensor", tgt: str) -> tuple[int, bytes]:
|
| 3126 |
row_w = int(t_f32.shape[-1])
|
| 3127 |
if tgt == "F32":
|
|
@@ -3145,157 +3126,174 @@ def export_safetensors_to_gguf(
|
|
| 3145 |
return _GGML_Q2_K, blocks_to_bytes(res.scales, res.qs, res.dm)
|
| 3146 |
raise ValueError(tgt)
|
| 3147 |
|
| 3148 |
-
|
| 3149 |
-
|
| 3150 |
-
|
| 3151 |
-
|
| 3152 |
-
raise InterruptedError("GGUF export cancelled by user.")
|
| 3153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3154 |
kind = item[0]
|
|
|
|
| 3155 |
if kind == "single":
|
| 3156 |
_, w_key, s_key, gname = item
|
| 3157 |
-
|
| 3158 |
-
t_shape = tuple(sl.get_shape())
|
| 3159 |
if is_dsv4 and gname.endswith(".attn_output_a.weight") and len(t_shape) == 2 and t_shape[0] == o_groups * o_lora_rank:
|
| 3160 |
t_shape = (o_groups, o_lora_rank, t_shape[1])
|
| 3161 |
g_dims = tuple(reversed(t_shape)) if t_shape else (1,)
|
| 3162 |
tgt = _choose_gguf_target(gname, t_shape or (1,))
|
| 3163 |
-
|
| 3164 |
-
|
| 3165 |
-
|
| 3166 |
-
|
| 3167 |
-
if lm:
|
| 3168 |
-
suf = lm.group(3)
|
| 3169 |
-
w_Sample = _payload_bytes(f.get_tensor(w_key).flatten()[:256])
|
| 3170 |
-
cache_key = ("single", suf, t_shape, tgt, w_Sample)
|
| 3171 |
-
if cache_key is not None and cache_key in payload_cache:
|
| 3172 |
-
out_type, g_dims, src_off, src_len = payload_cache[cache_key]
|
| 3173 |
-
raw_bytes = os.pread(tmp_data.fileno(), src_len, src_off)
|
| 3174 |
-
elif len(t_shape) == 2 and t_shape[0] > 4096 and s_key is None and tgt in ("BF16", "Q4_0"):
|
| 3175 |
-
# Stream large embedding/head matrices in 4096-row chunks to keep memory < 100 MB
|
| 3176 |
-
pad = _gguf_align(data_offset) - data_offset
|
| 3177 |
-
if pad > 0:
|
| 3178 |
-
tmp_data.write(b"\x00" * pad)
|
| 3179 |
-
data_offset += pad
|
| 3180 |
-
cur_off = data_offset
|
| 3181 |
-
written_len = 0
|
| 3182 |
-
out_type = _GGML_BF16 if tgt == "BF16" else _GGML_Q4_0
|
| 3183 |
-
for r0 in range(0, t_shape[0], 4096):
|
| 3184 |
-
r1 = min(r0 + 4096, t_shape[0])
|
| 3185 |
-
sub_t = sl[r0:r1].to(dev)
|
| 3186 |
-
if tgt == "BF16":
|
| 3187 |
-
b_part = sub_t.to(torch.bfloat16).view(torch.uint16).cpu().numpy().astype("<u2").tobytes()
|
| 3188 |
-
else:
|
| 3189 |
-
sub_np = sub_t.float().cpu().numpy().astype(np.float32)
|
| 3190 |
-
b_part, _, _ = quantize_tensor_q4_0(sub_np, cfg=hpc_cfg)
|
| 3191 |
-
tmp_data.write(b_part)
|
| 3192 |
-
written_len += len(b_part)
|
| 3193 |
-
del sub_t
|
| 3194 |
-
tmp_data.flush()
|
| 3195 |
-
data_offset += written_len
|
| 3196 |
-
gguf_tensors.append((gname, g_dims, out_type, cur_off))
|
| 3197 |
-
stats["tensors"] += 1
|
| 3198 |
-
stats["bf16" if out_type == _GGML_BF16 else "q4_0"] += 1
|
| 3199 |
-
if progress_cb is not None:
|
| 3200 |
-
progress_cb(idx_w, total_items, gname, tgt, stats)
|
| 3201 |
-
continue
|
| 3202 |
-
else:
|
| 3203 |
-
t_f32 = _dequant_single_to_f32_torch(w_key, s_key)
|
| 3204 |
-
if not t_shape:
|
| 3205 |
-
t_f32 = t_f32.reshape(1)
|
| 3206 |
-
out_type, raw_bytes = _encode_tensor_f32(t_f32, tgt)
|
| 3207 |
-
del t_f32
|
| 3208 |
else:
|
| 3209 |
_, (lidx, proj), members, gname = item
|
| 3210 |
first_w = members[0][1]
|
| 3211 |
e_shape = tuple(f.get_slice(first_w).get_shape())
|
| 3212 |
-
# If packed FP4 I8, logical in_dim is 2 * stored in_dim
|
| 3213 |
dt_e = _safetensors_dtype(f.get_slice(first_w).get_dtype())
|
| 3214 |
if dt_e == "I8" and members[0][2] is not None:
|
| 3215 |
e_shape = (e_shape[0], e_shape[1] * 2)
|
| 3216 |
full_shape = (len(members), e_shape[0], e_shape[1])
|
| 3217 |
g_dims = (e_shape[1], e_shape[0], len(members))
|
| 3218 |
tgt = _choose_gguf_target(gname, full_shape)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3219 |
|
| 3220 |
-
|
| 3221 |
-
|
| 3222 |
-
|
| 3223 |
-
|
| 3224 |
-
|
|
|
|
|
|
|
| 3225 |
else:
|
| 3226 |
-
|
| 3227 |
-
for _, wk, sk in members:
|
| 3228 |
-
ef32 = _dequant_single_to_f32_torch(wk, sk)
|
| 3229 |
-
_, eb = _encode_tensor_f32(ef32, tgt)
|
| 3230 |
-
chunks.append(eb)
|
| 3231 |
-
del ef32
|
| 3232 |
-
raw_bytes = b"".join(chunks)
|
| 3233 |
-
out_type = (
|
| 3234 |
-
_GGML_Q2_K
|
| 3235 |
-
if tgt == "Q2_K"
|
| 3236 |
-
else (_GGML_Q4_0 if tgt == "Q4_0" else (_GGML_BF16 if tgt == "BF16" else _GGML_F32))
|
| 3237 |
-
)
|
| 3238 |
|
| 3239 |
-
|
| 3240 |
-
|
| 3241 |
-
tmp_data.write(b"\x00" * pad)
|
| 3242 |
-
data_offset += pad
|
| 3243 |
-
cur_off = data_offset
|
| 3244 |
-
tmp_data.write(raw_bytes)
|
| 3245 |
-
tmp_data.flush()
|
| 3246 |
-
data_offset += len(raw_bytes)
|
| 3247 |
-
|
| 3248 |
-
if cache_key is not None and cache_key not in payload_cache:
|
| 3249 |
-
payload_cache[cache_key] = (out_type, g_dims, cur_off, len(raw_bytes))
|
| 3250 |
-
|
| 3251 |
-
gguf_tensors.append((gname, g_dims, out_type, cur_off))
|
| 3252 |
-
stats["tensors"] += 1
|
| 3253 |
-
if out_type == _GGML_Q2_K:
|
| 3254 |
-
stats["q2_k"] += 1
|
| 3255 |
-
elif out_type == _GGML_Q4_0:
|
| 3256 |
-
stats["q4_0"] += 1
|
| 3257 |
-
elif out_type == _GGML_BF16:
|
| 3258 |
-
stats["bf16"] += 1
|
| 3259 |
-
else:
|
| 3260 |
-
stats["f32"] += 1
|
| 3261 |
-
|
| 3262 |
-
if progress_cb is not None and (idx_w % 8 == 0 or idx_w == total_items):
|
| 3263 |
-
progress_cb(idx_w, total_items, gname, tgt, stats)
|
| 3264 |
-
|
| 3265 |
-
# Update effective expert count in arch metadata if stacked experts were pruned
|
| 3266 |
-
if expert_groups:
|
| 3267 |
-
first_group = next(iter(expert_groups.values()))
|
| 3268 |
-
arch["num_experts"] = len(first_group)
|
| 3269 |
-
|
| 3270 |
-
kv_pairs = _build_gguf_kv_pairs(
|
| 3271 |
-
arch,
|
| 3272 |
-
tok_path if tok_path.exists() else None,
|
| 3273 |
-
chat_path if chat_path.exists() else None,
|
| 3274 |
-
quant_format,
|
| 3275 |
-
st_path.stem,
|
| 3276 |
-
)
|
| 3277 |
|
| 3278 |
-
with out_path.open("wb") as fout:
|
| 3279 |
-
fout.write(struct.pack("<IIQQ", _GGUF_MAGIC, 3, len(gguf_tensors), len(kv_pairs)))
|
| 3280 |
-
for k, vt, raw_v in kv_pairs:
|
| 3281 |
-
fout.write(_pack_gguf_str(k))
|
| 3282 |
-
fout.write(struct.pack("<I", vt))
|
| 3283 |
-
fout.write(raw_v)
|
| 3284 |
-
for gname, g_dims, out_type, off in gguf_tensors:
|
| 3285 |
-
fout.write(_pack_gguf_str(gname))
|
| 3286 |
-
fout.write(struct.pack("<I", len(g_dims)))
|
| 3287 |
-
for d in g_dims:
|
| 3288 |
-
fout.write(struct.pack("<Q", int(d)))
|
| 3289 |
-
fout.write(struct.pack("<I", int(out_type)))
|
| 3290 |
-
fout.write(struct.pack("<Q", int(off)))
|
| 3291 |
-
data_start = _gguf_align(fout.tell())
|
| 3292 |
-
if data_start > fout.tell():
|
| 3293 |
-
fout.write(b"\x00" * (data_start - fout.tell()))
|
| 3294 |
-
tmp_data.seek(0)
|
| 3295 |
-
shutil.copyfileobj(tmp_data, fout, length=16 * 1024 * 1024)
|
| 3296 |
-
|
| 3297 |
-
tmp_data.close()
|
| 3298 |
-
os.unlink(tmp_data.name)
|
| 3299 |
stats["output_bytes"] = out_path.stat().st_size
|
| 3300 |
if verbose:
|
| 3301 |
print(
|
|
|
|
| 3051 |
gname = f"blk.{lidx}.{mapped_proj}"
|
| 3052 |
work_items.append(("experts", (lidx, proj), members, gname))
|
| 3053 |
|
| 3054 |
+
# Update effective expert count in arch metadata if stacked experts were pruned
|
| 3055 |
+
if expert_groups:
|
| 3056 |
+
first_group = next(iter(expert_groups.values()))
|
| 3057 |
+
arch["num_experts"] = len(first_group)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3058 |
|
| 3059 |
def _dequant_single_to_f32_torch(w_key: str, s_key: str | None) -> "torch.Tensor":
|
| 3060 |
wt = f.get_tensor(w_key).to(dev)
|
|
|
|
| 3083 |
if not is_emb and row_w % QK_K == 0 and n_el % QK_K == 0:
|
| 3084 |
return "Q2_K"
|
| 3085 |
return "BF16"
|
|
|
|
| 3086 |
if is_emb:
|
| 3087 |
return "Q4_0" if (row_w % QK4_0 == 0 and n_el % QK4_0 == 0) else "BF16"
|
| 3088 |
if row_w % QK_K == 0 and n_el % QK_K == 0:
|
|
|
|
| 3091 |
return "Q4_0"
|
| 3092 |
return "BF16"
|
| 3093 |
|
| 3094 |
+
def _target_type_and_bytes(tgt: str, torch_shape: tuple[int, ...]) -> tuple[int, int]:
|
| 3095 |
+
n_el = int(np.prod(torch_shape)) if torch_shape else 1
|
| 3096 |
+
if tgt == "F32":
|
| 3097 |
+
return _GGML_F32, n_el * 4
|
| 3098 |
+
if tgt == "BF16":
|
| 3099 |
+
return _GGML_BF16, n_el * 2
|
| 3100 |
+
if tgt == "Q4_0":
|
| 3101 |
+
return _GGML_Q4_0, (n_el // QK4_0) * Q4_0_BLOCK_BYTES
|
| 3102 |
+
if tgt == "Q2_K":
|
| 3103 |
+
return _GGML_Q2_K, (n_el // QK_K) * 84
|
| 3104 |
+
raise ValueError(tgt)
|
| 3105 |
+
|
| 3106 |
def _encode_tensor_f32(t_f32: "torch.Tensor", tgt: str) -> tuple[int, bytes]:
|
| 3107 |
row_w = int(t_f32.shape[-1])
|
| 3108 |
if tgt == "F32":
|
|
|
|
| 3126 |
return _GGML_Q2_K, blocks_to_bytes(res.scales, res.qs, res.dm)
|
| 3127 |
raise ValueError(tgt)
|
| 3128 |
|
| 3129 |
+
# Precompute exact GGUF tensor directory and offsets in O(1) so we write in a single pass
|
| 3130 |
+
gguf_tensors: list[tuple[str, tuple[int, ...], int, int]] = []
|
| 3131 |
+
planned_exec: list[tuple] = []
|
| 3132 |
+
data_offset = 0
|
|
|
|
| 3133 |
|
| 3134 |
+
if is_dsv4:
|
| 3135 |
+
last_l = max(int(arch.get("num_hidden_layers", 40)) - 1, 0)
|
| 3136 |
+
fn_k = f"layers.{last_l}.hc_ffn_fn"
|
| 3137 |
+
bs_k = f"layers.{last_l}.hc_ffn_base"
|
| 3138 |
+
sc_k = f"layers.{last_l}.hc_ffn_scale"
|
| 3139 |
+
if fn_k in keys_set and bs_k in keys_set and sc_k in keys_set:
|
| 3140 |
+
fn_t = f.get_tensor(fn_k).float()[:hc_mult].contiguous()
|
| 3141 |
+
bs_t = f.get_tensor(bs_k).float()[:hc_mult].contiguous()
|
| 3142 |
+
sc_t = f.get_tensor(sc_k).float()[:1].contiguous()
|
| 3143 |
+
for g_hc_name, hc_t in (
|
| 3144 |
+
("output_hc_fn.weight", fn_t),
|
| 3145 |
+
("output_hc_base.weight", bs_t),
|
| 3146 |
+
("output_hc_scale.weight", sc_t),
|
| 3147 |
+
):
|
| 3148 |
+
data_offset = _gguf_align(data_offset)
|
| 3149 |
+
raw_hc = hc_t.cpu().numpy().astype("<f4").tobytes()
|
| 3150 |
+
g_dims = tuple(reversed(hc_t.shape))
|
| 3151 |
+
gguf_tensors.append((g_hc_name, g_dims, _GGML_F32, data_offset))
|
| 3152 |
+
planned_exec.append(("raw_bytes", g_hc_name, _GGML_F32, data_offset, raw_hc))
|
| 3153 |
+
data_offset += len(raw_hc)
|
| 3154 |
+
|
| 3155 |
+
for item in work_items:
|
| 3156 |
kind = item[0]
|
| 3157 |
+
data_offset = _gguf_align(data_offset)
|
| 3158 |
if kind == "single":
|
| 3159 |
_, w_key, s_key, gname = item
|
| 3160 |
+
t_shape = tuple(f.get_slice(w_key).get_shape())
|
|
|
|
| 3161 |
if is_dsv4 and gname.endswith(".attn_output_a.weight") and len(t_shape) == 2 and t_shape[0] == o_groups * o_lora_rank:
|
| 3162 |
t_shape = (o_groups, o_lora_rank, t_shape[1])
|
| 3163 |
g_dims = tuple(reversed(t_shape)) if t_shape else (1,)
|
| 3164 |
tgt = _choose_gguf_target(gname, t_shape or (1,))
|
| 3165 |
+
out_type, out_sz = _target_type_and_bytes(tgt, t_shape or (1,))
|
| 3166 |
+
gguf_tensors.append((gname, g_dims, out_type, data_offset))
|
| 3167 |
+
planned_exec.append(("single", w_key, s_key, gname, t_shape, g_dims, tgt, out_type, out_sz, data_offset))
|
| 3168 |
+
data_offset += out_sz
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3169 |
else:
|
| 3170 |
_, (lidx, proj), members, gname = item
|
| 3171 |
first_w = members[0][1]
|
| 3172 |
e_shape = tuple(f.get_slice(first_w).get_shape())
|
|
|
|
| 3173 |
dt_e = _safetensors_dtype(f.get_slice(first_w).get_dtype())
|
| 3174 |
if dt_e == "I8" and members[0][2] is not None:
|
| 3175 |
e_shape = (e_shape[0], e_shape[1] * 2)
|
| 3176 |
full_shape = (len(members), e_shape[0], e_shape[1])
|
| 3177 |
g_dims = (e_shape[1], e_shape[0], len(members))
|
| 3178 |
tgt = _choose_gguf_target(gname, full_shape)
|
| 3179 |
+
out_type, out_sz = _target_type_and_bytes(tgt, full_shape)
|
| 3180 |
+
gguf_tensors.append((gname, g_dims, out_type, data_offset))
|
| 3181 |
+
planned_exec.append(("experts", (lidx, proj), members, gname, full_shape, g_dims, tgt, out_type, out_sz, data_offset))
|
| 3182 |
+
data_offset += out_sz
|
| 3183 |
+
|
| 3184 |
+
kv_pairs = _build_gguf_kv_pairs(
|
| 3185 |
+
arch,
|
| 3186 |
+
tok_path if tok_path.exists() else None,
|
| 3187 |
+
chat_path if chat_path.exists() else None,
|
| 3188 |
+
quant_format,
|
| 3189 |
+
st_path.stem,
|
| 3190 |
+
)
|
| 3191 |
+
|
| 3192 |
+
payload_cache: dict[tuple, bytes] = {}
|
| 3193 |
+
stats = {"tensors": 0, "q2_k": 0, "q4_0": 0, "bf16": 0, "f32": 0}
|
| 3194 |
+
total_items = len(planned_exec)
|
| 3195 |
+
|
| 3196 |
+
with out_path.open("wb") as fout:
|
| 3197 |
+
fout.write(struct.pack("<IIQQ", _GGUF_MAGIC, 3, len(gguf_tensors), len(kv_pairs)))
|
| 3198 |
+
for k, vt, raw_v in kv_pairs:
|
| 3199 |
+
fout.write(_pack_gguf_str(k))
|
| 3200 |
+
fout.write(struct.pack("<I", vt))
|
| 3201 |
+
fout.write(raw_v)
|
| 3202 |
+
for gname, g_dims, out_type, off in gguf_tensors:
|
| 3203 |
+
fout.write(_pack_gguf_str(gname))
|
| 3204 |
+
fout.write(struct.pack("<I", len(g_dims)))
|
| 3205 |
+
for d in g_dims:
|
| 3206 |
+
fout.write(struct.pack("<Q", int(d)))
|
| 3207 |
+
fout.write(struct.pack("<I", int(out_type)))
|
| 3208 |
+
fout.write(struct.pack("<Q", int(off)))
|
| 3209 |
+
data_start = _gguf_align(fout.tell())
|
| 3210 |
+
if data_start > fout.tell():
|
| 3211 |
+
fout.write(b"\x00" * (data_start - fout.tell()))
|
| 3212 |
+
|
| 3213 |
+
for idx_w, pitem in enumerate(planned_exec, 1):
|
| 3214 |
+
if stop_event is not None and stop_event.is_set():
|
| 3215 |
+
raise InterruptedError("GGUF export cancelled by user.")
|
| 3216 |
+
|
| 3217 |
+
pkind = pitem[0]
|
| 3218 |
+
if pkind == "raw_bytes":
|
| 3219 |
+
_, gname, out_type, cur_off, raw_bytes = pitem
|
| 3220 |
+
tgt = "F32"
|
| 3221 |
+
target_pos = data_start + cur_off
|
| 3222 |
+
if target_pos > fout.tell():
|
| 3223 |
+
fout.write(b"\x00" * (target_pos - fout.tell()))
|
| 3224 |
+
fout.write(raw_bytes)
|
| 3225 |
+
elif pkind == "single":
|
| 3226 |
+
_, w_key, s_key, gname, t_shape, g_dims, tgt, out_type, out_sz, cur_off = pitem
|
| 3227 |
+
target_pos = data_start + cur_off
|
| 3228 |
+
if target_pos > fout.tell():
|
| 3229 |
+
fout.write(b"\x00" * (target_pos - fout.tell()))
|
| 3230 |
+
|
| 3231 |
+
lm = LAYER_RE.match(w_key)
|
| 3232 |
+
cache_key = None
|
| 3233 |
+
if lm:
|
| 3234 |
+
suf = lm.group(3)
|
| 3235 |
+
w_sample = _payload_bytes(f.get_tensor(w_key).flatten()[:256])
|
| 3236 |
+
cache_key = ("single", suf, t_shape, tgt, w_sample)
|
| 3237 |
+
if cache_key is not None and cache_key in payload_cache:
|
| 3238 |
+
fout.write(payload_cache[cache_key])
|
| 3239 |
+
elif len(t_shape) == 2 and t_shape[0] > 4096 and s_key is None and tgt in ("BF16", "Q4_0"):
|
| 3240 |
+
sl = f.get_slice(w_key)
|
| 3241 |
+
for r0 in range(0, t_shape[0], 4096):
|
| 3242 |
+
r1 = min(r0 + 4096, t_shape[0])
|
| 3243 |
+
sub_t = sl[r0:r1].to(dev)
|
| 3244 |
+
if tgt == "BF16":
|
| 3245 |
+
b_part = sub_t.to(torch.bfloat16).view(torch.uint16).cpu().numpy().astype("<u2").tobytes()
|
| 3246 |
+
else:
|
| 3247 |
+
sub_np = sub_t.float().cpu().numpy().astype(np.float32)
|
| 3248 |
+
b_part, _, _ = quantize_tensor_q4_0(sub_np, cfg=hpc_cfg)
|
| 3249 |
+
fout.write(b_part)
|
| 3250 |
+
del sub_t
|
| 3251 |
+
else:
|
| 3252 |
+
t_f32 = _dequant_single_to_f32_torch(w_key, s_key)
|
| 3253 |
+
if not t_shape:
|
| 3254 |
+
t_f32 = t_f32.reshape(1)
|
| 3255 |
+
elif tuple(t_f32.shape) != t_shape:
|
| 3256 |
+
t_f32 = t_f32.reshape(t_shape)
|
| 3257 |
+
_, raw_bytes = _encode_tensor_f32(t_f32, tgt)
|
| 3258 |
+
del t_f32
|
| 3259 |
+
fout.write(raw_bytes)
|
| 3260 |
+
if cache_key is not None:
|
| 3261 |
+
payload_cache[cache_key] = raw_bytes
|
| 3262 |
+
else:
|
| 3263 |
+
_, (lidx, proj), members, gname, full_shape, g_dims, tgt, out_type, out_sz, cur_off = pitem
|
| 3264 |
+
target_pos = data_start + cur_off
|
| 3265 |
+
if target_pos > fout.tell():
|
| 3266 |
+
fout.write(b"\x00" * (target_pos - fout.tell()))
|
| 3267 |
+
|
| 3268 |
+
first_w = members[0][1]
|
| 3269 |
+
w_sample = _payload_bytes(f.get_tensor(first_w).flatten()[:256])
|
| 3270 |
+
cache_key = ("experts", proj, full_shape, tgt, w_sample)
|
| 3271 |
+
if cache_key in payload_cache:
|
| 3272 |
+
fout.write(payload_cache[cache_key])
|
| 3273 |
+
else:
|
| 3274 |
+
chunks = []
|
| 3275 |
+
for _, wk, sk in members:
|
| 3276 |
+
ef32 = _dequant_single_to_f32_torch(wk, sk)
|
| 3277 |
+
_, eb = _encode_tensor_f32(ef32, tgt)
|
| 3278 |
+
chunks.append(eb)
|
| 3279 |
+
del ef32
|
| 3280 |
+
raw_bytes = b"".join(chunks)
|
| 3281 |
+
fout.write(raw_bytes)
|
| 3282 |
+
payload_cache[cache_key] = raw_bytes
|
| 3283 |
|
| 3284 |
+
stats["tensors"] += 1
|
| 3285 |
+
if out_type == _GGML_Q2_K:
|
| 3286 |
+
stats["q2_k"] += 1
|
| 3287 |
+
elif out_type == _GGML_Q4_0:
|
| 3288 |
+
stats["q4_0"] += 1
|
| 3289 |
+
elif out_type == _GGML_BF16:
|
| 3290 |
+
stats["bf16"] += 1
|
| 3291 |
else:
|
| 3292 |
+
stats["f32"] += 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3293 |
|
| 3294 |
+
if progress_cb is not None and (idx_w % 8 == 0 or idx_w == total_items):
|
| 3295 |
+
progress_cb(idx_w, total_items, gname, tgt, stats)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3296 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3297 |
stats["output_bytes"] = out_path.stat().st_size
|
| 3298 |
if verbose:
|
| 3299 |
print(
|