Repository navigation
Defer some imports - #49663
Defer some imports#49663
Conversation
…ading Importing AutoConfig/AutoTokenizer pulled in the generation stack (watermark processors, GenerationMixin) and the GGUF loader, which import torch, plus sklearn.metrics via candidate_generator. Each is only needed on one code path, so import it there. Fixes huggingface#49378
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Also check that AutoConfig.for_model('llama') keeps sklearn, the candidate
generator and the gguf loader out of sys.modules, and that the assisted
candidate generator still reaches sklearn.metrics.roc_curve on first use.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Thank you for your contribution 🤗! CI Security Gate — automatic approval blockedThis PR was not automatically approved for CI because the security gate failed. Possible reasons:
See the workflow run for the exact violations. A maintainer can review and manually approve CI if a finding is a false positive. |
Co-Authored-By: Claude Opus 5.5 <[email protected]>
…orts Co-Authored-By: Claude Opus 5.5 <[email protected]> # Conflicts: # tests/utils/test_import_utils.py
| run(torch.zeros(3)) # a graph break inside the helper would raise here | ||
|
|
||
|
|
||
| def test_auto_classes_do_not_import_generation_or_sklearn(): |
There was a problem hiding this comment.
nope none of the tests are actually usefull they only cover some part.
What we could do is a hook and do a simple code checking there are no imports in globals. We can have this contract on stuff that should not require torch to AutoTokenizer and potentially AutoConfig.
Now if the import can just "release the gil" I think a lot of this would not be a pb.
Anyways The changes are good because minimal effort!
There was a problem hiding this comment.
Makes sense, I dropped the tests. Happy to do the import-contract check as a follow-up PR, maybe extending utils/check_import_complexity.py?
|
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. |
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
[For maintainers] Suggested jobs to run (before merge) run-slow: auto |
Cyrilvallez
left a comment
There was a problem hiding this comment.
Yep, fine with deferring those!
Fixes #49378
What
Loading a config or tokenizer pulled in the generation stack and scikit-learn through module-level imports that only matter once a model generates, uses a watermark, or loads a GGUF file. This moves them to first use:
generation/configuration_utils.py:WatermarkLogitsProcessor/SynthIDTextWatermarkLogitsProcessornow import insideconstruct_processor(type hint kept underTYPE_CHECKING).models/auto/auto_factory.py:GenerationMixinimports insideadd_generation_mixin_to_remote_model, the only place it is used.generation/candidate_generator.py:sklearn.metrics.roc_curveimports where the ROC threshold is computed. Theis_sklearn_available()check is unchanged.configuration_utils.py,models/auto/tokenization_auto.py:load_gguf_checkpointimports in the GGUF branch only.No behavior change for code that uses these features.
Numbers
AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")andAutoConfig.for_model("llama"), fresh process each, warm cache, offline, 6 interleaved runs, median wall time:-X importtimeon main:auto_factory2.9 s cumulative, of whichcandidate_generator->sklearn.metrics1.5 s. With this PRauto_factoryis 1 ms.Old, slow box: Intel i5-2430M (2011, 4 threads), Python 3.12.13, torch 2.14.1+cpu, scikit-learn 1.9.1, tokenizers 0.23.2. Absolute times will be much lower on modern hardware; the ratio is what matters.
Not in this PR: torch itself
torch is still imported when available. On current main it comes in through other module-level imports on the config path, e.g.
modeling_rope_utils.py:28andutils/type_validators.py:17-19(which importsACT2FNfromactivations). Thetype_validators->activations->integrations/hub_kernels->integrations/flash_attention->generation.continuous_batchingchain also still loadsgeneration.logits_processfor model configs like llama. Removing those touches a lot more modules, so I'd keep it for a follow-up if you want it. (My earlier comment on the issue said torch stays out; that was inaccurate.)Tests
tests/utils/test_import_utils.py: new subprocess test that importingAutoConfig/AutoTokenizerand building aPreTrainedConfigleavessklearn,generation.logits_process,generation.candidate_generatorandmodeling_gguf_pytorch_utilsout ofsys.modules, and thatAutoConfig.for_model("llama")leavessklearn,candidate_generatorand the gguf loader out. Fails on main, passes here.AssistedCandidateGenerator.update_candidate_strategystill reachesroc_curveand updates the threshold (skipped without sklearn).tests/utils/test_import_utils.py168 passed;tests/generation/test_watermarking.py+test_candidate_generator.py37 passed;test_logits_process.py -k "atermark or SynthID"12 passed;test_configuration_utils.py -k "atermark or SynthID"1 passed;ruff check/ruff format --check(0.14.10) clean;utils/check_dummies.py,check_inits.py,check_import_complexity.pyclean.tests/quantization/ggml, needggufand large downloads). The GGUF change is only moving the import into the branch that calls it.cc @ArthurZucker @itazap
AI disclosure: I used Claude Code to write the change and tests; I reviewed the diff and the measurements.