Skip to content

Commit abeccce

Browse files
authored
(#307) [v0.10] fix(vllm): require a fixed Python hash seed
1 parent 04c40be commit abeccce

3 files changed

Lines changed: 34 additions & 4 deletions

File tree

‎docs/developer/kv_offload.rst‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ Before using OpenLake as a KV offload backend, ensure that you have:
3636
* A working OpenLake configuration.
3737
* RDMA-capable hardware if you plan to use cross-node KV offload.
3838

39+
For the vLLM connector, set the same fixed ``PYTHONHASHSEED`` on every
40+
worker before starting Python, for example ``PYTHONHASHSEED=0 vllm serve
41+
<model> ...``. The connector accepts decimal integers from ``0`` through
42+
``4294967295``; unset, empty, ``random``, and invalid values fail startup.
43+
Changing this environment variable after Python has started does not
44+
change that process's hash seed.
45+
3946
Model revisions in the vLLM cache
4047
--------------------------------
4148

‎external/connectors/vllm/openlake_adapter.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,20 @@
5454
EXPANS_MAX_BATCH_BLOCKS = 64
5555

5656
_HASH_SEED_HELP = (
57-
"OpenLake external KV offloading requires PYTHONHASHSEED to be set for "
58-
"block-hash consistency. Please set it, e.g. "
57+
"OpenLake external KV offloading requires PYTHONHASHSEED to be a fixed "
58+
"decimal integer between 0 and 4294967295 for block-hash consistency. "
59+
"Set the same value before starting every Python worker, e.g. "
5960
"PYTHONHASHSEED=0 vllm serve <model> ..."
6061
)
6162

6263

6364
def _require_fixed_hash_seed() -> None:
64-
if os.getenv("PYTHONHASHSEED") is None:
65+
seed = os.getenv("PYTHONHASHSEED", "")
66+
try:
67+
valid = seed.isascii() and seed.isdecimal() and int(seed) <= 4294967295
68+
except ValueError:
69+
valid = False
70+
if not valid:
6571
raise RuntimeError(_HASH_SEED_HELP)
6672

6773

‎external/connectors/vllm/tests/test_openlake_adapter.py‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import unittest
2222
from pathlib import Path
2323
from types import SimpleNamespace
24-
from unittest.mock import Mock
24+
from unittest.mock import Mock, patch
2525

2626

2727
def _module(name: str) -> types.ModuleType:
@@ -167,6 +167,23 @@ def _parallel(**overrides):
167167
return SimpleNamespace(**values)
168168

169169

170+
class OpenLakeHashSeedTests(unittest.TestCase):
171+
def test_requires_fixed_in_range_decimal_seed(self):
172+
for seed in (None, "", "random", "abc", "-1", "4294967296", "1.5", "12", "9" * 5000):
173+
with self.subTest(seed=seed), patch.dict(os.environ):
174+
if seed is None:
175+
os.environ.pop("PYTHONHASHSEED", None)
176+
else:
177+
os.environ["PYTHONHASHSEED"] = seed
178+
with self.assertRaisesRegex(RuntimeError, "before starting every Python worker"):
179+
ADAPTER._require_fixed_hash_seed()
180+
181+
def test_accepts_fixed_seed_including_range_boundaries(self):
182+
for seed in ("0", "1", "42", "00042", "4294967295"):
183+
with self.subTest(seed=seed), patch.dict(os.environ, PYTHONHASHSEED=seed):
184+
ADAPTER._require_fixed_hash_seed()
185+
186+
170187
class OpenLakeRankNamespaceTests(unittest.TestCase):
171188
def test_compression_config_rejects_non_lossless_codecs(self):
172189
for field, codec, mode in (

0 commit comments

Comments
 (0)