Download code/models/tt_transformers/tests/test_vllm_kv_cache.py from raahemnabeel/qwen3-coder-next: direct link, hf CLI and curl.
- Browser
- Download file 5.55 kB
-
https://huggingface.co/raahemnabeel/qwen3-coder-next/resolve/main/code/models/tt_transformers/tests/test_vllm_kv_cache.py
- Command line
-
hf download hf://raahemnabeel/qwen3-coder-next/code/models/tt_transformers/tests/test_vllm_kv_cache.py
-
curl -L -o test_vllm_kv_cache.py https://huggingface.co/raahemnabeel/qwen3-coder-next/resolve/main/code/models/tt_transformers/tests/test_vllm_kv_cache.py
5.55 kB
| # SPDX-FileCopyrightText: © 2026 Tenstorrent USA, Inc. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| """Unit tests for the vLLM-side KV cache allocator helpers in | |
| ``generator_vllm.py``. | |
| Verifies the new per-layer entry point (``allocate_vllm_kv_cache_per_layer``) | |
| and that the legacy uniform-shape entry point (``allocate_vllm_kv_cache``) | |
| still delegates to it bit-for-bit. | |
| Real ttnn allocation requires a mesh device, so this test mocks | |
| ``ttnn.as_tensor`` / ``ttnn.ReplicateTensorToMesh`` and the ``dp_model`` | |
| handles. We verify call structure and shape routing, not the resulting | |
| tensor contents. | |
| """ | |
| from pathlib import Path | |
| from unittest.mock import MagicMock, patch | |
| import pytest | |
| import torch | |
| def dp_model(): | |
| """One submesh handle whose optimizations return None (so the allocator | |
| falls back to the bfloat8_b default — keeps the test independent of | |
| the model's optimization config table).""" | |
| submesh = MagicMock() | |
| args = MagicMock() | |
| args.optimizations = None # Force the bfloat8_b fallback path. | |
| model = MagicMock() | |
| model.mesh_device = submesh | |
| model.args = args | |
| return [model] | |
| def _make_ttnn_mock(): | |
| ttnn_mock = MagicMock() | |
| ttnn_mock.as_tensor.side_effect = lambda *a, **kw: ("tt-tensor", kw.get("dtype"), kw.get("cache_file_name")) | |
| ttnn_mock.bfloat8_b = "bfloat8_b-sentinel" | |
| ttnn_mock.bfloat16 = "bfloat16-sentinel" | |
| return ttnn_mock | |
| def test_per_layer_allocates_one_kv_pair_per_unique_tensor(dp_model): | |
| """Each unique ``tensor_idx`` allocates one (k, v) pair; layers that | |
| share a ``tensor_idx`` reuse the same handles.""" | |
| from models.tt_transformers.tt import generator_vllm | |
| # Layers 0, 1, 2 all use tensor_idx=0,1,2 respectively → three buffers. | |
| per_layer = [ | |
| ((4, 2, 32, 64), torch.bfloat16, 0), | |
| ((4, 2, 32, 64), torch.bfloat16, 1), | |
| ((4, 2, 32, 64), torch.bfloat16, 2), | |
| ] | |
| with patch.object(generator_vllm, "ttnn", new=_make_ttnn_mock()) as ttnn_mock: | |
| kv_cache = generator_vllm.allocate_vllm_kv_cache_per_layer( | |
| per_layer, dp_model=dp_model, tt_cache_path=Path("/tmp/tt-test-cache") | |
| ) | |
| # One submesh, three layers, two tensors per layer (k, v) = 6 calls. | |
| assert ttnn_mock.as_tensor.call_count == 6 | |
| assert len(kv_cache) == 1 # one submesh | |
| assert len(kv_cache[0]) == 3 # three layers | |
| assert all(len(layer) == 2 for layer in kv_cache[0]) # k, v | |
| def test_shared_tensor_idx_reuses_one_buffer(dp_model): | |
| """Layers sharing a ``tensor_idx`` (HMA tensor sharing) point at the | |
| same underlying ttnn handles and only one allocation runs per | |
| ``tensor_idx``.""" | |
| from models.tt_transformers.tt import generator_vllm | |
| # Layers 0 and 2 share tensor 0; layer 1 has its own tensor 1. | |
| per_layer = [ | |
| ((4, 2, 32, 64), torch.bfloat16, 0), | |
| ((4, 2, 32, 64), torch.bfloat16, 1), | |
| ((4, 2, 32, 64), torch.bfloat16, 0), | |
| ] | |
| with patch.object(generator_vllm, "ttnn", new=_make_ttnn_mock()) as ttnn_mock: | |
| kv_cache = generator_vllm.allocate_vllm_kv_cache_per_layer( | |
| per_layer, dp_model=dp_model, tt_cache_path=Path("/tmp/tt-test-cache") | |
| ) | |
| # 2 unique tensor_idx values × 2 (k, v) = 4 allocations. | |
| assert ttnn_mock.as_tensor.call_count == 4 | |
| # Layers 0 and 2 must reference the *same* handle list. | |
| assert kv_cache[0][0] is kv_cache[0][2] | |
| assert kv_cache[0][0] is not kv_cache[0][1] | |
| def test_per_layer_keys_cache_filename_on_tensor_idx(dp_model): | |
| """Cache filenames must distinguish independent buffers even when | |
| shapes are identical, so on-disk caches can't collide across layers | |
| that don't share a ``tensor_idx``.""" | |
| from models.tt_transformers.tt import generator_vllm | |
| per_layer = [ | |
| ((4, 2, 32, 64), torch.bfloat16, 0), | |
| ((4, 2, 32, 64), torch.bfloat16, 1), | |
| ] | |
| with patch.object(generator_vllm, "ttnn", new=_make_ttnn_mock()) as ttnn_mock: | |
| generator_vllm.allocate_vllm_kv_cache_per_layer( | |
| per_layer, dp_model=dp_model, tt_cache_path=Path("/tmp/tt-test-cache") | |
| ) | |
| cache_filenames = [str(call.kwargs["cache_file_name"]) for call in ttnn_mock.as_tensor.call_args_list] | |
| assert sum("_t0" in f for f in cache_filenames) == 2 | |
| assert sum("_t1" in f for f in cache_filenames) == 2 | |
| def test_legacy_uniform_shape_delegates_to_per_layer(dp_model): | |
| """The legacy ``allocate_vllm_kv_cache`` must produce identical output to | |
| calling ``allocate_vllm_kv_cache_per_layer`` with a per-layer triple | |
| list (each layer its own ``tensor_idx``), so existing single-group | |
| callers keep working unchanged.""" | |
| from models.tt_transformers.tt import generator_vllm | |
| shape = (4, 2, 32, 64) | |
| dtype = torch.bfloat16 | |
| num_layers = 3 | |
| with patch.object(generator_vllm, "ttnn", new=_make_ttnn_mock()) as ttnn_mock: | |
| legacy = generator_vllm.allocate_vllm_kv_cache( | |
| shape, dtype, num_layers, dp_model=dp_model, tt_cache_path=Path("/tmp/c") | |
| ) | |
| legacy_call_count = ttnn_mock.as_tensor.call_count | |
| with patch.object(generator_vllm, "ttnn", new=_make_ttnn_mock()) as ttnn_mock: | |
| per_layer = generator_vllm.allocate_vllm_kv_cache_per_layer( | |
| [(shape, dtype, i) for i in range(num_layers)], | |
| dp_model=dp_model, | |
| tt_cache_path=Path("/tmp/c"), | |
| ) | |
| per_layer_call_count = ttnn_mock.as_tensor.call_count | |
| assert legacy_call_count == per_layer_call_count | |
| assert len(legacy[0]) == len(per_layer[0]) == num_layers | |