apetersson/v41-quant-worker
0198
1#!/usr/bin/env python32"""Aggregate the per-shard manifests of a mixed-Q2 V4.1 expert checkpoint into one manifest and README.3 4Reads ``plan.json`` plus every ``quant-*.safetensors.manifest.json`` written by5``v41_quant_experts.py convert`` and writes ``manifest.json`` and ``README.md`` into the6artifact directory. Pure aggregation over recorded digests: it does not read the weights.7"""8 9from __future__ import annotations10 11import argparse12import hashlib13import json14from datetime import UTC, datetime15from pathlib import Path16 17LLAMA_COMMIT = "465e49b9cea78a68b9c244ffb48d0ee24a82873d"18 19README_TEMPLATE = """# DeepSeek-V4.1-Flash mixed-Q2 expert checkpoint ({stamp})20 21Quantised derivative of `{repo}` revision `{revision}`, produced on a 32-vCPU Runpod CPU pod22with the pinned llama.cpp ggml reference quantisers (`{llama_commit}`).23 24## What this is25 26The released checkpoint stores routed experts as MXFP4: 16 bytes of packed E2M1 values plus27one E8M0 scale byte per 32 weights (4.25 bits/weight). This artifact decodes exactly those28blocks and stores the 40 main-layer routed expert matrices as ggml blocks:29 30| projection | ggml type | bits/weight | tensors | weights |31|---|---|---:|---:|---:|32| gate/up `w1`, `w3` | IQ2_XXS | 2.0625 | {n_iq2} | {w_iq2} |33| down `w2` | Q2_K | 2.625 | {n_q2k} | {w_q2k} |34 35Block geometry (blocks run along the input/reduction dimension; ggml lists `ne` fastest-first, so36the same bytes are `ne=[in, out]`):37 38| tensor | logical out x in | ggml type | blocks/row | bytes/row | first block offset |39|---|---|---:|---:|---:|---|40| `w1.weight`, `w3.weight` | 2304 x 5120 | IQ2_XXS | 20 | 1320 | 0 |41| `w2.weight` | 5120 x 2304 | Q2_K | 9 | 756 | 0 |42 43Each expert tensor is a contiguous row-major sequence of those rows, so a carrier can read4420 blocks per row for gate/up and 9 per row for down with no extra permutation.45 46Total quantised payload **{quant_bytes} GB** for **{quant_weights}** routed weights47({bits} bits/weight average). With the non-routed weights held at native precision and the48Engram tables resident on the host, this fits one B200 180 GB or two RTX PRO 6000 96 GB cards.49 50Quantisation is **not imatrix-based**. No activation calibration was collected and no51importance matrix was consumed: IQ2_XXS was called with a constant unit importance vector52(the unweighted reference path). That is a deliberate recipe choice, not a calibrated one.53 54## Contents55 56| group | tensors | bytes |57|---|---:|---:|58{preserved_rows}59 60Every tensor other than the requantised experts is copied byte-for-byte from the source with61its original dtype string (`F8_E4M3`, `F8_E8M0`, `BF16`, `F32`, `I8`). Requantised expert62tensors keep their original names and are stored as `U8` block bytes; the per-tensor ggml63type, byte shape and block geometry are recorded in `manifest.json` and in each shard64manifest. MTP/DSpark expert tensors stay at native precision because DSpark stays disabled.65 66The four large Engram tensors (`layers.1.engram.embed.*`, `layers.14.engram.embed.*`,67{external_bytes} GB) are **not** copied: the release plan keeps Engram rows and scales native68on host storage. `manifest.json` records their source shard, byte range and source digest so a69loader can attach them from the immutable source revision. The 46,080 MXFP4 scale tensors of70the requantised experts ({dropped_bytes} GB) are dropped because IQ2_XXS and Q2_K carry their71own scales; their source digests are recorded as well.72 73## Layout74 75| output shard | source shard | tensors | bytes |76|---|---|---:|---:|77{shard_rows}78| **total** | | **{total_tensors}** | **{total_bytes} GB** |79 80`plan.json` holds the full tensor map (source shard, byte range, role, output shard, output81offset, output shape and type). Each `quant-*.safetensors` shard has a matching82`.manifest.json` with per-tensor source and output SHA-256 digests.83 84## Verification85 86```bash87python3 v41_quant_experts.py verify --out <this directory> --sample 0 # all digests88python3 v41_quant_audit.py --source <source dir> --out <this directory> \89 --json audit.json # fidelity sample90```91 92`audit.json` reports cosine similarity and relative RMS error of the dequantised blocks93against the MXFP4 source decode, computed with the independent gguf-py dequantisers from the94same pinned llama.cpp revision. With `--ggml-lib` it also recomputes the quantisation and95reports whether the stored digests are reproducible.96 97## Reproducibility98 99{environment_rows}100 101The ggml reference quantisers are deterministic for a given build and CPU target (repeated102recomputation reproduces the stored digests), but they are **not** bit-identical across SIMD103architectures: the ARM NEON and x86 AVX-512 paths select different codepoints in the IQ2_XXS104grid and can differ in Q2_K rounding. Re-running on a different architecture reproduces the105recipe, not these exact bytes. Reproduce or audit with the pinned commit above and the same106CPU class, or treat a differing digest as expected and compare fidelity through `audit.json`.107 108## Limits109 110This is a weights artifact. No V4.1 quantised runtime exists in the workspace, so nothing111here has been executed end to end and none of these numbers are behavioural results. The112blocks are the inputs a fused-kernel carrier needs; executing them requires new kernels for113IQ2_XXS/Q2_K experts plus host-resident Engram lookup.114"""115 116 117def human_gb(value: int) -> str:118 return f"{value / 1e9:,.2f}"119 120 121def main() -> int:122 parser = argparse.ArgumentParser(description=__doc__)123 parser.add_argument("--out", type=Path, required=True)124 parser.add_argument("--repo", default="deepseek-ai/DeepSeek-V4.1-Flash")125 parser.add_argument("--stamp", default=None)126 parser.add_argument("--check", action="store_true", help="fail if any planned shard is missing")127 parser.add_argument(128 "--environment",129 type=Path,130 help="JSON file describing the execution environment (CPU, SIMD, host, pod) to embed",131 )132 args = parser.parse_args()133 134 out = args.out135 plan = json.loads((out / "plan.json").read_text())136 role_by_name: dict[str, str] = {}137 type_by_name: dict[str, str] = {}138 for shard in plan["shards"]:139 for tensor in shard["tensors"]:140 role_by_name[tensor["name"]] = tensor["role"]141 if tensor["role"] == "quantised":142 type_by_name[tensor["name"]] = tensor["ggml_type"]143 144 per_type: dict[str, dict[str, int]] = {}145 per_role: dict[str, dict[str, int]] = {}146 shard_rows = []147 digest_index = []148 total_output_bytes = 0149 manifests = sorted(150 (json.loads(p.read_text()) for p in out.glob("quant-*.safetensors.manifest.json")),151 key=lambda m: m["output_shard"],152 )153 for manifest in manifests:154 shard_digest = hashlib.sha256()155 data_bytes = 0156 for tensor in sorted(manifest["tensors"], key=lambda t: t["name"]):157 role = role_by_name.get(tensor["name"], "unknown")158 per_role.setdefault(role, {"tensors": 0, "bytes": 0})159 per_role[role]["tensors"] += 1160 per_role[role]["bytes"] += tensor["output_bytes"]161 if role == "quantised":162 type_name = type_by_name[tensor["name"]]163 entry = per_type.setdefault(type_name, {"tensors": 0, "bytes": 0})164 entry["tensors"] += 1165 entry["bytes"] += tensor["output_bytes"]166 total_output_bytes += tensor["output_bytes"]167 data_bytes += tensor["output_bytes"]168 shard_digest.update(tensor["name"].encode())169 shard_digest.update(tensor["output_sha256"].encode())170 shard_rows.append(171 (172 manifest["output_shard"],173 manifest["source_shard"],174 len(manifest["tensors"]),175 manifest["file_bytes"],176 )177 )178 digest_index.append(179 {180 "output_shard": manifest["output_shard"],181 "source_shard": manifest["source_shard"],182 "tensors": len(manifest["tensors"]),183 "file_bytes": manifest["file_bytes"],184 "data_bytes": data_bytes,185 "digest_of_shard_digests": shard_digest.hexdigest(),186 }187 )188 189 expected = {s["output_shard"] for s in plan["shards"]}190 produced = {m["output_shard"] for m in manifests}191 missing = sorted(expected - produced)192 totals = plan["totals"]193 record = {194 "artifact": "DeepSeek-V4.1-Flash mixed-Q2 routed experts",195 "created_at_utc": args.stamp or datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ"),196 "source": {197 "repo": args.repo,198 "revision": plan["source_revision"],199 "tensors": totals["source_tensors"],200 },201 "recipe": plan["recipe"],202 "importance": plan["importance"],203 "quantiser": f"llama.cpp ggml reference quantisers, commit {LLAMA_COMMIT}",204 "totals": {205 **totals,206 "shards_planned": len(expected),207 "shards_produced": len(produced),208 "missing_shards": missing,209 "unexpected_shards": sorted(produced - expected),210 "bytes_by_role": per_role,211 "quantised_bytes_by_type": per_type,212 "output_bytes_from_manifests": total_output_bytes,213 },214 "environment": json.loads(args.environment.read_text()) if args.environment else {},215 "external_native": plan["external"],216 "dropped_expert_scales": len(plan["dropped"]),217 "shards": digest_index,218 }219 (out / "manifest.json").write_text(json.dumps(record, indent=1) + "\n")220 221 role_rows = "\n".join(222 f"| {role} | {values['tensors']:,} | {human_gb(values['bytes'])} |"223 for role, values in sorted(per_role.items())224 )225 shard_rows_md = "\n".join(226 f"| `{name}` | `{source}` | {tensors:,} | {human_gb(file_bytes)} |"227 for name, source, tensors, file_bytes in shard_rows228 )229 iq2 = per_type.get("IQ2_XXS", {"tensors": 0, "bytes": 0})230 q2k = per_type.get("Q2_K", {"tensors": 0, "bytes": 0})231 readme = README_TEMPLATE.format(232 stamp=record["created_at_utc"],233 repo=args.repo,234 revision=plan["source_revision"],235 llama_commit=LLAMA_COMMIT,236 n_iq2=f"{iq2['tensors']:,}",237 n_q2k=f"{q2k['tensors']:,}",238 w_iq2=f"{(iq2['bytes'] // 66) * 256:,}",239 w_q2k=f"{(q2k['bytes'] // 84) * 256:,}",240 quant_bytes=human_gb(totals["quantised_bytes"]),241 quant_weights=f"{totals['quantised_logical_weights']:,}",242 bits=round(8 * totals["quantised_bytes"] / totals["quantised_logical_weights"], 4),243 preserved_rows=role_rows,244 external_bytes=human_gb(totals["external_bytes"]),245 dropped_bytes=human_gb(totals["dropped_bytes"]),246 environment_rows="\n".join(247 f"- {key}: `{value}`"248 for key, value in sorted(249 (json.loads(args.environment.read_text()) if args.environment else {}).items()250 )251 )252 or "- not recorded",253 shard_rows=shard_rows_md,254 total_tensors=sum(len(m["tensors"]) for m in manifests),255 total_bytes=human_gb(sum(m["file_bytes"] for m in manifests)),256 )257 (out / "README.md").write_text(readme)258 print(259 json.dumps({k: v for k, v in record["totals"].items() if not isinstance(v, dict)}, indent=1)260 )261 print(json.dumps({"by_role": per_role, "by_type": per_type}, indent=1))262 if missing:263 print(f"WARNING missing shards: {len(missing)}")264 return 1 if (missing and args.check) else 0265 266 267if __name__ == "__main__":268 raise SystemExit(main())269 