Skip to content

Unwrap text_config in AutoModelFor*.from_config#45770

Merged
zucchini-nlp merged 3 commits intohuggingface:mainfrom
jamesbraza:fix-automodel-from-config-text-config-unwrap-45759
May 5, 2026
Merged

Unwrap text_config in AutoModelFor*.from_config#45770
zucchini-nlp merged 3 commits intohuggingface:mainfrom
jamesbraza:fix-automodel-from-config-text-config-unwrap-45759

Conversation

@jamesbraza
Copy link
Copy Markdown
Contributor

Comment on lines +242 to +243
# TODO: Validate that copying the parent quantization config to the text sub-config preserves
# modules_to_not_convert and skip-module matching when composite-model module prefixes differ.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Matching #45494 here, fyi

Comment thread tests/models/gemma3/test_modeling_gemma3.py
Comment on lines +241 to 250
if model_class.config_class == config.sub_configs.get("text_config", None):
# TODO: Validate that copying the parent quantization config to the text sub-config preserves
# modules_to_not_convert and skip-module matching when composite-model module prefixes differ.
parent_config = config
config = config.get_text_config()
# Propagate quantization_config from the composite parent config so that
# `get_hf_quantizer` can correctly detect the model as pre-quantized.
if hasattr(parent_config, "quantization_config"):
config.quantization_config = parent_config.quantization_config
return model_class._from_config(config, **kwargs)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh i am not even sure we are actually using it, except for qwen3.5. From what I see in mapping, gemma models will load a VLM class. And this makes sense if a complete config is passed/downloaded

Not sure what was the idea with qwen3.5 as I wasn't there when shipping the model, but a VLM class should be completely capable of running text-only samples

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw I just re-ran the minimal reproducer from #45759 for Qwen/Qwen3.6-35B-A3B, the crash I reported does happen. This makes sense because qwen3_5_moe backs Qwen/Qwen3.6-… too.

a VLM class should be completely capable of running text-only samples

My motivation mainly is for SkyRL's FSDP setup it wants AutoModelForCausalLM to give back a text-only class. Mainly this PR just brings from_config in line with from_pretrained's current behavior.

Are you thinking something else? I think I may not be fully appreciating your comment here.

@Qodo-Free-For-OSS
Copy link
Copy Markdown

Hi, _BaseAutoModelClass.from_config and .from_pretrained now copy quantization_config onto the unwrapped text config whenever the parent has the attribute, even if the value is None; downstream quantizer detection treats this as pre-quantized and will crash on None.get(...).

Severity: action required | Category: correctness

How to fix: Guard quantization_config propagation

Agent prompt to fix - you can give this to your LLM of choice:

Issue description

AutoModelFor*.from_config/from_pretrained now propagates quantization_config from a composite parent config to the unwrapped text_config. If the parent has quantization_config=None, the propagated attribute presence causes get_hf_quantizer() to treat the model as pre-quantized and crash when it calls .get() on None.

Issue Context

get_hf_quantizer uses hasattr(config, "quantization_config") (not value checks) to decide pre_quantized, and AutoHfQuantizer.supports_quant_method() assumes a dict-like object and calls .get().

Fix Focus Areas

  • src/transformers/models/auto/auto_factory.py[241-249]
  • src/transformers/models/auto/auto_factory.py[394-402]

What to change

  • Only set config.quantization_config on the text sub-config when the parent value is not None.
  • Prefer getattr(parent_config, "quantization_config", None) over hasattr.
  • Consider also preserving an existing non-None quantization_config already present on the text sub-config (avoid overwriting).

Qodo code review - free for open-source.

jamesbraza and others added 2 commits May 4, 2026 09:48
Mirror the existing from_pretrained text_config unwrap into from_config so
the composite-config -> text-only-model "VLM compatibility" mapping (e.g.
Qwen3.5 / Qwen3.5-MoE) works for meta-init paths too. Without this,
AutoModelForCausalLM.from_config(Qwen3_5MoeConfig(...)) fails with
AttributeError because the text-only model class receives the composite
config. Also propagate quantization_config from the parent so pre-quantized
detection still works, mirroring PR huggingface#45494.

Add a parametrized regression test covering both from_pretrained and
from_config in the qwen3_5 and qwen3_5_moe model test files,
and extend the existing gemma3 test_automodelforcausallm to match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The unwrap branch in AutoModelFor*.from_config never triggers for gemma3
(its MODEL_FOR_CAUSAL_LM_MAPPING entry routes Gemma3Config to the VLM
class Gemma3ForConditionalGeneration, whose config_class is Gemma3Config
itself, not Gemma3TextConfig). The new from_config parameterization
therefore exercised only the pre-existing path and added no coverage of
the fix.
@jamesbraza jamesbraza force-pushed the fix-automodel-from-config-text-config-unwrap-45759 branch from 80fd48f to 42d9f7a Compare May 4, 2026 16:48
`hasattr(parent_config, "quantization_config")` returns True even when
the value is `None` (e.g. a config.json containing
`"quantization_config": null`, or a dequantization step that cleared
the attribute). The previous propagation copied that None onto the
unwrapped text sub-config, and `from_pretrained`'s downstream
`get_hf_quantizer` keys off `hasattr` to set `pre_quantized=True`, then
crashes inside `AutoHfQuantizer.supports_quant_method(None)` on
`None.get(...)`.

Switch to `getattr(parent_config, "quantization_config", None) is not
None` at both call sites so absent and None collapse into the same
"don't propagate" case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

[For maintainers] Suggested jobs to run (before merge)

run-slow: auto, qwen3_5, qwen3_5_moe

@jamesbraza
Copy link
Copy Markdown
Contributor Author

Hi, _BaseAutoModelClass.from_config and .from_pretrained now copy quantization_config onto the unwrapped text config whenever the parent has the attribute, even if the value is None; downstream quantizer detection treats this as pre-quantized and will crash on None.get(...).

Severity: action required | Category: correctness

How to fix: Guard quantization_config propagation

...

Sure @Qodo-Free-For-OSS , just pushed a commit adding this to both call sites in auto_factory.py (from_config and from_pretrained):

# Check both `quantization_config` being present and also not null,
# as a `config.json` can have `"quantization_config": null` in it
parent_quant = getattr(parent_config, "quantization_config", None)
if parent_quant is not None:
    config.quantization_config = parent_quant

@jamesbraza jamesbraza requested a review from zucchini-nlp May 4, 2026 19:01
Copy link
Copy Markdown
Member

@zucchini-nlp zucchini-nlp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I don't mind it, since we already support loading only LM part of Qwen3-5 from_pretrained

My comments aren't really directed to this PR. The fact that we allowed and support loading one model type inside a different one wasn't a good idea imo. As said, slipped off my radar so let's get it in for consistency in from_config/from_pretrained

@HuggingFaceDocBuilderDev
Copy link
Copy Markdown

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.

@zucchini-nlp zucchini-nlp added this pull request to the merge queue May 5, 2026
Merged via the queue into huggingface:main with commit 136befe May 5, 2026
29 checks passed
@jamesbraza jamesbraza deleted the fix-automodel-from-config-text-config-unwrap-45759 branch May 5, 2026 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AutoModelForCausalLM.from_config does not unwrap text_config for composite Qwen 3.5 and 3.6 multimodal configs

4 participants