A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 2, 11:00 UTC
Add vLLM library info to Hugging Face Hub requests (#43857)
Signed-off-by: Wauplin <lucainp@gmail.com> Signed-off-by: Lucain Pouget <lucain@huggingface.co> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Lucain committed
May 29, 2026 at 16:04 UTC
11dfa3169d16b85adf74f7a9fc386b50b67bc732
13 files changed
+78
-43
tests/lora/test_utils.py
+2
-2
@@ -175,7 +175,7 @@ def test_get_adapter_absolute_path_local_existing(mock_abspath, mock_exist):
175
assert get_adapter_absolute_path(path) == absolute_path
176
177
178
-@patch("huggingface_hub.snapshot_download")
178
+@patch("huggingface_hub.HfApi.snapshot_download")
179
@patch("os.path.exists")
180
def test_get_adapter_absolute_path_huggingface(mock_exist, mock_snapshot_download):
181
# Hugging Face model identifier
@@ -186,7 +186,7 @@ def test_get_adapter_absolute_path_huggingface(mock_exist, mock_snapshot_downloa
186
assert get_adapter_absolute_path(path) == absolute_path
187
188
189
-@patch("huggingface_hub.snapshot_download")
189
+@patch("huggingface_hub.HfApi.snapshot_download")
190
@patch("os.path.exists")
191
def test_get_adapter_absolute_path_huggingface_error(
192
mock_exist, mock_snapshot_download
vllm/assets/video.py
+2
-2
@@ -7,10 +7,10 @@ from typing import Any, ClassVar, Literal
7
8
import numpy as np
9
import numpy.typing as npt
10
-from huggingface_hub import hf_hub_download
10
from PIL import Image
11
12
from vllm.multimodal.media.audio import load_audio_pyav
13
+from vllm.transformers_utils.repo_utils import hf_api
14
15
from .base import get_cache_dir
16
@@ -27,7 +27,7 @@ def download_video_asset(filename: str) -> str:
27
video_path = video_directory / filename
28
video_path_str = str(video_path)
29
if not video_path.exists():
30
- video_path_str = hf_hub_download(
30
+ video_path_str = hf_api().hf_hub_download(
31
repo_id="raushan-testing-hf/videos-test",
32
filename=filename,
33
repo_type="dataset",
vllm/benchmarks/datasets/datasets.py
+5
-2
@@ -31,7 +31,6 @@ from typing import Any, cast
31
32
import numpy as np
33
import pybase64 as base64
34
-from huggingface_hub import snapshot_download
34
from PIL import Image
35
from typing_extensions import deprecated
36
@@ -46,6 +45,7 @@ from vllm.lora.utils import get_adapter_absolute_path
45
from vllm.multimodal.audio import get_audio_duration
46
from vllm.multimodal.image import convert_image_mode
47
from vllm.tokenizers import TokenizerLike
48
+from vllm.transformers_utils.repo_utils import hf_api
49
from vllm.utils.argparse_utils import FlexibleArgumentParser
50
from vllm.utils.import_utils import PlaceholderModule
51
from vllm.utils.mistral import is_mistral_tokenizer
@@ -3334,7 +3334,10 @@ class MMVUDataset(HuggingFaceDataset):
3334
self._remote_path_root = (
3335
f"https://huggingface.co/datasets/{self.hf_name}/resolve/main"
3336
)
3337
- self._local_path_root = snapshot_download(self.hf_name, repo_type="dataset")
3337
+ self._local_path_root = hf_api().snapshot_download(
3338
+ self.hf_name,
3339
+ repo_type="dataset",
3340
+ )
3341
3342
def sample(
3343
self,
vllm/lora/utils.py
+4
-2
@@ -4,7 +4,6 @@
4
import os
5
from typing import TYPE_CHECKING
6
7
-import huggingface_hub
7
import regex as re
8
from huggingface_hub.utils import HfHubHTTPError, HFValidationError
9
from torch import nn
@@ -37,6 +36,7 @@ from vllm.lora.layers import (
36
from vllm.model_executor.layers.fused_moe import FusedMoE
37
from vllm.model_executor.layers.linear import LinearBase
38
from vllm.model_executor.utils import get_moe_expert_mapping, get_packed_modules_mapping
39
+from vllm.transformers_utils.repo_utils import hf_api
40
41
if TYPE_CHECKING:
42
from vllm.model_executor.layers.logits_processor import LogitsProcessor
@@ -340,7 +340,9 @@ def get_adapter_absolute_path(lora_path: str) -> str:
340
error_log = "Error downloading the ModelScope model"
341
else:
342
# Otherwise, we assume the path is a Hugging Face Hub repo.
343
- download_fn = lambda: huggingface_hub.snapshot_download(repo_id=lora_path)
343
+ download_fn = lambda: hf_api().snapshot_download(
344
+ repo_id=lora_path,
345
+ )
346
download_exceptions = (HfHubHTTPError, HFValidationError)
347
error_log = "Error downloading the HuggingFace model"
348
vllm/model_executor/model_loader/bitsandbytes_loader.py
+2
-3
@@ -10,7 +10,6 @@ from typing import Any
10
11
import numpy as np
12
import torch
13
-from huggingface_hub import HfApi
13
from packaging import version
14
from torch import nn
15
from transformers.utils import SAFE_WEIGHTS_INDEX_NAME
@@ -48,6 +47,7 @@ from vllm.model_executor.utils import (
47
set_weight_attrs,
48
)
49
from vllm.platforms import current_platform
50
+from vllm.transformers_utils.repo_utils import hf_api
51
from vllm.utils.torch_utils import set_default_torch_dtype
52
53
logger = init_logger(__name__)
@@ -97,8 +97,7 @@ class BitsAndBytesModelLoader(BaseModelLoader):
97
if weight_files:
98
return model_name_or_path, weight_files, pattern
99
else:
100
- hf_api = HfApi()
101
- repo_files = hf_api.list_repo_files(repo_id=model_name_or_path)
100
+ repo_files = hf_api().list_repo_files(repo_id=model_name_or_path)
101
for pattern in allowed_patterns:
102
matching_files = fnmatch.filter(repo_files, pattern)
103
if matching_files:
vllm/model_executor/model_loader/gguf_loader.py
+2
-2
@@ -8,7 +8,6 @@ import gguf
8
import regex as re
9
import torch
10
import torch.nn as nn
11
-from huggingface_hub import hf_hub_download
11
from transformers import AutoModelForCausalLM, AutoModelForImageTextToText
12
13
from vllm.config import ModelConfig, VllmConfig
@@ -27,6 +26,7 @@ from vllm.model_executor.model_loader.weight_utils import (
26
gguf_quant_weights_iterator_multi,
27
)
28
from vllm.transformers_utils.gguf_utils import detect_gguf_multimodal
29
+from vllm.transformers_utils.repo_utils import hf_api
30
from vllm.utils.torch_utils import set_default_torch_dtype
31
32
if TYPE_CHECKING:
@@ -57,7 +57,7 @@ class GGUFModelLoader(BaseModelLoader):
57
# repo id/filename.gguf
58
if "/" in model_name_or_path and model_name_or_path.endswith(".gguf"):
59
repo_id, filename = model_name_or_path.rsplit("/", 1)
60
- return hf_hub_download(
60
+ return hf_api().hf_hub_download(
61
repo_id=repo_id,
62
filename=filename,
63
revision=model_config.revision,
vllm/model_executor/model_loader/tensorizer.py
+2
-2
@@ -16,7 +16,6 @@ from typing import TYPE_CHECKING, Any, ClassVar
16
17
import regex as re
18
import torch
19
-from huggingface_hub import snapshot_download
19
from torch import nn
20
from torch.utils._python_dispatch import TorchDispatchMode
21
from transformers import PretrainedConfig
@@ -26,6 +25,7 @@ from vllm.config import ModelConfig, ParallelConfig, VllmConfig, set_current_vll
25
from vllm.logger import init_logger
26
from vllm.model_executor.layers.vocab_parallel_embedding import VocabParallelEmbedding
27
from vllm.platforms import current_platform
28
+from vllm.transformers_utils.repo_utils import hf_api
29
from vllm.utils.argparse_utils import FlexibleArgumentParser
30
from vllm.utils.import_utils import PlaceholderModule
31
@@ -629,7 +629,7 @@ def serialize_extra_artifacts(
629
)
630
631
with tempfile.TemporaryDirectory() as tmpdir:
632
- snapshot_download(
632
+ hf_api().snapshot_download(
633
served_model_name,
634
local_dir=tmpdir,
635
ignore_patterns=[
vllm/model_executor/model_loader/weight_utils.py
+7
-7
@@ -23,7 +23,6 @@ import huggingface_hub.constants
23
import numpy as np
24
import regex as re
25
import torch
26
-from huggingface_hub import HfFileSystem, hf_hub_download, snapshot_download
26
from safetensors.torch import load, load_file, safe_open, save_file
27
from tqdm.auto import tqdm
28
from transformers.utils import SAFE_WEIGHTS_INDEX_NAME
@@ -46,6 +45,7 @@ from vllm.model_executor.model_loader.ep_weight_filter import (
45
)
46
from vllm.platforms import current_platform
47
from vllm.tracing import instrument
48
+from vllm.transformers_utils.repo_utils import hf_api, hf_fs
49
from vllm.utils.import_utils import PlaceholderModule
50
51
try:
@@ -373,7 +373,7 @@ def get_quant_config(
373
if not is_local:
374
# Download the config files.
375
with get_lock(model_config.model, load_config.download_dir):
376
- hf_folder = snapshot_download(
376
+ hf_folder = hf_api().snapshot_download(
377
model_config.model,
378
revision=model_config.revision,
379
allow_patterns="*.json",
@@ -431,7 +431,7 @@ def get_sparse_attention_config(
431
if not is_local:
432
# Download the config files.
433
with get_lock(model_name_or_path, load_config.download_dir):
434
- hf_folder = snapshot_download(
434
+ hf_folder = hf_api().snapshot_download(
435
model_name_or_path,
436
revision=model_config.revision,
437
allow_patterns="*.json",
@@ -534,7 +534,7 @@ def download_weights_from_hf(
534
# Attempt to reduce allow_patterns to a single pattern
535
# so we only have to call snapshot_download once.
536
try:
537
- fs = HfFileSystem()
537
+ fs = hf_fs()
538
file_list = fs.ls(
539
os.path.join(model_name_or_path, subfolder or ""),
540
detail=False,
@@ -546,7 +546,7 @@ def download_weights_from_hf(
546
# unnecessary files (e.g., from subdirectories like "original/").
547
index_file = f"{model_name_or_path}/{SAFE_WEIGHTS_INDEX_NAME}"
548
if "*.safetensors" in allow_patterns and index_file in file_list:
549
- index_path = hf_hub_download(
549
+ index_path = hf_api().hf_hub_download(
550
repo_id=model_name_or_path,
551
filename=SAFE_WEIGHTS_INDEX_NAME,
552
cache_dir=cache_dir,
@@ -582,7 +582,7 @@ def download_weights_from_hf(
582
with get_lock(model_name_or_path, cache_dir):
583
start_time = time.perf_counter()
584
for allow_pattern in allow_patterns:
585
- hf_folder = snapshot_download(
585
+ hf_folder = hf_api().snapshot_download(
586
model_name_or_path,
587
allow_patterns=allow_pattern,
588
ignore_patterns=ignore_patterns,
@@ -631,7 +631,7 @@ def download_safetensors_index_file_from_hf(
631
with get_lock(model_name_or_path, cache_dir):
632
try:
633
# Download the safetensors index file.
634
- hf_hub_download(
634
+ hf_api().hf_hub_download(
635
repo_id=model_name_or_path,
636
filename=index_file,
637
cache_dir=cache_dir,
vllm/plugins/lora_resolvers/hf_hub_resolver.py
+6
-4
@@ -3,13 +3,12 @@
3
import asyncio
4
import os
5
6
-from huggingface_hub import HfApi, snapshot_download
7
-
6
import vllm.envs as envs
7
from vllm.logger import init_logger
8
from vllm.lora.request import LoRARequest
9
from vllm.lora.resolver import LoRAResolverRegistry
10
from vllm.plugins.lora_resolvers.filesystem_resolver import FilesystemResolver
11
+from vllm.transformers_utils.repo_utils import hf_api
12
13
logger = init_logger(__name__)
14
@@ -49,7 +48,7 @@ class HfHubResolver(FilesystemResolver):
48
return None
49
50
repo_path = await asyncio.to_thread(
52
- snapshot_download,
51
+ hf_api().snapshot_download,
52
repo_id=maybe_repo,
53
allow_patterns=f"{maybe_subpath}/*" if maybe_subpath != "." else "*",
54
)
@@ -110,7 +109,10 @@ class HfHubResolver(FilesystemResolver):
109
Args:
110
repo_name: Name of the HF hub repo to inspect.
111
"""
113
- repo_files = await asyncio.to_thread(HfApi().list_repo_files, repo_id=repo_name)
112
+ repo_files = await asyncio.to_thread(
113
+ hf_api().list_repo_files,
114
+ repo_id=repo_name,
115
+ )
116
adapter_dirs = {
117
os.path.dirname(name)
118
for name in repo_files
vllm/tokenizers/grok2.py
+3
-3
@@ -8,7 +8,6 @@ from collections.abc import Collection, Sequence, Set
8
from pathlib import Path
9
from typing import Any, Literal, overload
10
11
-from huggingface_hub import hf_hub_download
11
from huggingface_hub.utils import (
12
EntryNotFoundError,
13
HfHubHTTPError,
@@ -20,6 +19,7 @@ from transformers.utils import chat_template_utils as hf_chat_utils
19
20
from vllm.entrypoints.chat_utils import ChatCompletionMessageParam
21
from vllm.logger import init_logger
22
+from vllm.transformers_utils.repo_utils import hf_api
23
24
from .protocol import TokenizerLike
25
@@ -70,7 +70,7 @@ def _maybe_load_tokenizer_config(
70
return {}
71
72
try:
73
- config_file = hf_hub_download(
73
+ config_file = hf_api().hf_hub_download(
74
repo_id=repo_id,
75
filename="tokenizer_config.json",
76
revision=revision,
@@ -208,7 +208,7 @@ class Grok2Tokenizer(TokenizerLike):
208
repo_id = None
209
else:
210
vocab_file = Path(
211
- hf_hub_download(
211
+ hf_api().hf_hub_download(
212
repo_id=str(path_or_repo_id),
213
filename="tokenizer.tok.json",
214
revision=revision,
vllm/tokenizers/kimi_audio.py
+4
-4
@@ -10,13 +10,13 @@ from typing import Any, overload
10
11
import pybase64
12
import tiktoken
13
-from huggingface_hub import hf_hub_download
13
from transformers import AddedToken, BatchEncoding
14
from transformers.utils import chat_template_utils as hf_chat_utils
15
16
from vllm.entrypoints.chat_utils import ChatCompletionMessageParam
17
from vllm.logger import init_logger
18
from vllm.tokenizers.protocol import TokenizerLike
19
+from vllm.transformers_utils.repo_utils import hf_api
20
21
logger = init_logger(__name__)
22
@@ -78,7 +78,7 @@ class KimiAudioTokenizer(TokenizerLike):
78
79
# Try to download tiktoken.model or tokenizer.model
80
try:
81
- vocab_path = hf_hub_download(
81
+ vocab_path = hf_api().hf_hub_download(
82
repo_id=repo_id,
83
filename="tiktoken.model",
84
revision=revision,
@@ -87,7 +87,7 @@ class KimiAudioTokenizer(TokenizerLike):
87
vocab_file = Path(vocab_path)
88
except Exception:
89
try:
90
- vocab_path = hf_hub_download(
90
+ vocab_path = hf_api().hf_hub_download(
91
repo_id=repo_id,
92
filename="tokenizer.model",
93
revision=revision,
@@ -101,7 +101,7 @@ class KimiAudioTokenizer(TokenizerLike):
101
102
# Also download tokenizer_config.json if available
103
with contextlib.suppress(Exception):
104
- hf_hub_download(
104
+ hf_api().hf_hub_download(
105
repo_id=repo_id,
106
filename="tokenizer_config.json",
107
revision=revision,
vllm/transformers_utils/config.py
+4
-3
@@ -12,7 +12,7 @@ from typing import Any, Literal, TypeAlias
12
13
import huggingface_hub
14
import torch
15
-from huggingface_hub import constants, get_safetensors_metadata
15
+from huggingface_hub import constants
16
from packaging.version import Version
17
from safetensors.torch import _TYPES as _SAFETENSORS_TO_TORCH_DTYPE
18
from transformers import GenerationConfig, PretrainedConfig
@@ -43,6 +43,7 @@ from .gguf_utils import (
43
from .repo_utils import (
44
file_or_path_exists,
45
get_hf_file_to_dict,
46
+ hf_api,
47
list_repo_files,
48
try_get_local_file,
49
with_retry,
@@ -1143,7 +1144,7 @@ def try_get_safetensors_metadata(
1144
revision: str | None = None,
1145
):
1146
get_safetensors_metadata_partial = partial(
1146
- get_safetensors_metadata, model, revision=revision
1147
+ hf_api().get_safetensors_metadata, model, revision=revision
1148
)
1149
1150
try:
@@ -1237,7 +1238,7 @@ def get_safetensors_params_metadata(
1238
# local HF cache: weights may already be cached from a prior run, and
1239
# weight loading itself uses the same cache.
1240
try:
1240
- local_dir = huggingface_hub.snapshot_download(
1241
+ local_dir = hf_api().snapshot_download(
1242
repo_id=model,
1243
revision=revision,
1244
allow_patterns=["*.safetensors"],
vllm/transformers_utils/repo_utils.py
+35
-7
@@ -12,8 +12,7 @@ from pathlib import Path
12
from typing import TypeVar
13
14
import huggingface_hub
15
-from huggingface_hub import hf_hub_download, try_to_load_from_cache
16
-from huggingface_hub import list_repo_files as hf_list_repo_files
15
+from huggingface_hub import HfApi, try_to_load_from_cache
16
from huggingface_hub.utils import (
17
EntryNotFoundError,
18
HfHubHTTPError,
@@ -24,9 +23,31 @@ from huggingface_hub.utils import (
23
24
from vllm import envs
25
from vllm.logger import init_logger
26
+from vllm.version import __version__ as VLLM_VERSION
27
28
logger = init_logger(__name__)
29
30
+_hf_api: HfApi | None = None
31
+
32
+
33
+def hf_api() -> HfApi:
34
+ """Return a shared HfApi instance tagged with vLLM's library info."""
35
+ global _hf_api
36
+ if _hf_api is None:
37
+ _hf_api = HfApi(
38
+ library_name="vllm",
39
+ library_version=VLLM_VERSION,
40
+ )
41
+ return _hf_api
42
+
43
+
44
+def hf_fs() -> "huggingface_hub.HfFileSystem":
45
+ """Return a fresh HfFileSystem tagged with vLLM's library info."""
46
+ return huggingface_hub.HfFileSystem(
47
+ library_name="vllm",
48
+ library_version=VLLM_VERSION,
49
+ )
50
+
51
52
_R = TypeVar("_R")
53
@@ -80,7 +101,7 @@ def list_repo_files(
101
revision=revision,
102
token=os.getenv("MODELSCOPE_API_TOKEN", None),
103
)
83
- return hf_list_repo_files(
104
+ return hf_api().list_repo_files(
105
repo_id, revision=revision, repo_type=repo_type, token=token
106
)
107
except huggingface_hub.errors.OfflineModeIsEnabled:
@@ -215,9 +236,10 @@ def get_model_path(model: str | Path, revision: str | None = None):
236
237
return snapshot_download(model_id=model, **common_kwargs)
238
218
- from huggingface_hub import snapshot_download
219
-
220
- return snapshot_download(repo_id=model, **common_kwargs)
239
+ return hf_api().snapshot_download(
240
+ repo_id=model,
241
+ **common_kwargs,
242
+ )
243
244
245
def _try_download_from_hf_hub(
@@ -231,7 +253,13 @@ def _try_download_from_hf_hub(
253
if Path(model).is_dir():
254
return None
255
try:
234
- return Path(hf_hub_download(model, file_name, revision=revision))
256
+ return Path(
257
+ hf_api().hf_hub_download(
258
+ model,
259
+ file_name,
260
+ revision=revision,
261
+ )
262
+ )
263
except huggingface_hub.errors.OfflineModeIsEnabled:
264
return None
265
except (