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 12, 13:30 UTC
[Misc] Add backup hash algorithm for FIPS constrained environments (#28795)
Signed-off-by: George D. Torres <gdavtor@gmail.com> Signed-off-by: George D. Torres <41129492+geodavic@users.noreply.github.com> Signed-off-by: Russell Bryant <rbryant@redhat.com> Co-authored-by: Russell Bryant <rbryant@redhat.com>
George D. Torres committed
Nov 25, 2025 at 18:50 UTC
56531b79ccc746bb579a49411f32be31bc307d4b
16 files changed
+56
-38
vllm/compilation/caching.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
import inspect
5
import os
6
import pickle
@@ -14,6 +13,7 @@ import vllm.envs as envs
13
from vllm.config import VllmConfig, get_current_vllm_config
14
from vllm.config.utils import hash_factors
15
from vllm.logger import init_logger
16
+from vllm.utils.hashing import safe_hash
17
18
try:
19
from torch._dynamo.aot_compile import SerializableCallable
@@ -160,7 +160,7 @@ def _compute_code_hash_with_content(file_contents: dict[str, str]) -> str:
160
# e.g. exec(). We can't actually check these.
161
continue
162
hash_content.append(content)
163
- return hashlib.md5(
163
+ return safe_hash(
164
"\n".join(hash_content).encode(), usedforsecurity=False
165
).hexdigest()
166
vllm/compilation/compiler_interface.py
+7
-7
@@ -2,7 +2,6 @@
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
import contextlib
4
import copy
5
-import hashlib
5
import os
6
from collections.abc import Callable
7
from contextlib import ExitStack
@@ -16,6 +15,7 @@ import torch.fx as fx
15
import vllm.envs as envs
16
from vllm.compilation.counter import compilation_counter
17
from vllm.config import VllmConfig
18
+from vllm.utils.hashing import safe_hash
19
from vllm.utils.torch_utils import is_torch_equal_or_newer
20
21
@@ -197,9 +197,9 @@ class InductorStandaloneAdaptor(CompilerInterface):
197
198
def compute_hash(self, vllm_config: VllmConfig) -> str:
199
factors = get_inductor_factors()
200
- hash_str = hashlib.md5(
201
- str(factors).encode(), usedforsecurity=False
202
- ).hexdigest()[:10]
200
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()[
201
+ :10
202
+ ]
203
return hash_str
204
205
def initialize_cache(
@@ -286,9 +286,9 @@ class InductorAdaptor(CompilerInterface):
286
287
def compute_hash(self, vllm_config: VllmConfig) -> str:
288
factors = get_inductor_factors()
289
- hash_str = hashlib.md5(
290
- str(factors).encode(), usedforsecurity=False
291
- ).hexdigest()[:10]
289
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()[
290
+ :10
291
+ ]
292
return hash_str
293
294
def initialize_cache(
vllm/config/device.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
from dataclasses import field
5
from typing import Any, Literal
6
@@ -10,6 +9,7 @@ from pydantic import ConfigDict, SkipValidation
9
from pydantic.dataclasses import dataclass
10
11
from vllm.config.utils import config
12
+from vllm.utils.hashing import safe_hash
13
14
Device = Literal["auto", "cuda", "cpu", "tpu", "xpu"]
15
@@ -45,7 +45,7 @@ class DeviceConfig:
45
# the device/platform information will be summarized
46
# by torch/vllm automatically.
47
factors: list[Any] = []
48
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
48
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
49
return hash_str
50
51
def __post_init__(self):
vllm/config/kv_transfer.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
import uuid
5
from dataclasses import field
6
from typing import Any, Literal, get_args
@@ -9,6 +8,7 @@ from typing import Any, Literal, get_args
8
from pydantic.dataclasses import dataclass
9
10
from vllm.config.utils import config
11
+from vllm.utils.hashing import safe_hash
12
13
KVProducer = Literal["kv_producer", "kv_both"]
14
KVConsumer = Literal["kv_consumer", "kv_both"]
@@ -79,7 +79,7 @@ class KVTransferConfig:
79
# no factors to consider.
80
# this config will not affect the computation graph.
81
factors: list[Any] = []
82
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
82
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
83
return hash_str
84
85
def __post_init__(self) -> None:
vllm/config/load.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
from typing import TYPE_CHECKING, Any
5
6
from pydantic import Field, field_validator
@@ -9,6 +8,7 @@ from pydantic.dataclasses import dataclass
8
9
from vllm.config.utils import config
10
from vllm.logger import init_logger
11
+from vllm.utils.hashing import safe_hash
12
13
if TYPE_CHECKING:
14
from vllm.model_executor.model_loader import LoadFormats
@@ -104,7 +104,7 @@ class LoadConfig:
104
# no factors to consider.
105
# this config will not affect the computation graph.
106
factors: list[Any] = []
107
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
107
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
108
return hash_str
109
110
@field_validator("load_format", mode="after")
vllm/config/lora.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
from typing import TYPE_CHECKING, Any, Literal
5
6
import torch
@@ -11,6 +10,7 @@ from typing_extensions import Self
10
11
from vllm.config.utils import config
12
from vllm.logger import init_logger
13
+from vllm.utils.hashing import safe_hash
14
15
if TYPE_CHECKING:
16
from vllm.config import ModelConfig
@@ -74,7 +74,7 @@ class LoRAConfig:
74
factors.append(self.fully_sharded_loras)
75
factors.append(self.lora_dtype)
76
77
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
77
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
78
return hash_str
79
80
@model_validator(mode="after")
vllm/config/multimodal.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
from collections.abc import Mapping
5
from typing import TYPE_CHECKING, Any, Literal, TypeAlias
6
@@ -9,6 +8,7 @@ from pydantic import ConfigDict, Field, field_validator, model_validator
8
from pydantic.dataclasses import dataclass
9
10
from vllm.config.utils import config
11
+from vllm.utils.hashing import safe_hash
12
13
if TYPE_CHECKING:
14
from vllm.attention.backends.registry import AttentionBackendEnum
@@ -216,7 +216,7 @@ class MultiModalConfig:
216
if self.mm_encoder_attn_backend is not None
217
else None
218
]
219
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
219
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
220
return hash_str
221
222
def get_limit_per_prompt(self, modality: str) -> int:
vllm/config/observability.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
from functools import cached_property
5
from typing import Any, Literal, cast
6
@@ -11,6 +10,7 @@ from pydantic.dataclasses import dataclass
10
11
from vllm import version
12
from vllm.config.utils import config
13
+from vllm.utils.hashing import safe_hash
14
15
DetailedTraceModules = Literal["model", "worker", "all"]
16
@@ -78,7 +78,7 @@ class ObservabilityConfig:
78
# no factors to consider.
79
# this config will not affect the computation graph.
80
factors: list[Any] = []
81
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
81
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
82
return hash_str
83
84
@field_validator("show_hidden_metrics_for_version")
vllm/config/pooler.py
+2
-2
@@ -1,13 +1,13 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
from typing import Any
5
6
from pydantic.dataclasses import dataclass
7
8
from vllm.config.utils import config
9
from vllm.logger import init_logger
10
+from vllm.utils.hashing import safe_hash
11
12
logger = init_logger(__name__)
13
@@ -102,7 +102,7 @@ class PoolerConfig:
102
# no factors to consider.
103
# this config will not affect the computation graph.
104
factors: list[Any] = []
105
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
105
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
106
return hash_str
107
108
vllm/config/scheduler.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
from collections.abc import Callable
5
from dataclasses import InitVar
6
from typing import TYPE_CHECKING, Any, ClassVar, Literal, cast
@@ -12,6 +11,7 @@ from typing_extensions import Self, deprecated
11
12
from vllm.config.utils import config
13
from vllm.logger import init_logger
14
+from vllm.utils.hashing import safe_hash
15
from vllm.utils.import_utils import resolve_obj_by_qualname
16
17
if TYPE_CHECKING:
@@ -178,7 +178,7 @@ class SchedulerConfig:
178
# no factors to consider.
179
# this config will not affect the computation graph.
180
factors: list[Any] = []
181
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
181
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
182
return hash_str
183
184
@field_validator("scheduler_cls", "async_scheduling", mode="wrap")
vllm/config/speculative.py
+2
-2
@@ -2,7 +2,6 @@
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
import ast
5
-import hashlib
5
from typing import TYPE_CHECKING, Any, Literal, get_args
6
7
from pydantic import Field, SkipValidation, model_validator
@@ -13,6 +12,7 @@ from vllm.config.model import ModelConfig
12
from vllm.config.parallel import ParallelConfig
13
from vllm.config.utils import config
14
from vllm.logger import init_logger
15
+from vllm.utils.hashing import safe_hash
16
from vllm.utils.import_utils import LazyLoader, has_arctic_inference
17
18
if TYPE_CHECKING:
@@ -162,7 +162,7 @@ class SpeculativeConfig:
162
# Eagle3 affects the computation graph because it returns intermediate
163
# hidden states in addition to the final hidden state.
164
factors.append(self.method == "eagle3")
165
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
165
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
166
return hash_str
167
168
@staticmethod
vllm/config/structured_outputs.py
+2
-2
@@ -1,7 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
-import hashlib
4
from typing import Any, Literal
5
6
from pydantic import model_validator
@@ -9,6 +8,7 @@ from pydantic.dataclasses import dataclass
8
from typing_extensions import Self
9
10
from vllm.config.utils import config
11
+from vllm.utils.hashing import safe_hash
12
13
StructuredOutputsBackend = Literal[
14
"auto", "xgrammar", "guidance", "outlines", "lm-format-enforcer"
@@ -58,7 +58,7 @@ class StructuredOutputsConfig:
58
# no factors to consider.
59
# this config will not affect the computation graph.
60
factors: list[Any] = []
61
- hash_str = hashlib.md5(str(factors).encode(), usedforsecurity=False).hexdigest()
61
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()
62
return hash_str
63
64
@model_validator(mode="after")
vllm/config/vllm.py
+5
-5
@@ -3,7 +3,6 @@
3
4
import copy
5
import getpass
6
-import hashlib
6
import json
7
import os
8
import tempfile
@@ -25,6 +24,7 @@ from vllm.config.speculative import EagleModelTypes
24
from vllm.logger import enable_trace_function_call, init_logger
25
from vllm.transformers_utils.runai_utils import is_runai_obj_uri
26
from vllm.utils import random_uuid
27
+from vllm.utils.hashing import safe_hash
28
29
from .cache import CacheConfig
30
from .compilation import CompilationConfig, CompilationMode, CUDAGraphMode
@@ -193,7 +193,7 @@ class VllmConfig:
193
vllm_factors.append("None")
194
if self.additional_config:
195
if isinstance(additional_config := self.additional_config, dict):
196
- additional_config_hash = hashlib.md5(
196
+ additional_config_hash = safe_hash(
197
json.dumps(additional_config, sort_keys=True).encode(),
198
usedforsecurity=False,
199
).hexdigest()
@@ -204,9 +204,9 @@ class VllmConfig:
204
vllm_factors.append("None")
205
factors.append(vllm_factors)
206
207
- hash_str = hashlib.md5(
208
- str(factors).encode(), usedforsecurity=False
209
- ).hexdigest()[:10]
207
+ hash_str = safe_hash(str(factors).encode(), usedforsecurity=False).hexdigest()[
208
+ :10
209
+ ]
210
return hash_str
211
212
def pad_for_cudagraph(self, batch_size: int) -> int:
vllm/distributed/kv_transfer/kv_connector/v1/shared_storage_connector.py
+2
-2
@@ -1,6 +1,5 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
-import hashlib
3
import os
4
from dataclasses import dataclass, field
5
from typing import TYPE_CHECKING, Any, Optional
@@ -15,6 +14,7 @@ from vllm.distributed.kv_transfer.kv_connector.v1.base import (
14
KVConnectorRole,
15
)
16
from vllm.logger import init_logger
17
+from vllm.utils.hashing import safe_hash
18
from vllm.v1.attention.backends.mla.common import MLACommonMetadata
19
from vllm.v1.core.sched.output import SchedulerOutput
20
@@ -423,7 +423,7 @@ class SharedStorageConnector(KVConnectorBase_V1):
423
if mm_hashes:
424
mm_str = "-".join(mm_hashes)
425
token_bytes += mm_str.encode("utf-8")
426
- input_ids_hash = hashlib.md5(token_bytes, usedforsecurity=False).hexdigest()
426
+ input_ids_hash = safe_hash(token_bytes, usedforsecurity=False).hexdigest()
427
428
foldername = os.path.join(self._storage_path, input_ids_hash)
429
if create_folder:
vllm/model_executor/models/registry.py
+2
-2
@@ -5,7 +5,6 @@ Whenever you add an architecture to this page, please also update
5
`tests/models/registry.py` with example HuggingFace models for it.
6
"""
7
8
-import hashlib
8
import importlib
9
import json
10
import os
@@ -32,6 +31,7 @@ from vllm.config import (
31
from vllm.logger import init_logger
32
from vllm.logging_utils import logtime
33
from vllm.transformers_utils.dynamic_module import try_get_class_from_dynamic_module
34
+from vllm.utils.hashing import safe_hash
35
36
from .interfaces import (
37
has_inner_state,
@@ -654,7 +654,7 @@ class _LazyRegisteredModel(_BaseRegisteredModel):
654
655
if model_path.exists():
656
with open(model_path, "rb") as f:
657
- module_hash = hashlib.md5(f.read(), usedforsecurity=False).hexdigest()
657
+ module_hash = safe_hash(f.read(), usedforsecurity=False).hexdigest()
658
659
mi = self._load_modelinfo_from_cache(module_hash)
660
if mi is not None:
vllm/utils/hashing.py
+18
@@ -5,6 +5,7 @@ from __future__ import annotations
5
6
import hashlib
7
import pickle
8
+from _hashlib import HASH, UnsupportedDigestmodError
9
from collections.abc import Callable
10
from typing import Any
11
@@ -61,3 +62,20 @@ def get_hash_fn_by_name(hash_fn_name: str) -> Callable[[Any], bytes]:
62
return sha256_cbor
63
64
raise ValueError(f"Unsupported hash function: {hash_fn_name}")
65
+
66
+
67
+def safe_hash(data: bytes, usedforsecurity: bool = True) -> HASH:
68
+ """Hash for configs, defaulting to md5 but falling back to sha256
69
+ in FIPS constrained environments.
70
+
71
+ Args:
72
+ data: bytes
73
+ usedforsecurity: Whether the hash is used for security purposes
74
+
75
+ Returns:
76
+ Hash object
77
+ """
78
+ try:
79
+ return hashlib.md5(data, usedforsecurity=usedforsecurity)
80
+ except (UnsupportedDigestmodError, ValueError):
81
+ return hashlib.sha256(data)