21-v1_worker_gpu_block_table.py.diff 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. --- baked-ours/v1/worker/gpu/block_table.py 2026-09-10 19:56:14.000000000 +0200
  2. +++ baked/v1/worker/gpu/block_table.py 2026-09-11 10:13:47.000000000 +0200
  3. @@ -27,6 +27,7 @@
  4. cp_rank: int = 0,
  5. cp_interleave: int = 1,
  6. slot_mapping_enabled: list[bool] | None = None,
  7. + cp_sharded: list[bool] | None = None,
  8. ):
  9. self.block_sizes = block_sizes
  10. self.kernel_block_sizes = kernel_block_sizes
  11. @@ -44,6 +45,13 @@
  12. slot_mapping_enabled = [True] * self.num_kv_cache_groups
  13. assert len(slot_mapping_enabled) == self.num_kv_cache_groups
  14. self._slot_mapping_enabled = slot_mapping_enabled
  15. + # Per group: True = positions are round-robined across the cp_size
  16. + # ranks (this rank stores 1/cp_size of them); False = DCP-replicated
  17. + # group, every rank stores every position at its plain block geometry.
  18. + if cp_sharded is None:
  19. + cp_sharded = [True] * self.num_kv_cache_groups
  20. + assert len(cp_sharded) == self.num_kv_cache_groups
  21. + self._cp_sharded = cp_sharded
  22. self.blocks_per_kv_block = [
  23. bs // kbs for bs, kbs in zip(block_sizes, kernel_block_sizes)
  24. @@ -108,6 +116,9 @@
  25. self.slot_mapping_enabled = torch.tensor(
  26. self._slot_mapping_enabled, dtype=torch.bool, device=self.device
  27. )
  28. + self.cp_sharded = torch.tensor(
  29. + self._cp_sharded, dtype=torch.bool, device=self.device
  30. + )
  31. self.input_block_table_ptrs = self._make_ptr_tensor(self.input_block_tables)
  32. def append_block_ids(
  33. @@ -211,6 +222,7 @@
  34. self.block_sizes_tensor,
  35. self.kernel_block_sizes_tensor,
  36. self.slot_mapping_enabled,
  37. + self.cp_sharded,
  38. slot_mappings,
  39. slot_mappings.stride(0),
  40. self.cp_rank,
  41. @@ -284,6 +296,7 @@
  42. block_sizes, # [num_kv_cache_groups]
  43. kernel_block_sizes, # [num_kv_cache_groups]
  44. slot_mapping_enabled, # [num_kv_cache_groups]
  45. + cp_sharded, # [num_kv_cache_groups]
  46. slot_mappings_ptr, # [num_kv_cache_groups, max_num_tokens]
  47. slot_mappings_stride,
  48. cp_rank,
  49. @@ -313,6 +326,7 @@
  50. kv_block_size = tl.load(block_sizes + group_id)
  51. kernel_block_size = tl.load(kernel_block_sizes + group_id)
  52. mapping_enabled = tl.load(slot_mapping_enabled + group_id)
  53. + group_sharded = tl.load(cp_sharded + group_id)
  54. req_state_idx = tl.load(idx_mapping + batch_idx)
  55. start_idx = tl.load(query_start_loc + batch_idx)
  56. @@ -326,15 +340,19 @@
  57. local_positions = positions
  58. is_local = True
  59. else:
  60. - # Context parallelism is used.
  61. + # Context parallelism is used. Sharded groups round-robin positions
  62. + # across the CP ranks; DCP-replicated groups (cp_sharded False)
  63. + # keep every position on every rank at the plain block geometry.
  64. virtual_block_size = kv_block_size * CP_SIZE
  65. virtual_block_indices = positions // virtual_block_size
  66. virtual_block_offsets = positions % virtual_block_size
  67. - is_local = virtual_block_offsets // CP_INTERLEAVE % CP_SIZE == cp_rank
  68. + owner_is_me = virtual_block_offsets // CP_INTERLEAVE % CP_SIZE == cp_rank
  69. rounds = virtual_block_offsets // (CP_INTERLEAVE * CP_SIZE)
  70. remainder = virtual_block_offsets % CP_INTERLEAVE
  71. local_offsets = rounds * CP_INTERLEAVE + remainder
  72. - local_positions = virtual_block_indices * kv_block_size + local_offsets
  73. + sharded_positions = virtual_block_indices * kv_block_size + local_offsets
  74. + local_positions = tl.where(group_sharded, sharded_positions, positions)
  75. + is_local = tl.where(group_sharded, owner_is_me, True)
  76. block_indices = tl.where(
  77. mapping_enabled, local_positions // kernel_block_size, 0