You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AttributeError: 'Linear' object has no attribute 'weight_scale' — ModelMergeSimple on a quantized (fp8/QuantizedTensor) model: unguarded getattr in get_key_weight vs synthetic quant state-dict keys #14382
I have tried disabling custom nodes and the issue persists (see how to disable custom nodes if you need help)
Core nodes only — no custom nodes involved in the repro.
Expected Behavior
ModelMergeSimple (and the other get_key_patches-based merge nodes) should be able to merge a checkpoint whose weights were loaded as QuantizedTensor (e.g. an FP8 e4m3fn mixed-precision quantized checkpoint). The real .weight keys already have a working convert_weight dequantization path in get_key_weight, so quantized merging is clearly intended to work.
Actual Behavior
Deterministic crash at the merge node, before any sampling, whenever model2 (the model get_key_patches is called on) is a quantized checkpoint:
AttributeError: 'Linear' object has no attribute 'weight_scale'
Observed on a v0.24.0-based build; I verified the relevant code is unchanged on current master (line numbers below are from master).
Connect both to ModelMergeSimple (quantized model as model2) and queue.
Instant AttributeError — 100% reproducible, no GPU/sampling needed.
Affects every node that calls get_key_patches on a quantized model: ModelMergeSimple, ModelMergeBlocks, ModelMergeSubtract, ModelMergeAdd, CLIPMergeSimple, CheckpointSave-after-merge, etc.
Debug Logs
Traceback (most recent call last):
File "ComfyUI/comfy_extras/nodes_model_merging.py", line 28,in merge
kp = model2.get_key_patches("diffusion_model.")
File "ComfyUI/comfy/model_patcher.py", line 822,in get_key_patches
weight, set_func, convert_func = get_key_weight(self.model, k)
File "ComfyUI/comfy/model_patcher.py", line 186,in get_key_weight
weight = getattr(op, op_keys[1])
File "torch/nn/modules/module.py", line 1928,in __getattr__
raise AttributeError(
AttributeError: 'Linear' object has no attribute 'weight_scale'
(Traceback trimmed to the relevant frames; from a headless server deployment.)
Other
Root cause
The Mixed Precision Quantization System makes quantized layers' state_dict() emit synthetic top-level keys that are not module attributes:
comfy/ops.py:1118_quantized_weight_state_dict writes {prefix}weight_scale (via module.weight.state_dict(f"{prefix}weight")), {prefix}comfy_quant (line 1136), {prefix}input_scale (extra_quant_params, line 1181), and {prefix}weight_scale_2 for nvfp4.
On load these keys are popped and absorbed into the QuantizedTensor layout params — _load_quantized_module explicitly skipsregister_parameter for weight_scale / weight_scale_2 (comfy/ops.py:1103-1104). So they exist only in the state dict, never on the module.
Meanwhile ModelPatcher.get_key_patches (comfy/model_patcher.py:813) iterates allmodel_state_dict() keys and feeds each one to get_key_weight, which does an unguarded lookup (comfy/model_patcher.py:186):
weight=getattr(op, op_keys[1])
For some.layer.weight_scale this resolves the module fine but then hits torch.nn.Module.__getattr__ → AttributeError.
The old fix f9f9faf ("Fixed model merging issue with scaled fp8", 2024) only covered the legacy scaled_fp8 buffer format, which is a real module attribute — it doesn't help with the new synthetic keys.
Suggested fix (running in our fork, resolves the crash; quantized .weight keys keep their convert_weight dequant path so merging still works as designed):
If returning None from get_key_weight is considered too broad (see the discussion in #11585 about not sweeping bugs under the rug), an alternative is for get_key_patches to explicitly skip the known synthetic suffixes (comfy_quant, weight_scale, weight_scale_2, input_scale). Unlike #11585 (triggered by a custom node's RMS_norm.gamma), here the offending keys are generated by core's own quantized state_dict(), so core nodes alone hit it.
Custom Node Testing
Core nodes only — no custom nodes involved in the repro.
Expected Behavior
ModelMergeSimple(and the otherget_key_patches-based merge nodes) should be able to merge a checkpoint whose weights were loaded asQuantizedTensor(e.g. an FP8 e4m3fn mixed-precision quantized checkpoint). The real.weightkeys already have a workingconvert_weightdequantization path inget_key_weight, so quantized merging is clearly intended to work.Actual Behavior
Deterministic crash at the merge node, before any sampling, whenever model2 (the model
get_key_patchesis called on) is a quantized checkpoint:Observed on a v0.24.0-based build; I verified the relevant code is unchanged on current master (line numbers below are from master).
Steps to Reproduce
comfy_quantmetadata so its weights load asQuantizedTensorvia the Mixed Precision Quantization System, Mixed Precision Quantization System #10498 / Make old scaled fp8 format use the new mixed quant ops system. #11000).ModelMergeSimple(quantized model asmodel2) and queue.AttributeError— 100% reproducible, no GPU/sampling needed.Affects every node that calls
get_key_patcheson a quantized model:ModelMergeSimple,ModelMergeBlocks,ModelMergeSubtract,ModelMergeAdd,CLIPMergeSimple,CheckpointSave-after-merge, etc.Debug Logs
(Traceback trimmed to the relevant frames; from a headless server deployment.)
Other
Root cause
The Mixed Precision Quantization System makes quantized layers'
state_dict()emit synthetic top-level keys that are not module attributes:comfy/ops.py:1118_quantized_weight_state_dictwrites{prefix}weight_scale(viamodule.weight.state_dict(f"{prefix}weight")),{prefix}comfy_quant(line 1136),{prefix}input_scale(extra_quant_params, line 1181), and{prefix}weight_scale_2for nvfp4.QuantizedTensorlayout params —_load_quantized_moduleexplicitly skipsregister_parameterforweight_scale/weight_scale_2(comfy/ops.py:1103-1104). So they exist only in the state dict, never on the module.Meanwhile
ModelPatcher.get_key_patches(comfy/model_patcher.py:813) iterates allmodel_state_dict()keys and feeds each one toget_key_weight, which does an unguarded lookup (comfy/model_patcher.py:186):For
some.layer.weight_scalethis resolves the module fine but then hitstorch.nn.Module.__getattr__→AttributeError.The old fix f9f9faf ("Fixed model merging issue with scaled fp8", 2024) only covered the legacy
scaled_fp8buffer format, which is a real module attribute — it doesn't help with the new synthetic keys.Suggested fix (running in our fork, resolves the crash; quantized
.weightkeys keep theirconvert_weightdequant path so merging still works as designed):plus skipping
Noneentries inget_key_patches:If returning
Nonefromget_key_weightis considered too broad (see the discussion in #11585 about not sweeping bugs under the rug), an alternative is forget_key_patchesto explicitly skip the known synthetic suffixes (comfy_quant,weight_scale,weight_scale_2,input_scale). Unlike #11585 (triggered by a custom node'sRMS_norm.gamma), here the offending keys are generated by core's own quantizedstate_dict(), so core nodes alone hit it.Related but not duplicates
ModelMergeSimple+ quantizedmodel2you never even reach saving.getattrline, different trigger (custom-nodeRMS_normwithout.weight).