{"record":{"id":"175a49bc873e37d9","repo":"xai-org/x-algorithm","slug":"unexpected-head-param-layout-sorted-params-exp","errorCode":null,"errorMessage":"unexpected head param layout {sorted(params)} (expected {sorted(expected)})","messagePattern":"unexpected head param layout (.+?) \\(expected (.+?)\\)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"bdsm/runtime/task_heads.py","lineNumber":43,"sourceCode":"\n\ndef head_logits(params: dict, x: jax.Array) -> jax.Array:\n    n_layers = len(params) // 2\n    for i in range(n_layers):\n        x = x @ params[f\"w{i}\"] + params[f\"b{i}\"]\n        if i < n_layers - 1:\n            x = jax.nn.gelu(x)\n    return x\n\n\ndef load_head_params(head_checkpoint: str) -> dict:\n    arrays = np.load(os.path.join(head_checkpoint, \"head_params.npz\"))\n    params = {}\n    for key in arrays.files:\n        params[key.split(\"/\")[-1]] = arrays[key]\n    expected = {\"w0\", \"b0\", \"w1\", \"b1\", \"w2\", \"b2\"}\n    if set(params) != expected:\n        raise RuntimeError(\n            f\"unexpected head param layout {sorted(params)} (expected {sorted(expected)})\"\n        )\n    return params\n","sourceCodeStart":25,"sourceCodeEnd":47,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/bdsm/runtime/task_heads.py#L25-L47","documentation":"load_head_params loads head_params.npz, strips each key to its last '/'-segment, and requires exactly the set {w0,b0,w1,b1,w2,b2}. Any other layout (missing layer, extra keys like batch-norm params, different naming) aborts with the sorted key diff.","triggerScenarios":"Loading a head checkpoint exported from a 4-layer head (w3 present), a head with layer-norm keys (gamma/beta), or keys that do not follow the wN/bN naming; npz saved from an older format whose key prefixes collapse to unexpected segments.","commonSituations":"Architecture change to the head MLP without updating the loader/exporter; loading a backbone param file by mistake; export script renaming keys.","solutions":["Inspect np.load(...).files of head_params.npz and compare with {w0,b0,w1,b1,w2,b2}","Re-export the head with the exact 3-layer wN/bN naming the loader expects","If the head architecture legitimately changed, update the expected set in task_heads.py and rebuild","Make sure you are pointing at a head checkpoint, not a backbone npz"],"exampleFix":"# export heads with exactly these param names:\nnp.savez('head_params.npz', w0=w0, b0=b0, w1=w1, b1=b1, w2=w2, b2=b2)","handlingStrategy":"validation","validationCode":"arrays = np.load(npz)\nnames = {k.split('/')[-1] for k in arrays.files}\nassert names == {'w0','b0','w1','b1','w2','b2'}, names ^ {'w0','b0','w1','b1','w2','b2'}","typeGuard":"def is_expected_head_layout(names: set) -> bool:\n    return names == {'w0', 'b0', 'w1', 'b1', 'w2', 'b2'}","tryCatchPattern":"try:\n    params = load_head_params(ckpt)\nexcept RuntimeError as e:\n    if 'unexpected head param layout' in str(e):\n        raise SystemExit(f\"bad head export: {e}; re-export with wN/bN keys\")\n    raise","preventionTips":["Use the canonical exporter to write head_params.npz","Add a layout assertion to checkpoint-export CI","Keep head architecture and loader expectations in one module"],"tags":["python","model-loading","checkpoint","validation"],"backgroundTag":"model-shape-mismatch","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}