{"record":{"id":"6dc7f6791afd3d61","repo":"Comfy-Org/ComfyUI","slug":"missing-nvfp4-scales-for-layer-layer-name","errorCode":null,"errorMessage":"Missing NVFP4 scales for layer {layer_name}","messagePattern":"Missing NVFP4 scales for layer (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"comfy/ops.py","lineNumber":1174,"sourceCode":"            raise ValueError(f\"Unknown quantization format for layer {layer_name}\")\n\n        qconfig = QUANT_ALGOS[module.quant_format]\n        module.layout_type = qconfig[\"comfy_tensor_layout\"]\n        layout_cls = get_layout_class(module.layout_type)\n\n        # Per-format scales; fp8 dtype views handle both legacy uint8-on-disk and native fp8.\n        if module.quant_format in (\"float8_e4m3fn\", \"float8_e5m2\"):\n            scales = {\"scale\": pop_scale(\"weight_scale\")}\n        elif module.quant_format == \"mxfp8\":\n            bs = pop_scale(\"weight_scale\", torch.float8_e8m0fnu)\n            if bs is None:\n                raise ValueError(f\"Missing MXFP8 block scales for layer {layer_name}\")\n            scales = {\"scale\": bs}\n        elif module.quant_format == \"nvfp4\":\n            ts = pop_scale(\"weight_scale_2\")\n            bs = pop_scale(\"weight_scale\", torch.float8_e4m3fn)\n            if ts is None or bs is None:\n                raise ValueError(f\"Missing NVFP4 scales for layer {layer_name}\")\n            scales = {\"scale\": ts, \"block_scale\": bs}\n        elif module.quant_format == \"int8_tensorwise\":\n            scale = pop_scale(\"weight_scale\")\n            if scale is None:\n                raise ValueError(f\"Missing INT8 weight scale for layer {layer_name}\")\n            scales = {\"scale\": scale}\n            params_conf = layer_conf.get(\"params\", {})\n            if not isinstance(params_conf, dict):\n                params_conf = {}\n            if layer_conf.get(\"convrot\", params_conf.get(\"convrot\", False)):\n                scales[\"convrot\"] = True\n                scales[\"convrot_groupsize\"] = int(\n                    layer_conf.get(\"convrot_groupsize\", params_conf.get(\"convrot_groupsize\", 256))\n                )\n        elif module.quant_format == \"convrot_w4a4\":\n            scale = pop_scale(\"weight_scale\")\n            if scale is None:\n                raise ValueError(f\"Missing ConvRot W4A4 weight scale for layer {layer_name}\")","sourceCodeStart":1156,"sourceCodeEnd":1192,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy/ops.py#L1156-L1192","documentation":"Raised by _load_quantized_module in comfy/ops.py when a layer's `comfy_quant` metadata declares quant_format 'nvfp4' but the state dict does not contain both `weight_scale_2` (the per-tensor secondary scale) and `weight_scale` (the fp8-e4m3 block scale). NVFP4 quantization needs both scales to reconstruct weight values, so loading aborts. The error names the exact layer so you can find which Linear/Conv is missing keys.","triggerScenarios":"Loading a GGUF/safetensors checkpoint that was quantized to NVFP4 where `comfy_quant` config is present but `weight_scale` or `weight_scale_2` keys were stripped, renamed, or saved under a different prefix; merging a state dict that only carries the quantized weight tensor; partially sharded checkpoints where scale shards were not concatenated.","commonSituations":"Using an external NVFP4 conversion tool that does not emit ComfyUI's expected scale key names; hand-editing or re-saving quantized checkpoints; downloading an incomplete/corrupted quantized model; checkpoints quantized with a newer/older key naming convention.","solutions":["Inspect the checkpoint keys (e.g. torch.load / safetensors keys) for `<layer_prefix>.weight_scale` and `<layer_prefix>.weight_scale_2` and confirm both exist next to `<layer_prefix>.weight` and `<layer_prefix>.comfy_quant`.","Re-quantize the model with ComfyUI's own quantization path so both NVFP4 scales are emitted with the expected key names.","Re-download the quantized checkpoint in case the file is truncated or a shard is missing.","If the scales genuinely cannot be supplied, dequantize the layer back to fp16/bf16 or drop the `comfy_quant` entry so it loads as a plain dense layer."],"exampleFix":"# before: state dict has only\n# model.layers.0.self_attn.q_proj.weight\n# model.layers.0.self_attn.q_proj.comfy_quant\n# (missing weight_scale / weight_scale_2 -> ValueError)\n\n# after: include both scales\n# model.layers.0.self_attn.q_proj.weight\n# model.layers.0.self_attn.q_proj.weight_scale       # fp8 e4m3 block scale\n# model.layers.0.self_attn.q_proj.weight_scale_2     # per-tensor scale\n# model.layers.0.self_attn.q_proj.comfy_quant","handlingStrategy":"validation","validationCode":"prefix = 'model.layers.0.self_attn.q_proj.'\nneed = {prefix + 'weight_scale_2', prefix + 'weight_scale'}\nmissing = need - set(sd.keys())\nassert not missing, f'NVFP4 layer missing scales: {missing}'","typeGuard":null,"tryCatchPattern":"try:\n    model_patcher = load_diffusion_model(path)\nexcept ValueError as e:\n    if 'Missing NVFP4 scales' in str(e):\n        raise SystemExit(f'{path} is an incomplete NVFP4 quantization; re-quantize or re-download')\n    raise","preventionTips":["Quantize models only with ComfyUI's own quantization utilities so scale key names always match the loader.","When merging or filtering state dicts, never drop keys named weight_scale, weight_scale_2, weight_s_rel.","After downloading a quantized checkpoint, verify scale keys exist before loading."],"tags":["quantization","nvfp4","checkpoint-loading","state-dict"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}