@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 56531b79cc
Fork 0

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)