Resolve the Hub revision once per load instead of passing a private _commit_hash around - #47611
Resolve the Hub revision once per load instead of passing a private _commit_hash around#47611Wauplin wants to merge 1 commit into
Conversation
|
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. |
|
let's wait for huggingface/huggingface_hub#4604 to be shipped first |
fb3eb93 to
5c02c9e
Compare
|
[For maintainers] Suggested jobs to run (before merge) run-slow: auto, bark, ernie4_5_vl_moe |
Replace the private `_commit_hash` plumbing by resolving the requested revision with `HfApi.resolve_revision` at each public loading entry point, then passing the returned `ResolvedRevision` around as the regular `revision` argument. Signed-off-by: Wauplin <lucainp@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5c02c9e to
9adb84e
Compare
|
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. |
CI recapDashboard: View test results in Grafana
|
Follow-up on
huggingface_hubv1.26.0, which shippedresolve_revision/ResolvedRevision. Same change as vllm-project/vllm#49990 (in production since) and huggingface/diffusers#14340. Alternative to #47583, same goal, opposite approach.Important
Blocked on huggingface/huggingface_hub#4767, which makes a
ResolvedRevisiononly pin the repo it was resolved for. Thehuggingface_hubminimum here is set to1.30.0and needs adjusting to whatever release ships it.What
Loading a model, a tokenizer or a pipeline fetches many files from the same repo one by one (
config.json, the weight index, each shard, the tokenizer files, remote code, adapters, ...). Each of those lookups resolvesrevision="main"on its own, and nothing guarantees that two of them land on the same commit.transformersalready had a mechanism against this — the private_commit_hashkwarg, threaded from call to call — but it has to be passed explicitly everywhere and has been dropped in several loading paths over time (#47583 is the fourth or fifth round of putting it back).This PR resolves the revision once, at the top of every public loading entry point, and passes the resulting
ResolvedRevisiondown as the regularrevisionargument.revisionis already plumbed everywhere, so nothing else needs threading around and_commit_hashis removed entirely. AsResolvedRevisionis astrsubclass whose string value stays the revision the user asked for, URLs and error messages are unchanged.utils.hub.resolve_revisionwrapsHfApi.resolve_revision: no-op for local folders and for callers passingproxies(the sharedHfApiclient cannot honor per-call proxies), and fail-open — on any Hub error the revision the caller asked for is used as is, so the regular loading path reports the problem with its usual message.PreTrainedConfig,GenerationConfig,PreTrainedModel,PreTrainedTokenizerBase,MistralCommonBackend,ProcessorMixin,ImageProcessingMixin,BaseVideoProcessor,FeatureExtractionMixin, everyAuto*class,pipeline,load_adapterand the Bark/Ernie special paths.ResolvedRevisionis only trusted by the repo it was resolved for, so a component loaded from elsewhere resolves the revision that was requested.cached_filestrusts the cache whenever the revision pins a commit, for present and known-missing files, so noHEADis sent for something the cache already knows about.RequestCountercountedurllib3log lines, which observes nothing since the Hub client moved tohttpx; it now countshttpxrequests. The twotest_cached_*_has_minimum_calls_to_headtests that were skipped as "failing on main" are enabled again.huggingface_hubbumped: #4692 is needed as well (the config kwargs of a load are deep-copied, which would otherwise lose the resolved commit).Measurements
HTTP calls on a warm cache, counted by wrapping
httpx.Client.send:mainAutoModel.from_pretrainedAutoModel.from_pretrained(sharded)AutoTokenizer.from_pretrainedpipeline("text-classification")revision=<commit hash>The 3 remaining calls are the revision resolution plus the two repository listings the tokenizer uses to discover its chat templates and vocabulary files. A cold cache is a wash: one
repo_infomore, a fewHEADs less (9 → 8 for a model, 28 → 27 for the pipeline).Behavior changes worth a look during review
config._commit_hashandgeneration_config._commit_hashno longer exist. They were private, but they were readable.BarkProcessorused topopthe download kwargs, so its tokenizer was loaded without the requestedrevisionand only the first of the three voice preset files honored them. Both now use the resolved revision.Testing
tests/utils,tests/models/auto,tests/tokenization,tests/peft_integrationandtests/pipelines/test_pipelines_common.pypass, except failures that reproduce onmainin the same environment. Error messages and loaded objects were also compared againstmainon ~30 scenarios (bad revision, missing repo, gated repo, no weights, offline mode, local folder, cross-repo config/tokenizer, adapters loaded through anAuto*class, a concrete class andload_adapter): identical, only the request counts change.AI assistance
This draft was prepared with AI assistance. The submitting human should review and understand every changed line before marking it ready for review.