[Bugfix] Resolve the Hub revision once per repo (#56092)
Signed-off-by: Wauplin <lucainp@gmail.com> Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 5
Harry Mellor
mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent
a7d203efe5
commit
344fcc252a
@@ -3867,19 +3867,12 @@ def test_load_config_rejects_non_string_load_format(bad_load_format):
|
||||
LoadConfig(load_format=bad_load_format)
|
||||
|
||||
|
||||
# A real Qwen3-0.6B model revision that is used in the tests below.
|
||||
# A real Qwen3-0.6B model revision that is used in the test below.
|
||||
REVISION = "c1899de289a04d12100db370d81485cdf75e47ca"
|
||||
|
||||
|
||||
@patch("vllm.config.model.resolve_revision", return_value=ResolvedRevision(REVISION))
|
||||
def test_revision_not_resolved_when_weights_differ_from_model(mock_resolve):
|
||||
model_weights = "unsloth/Qwen3-0.6B-GGUF:Q8_0"
|
||||
config = ModelConfig("Qwen/Qwen3-0.6B", model_weights=model_weights)
|
||||
assert config.revision is None
|
||||
|
||||
|
||||
@patch("vllm.config.model.resolve_revision", return_value=ResolvedRevision(REVISION))
|
||||
def test_revision_resolved_when_weights_match_model(mock_resolve):
|
||||
def test_revision_resolved_for_model(mock_resolve):
|
||||
model = "Qwen/Qwen3-0.6B"
|
||||
config = ModelConfig(model)
|
||||
assert isinstance(config.revision, ResolvedRevision)
|
||||
|
||||
@@ -208,6 +208,7 @@ def test_model_config_generation_fallback_forwards_code_revision():
|
||||
model="org/model",
|
||||
trust_remote_code=True,
|
||||
revision="model-pin",
|
||||
_hf_config_revision=None,
|
||||
code_revision="code-pin",
|
||||
config_format="auto",
|
||||
hf_token=None,
|
||||
|
||||
+18
-13
@@ -589,22 +589,27 @@ class ModelConfig:
|
||||
self.maybe_pull_model_tokenizer_for_runai(self.model, self.tokenizer)
|
||||
|
||||
# If loading model/tokenizer from HF Hub, resolve the revision once
|
||||
# to prevent resolving it multiple times downstream.
|
||||
# If the weights come from a different repo, we cannot eagerly resolve revision
|
||||
weights_from_model = not self.model_weights or self.model_weights == self.model
|
||||
# If the config comes from a different repo, we cannot eagerly resolve revision
|
||||
config_from_model = not self.hf_config_path or self.hf_config_path == self.model
|
||||
can_resolve_model_revision = config_from_model and weights_from_model
|
||||
if can_resolve_model_revision:
|
||||
self.revision = resolve_revision(
|
||||
self.model,
|
||||
# to prevent resolving it multiple times downstream. A resolved revision
|
||||
# only pins the repo it was resolved for, so each repo needs its own call.
|
||||
self.revision = resolve_revision(
|
||||
self.model,
|
||||
self.revision,
|
||||
self.hf_token,
|
||||
)
|
||||
|
||||
# The config can live in another repo, which `self.revision` does not pin.
|
||||
# It stays `None` if the config comes from `self.model`, so that call sites
|
||||
# fall back to `self.revision` the same way they fall back to `self.model`.
|
||||
self._hf_config_revision = None
|
||||
if self.hf_config_path and self.hf_config_path != self.model:
|
||||
self._hf_config_revision = resolve_revision(
|
||||
self.hf_config_path,
|
||||
self.revision,
|
||||
self.hf_token,
|
||||
)
|
||||
|
||||
if (
|
||||
can_resolve_model_revision
|
||||
and self.tokenizer == self.model
|
||||
self.tokenizer == self.model
|
||||
and self.tokenizer_revision == requested_revision
|
||||
):
|
||||
self.tokenizer_revision = self.revision
|
||||
@@ -632,7 +637,7 @@ class ModelConfig:
|
||||
hf_config = get_config(
|
||||
self.hf_config_path or self.model,
|
||||
self.trust_remote_code,
|
||||
self.revision,
|
||||
self._hf_config_revision or self.revision,
|
||||
self.code_revision,
|
||||
self.config_format,
|
||||
hf_overrides_kw=hf_overrides_kw,
|
||||
@@ -1779,7 +1784,7 @@ class ModelConfig:
|
||||
config = try_get_generation_config(
|
||||
self.hf_config_path or self.model,
|
||||
trust_remote_code=self.trust_remote_code,
|
||||
revision=self.revision,
|
||||
revision=self._hf_config_revision or self.revision,
|
||||
code_revision=self.code_revision,
|
||||
config_format=self.config_format,
|
||||
hf_token=self.hf_token,
|
||||
|
||||
@@ -15,6 +15,7 @@ from vllm.model_executor.model_loader.weight_utils import (
|
||||
download_weights_from_hf,
|
||||
runai_safetensors_weights_iterator,
|
||||
)
|
||||
from vllm.transformers_utils.repo_utils import resolve_revision
|
||||
from vllm.transformers_utils.runai_utils import is_runai_obj_uri, list_safetensors
|
||||
|
||||
|
||||
@@ -87,6 +88,11 @@ class RunaiModelStreamerLoader(BaseModelLoader):
|
||||
safetensors_pattern = "*.safetensors"
|
||||
index_file = SAFE_WEIGHTS_INDEX_NAME
|
||||
|
||||
if not is_local and not is_object_storage_path:
|
||||
# `model_weights` can point to another repo than the one `revision` was
|
||||
# resolved for, which does not pin this one.
|
||||
revision = resolve_revision(model_name_or_path, revision)
|
||||
|
||||
hf_folder = (
|
||||
model_name_or_path
|
||||
if (is_local or is_object_storage_path)
|
||||
|
||||
@@ -63,6 +63,11 @@ def resolve_revision(
|
||||
requested revision that also carries the commit hash, so downstream error
|
||||
messages stay readable and offline loads reuse the cached `refs/` entry.
|
||||
|
||||
A commit hash only means something for the repo it was resolved against, so
|
||||
a repo that is not `repo_id` needs its own call. Passing a revision resolved
|
||||
for another repo back in is safe: the revision initially requested is
|
||||
resolved again, against `repo_id` this time.
|
||||
|
||||
Returns:
|
||||
The resolved revision, or `revision` unchanged if it cannot be resolved
|
||||
(local path, ModelScope, or any Hub error).
|
||||
|
||||
Reference in New Issue
Block a user