Land the MeroMero v2-31B NVFP4A16 quant and record the pinned-transformers trap
The v2 dense quant had failed four times. Attempt 5 lands it at 19 G. The blocker was not what it looked like. `AmbiguousGlobalPerLayerAttributeError` on `head_dim` read as a malformed upload -- DogOnKeyboard's config carries a `per_layer_config` key zerofata's canonical one lacks -- and the standing fix was to force `allow_global_per_layer_attribute_access=True`. Both halves were wrong. `pip install llmcompressor==0.13.0` downgrades transformers 5.16.1 -> 5.14.1. The config was serialized by 5.16.1, which materializes `per_layer_config` from `global_head_dim` + `layer_types`; 5.14.1 carries the heterogeneity guard but not the gemma4 resolver. Under the image's own transformers the same config loads fine. `:latest` was also re-pulled during attempt 4 and no earlier run, so the toolchain moved mid-diagnosis. Two things separated "malformed upload" from "moved toolchain": reproducing the real failing call (a bare AutoConfig load does not reproduce it; the trigger is reached through AutoTokenizer) and keeping zerofata's canonical tree, quantized cleanly on 2026-08-21, as a positive control. The fix drops `per_layer_config` rather than forcing global access. It is exactly redundant -- keys are precisely the ten full_attention layer indices, sole value (512, 4), verbatim the global fields -- and forcing instead would make `config.head_dim` answer 256 to the callers building the 512-wide layers. patch_perlayer.py re-proves that redundancy at apply time and refuses if it ever stops holding. Verified on the tensor table rather than the exit code: the output is identical family-for-family and count-for-count to the August canonical quant, with 356 BF16 vision-tower tensors preserved and input_activations=None. A GPU-free load leaves 0 tensors on meta and generates coherent prose. The section 4.4 serve test has NOT run -- GPU1 has 19.9 GB free against 19.5 GB of weights, so it needs a live seat displaced. Also fixes the A4B output, which had a truncation cap baked into its tokenizer (max_length 8192) from being quantized with the calibration corpus. Playbook gains section 3.17 for the pinned-transformers class and sharpens 3.16 to say drop the dataset outright for any A16 scheme.
This commit is contained in:
+58
-8
@@ -1,7 +1,8 @@
|
||||
# `[2026-09-10]` MeroMero acquisition — the A4B quant landed, the v2 dense has failed FOUR times
|
||||
# `[2026-09-10]` MeroMero — both quants landed; the v2 dense took five attempts
|
||||
|
||||
Operator wanted a MeroMero seat. Getting there cost four quant attempts and corrected two of my own
|
||||
wrong hypotheses, so the failure chain is the durable part.
|
||||
Operator wanted a MeroMero seat. Getting there cost five quant attempts and corrected three wrong
|
||||
hypotheses (two of the previous session's, one of mine), so the failure chain is the durable part.
|
||||
**Both outputs now exist and are verified against a known-good tree. Neither is serving yet.**
|
||||
|
||||
## The family, because I got it wrong first
|
||||
|
||||
@@ -60,13 +61,62 @@ playbook §3.16: weight-only A16 runs a `DataFreePipeline` and never touches the
|
||||
truncation cap into the shipped tokenizer. Removing it kills both for zero loss.
|
||||
3. **My own bug**: the reference module runs argparse with `required=True` at IMPORT, so blanking
|
||||
`sys.argv` still exited 2. Placeholder args, real argv restored after.
|
||||
4. **`AmbiguousGlobalPerLayerAttributeError: 'head_dim' is a per-layer attribute`** — OPEN. The
|
||||
DogOnKeyboard config carries a `per_layer_config` key that zerofata's lacks (it was the one key in
|
||||
the diff I noted and did not chase). transformers refuses global access to `head_dim` on a
|
||||
heterogeneous config; the fix is likely `allow_global_per_layer_attribute_access=True`, with the
|
||||
warning that a caller assuming homogeneity may then read the wrong value.
|
||||
4. **`AmbiguousGlobalPerLayerAttributeError: 'head_dim' is a per-layer attribute`** — RESOLVED,
|
||||
and **not what it looked like**. See "The attempt-4 trap" below.
|
||||
5. Clean. `rc=0`, 19 G, 3m07s.
|
||||
|
||||
⚠ **My wrapper reported `rc=0` on a failed run** because it read `$?` after an `echo`. A wrapper that
|
||||
reports success on failure is the false-reassurance class; fixed to capture `$?` immediately.
|
||||
|
||||
|
||||
## The attempt-4 trap — the toolchain moved, the config was fine
|
||||
|
||||
The standing hypothesis was that DogOnKeyboard's `per_layer_config` key was the defect and
|
||||
`allow_global_per_layer_attribute_access=True` was the fix. Both halves were wrong, and the second
|
||||
half would have shipped a risk for no reason.
|
||||
|
||||
**`pip install llmcompressor==0.13.0` downgrades transformers 5.16.1 → 5.14.1.** The config was
|
||||
serialized *by* 5.16.1, which materializes `per_layer_config` out of `global_head_dim` +
|
||||
`layer_types`; 5.14.1 has the heterogeneity guard but not the gemma4 resolver, so it refuses the
|
||||
global read. Under the image's own 5.16.1 the identical config loads fine. On top of that,
|
||||
`vllm/vllm-openai:latest` was re-pulled *during attempt 4 and in no earlier run* — the pull line is
|
||||
in that block alone — so the error changed for reasons unrelated to anything under test.
|
||||
|
||||
Two things made this findable, and neither was inspection:
|
||||
|
||||
- **Reproducing the real call.** A bare `AutoConfig.from_pretrained` does not reproduce it; the
|
||||
trigger is reached through `AutoTokenizer`. Testing the config alone would have cleared it.
|
||||
- **A known-good positive control.** zerofata's canonical v2, quantized cleanly on 2026-08-21, is
|
||||
what separated "this upload is malformed" from "this toolchain moved". Four green variants and one
|
||||
red one are noise without it.
|
||||
|
||||
**Fix: drop `per_layer_config`, don't force global access.** It is exactly redundant — keys are
|
||||
precisely the ten `full_attention` layer indices, sole value `(512, 4)`, verbatim the global fields.
|
||||
Forcing instead leaves the config heterogeneous and makes `config.head_dim` answer 256 to every
|
||||
caller including the ones building the 512-wide layers; geometry survived it in a meta-device check,
|
||||
but llmcompressor's onloading is an unaudited caller and that is what the warning is about. The
|
||||
patch re-proves the redundancy at apply time and refuses if it ever stops holding.
|
||||
|
||||
## What landed, and what is verified
|
||||
|
||||
- `G4-MeroMero-v2-31B-heretic-NVFP4A16` — **19 G**, and its tensor table is **identical family for
|
||||
family and count for count to the 2026-08-21 canonical quant**: 410 U8 packed + 410 F8_E4M3 +
|
||||
410 F32 scales on the LM Linears, **356 BF16 vision-tower tensors preserved**,
|
||||
`input_activations=None` (genuinely A16). Shard sizes match that tree byte for byte.
|
||||
- CPU load-and-generate: 0 tensors left on meta, decompresses, emits coherent prose. n=1, greedy,
|
||||
24 tokens — an "is it wired up" check and nothing more.
|
||||
- ⚠ **The A4B output had the §3.14 truncation cap baked in** (`max_length: 8192`), because it was
|
||||
quantized *with* the corpus. Caught and fixed; backup at `tokenizer.json.bak-pre-truncfix`. The v2,
|
||||
run data-free, came out `truncation: null`.
|
||||
|
||||
## Still owed
|
||||
|
||||
**The §4.4 serve test has NOT run.** GPU1 has 19.9 GB free against 19.5 GB of weights, so it cannot
|
||||
happen without displacing a live seat — operator's call. Until it does, *"vllm servable"* is
|
||||
unverified for this tree, and the dense 31B's 60-layer / kv-16 geometry still does not fit 262k on
|
||||
GPU1 beside the current tenants regardless.
|
||||
|
||||
Instruments and the full write-up: `services/meromero-quant/`. General lessons:
|
||||
`docs/pfi/model-quantization-playbook.md` §3.16, **§3.17 (new)**, §4.3.
|
||||
|
||||
Related: [[2026-09-10-r49-babybronte-d1-d3-and-the-1-epoch-pilot]]
|
||||
@@ -116,4 +116,4 @@ resolved at run start AND end.
|
||||
|
||||
Handoff bundle for adjudication at `/mnt/smithy/handoff/r49/`.
|
||||
|
||||
Related: [[2026-09-10-meromero-acquisition-and-four-quant-failures]]
|
||||
Related: [[2026-09-10-meromero-quants-and-the-pinned-transformers-trap]]
|
||||
|
||||
Reference in New Issue
Block a user