{"record":{"id":"e699805018aec3ca","repo":"keras-team/keras","slug":"cannot-save-layer-self-name-because-it-is-quan-e69980","errorCode":null,"errorMessage":"Cannot save layer '{self.name}' because it is quantized with mode '{mode}' but has never been calibrated. Its quantized weights are uninitialized, so saving would produce a corrupted model. Run calibration first, e.g. via `model.quantize(...)` with a quantization layer structure that covers this layer, or exclude the layer from quantization with `filters`.","messagePattern":"Cannot save layer '(.+?)' because it is quantized with mode '(.+?)' but has never been calibrated\\. Its quantized weights are uninitialized, so saving would produce a corrupted model\\. Run calibration first, e\\.g\\. via `model\\.quantize\\(\\.\\.\\.\\)` with a quantization layer structure that covers this layer, or exclude the layer from quantization with `filters`\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"keras/src/layers/core/einsum_dense.py","lineNumber":403,"sourceCode":"        self.lora_alpha = lora_alpha if lora_alpha is not None else rank\n\n    def save_own_variables(self, store):\n        # Do nothing if the layer isn't yet built\n        if not self.built:\n            return\n        mode = self.quantization_mode\n        if mode not in self.variable_serialization_spec:\n            raise self._quantization_mode_error(mode)\n\n        # GPTQ/AWQ layers are only serializable after calibration. Before\n        # calibration, the quantized variables hold uninitialized values\n        # while the real weights live in the float `_kernel`, which has no\n        # slot in the serialization spec, so saving would silently drop the\n        # actual weights and produce a corrupted model on reload.\n        if (\n            mode == \"gptq\" and not getattr(self, \"is_gptq_calibrated\", False)\n        ) or (mode == \"awq\" and not getattr(self, \"is_awq_calibrated\", False)):\n            raise ValueError(\n                f\"Cannot save layer '{self.name}' because it is quantized \"\n                f\"with mode '{mode}' but has never been calibrated. Its \"\n                \"quantized weights are uninitialized, so saving would \"\n                \"produce a corrupted model. Run calibration first, e.g. via \"\n                \"`model.quantize(...)` with a quantization layer structure \"\n                \"that covers this layer, or exclude the layer from \"\n                \"quantization with `filters`.\"\n            )\n\n        # Kernel plus optional merged LoRA-aware scale/zero (returns\n        # (kernel, None, None) for None/gptq)\n        kernel_value, merged_kernel_scale, merged_kernel_zero = (\n            self._get_kernel_with_merged_lora()\n        )\n        # Variables are stored under their integer position (\"0\", \"1\", ...)\n        # within the mode's serialization spec. Each branch picks the value\n        # for the current spec entry (or skips it); the write happens at a\n        # single point so save and load stay position-consistent.","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/core/einsum_dense.py#L385-L421","documentation":"When saving, EinsumDense.save_own_variables refuses to serialize a GPTQ/AWQ-quantized layer that was never calibrated: the packed integer kernel is uninitialized, and the real float weights live in _kernel which has no slot in the serialization spec, so saving would silently drop the actual weights and produce a corrupted model on reload. The ValueError names the layer and mode so calibration can be fixed before save.","triggerScenarios":"model.quantize(...) with mode 'gptq' or 'awq' followed by model.save(...) before any calibration pass ran; saving a quantized model where is_gptq_calibrated / is_awq_calibrated is still False; a checkpoint callback firing mid-quantization pipeline.","commonSituations":"Saving right after configuring quantization (no calibration data passed); interrupted calibration pipelines that still hit a checkpoint callback; merging or re-saving quantized models without running the calibration step from the recipe.","solutions":["Run calibration before saving: call model.quantize(...) with representative data so GPTQ/AWQ calibration completes for this layer.","Exclude this layer from quantization via the filters argument of model.quantize if it does not need quantizing.","If quantization was applied by mistake, rebuild the layer in float mode and re-save."],"exampleFix":"# before\nmodel.quantize(quantization_config)  # no calibration data\nmodel.save('m.keras')  # ValueError\n\n# after\nmodel.quantize(quantization_config)  # includes calibration pass\n# or exclude the layer: model.quantize(cfg, filters=[layer.name])\nmodel.save('m.keras')","handlingStrategy":"validation","validationCode":"for l in model.layers:\n    mode = getattr(l, 'quantization_mode', None)\n    if mode == 'gptq' and not getattr(l, 'is_gptq_calibrated', False):\n        raise RuntimeError(f'{l.name}: GPTQ not calibrated')\n    if mode == 'awq' and not getattr(l, 'is_awq_calibrated', False):\n        raise RuntimeError(f'{l.name}: AWQ not calibrated')\nmodel.save(path)","typeGuard":null,"tryCatchPattern":"try:\n    model.save(path)\nexcept ValueError as e:\n    if 'never been calibrated' in str(e):\n        run_calibration()\n        model.save(path)\n    else:\n        raise","preventionTips":["Run calibration immediately after quantize() and before any checkpoint callback.","Add a pre-save assertion that every quantized layer reports calibrated."],"tags":["keras","quantization","gptq","awq","model-saving","calibration"],"backgroundTag":"quantized-model-save-corruption","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}