Fix JSONDecodeError when a layer's comfy_quant marker is empty - #16474
chelsealong wants to merge 2 commits into
Conversation
Some quantized checkpoints (e.g. int8_convrot text encoders) store an empty comfy_quant tensor for layers that aren't quantized, such as the token embedding, instead of omitting the key. json.loads() on the resulting empty byte string raised "Expecting value: line 1 column 1 (char 0)" and aborted CLIP loading. Treat an empty marker the same as a missing one (load the layer as plain full-precision weight). Fixes Comfy-Org#16472
The prior test only exercised the Linear/_load_quantized_module path. The reported crash (Comfy-Org#16472) actually occurred in MixedPrecisionOps.Embedding._load_from_state_dict (comfy/ops.py:1628, the token embedding table of an int8_convrot text encoder), which had no coverage.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: Comfy-Org/ComfyUI/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📜 Recent review details⏰ Context from checks skipped due to timeout. (6)
🧰 Additional context used📓 Path-based instructions (3)Core ML/diffusion engine.⚙️ CodeRabbit configuration file Files:
IMPORTANT: Only comment on issues directly introduced by this PR's code changes.⚙️ CodeRabbit configuration file Files:
Documentation and README edits should be concise, factual, and tied to the changed behavior.📄 CodeRabbit inference engine (AGENTS.md) Files:
🪛 ast-grep (0.45.3)comfy/ops.py[warning] 1347-1709: Do not use an empty list as a default parameter Note: [CWE-710] Improper Adherence to Coding Standards (mutable default argument). (no-empty-list-as-parameter) 🔇 Additional comments (4)
📝 WalkthroughWalkthroughThe quantized module loader and Priority: ➖ Normal Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to Empty quantization markers now load as unquantized weights, preventing the Qwen text-encoder loading failure. The focused regression coverage supports merging this change. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
|
I don't understand how to reproduce this, with what model file does this happen? |
|
From the linked issue (#16472), the model is |
|
Well I can't reproduce it, and that's the only text encoder I've ever used with this model. |
|
Checked the actual file the Qwen 2.1 template uses: So the officially-hosted file doesn't hit this path, which lines up with @kijai not being able to reproduce it. The reporter's traceback is real, but the likely cause is a truncated/incomplete local download rather than the file itself shipping an empty marker — that The code change itself is still a reasonable no-op safety net for a malformed/truncated marker (it only changes behavior when the tensor is actually empty), but it isn't reproducible against the current, complete model file. |
Fixes #16472
Problem
Loading the Qwen 2.1 image-edit template's text encoder
(
qwen3vl_8b_int8_convrot.safetensors) fails with:Root cause
comfy/ops.pyreads each quantized layer's config from a<prefix>.comfy_quanttensor and always JSON-decodes it once the keyis present:
Some quantized checkpoints store this marker for a layer that isn't
actually quantized (e.g. the token embedding table in this
int8_convrot text encoder) as a present-but-empty tensor rather
than omitting the key entirely.
json.loads(b"")raisesJSONDecodeError: Expecting value: line 1 column 1 (char 0)— exactlythe error in the traceback — which aborts loading the whole CLIP
model.
This code path exists twice in
comfy/ops.py: once in the shared_load_quantized_modulehelper used byLinear/Conv/etc., and oncein
MixedPrecisionOps.Embedding._load_from_state_dict.Fix
Treat an empty
comfy_quanttensor the same as a missing one: skipthe JSON decode and fall through to the existing "not quantized" path
that loads the layer as a plain full-precision weight.
Test plan
Added two tests to
tests-unit/comfy_quant/test_mixed_precision.py,one per affected code path:
test_empty_comfy_quant_marker_treated_as_unquantizedcovers theLinear/Convpath (_load_quantized_module).test_empty_comfy_quant_marker_on_embedding_treated_as_unquantizedcovers
MixedPrecisionOps.Embedding._load_from_state_dictdirectly— the actual path in the reported traceback (the token embedding
table of the int8_convrot text encoder).
Each builds a state dict with an empty
comfy_quanttensor andasserts the layer loads without error and stays a plain
(non-quantized) weight.
Verified the Embedding test reproduces the exact reported error
without the fix, matching the issue's traceback function and line
number:
ruff check comfy/ops.py tests-unit/comfy_quant/test_mixed_precision.pypasses with no findings.AI disclosure
This change was written by an autonomous Claude-based coding agent, with the diff reviewed for correctness before submission.