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

[v1] Pass BlockTable and KVCacheSpec to AttentionMetadataBuilders (#17483)

Signed-off-by: Chen Zhang <zhangch99@outlook.com>

Chen Zhang committed May 11, 2025 at 07:12 UTC 950751a9870f040ad0f1a876a8c8a03ecb97000b
11 files changed +132 -68
tests/v1/worker/test_gpu_input_batch.py
+3
@@ -221,6 +221,7 @@ def test_sampling_metadata_in_input_batch(device: str, batch_size: int):
221 max_num_reqs=batch_size,
222 max_model_len=1024,
223 max_num_blocks_per_req=10,
224 + max_num_batched_tokens=1024,
225 device=torch.device(device),
226 pin_memory=is_pin_memory_available(),
227 vocab_size=1024,
@@ -310,6 +311,7 @@ def test_swap_states_in_input_batch(device: str, batch_size: int,
311 max_num_reqs=batch_size,
312 max_model_len=1024,
313 max_num_blocks_per_req=10,
314 + max_num_batched_tokens=1024,
315 device=torch.device(device),
316 pin_memory=is_pin_memory_available(),
317 vocab_size=1024,
@@ -318,6 +320,7 @@ def test_swap_states_in_input_batch(device: str, batch_size: int,
320 max_num_reqs=batch_size,
321 max_model_len=1024,
322 max_num_blocks_per_req=10,
323 + max_num_batched_tokens=1024,
324 device=torch.device(device),
325 pin_memory=is_pin_memory_available(),
326 vocab_size=1024,
tests/v1/worker/test_gpu_model_runner.py
+20 -1
@@ -1,14 +1,31 @@
1 # SPDX-License-Identifier: Apache-2.0
2 +import weakref
3 +
4 import pytest
5 +import torch
6
7 from vllm.config import CacheConfig, ModelConfig, SchedulerConfig, VllmConfig
8 from vllm.sampling_params import SamplingParams
9 from vllm.v1.core.sched.output import (CachedRequestData, NewRequestData,
10 SchedulerOutput)
11 +from vllm.v1.kv_cache_interface import FullAttentionSpec
12 from vllm.v1.sample.metadata import SamplingMetadata
13 from vllm.v1.worker.gpu_model_runner import GPUModelRunner
14
15
16 +def initialize_kv_cache(runner: GPUModelRunner):
17 + """
18 + Only perform necessary steps in GPUModelRunner.initialize_kv_cache()
19 + """
20 + kv_cache_spec = FullAttentionSpec(block_size=16,
21 + num_kv_heads=1,
22 + head_size=64,
23 + dtype=torch.float16,
24 + use_mla=False)
25 + runner.attn_metadata_builder = runner.attn_backend.get_builder_cls()(
26 + weakref.proxy(runner), kv_cache_spec, runner.input_batch.block_table)
27 +
28 +
29 @pytest.fixture
30 def model_runner():
31 scheduler_config = SchedulerConfig(
@@ -38,7 +55,9 @@ def model_runner():
55 )
56
57 device = "cuda"
41 - return GPUModelRunner(vllm_config, device)
58 + runner = GPUModelRunner(vllm_config, device)
59 + initialize_kv_cache(runner)
60 + return runner
61
62
63 def _schedule_new_request(*req_ids: str) -> SchedulerOutput:
vllm/v1/attention/backends/flash_attn.py
+30 -17
@@ -19,6 +19,8 @@ from vllm.logger import init_logger
19 from vllm.platforms import current_platform
20 from vllm.utils import cdiv
21 from vllm.v1.attention.backends.utils import CommonAttentionMetadata
22 +from vllm.v1.kv_cache_interface import AttentionSpec
23 +from vllm.v1.worker.block_table import BlockTable
24
25 if TYPE_CHECKING:
26 from vllm.v1.core.sched.output import SchedulerOutput
@@ -167,7 +169,7 @@ def make_local_attention_virtual_batches(
169 query_start_loc_np: np.ndarray,
170 seq_lens_np: np.ndarray,
171 block_table: torch.Tensor,
170 - page_size: int = 0,
172 + block_size: int = 0,
173 ) -> tuple[np.ndarray, np.ndarray, np.ndarray, torch.Tensor]:
174 q_seqlens = query_start_loc_np[1:] - query_start_loc_np[:-1]
175 actual_batch_size = seq_lens_np.shape[0]
@@ -238,14 +240,14 @@ def make_local_attention_virtual_batches(
240 # For the example the local attention blocks start at:
241 # _b0_ _____b1_____ _b2_
242 # k_seqstarts_absolute = [0, 4, 4, 8, 12, 16, 4, 8]
241 - block_starts = k_seqstarts_absolute // page_size
242 - assert attn_chunk_size % page_size == 0, \
243 + block_starts = k_seqstarts_absolute // block_size
244 + assert attn_chunk_size % block_size == 0, \
245 f"attn_chunk_size {attn_chunk_size} is not " \
244 - f"divisible by page_size {page_size}"
245 - pages_per_local_batch = attn_chunk_size // page_size
246 + f"divisible by block_size {block_size}"
247 + pages_per_local_batch = attn_chunk_size // block_size
248
249 # Create a block_table for the local attention blocks
248 - # For out example if we have a block-table like (assuming page_size=2):
250 + # For out example if we have a block-table like (assuming block_size=2):
251 # block_table = [
252 # [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], < batch 0
253 # [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], < batch 1
@@ -289,7 +291,8 @@ def _get_sliding_window_configs(
291
292 class FlashAttentionMetadataBuilder:
293
292 - def __init__(self, runner: "GPUModelRunner"):
294 + def __init__(self, runner: "GPUModelRunner", kv_cache_spec: AttentionSpec,
295 + block_table: BlockTable):
296 model_config = runner.model_config
297 compilation_config = runner.vllm_config.compilation_config
298
@@ -299,7 +302,9 @@ class FlashAttentionMetadataBuilder:
302 self.num_heads_kv = model_config.get_num_kv_heads(
303 runner.parallel_config)
304 self.headdim = model_config.get_head_size()
302 - self.page_size = self.runner.block_size
305 + self.block_size = kv_cache_spec.block_size
306 + self.kv_cache_spec = kv_cache_spec
307 + self.block_table = block_table
308
309 if get_flash_attn_version() == 3:
310 self.aot_schedule = not compilation_config.full_cuda_graph
@@ -323,9 +328,17 @@ class FlashAttentionMetadataBuilder:
328 max_seq_len = self.runner.seq_lens_np[:num_reqs].max()
329 query_start_loc = common_attn_metadata.query_start_loc
330 seq_lens = common_attn_metadata.seq_lens
326 - block_table = (
327 - self.runner.input_batch.block_table.get_device_tensor()[:num_reqs])
328 - slot_mapping = self.runner.slot_mapping[:num_actual_tokens]
331 + block_table = self.block_table
332 + block_table_tensor = block_table.get_device_tensor()[:num_reqs]
333 +
334 + block_table.slot_mapping[:num_actual_tokens].copy_(
335 + block_table.slot_mapping_cpu[:num_actual_tokens],
336 + non_blocking=True)
337 + # Fill unused with -1. Needed for reshape_and_cache in full cuda graph
338 + # mode.
339 + block_table.slot_mapping[num_actual_tokens:].fill_(-1)
340 +
341 + slot_mapping = block_table.slot_mapping[:num_actual_tokens]
342
343 if self.aot_sliding_window is None:
344 self.aot_sliding_window = (-1, -1)
@@ -354,7 +367,7 @@ class FlashAttentionMetadataBuilder:
367 num_heads_q=self.num_heads_q,
368 num_heads_kv=self.num_heads_kv,
369 headdim=self.headdim,
357 - page_size=self.page_size,
370 + page_size=self.block_size,
371 cu_seqlens_q=cu_query_lens,
372 causal=causal,
373 window_size=self.aot_sliding_window,
@@ -365,12 +378,12 @@ class FlashAttentionMetadataBuilder:
378 local_attn_metadata = None
379 if self.runner.attention_chunk_size is not None:
380 seqlens_q_local_np, virt_q_cu_seqlens_np, virt_k_seqlens_np, \
368 - virt_block_table = make_local_attention_virtual_batches(
381 + virt_block_table_tensor = make_local_attention_virtual_batches(
382 self.runner.attention_chunk_size,
383 self.runner.query_start_loc_np[:num_reqs + 1],
384 self.runner.seq_lens_np[:num_reqs],
372 - block_table,
373 - self.runner.block_size,
385 + block_table_tensor,
386 + self.block_size,
387 )
388 local_query_start_loc = torch.from_numpy(virt_q_cu_seqlens_np).to(
389 self.runner.device, non_blocking=True)
@@ -389,7 +402,7 @@ class FlashAttentionMetadataBuilder:
402 local_attn_metadata = FlashAttentionMetadata.LocalAttentionMetadata(
403 local_query_start_loc=local_query_start_loc,
404 local_seqused_k=local_seqused_k,
392 - local_block_table=virt_block_table,
405 + local_block_table=virt_block_table_tensor,
406 local_max_query_len=local_max_query_len,
407 local_max_seq_len=local_max_seq_len,
408 local_scheduler_metadata=local_scheduler_metadata,
@@ -440,7 +453,7 @@ class FlashAttentionMetadataBuilder:
453 query_start_loc=query_start_loc,
454 max_seq_len=max_seq_len,
455 seq_lens=seq_lens,
443 - block_table=block_table,
456 + block_table=block_table_tensor,
457 slot_mapping=slot_mapping,
458 use_cascade=use_cascade,
459 common_prefix_len=common_prefix_len,
vllm/v1/attention/backends/flashinfer.py
+20 -15
@@ -19,6 +19,8 @@ from vllm.config import (VllmConfig, get_current_vllm_config,
19 from vllm.logger import init_logger
20 from vllm.v1.attention.backends.flash_attn import use_cascade_attention
21 from vllm.v1.attention.backends.utils import CommonAttentionMetadata
22 +from vllm.v1.kv_cache_interface import AttentionSpec
23 +from vllm.v1.worker.block_table import BlockTable
24
25 if TYPE_CHECKING:
26 from vllm.v1.core.sched.output import SchedulerOutput
@@ -202,7 +204,8 @@ class FlashInferMetadata:
204
205 class FlashInferMetadataBuilder:
206
205 - def __init__(self, runner: GPUModelRunner):
207 + def __init__(self, runner: GPUModelRunner, kv_cache_spec: AttentionSpec,
208 + block_table: BlockTable):
209 self.runner = runner
210 self._workspace_buffer = None
211 self._prefill_wrapper = None # Wrapper for prefill/append
@@ -213,6 +216,8 @@ class FlashInferMetadataBuilder:
216 self.global_hyperparameters: Optional[PerLayerParameters] = None
217
218 self.vllm_config = get_current_vllm_config()
219 + self.kv_cache_spec = kv_cache_spec
220 + self.block_table = block_table
221
222 def reorder_batch(self, input_batch: InputBatch,
223 scheduler_output: SchedulerOutput) -> bool:
@@ -400,13 +405,12 @@ class FlashInferMetadataBuilder:
405 assert self._num_decodes + self._num_prefills == num_reqs
406 assert (self._num_decode_tokens +
407 self._num_prefill_tokens == num_actual_tokens)
403 - page_size = self.runner.block_size
408 + page_size = self.kv_cache_spec.block_size
409 device = self.runner.device
410 qo_indptr = common_attn_metadata.query_start_loc
411 seq_lens = common_attn_metadata.seq_lens
407 - block_table = (
408 - self.runner.input_batch.block_table.get_device_tensor()[:num_reqs])
409 - slot_mapping = self.runner.slot_mapping_cpu[:num_actual_tokens].to(
412 + block_table_tensor = self.block_table.get_device_tensor()[:num_reqs]
413 + slot_mapping = self.block_table.slot_mapping_cpu[:num_actual_tokens].to(
414 self.runner.device, non_blocking=True).long()
415
416 block_table_bounds = (seq_lens + page_size - 1) // page_size
@@ -422,12 +426,13 @@ class FlashInferMetadataBuilder:
426 shared_kv_page_indptr = torch.tensor([0, num_common_kv_blocks],
427 dtype=torch.int32,
428 device=device)
425 - shared_kv_page_indices = block_table[0, :num_common_kv_blocks]
429 + shared_kv_page_indices = block_table_tensor[
430 + 0, :num_common_kv_blocks]
431 shared_kv_last_page_len = torch.tensor([page_size],
432 dtype=torch.int32,
433 device=device)
434 # Remove the blocks of the shared prefix from all requests.
430 - block_table = block_table[:, num_common_kv_blocks:]
435 + block_table_tensor = block_table_tensor[:, num_common_kv_blocks:]
436 block_table_bounds -= num_common_kv_blocks
437 else:
438 shared_qo_indptr = None
@@ -435,11 +440,11 @@ class FlashInferMetadataBuilder:
440 shared_kv_page_indices = None
441 shared_kv_last_page_len = None
442
438 - mask = (torch.arange(block_table.size(1),
439 - dtype=block_table.dtype,
440 - device=block_table.device).unsqueeze(0)
443 + mask = (torch.arange(block_table_tensor.size(1),
444 + dtype=block_table_tensor.dtype,
445 + device=block_table_tensor.device).unsqueeze(0)
446 < block_table_bounds.unsqueeze(1))
442 - paged_kv_indices = block_table[mask]
447 + paged_kv_indices = block_table_tensor[mask]
448
449 paged_kv_indptr = torch.cat([
450 torch.zeros(1,
@@ -459,10 +464,10 @@ class FlashInferMetadataBuilder:
464 paged_kv_indices=paged_kv_indices,
465 paged_kv_last_page_len=paged_kv_last_page_len,
466 num_qo_heads=self.runner.num_query_heads,
462 - num_kv_heads=self.runner.num_kv_heads,
463 - head_dim=self.runner.head_size,
467 + num_kv_heads=self.kv_cache_spec.num_kv_heads,
468 + head_dim=self.kv_cache_spec.head_size,
469 page_size=page_size,
465 - data_type=self.runner.kv_cache_dtype,
470 + data_type=self.kv_cache_spec.dtype,
471 q_data_type=self.runner.dtype,
472 slot_mapping=slot_mapping,
473 num_decodes=self._num_decodes,
@@ -481,7 +486,7 @@ class FlashInferMetadataBuilder:
486 return attn_metadata
487
488 def use_cascade_attention(self, *args, **kwargs) -> bool:
484 - if self.runner.kv_cache_dtype != self.runner.model_config.dtype:
489 + if self.kv_cache_spec.dtype != self.runner.model_config.dtype:
490 # TODO: The cascade wrapper currently does not support setting
491 # kv cache dtype to something different from query dtype.
492 return False
vllm/v1/attention/backends/mla/common.py
+15 -8
@@ -207,6 +207,8 @@ from vllm.model_executor.layers.linear import (ColumnParallelLinear,
207 from vllm.platforms import current_platform
208 from vllm.utils import cdiv, round_down
209 from vllm.v1.attention.backends.utils import CommonAttentionMetadata
210 +from vllm.v1.kv_cache_interface import AttentionSpec
211 +from vllm.v1.worker.block_table import BlockTable
212
213 try:
214 from vllm.vllm_flash_attn import flash_attn_varlen_func
@@ -334,6 +336,8 @@ class MLACommonMetadataBuilder(Generic[M]):
336
337 def __init__(self,
338 runner: "GPUModelRunner",
339 + kv_cache_spec: AttentionSpec,
340 + block_table: BlockTable,
341 metadata_cls: Optional[type[M]] = None):
342 self.metadata_cls = metadata_cls \
343 if metadata_cls is not None else MLACommonMetadata
@@ -346,10 +350,11 @@ class MLACommonMetadataBuilder(Generic[M]):
350 runner.parallel_config)
351 self.mla_dims = get_mla_dims(model_config)
352 self.aot_schedule = is_vllm_fa and (get_flash_attn_version() == 3)
353 + self.kv_cache_spec = kv_cache_spec
354
355 # Dont try to access the runner on AMD
356 if self.aot_schedule:
352 - self.page_size = self.runner.block_size
357 + self.page_size = self.kv_cache_spec.block_size
358
359 if self.chunked_prefill_enabled:
360 self.chunked_prefill_workspace_size = min(
@@ -375,6 +380,7 @@ class MLACommonMetadataBuilder(Generic[M]):
380 dtype=model_config.dtype,
381 device=runner.device,
382 )
383 + self.block_table = block_table
384
385 def reorder_batch(self, input_batch: "InputBatch",
386 scheduler_output: "SchedulerOutput") -> bool:
@@ -436,9 +442,10 @@ class MLACommonMetadataBuilder(Generic[M]):
442
443 return modified_batch
444
439 - def _build_decode(self, block_table: torch.Tensor, seq_lens: torch.Tensor):
445 + def _build_decode(self, block_table_tensor: torch.Tensor,
446 + seq_lens: torch.Tensor):
447 return MLACommonDecodeMetadata(
441 - block_table=block_table,
448 + block_table=block_table_tensor,
449 seq_lens=seq_lens,
450 )
451
@@ -451,9 +458,9 @@ class MLACommonMetadataBuilder(Generic[M]):
458 # function. We should avoid GPU -> CPU sync as much as possible because
459 # it blocks on all previous kernels.
460 device = self.runner.device
454 - block_table = (
455 - self.runner.input_batch.block_table.get_device_tensor()[:num_reqs])
456 - slot_mapping = self.runner.slot_mapping_cpu[:num_actual_tokens].to(
461 + block_table = self.block_table
462 + block_table_tensor = block_table.get_device_tensor()[:num_reqs]
463 + slot_mapping = block_table.slot_mapping_cpu[:num_actual_tokens].to(
464 device, non_blocking=True).long()
465
466 query_start_loc = common_attn_metadata.query_start_loc
@@ -530,7 +537,7 @@ class MLACommonMetadataBuilder(Generic[M]):
537 self.chunked_prefill_workspace_size
538
539 prefill_metadata = MLACommonPrefillMetadata(
533 - block_table=block_table[reqs_start:, ...],
540 + block_table=block_table_tensor[reqs_start:, ...],
541 query_start_loc=prefill_query_start_loc,
542 max_query_len=max_query_len,
543 chunked_context=chunked_context_metadata,
@@ -539,7 +546,7 @@ class MLACommonMetadataBuilder(Generic[M]):
546 decode_metadata = None
547 if self._num_decodes > 0:
548 decode_metadata = self._build_decode(
542 - block_table=block_table[:self._num_decodes, ...],
549 + block_table_tensor=block_table_tensor[:self._num_decodes, ...],
550 seq_lens=seq_lens[:self._num_decodes],
551 )
552
vllm/v1/attention/backends/mla/flashmla.py
+7 -4
@@ -16,6 +16,8 @@ from vllm.v1.attention.backends.mla.common import (MLACommonBackend,
16 MLACommonImpl,
17 MLACommonMetadata,
18 MLACommonMetadataBuilder)
19 +from vllm.v1.kv_cache_interface import AttentionSpec
20 +from vllm.v1.worker.block_table import BlockTable
21
22 logger = init_logger(__name__)
23
@@ -52,13 +54,14 @@ class FlashMLAMetadata(MLACommonMetadata[FlashMLADecodeMetadata]):
54
55 class FlashMLAMetadataBuilder(MLACommonMetadataBuilder[FlashMLAMetadata]):
56
55 - def __init__(self, runner):
56 - super().__init__(runner)
57 + def __init__(self, runner, kv_cache_spec: AttentionSpec,
58 + block_table: BlockTable):
59 + super().__init__(runner, kv_cache_spec, block_table)
60
61 self.num_q_heads = self.runner.model_config.get_num_attention_heads(
62 self.runner.parallel_config)
63
61 - def _build_decode(self, block_table: torch.Tensor,
64 + def _build_decode(self, block_table_tensor: torch.Tensor,
65 seq_lens: torch.Tensor) -> FlashMLADecodeMetadata:
66 tile_scheduler_metadata, num_splits = \
67 get_mla_metadata(
@@ -68,7 +71,7 @@ class FlashMLAMetadataBuilder(MLACommonMetadataBuilder[FlashMLAMetadata]):
71 )
72
73 return FlashMLADecodeMetadata(
71 - block_table=block_table,
74 + block_table=block_table_tensor,
75 seq_lens=seq_lens,
76 tile_scheduler_metadata=tile_scheduler_metadata,
77 num_splits=num_splits,
vllm/v1/attention/backends/mla/rocm_aiter_mla.py
+5 -2
@@ -14,6 +14,8 @@ from vllm.v1.attention.backends.mla.common import (MLACommonBackend,
14 MLACommonImpl,
15 MLACommonMetadata,
16 MLACommonMetadataBuilder)
17 +from vllm.v1.kv_cache_interface import AttentionSpec
18 +from vllm.v1.worker.block_table import BlockTable
19
20 # yapf: enable
21
@@ -59,8 +61,9 @@ class AiterMLAMetadata(MLACommonMetadata[AiterMLADecodeMetadata]):
61
62 class AiterMLAMetadataBuilder(MLACommonMetadataBuilder[AiterMLAMetadata]):
63
62 - def __init__(self, runner):
63 - super().__init__(runner)
64 + def __init__(self, runner, kv_cache_spec: AttentionSpec,
65 + block_table: BlockTable):
66 + super().__init__(runner, kv_cache_spec, block_table)
67 max_model_len = self.runner.model_config.max_model_len
68 assert max_model_len == 32768,\
69 "AITER MLA requires max_model_len=32768"
vllm/v1/worker/block_table.py
+11
@@ -14,11 +14,13 @@ class BlockTable:
14 self,
15 max_num_reqs: int,
16 max_num_blocks_per_req: int,
17 + max_num_batched_tokens: int,
18 pin_memory: bool,
19 device: torch.device,
20 ):
21 self.max_num_reqs = max_num_reqs
22 self.max_num_blocks_per_req = max_num_blocks_per_req
23 + self.max_num_batched_tokens = max_num_batched_tokens
24 self.pin_memory = pin_memory
25 self.device = device
26
@@ -36,6 +38,15 @@ class BlockTable:
38 self.block_table_np = self.block_table_cpu.numpy()
39 self.num_blocks_per_row = np.zeros(max_num_reqs, dtype=np.int32)
40
41 + self.slot_mapping_cpu = torch.zeros(self.max_num_batched_tokens,
42 + dtype=torch.int64,
43 + device="cpu",
44 + pin_memory=self.pin_memory)
45 + self.slot_mapping_np = self.slot_mapping_cpu.numpy()
46 + self.slot_mapping = torch.zeros(self.max_num_batched_tokens,
47 + dtype=torch.int64,
48 + device=self.device)
49 +
50 def append_row(
51 self,
52 block_ids: list[int],
vllm/v1/worker/gpu_input_batch.py
+3
@@ -59,6 +59,7 @@ class InputBatch:
59 max_num_reqs: int,
60 max_model_len: int,
61 max_num_blocks_per_req: int,
62 + max_num_batched_tokens: int,
63 device: torch.device,
64 pin_memory: bool,
65 vocab_size: int,
@@ -66,6 +67,7 @@ class InputBatch:
67 self.max_num_reqs = max_num_reqs
68 self.max_model_len = max_model_len
69 self.max_num_blocks_per_req = max_num_blocks_per_req
70 + self.max_num_batched_tokens = max_num_batched_tokens
71 self.device = device
72 self.pin_memory = pin_memory
73 self.vocab_size = vocab_size
@@ -100,6 +102,7 @@ class InputBatch:
102 self.block_table = BlockTable(
103 max_num_reqs=max_num_reqs,
104 max_num_blocks_per_req=max_num_blocks_per_req,
105 + max_num_batched_tokens=max_num_batched_tokens,
106 pin_memory=pin_memory,
107 device=device,
108 )
vllm/v1/worker/gpu_model_runner.py
+9 -12
@@ -150,8 +150,6 @@ class GPUModelRunner(LoRAModelRunnerMixin):
150 f"FA3. Current attention backend is {attn_backend_name}, "
151 f"FlashAttention version is {flash_attn_version}.")
152
153 - self.attn_metadata_builder = self.attn_backend.get_builder_cls()(
154 - weakref.proxy(self))
153 self.cascade_attn_enabled = not self.model_config.disable_cascade_attn
154
155 # Multi-modal data support
@@ -174,6 +172,7 @@ class GPUModelRunner(LoRAModelRunnerMixin):
172 # Initialize in initialize_kv_cache
173 self.kv_caches: list[torch.Tensor] = []
174 # self.kv_cache_config: KVCacheConfig
175 + # self.attn_metadata_builder: type[AttentionMetadataBuilder]
176
177 # req_id -> (input_id -> encoder_output)
178 self.encoder_cache: dict[str, dict[int, torch.Tensor]] = {}
@@ -203,6 +202,7 @@ class GPUModelRunner(LoRAModelRunnerMixin):
202 max_num_reqs=self.max_num_reqs,
203 max_model_len=self.max_model_len,
204 max_num_blocks_per_req=self.max_num_blocks_per_req,
205 + max_num_batched_tokens=self.max_num_tokens,
206 device=self.device,
207 pin_memory=self.pin_memory,
208 vocab_size=model_config.get_vocab_size(),
@@ -291,11 +291,6 @@ class GPUModelRunner(LoRAModelRunnerMixin):
291 device="cpu",
292 pin_memory=self.pin_memory)
293 self.positions_np = self.positions_cpu.numpy()
294 - self.slot_mapping_cpu = torch.zeros(self.max_num_tokens,
295 - dtype=torch.int64,
296 - device="cpu",
297 - pin_memory=self.pin_memory)
298 - self.slot_mapping_np = self.slot_mapping_cpu.numpy()
294 self.query_start_loc_cpu = torch.zeros(self.max_num_reqs + 1,
295 dtype=torch.int32,
296 device="cpu",
@@ -586,7 +581,8 @@ class GPUModelRunner(LoRAModelRunnerMixin):
581 block_offsets = positions_np % self.block_size
582 np.add(block_numbers * self.block_size,
583 block_offsets,
589 - out=self.slot_mapping_np[:total_num_scheduled_tokens])
584 + out=self.input_batch.block_table.
585 + slot_mapping_np[:total_num_scheduled_tokens])
586
587 # Prepare the attention metadata.
588 self.query_start_loc_np[0] = 0
@@ -614,12 +610,8 @@ class GPUModelRunner(LoRAModelRunnerMixin):
610 self.query_start_loc_cpu[:num_reqs + 1], non_blocking=True)
611 self.seq_lens[:num_reqs].copy_(self.seq_lens_cpu[:num_reqs],
612 non_blocking=True)
617 - self.slot_mapping[:total_num_scheduled_tokens].copy_(
618 - self.slot_mapping_cpu[:total_num_scheduled_tokens],
619 - non_blocking=True)
613
614 # Fill unused with -1. Needed for reshape_and_cache
622 - self.slot_mapping[total_num_scheduled_tokens:].fill_(-1)
615 self.seq_lens[num_reqs:].fill_(0)
616 self.query_start_loc[num_reqs + 1:].fill_(-1)
617
@@ -1821,6 +1813,11 @@ class GPUModelRunner(LoRAModelRunnerMixin):
1813 self.vllm_config.compilation_config.static_forward_context,
1814 self.kv_caches)
1815
1816 + self.attn_metadata_builder = self.attn_backend.get_builder_cls()(
1817 + weakref.proxy(self),
1818 + kv_cache_config.kv_cache_groups[0].kv_cache_spec,
1819 + self.input_batch.block_table)
1820 +
1821 def get_kv_cache_spec(self) -> dict[str, KVCacheSpec]:
1822 """
1823 Generates the KVCacheSpec by parsing the kv cache format from each
vllm/v1/worker/tpu_model_runner.py
+9 -9
@@ -179,6 +179,7 @@ class TPUModelRunner(LoRAModelRunnerMixin):
179 max_num_reqs=self.max_num_reqs,
180 max_model_len=self.max_model_len,
181 max_num_blocks_per_req=self.max_num_blocks_per_req,
182 + max_num_batched_tokens=self.max_num_tokens,
183 device=self.device,
184 pin_memory=self.pin_memory,
185 vocab_size=self.vocab_size,
@@ -197,10 +198,6 @@ class TPUModelRunner(LoRAModelRunnerMixin):
198 device="cpu")
199 self.positions_np = self.positions_cpu.numpy()
200
200 - self.slot_mapping_cpu = torch.zeros(self.max_num_tokens,
201 - dtype=torch.int64,
202 - device="cpu")
203 - self.slot_mapping_np = self.slot_mapping_cpu.numpy()
201 self.block_table_cpu = torch.zeros(
202 (self.max_num_reqs, self.max_num_blocks_per_req),
203 dtype=self.input_batch.block_table.get_cpu_tensor().dtype,
@@ -533,7 +530,8 @@ class TPUModelRunner(LoRAModelRunnerMixin):
530 block_offsets = positions_np % self.block_size
531 np.add(block_numbers * self.block_size,
532 block_offsets,
536 - out=self.slot_mapping_np[:total_num_scheduled_tokens])
533 + out=self.input_batch.block_table.
534 + slot_mapping_cpu[:total_num_scheduled_tokens])
535
536 # Prepare the attention metadata.
537 self.query_start_loc_np[0] = 0
@@ -557,10 +555,12 @@ class TPUModelRunner(LoRAModelRunnerMixin):
555 self.position_ids = self.positions_cpu[:
556 padded_total_num_scheduled_tokens].to(
557 self.device)
560 - self.slot_mapping_cpu[total_num_scheduled_tokens:] = _PAD_SLOT_ID
561 - slot_mapping = self.slot_mapping_cpu[:
562 - padded_total_num_scheduled_tokens].to(
563 - self.device)
558 + self.input_batch.block_table.slot_mapping_cpu[
559 + total_num_scheduled_tokens:] = _PAD_SLOT_ID
560 + slot_mapping = (
561 + self.input_batch.block_table.
562 + slot_mapping_cpu[:padded_total_num_scheduled_tokens].to(
563 + self.device))
564 block_tables = self.block_table_cpu[:self.max_num_reqs]
565 block_tables[:num_reqs, :self.max_num_blocks_per_req] = (
566 self.input_batch.block_table.get_cpu_tensor()[:num_reqs])