@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 538e830caa
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 11, 00:00 UTC

[KVEvent] User request.block_hash for parent block_hash (#30544)

Signed-off-by: Chen Zhang <zhangch99@outlook.com> Signed-off-by: Yifan Qiao <yifanqiao@berkeley.edu> Co-authored-by: Yifan Qiao <yifanqiao@berkeley.edu>

Chen Zhang committed Dec 23, 2025 at 18:23 UTC 538e830caab8d0e7c2557adb975dca3c5af296be
2 files changed +64 -3
tests/v1/core/test_prefix_caching.py
+63
@@ -1356,6 +1356,69 @@ def test_kv_cache_events(blocks_to_cache: int):
1356 assert len(manager.block_pool.cached_block_hash_to_block) == 0
1357
1358
1359 +def test_null_parent_block_hash():
1360 + block_size = 1
1361 + num_cached_blocks = 2
1362 + num_full_blocks = 4
1363 +
1364 + pool = BlockPool(
1365 + num_gpu_blocks=8,
1366 + enable_caching=True,
1367 + hash_block_size=block_size,
1368 + enable_kv_cache_events=True,
1369 + )
1370 +
1371 + req = make_request(
1372 + "req_null_parent",
1373 + prompt_token_ids=[10, 11, 12, 13],
1374 + block_size=block_size,
1375 + hash_fn=sha256,
1376 + )
1377 + assert len(req.block_hashes) == num_full_blocks
1378 +
1379 + # Physical parent is `null_block` (no hash), while the logical parent hash
1380 + # still exists in `request.block_hashes[num_cached_blocks - 1]`.
1381 + assert pool.null_block.block_hash is None
1382 + new_blocks = pool.get_new_blocks(num_full_blocks - 1)
1383 + blocks = [
1384 + new_blocks[: num_cached_blocks - 1],
1385 + pool.null_block, # physical parent
1386 + *new_blocks[num_cached_blocks - 1 :],
1387 + ]
1388 +
1389 + pool.cache_full_blocks(
1390 + request=req,
1391 + blocks=blocks,
1392 + num_cached_blocks=num_cached_blocks,
1393 + num_full_blocks=num_full_blocks,
1394 + block_size=block_size,
1395 + kv_cache_group_id=0,
1396 + )
1397 +
1398 + events = pool.take_events()
1399 + assert len(events) == 1
1400 + event = events[0]
1401 + assert isinstance(event, BlockStored)
1402 +
1403 + expected_parent = kv_cache_utils.maybe_convert_block_hash(
1404 + req.block_hashes[num_cached_blocks - 1]
1405 + )
1406 + assert event.parent_block_hash == expected_parent
1407 + assert event.parent_block_hash is not None
1408 +
1409 + expected_new_hashes = [
1410 + kv_cache_utils.maybe_convert_block_hash(h)
1411 + for h in req.block_hashes[num_cached_blocks:num_full_blocks]
1412 + ]
1413 + assert event.block_hashes == expected_new_hashes
1414 +
1415 + # Ensure we didn't accidentally assign a hash to the null block.
1416 + assert pool.null_block.block_hash is None
1417 + # Sanity check: newly cached physical blocks should have hashes assigned.
1418 + assert blocks[num_cached_blocks].block_hash is not None
1419 + assert blocks[num_full_blocks - 1].block_hash is not None
1420 +
1421 +
1422 @pytest.mark.parametrize("blocks_to_cache", [2, 3, 10])
1423 def test_kv_cache_events_with_lora(blocks_to_cache: int):
1424 """Test BlockStored events contain correct lora_id when using LoRA requests."""
vllm/v1/core/block_pool.py
+1 -3
@@ -270,10 +270,8 @@ class BlockPool:
270 if num_cached_blocks == 0:
271 parent_block_hash: ExternalBlockHash | None = None
272 else:
273 - parent_block = blocks[num_cached_blocks - 1]
274 - assert parent_block.block_hash is not None
273 parent_block_hash = maybe_convert_block_hash(
276 - get_block_hash(parent_block.block_hash)
274 + block_hashes[num_cached_blocks - 1]
275 )
276
277 self.kv_event_queue.append(