"""Remove the redundant `per_layer_config` block that blocks attempt 4. Why this and not `allow_global_per_layer_attribute_access=True`: * `per_layer_config` here carries NO information. Its keys are exactly the ten full_attention layer indices [5,11,...,59] and its only distinct value is (head_dim 512, num_key_value_heads 4) -- which `global_head_dim: 512` and `num_global_key_value_heads: 4`, already in this config, say verbatim. Removing it is lossless, and it is the difference in what the two toolchain versions can read: transformers 5.16.1 (which authored this file) emits the per-layer form; llmcompressor 0.13.0 PINS transformers to 5.14.1, which has the heterogeneity guard but not the gemma4 resolver, so it refuses the read. * Forcing global access leaves the config heterogeneous and makes `config.head_dim` answer 256 to every caller -- including the ones building the 512-wide full-attention layers. Geometry survived that in my meta-device check, but llmcompressor's own onloading code is a caller I have not audited, and it is precisely what transformers' warning is about. No reason to take that when the lossless option verifies identically. Verified on transformers 5.14.1, the version the quant actually runs: this config then reports head_dim/num_key_value_heads/global_head_dim/num_global_key_value_heads identical to zerofata's canonical tree -- the config that quantized successfully on 2026-08-21 -- and builds k_proj (2048, 5376) on layer 5 and (4096, 5376) on layer 0, matching the checkpoint. """ import json import shutil from pathlib import Path CFG = Path("/tank/aimodels/G4-MeroMero-v2-31B-heretic-bf16/config.json") BAK = CFG.with_name("config.json.bak-pre-perlayer-20260910") NOTE = ( " | infra-ops 2026-09-10 (2nd patch): removed text_config.per_layer_config, " "a transformers-5.16.1 serialization artifact that llmcompressor 0.13.0's " "pinned transformers 5.14.1 cannot read (AmbiguousGlobalPerLayerAttributeError " "on head_dim). It was exactly redundant with global_head_dim=512 / " "num_global_key_value_heads=4 -- keys were the 10 full_attention layers, sole " "value (512, 4). Config now matches zerofata's canonical shape. Original at " "config.json.bak-pre-perlayer-20260910." ) cfg = json.loads(CFG.read_text()) t = cfg["text_config"] plc = t.get("per_layer_config") if plc is None: print("per_layer_config already absent -- nothing to do") raise SystemExit(0) # Re-prove the redundancy here rather than trusting the earlier session: a patch # that silences an error on a config it did not actually verify is how a quietly # wrong quant ships. full = {i for i, x in enumerate(t["layer_types"]) if x == "full_attention"} assert {int(k) for k in plc} == full, f"per_layer_config keys {sorted(plc)} != full-attn layers {sorted(full)}" vals = {(v["head_dim"], v["num_key_value_heads"]) for v in plc.values()} assert vals == {(t["global_head_dim"], t["num_global_key_value_heads"])}, \ f"per_layer_config carries {vals}, not the global (512, 4) -- NOT redundant, do not drop" print(f"redundancy re-verified: {len(plc)} entries, all {vals.pop()}, " f"== (global_head_dim, num_global_key_value_heads)") if not BAK.exists(): shutil.copy2(CFG, BAK) print(f"backed up -> {BAK.name}") else: print(f"backup {BAK.name} already exists, left alone") t.pop("per_layer_config") cfg["_patched_by"] = cfg.get("_patched_by", "") + NOTE tmp = CFG.with_suffix(".json.tmp") tmp.write_text(json.dumps(cfg, indent=2) + "\n") tmp.replace(CFG) print(f"patched {CFG}")