Repository navigation
Fix CLIP _init_weights when a child module carries quantized weights - #47921
Rocketknight1 merged 4 commits into
Conversation
Rocketknight1
left a comment
There was a problem hiding this comment.
I took a look and this does make sense. Most models don't use this approach but CLIP does, and it does break when combined with quantization. The fix is clean enough too, so I'm happy to merge it!
|
Also @Bluear7878 although this pattern is quite common, most models use the base method for init weights, which doesn't trigger this issue. So the only models where this init pattern is problematic are the ones that override the weight init method and access child weights like this. |
`CLIPPreTrainedModel._init_weights` initializes the parameters of child modules by name (`module.q_proj.weight`, `module.fc1.weight`, ...). A quantized checkpoint replaces `weight` on those children with packed tensors -- `weight_packed` for compressed-tensors, `qweight` for GPTQ/AWQ -- so loading one raises `AttributeError: 'Linear' object has no attribute 'weight'` from the init pass that `from_pretrained` runs for the keys that are missing from the checkpoint. Route every child-weight initialization through a helper that skips a child that has no `weight`, mirroring the guard the generic `PreTrainedModel._init_weights` already applies to `nn.Linear`. Initialization of a non-quantized model is unchanged. MetaCLIP-2 inlines this method through modular, so its modeling file is regenerated.
04196be to
3630a9e
Compare
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
Head branch was pushed to by a user without write access
|
[For maintainers] Suggested jobs to run (before merge) run-slow: clip, metaclip_2 |
CI recapDashboard: View test results in Grafana |
What does this PR do?
Fixes #47920
CLIPPreTrainedModel._init_weightsinitializes the parameters of child modules by name —module.q_proj.weight,module.fc1.weight,module.text_projection.weight, and so on. A quantizedcheckpoint replaces
weighton those children with packed tensors (weight_packedforcompressed-tensors,
qweightfor GPTQ/AWQ), so loading one raisesfrom the initialization pass that runs at the end of loading:
_finalize_model_loading→_initialize_missing_keys→initialize_weights→smart_apply→_init_weights(
modeling_utils.py:4517,:2476-2491). For a packed format the packed layout is installed beforethe weights are loaded, by
transformersitself —CompressedTensorsHfQuantizer._process_model_before_weight_loadingcallsself.compressor.compress_model(model)(quantizers/quantizer_compressed_tensors.py:117-121).A container such as
CLIPAttentionowns no parameter of its own, so_initialize_weights' skipconditions never apply to it for a class living in
transformers.*, and it always reaches_init_weights.This PR routes every child-weight initialization in
CLIPPreTrainedModel._init_weightsthrough asmall helper that skips a child with no
weight, which is the guard the genericPreTrainedModel._init_weightsalready applies tonn.Linear/nn.Conv*(modeling_utils.py:2392)and to the norms (
:2418-2421, "Norms can exist without weights"). It is the same shape as themerged #38013, which fixed this class of failure in
modeling_qwen2_5_omni.pyfor AutoAWQcheckpoints.
MetaClip2PreTrainedModelinherits this method through modular and the converter inlines the body,so
models/metaclip_2/modeling_metaclip_2.pyis regenerated in the same commit(
python utils/modular_model_converter.py --files_to_parse src/transformers/models/metaclip_2/modular_metaclip_2.py);MetaCLIP-2 gets the fix with it.
Initialization of a non-quantized model is unchanged: the seeded
state_dictof a tinyCLIPModelhashes to the same SHA-256 before and after the patch (
a6808d27…). The change also removes apre-existing crash for
CLIPForImageClassificationwithnum_labels == 0, whereclassifieris annn.Identity.Verification
The 8 failures are all
test_multi_gpu_data_parallel_forward(4 in the CLIP file, 4 in the MetaCLIP-2file). They are pre-existing on this machine: the same 8 fail on the parent commit, and nothing else in
those five files fails.
The
typeschecker fails identically on the parent commit with thetyversion I have installed, soit is not affected by this diff.
Scope
The same pattern —
_init_weightsdereferencing a child module's.weight/.bias— is present in 83of 488
modeling_*.pyfiles onmain, and I measured the identicalAttributeErrorforT5,Mamba2,LLaVA(CLIP vision tower) andGemma3(SigLIP vision tower). The issue linked above hasthe full analysis, including why marking the quantized modules
_is_hf_initialized(as thebitsandbytes/torchao/quanto/mxfp4/sinq integrations do) does not fix it, and why the 4.x
"skip a fully loaded subtree" rule does not either. I kept this PR to CLIP; happy to extend the guard
to the other families in whatever batching you prefer.
Code Agent Policy
Not applicable — I am not a first-time contributor (#46277, #47940). Per the Agentic contributions
section of
CONTRIBUTING.md: this change was prepared with AI assistance (Claude Code). I havereviewed every changed line, the analysis and every number above come from runs against the installed
packages, the test commands and results are quoted above, the coordination link is #47920, and I am
not aware of another open PR touching CLIP's
_init_weights. I opened this alongside the issue so thediff is concrete rather than hypothetical -- if you would rather settle the scope there first (one
model vs. the 83 files that share the pattern), say so and I will hold this PR until then.
Before submitting
Pull Request checks?
to it if that's the case. — see the linked issue
tests/models/clip/test_modeling_clip.py::CLIPModelTest::test_init_weights_with_quantized_childrenWho can review?
@Cyrilvallez (the failure is in the
from_pretrainedinitialization pass), @molbap (CLIP)