@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 4516d44b7f
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 13, 05:45 UTC

[DCP] Support Decode Context Parallel (DCP) for GQA with Flashinfer (#25438)

Signed-off-by: gaojc <1055866782@qq.com> Signed-off-by: Jingchun Gao <gaojingchun1@huawei.com> Signed-off-by: Jingchun Gao <63247409+gjc0824@users.noreply.github.com> Signed-off-by: QiuChunshuo <qiuchunshuo@huawei.com> Co-authored-by: gaojingchun (A) <g00955623@china.huawei.com> Co-authored-by: Jingchun Gao <gaojingchun1@huawei.com> Co-authored-by: QiuChunshuo <qiuchunshuo@huawei.com>

Jingchun Gao committed Nov 14, 2025 at 19:24 UTC 4516d44b7f990b8f92450e73720b89cc8ac155ca
5 files changed +331 -51
tests/distributed/test_context_parallel.py
+15 -2
@@ -39,6 +39,7 @@ class ParallelSetup(NamedTuple):
39 class CPTestOptions(NamedTuple):
40 multi_node_only: bool
41 load_format: str | None = None
42 + attn_backend: str | None = None
43
44
45 @dataclass
@@ -58,6 +59,7 @@ class CPTestSettings:
59 multi_node_only: bool = False,
60 runner: RunnerOption = "auto",
61 load_format: str | None = None,
62 + attn_backend: str | None = None,
63 ):
64 parallel_setups = []
65 for eager_mode_val in [False]:
@@ -79,7 +81,9 @@ class CPTestSettings:
81 distributed_backends=["mp"],
82 runner=runner,
83 test_options=CPTestOptions(
82 - multi_node_only=multi_node_only, load_format=load_format
84 + multi_node_only=multi_node_only,
85 + load_format=load_format,
86 + attn_backend=attn_backend,
87 ),
88 )
89
@@ -117,7 +121,7 @@ def _compare_cp_with_tp(
121 chunked_prefill,
122 ) = parallel_setup
123
120 - multi_node_only, load_format = test_options
124 + multi_node_only, load_format, attn_backend = test_options
125
126 model_info = HF_EXAMPLE_MODELS.find_hf_info(model_id)
127 model_info.check_transformers_version(on_fail="skip")
@@ -177,6 +181,13 @@ def _compare_cp_with_tp(
181 if hf_overrides:
182 common_args.extend(["--hf-overrides", json.dumps(hf_overrides)])
183
184 + if not attn_backend:
185 + cp_env = tp_env = {}
186 + else:
187 + cp_env = tp_env = {
188 + "VLLM_ATTENTION_BACKEND": attn_backend,
189 + }
190 +
191 cp_args = [
192 *common_args,
193 "--tensor-parallel-size",
@@ -205,6 +216,8 @@ def _compare_cp_with_tp(
216 model_id,
217 cp_args,
218 tp_args,
219 + cp_env,
220 + tp_env,
221 method=method,
222 max_wait_seconds=720,
223 )
vllm/config/model.py
+8
@@ -1183,6 +1183,14 @@ class ModelConfig:
1183 f"but got {decode_context_parallel_size}"
1184 )
1185
1186 + num_q_per_kv = total_num_attention_heads // total_num_kv_heads
1187 + assert num_q_per_kv % decode_context_parallel_size == 0, (
1188 + f"Total number of q per kv attn heads ({num_q_per_kv})"
1189 + " must be divisible by dcp world size when enable "
1190 + "decode context parallel for GQA "
1191 + f"({parallel_config.decode_context_parallel_size})."
1192 + )
1193 +
1194 def get_sliding_window(self) -> int | None:
1195 """Get the sliding window size from the HF text config if present."""
1196 return getattr(self.hf_text_config, "sliding_window", None)
vllm/utils/flashinfer.py
+9
@@ -259,6 +259,7 @@ def use_trtllm_attention(
259 num_kv_heads: int,
260 num_tokens: int,
261 max_seq_len: int,
262 + dcp_world_size: int,
263 kv_cache_dtype: str,
264 q_dtype: torch.dtype,
265 is_prefill: bool,
@@ -272,6 +273,14 @@ def use_trtllm_attention(
273 if force_use_trtllm is not None and not force_use_trtllm:
274 return False
275
276 + # Decode context parallel is not supported
277 + if dcp_world_size > 1:
278 + logger.warning_once(
279 + "Trtllm does not support returning LSE and as a result "
280 + "does not support DCP, reverting to FlashInfer"
281 + )
282 + return False
283 +
284 # The platform is not supported
285 if not supports_trtllm_attention():
286 if force_use_trtllm:
vllm/v1/attention/backends/flashinfer.py
+294 -49
@@ -10,6 +10,7 @@ import torch
10 from flashinfer import (
11 BatchDecodeWithPagedKVCacheWrapper,
12 BatchPrefillWithPagedKVCacheWrapper,
13 + BatchPrefillWithRaggedKVCacheWrapper,
14 MultiLevelCascadeAttentionWrapper,
15 )
16 from flashinfer.decode import _get_range_buf, trtllm_batch_decode_with_kv_cache
@@ -24,8 +25,11 @@ from vllm.attention.backends.abstract import (
25 AttentionType,
26 MultipleOf,
27 )
28 +from vllm.attention.ops.common import cp_lse_ag_out_rs
29 +from vllm.attention.ops.merge_attn_states import merge_attn_states
30 from vllm.config import CUDAGraphMode, VllmConfig
31 from vllm.config.cache import CacheDType
32 +from vllm.distributed.parallel_state import get_dcp_group
33 from vllm.logger import init_logger
34 from vllm.model_executor.layers.batch_invariant import (
35 vllm_is_batch_invariant,
@@ -50,6 +54,7 @@ from vllm.v1.attention.backends.utils import (
54 AttentionMetadataBuilder,
55 CommonAttentionMetadata,
56 KVCacheLayoutType,
57 + get_dcp_local_seq_lens,
58 get_kv_cache_layout,
59 get_per_layer_parameters,
60 infer_global_hyperparameters,
@@ -160,6 +165,113 @@ def trtllm_prefill_attn_kvfp8_dequant(
165 return mock_kv_cache, mock_block_table
166
167
168 +class BatchDCPPrefillWrapper:
169 + def __init__(
170 + self,
171 + workspace_buffer: torch.Tensor | None = None,
172 + ):
173 + self._context = BatchPrefillWithPagedKVCacheWrapper(
174 + workspace_buffer, get_kv_cache_layout()
175 + )
176 + self._new_tokens = BatchPrefillWithRaggedKVCacheWrapper(
177 + workspace_buffer, get_kv_cache_layout()
178 + )
179 +
180 + def plan(
181 + self,
182 + qo_indptr_cpu: torch.Tensor,
183 + paged_kv_indptr_cpu: torch.Tensor,
184 + paged_kv_indices: torch.Tensor,
185 + paged_kv_last_page_len_cpu: torch.Tensor,
186 + prefill_start: int,
187 + page_size: int,
188 + num_qo_heads: int,
189 + dcp_world_size: int,
190 + num_kv_heads: int,
191 + head_dim: int,
192 + sm_scale: float,
193 + window_left: int,
194 + logits_soft_cap: float | None,
195 + q_data_type: torch.dtype,
196 + kv_cache_dtype: torch.dtype,
197 + prefill_fixed_split_size: int,
198 + disable_split_kv: bool,
199 + ):
200 + """Plan the prefill operation with given parameters."""
201 + self._context.plan(
202 + qo_indptr_cpu,
203 + paged_kv_indptr_cpu,
204 + paged_kv_indices,
205 + paged_kv_last_page_len_cpu[prefill_start:],
206 + num_qo_heads * dcp_world_size,
207 + num_kv_heads,
208 + head_dim,
209 + page_size,
210 + causal=False, # This is context run
211 + sm_scale=sm_scale,
212 + window_left=window_left,
213 + logits_soft_cap=logits_soft_cap,
214 + q_data_type=q_data_type,
215 + kv_data_type=kv_cache_dtype,
216 + fixed_split_size=prefill_fixed_split_size,
217 + disable_split_kv=disable_split_kv,
218 + )
219 + self._new_tokens.plan(
220 + qo_indptr=qo_indptr_cpu,
221 + kv_indptr=qo_indptr_cpu,
222 + num_qo_heads=num_qo_heads,
223 + num_kv_heads=num_kv_heads,
224 + head_dim_qk=head_dim,
225 + head_dim_vo=head_dim,
226 + causal=True, # This is newtokens run
227 + sm_scale=sm_scale,
228 + window_left=window_left,
229 + logits_soft_cap=logits_soft_cap,
230 + q_data_type=q_data_type,
231 + )
232 +
233 + def run(
234 + self,
235 + layer: torch.nn.Module,
236 + prefill_query: torch.Tensor,
237 + kv_cache_permute: torch.Tensor,
238 + key: torch.Tensor,
239 + value: torch.Tensor,
240 + out: torch.Tensor,
241 + ):
242 + prefill_query_across_dcp = get_dcp_group().all_gather(
243 + prefill_query.contiguous(), dim=1
244 + )
245 + output_context_tmp, lse_context_tmp = self._context.run(
246 + prefill_query_across_dcp,
247 + kv_cache_permute,
248 + k_scale=layer._k_scale_float,
249 + v_scale=layer._v_scale_float,
250 + return_lse=True,
251 + )
252 + output_context, lse_context = cp_lse_ag_out_rs(
253 + output_context_tmp, lse_context_tmp, get_dcp_group(), return_lse=True
254 + )
255 + lse_context = lse_context.transpose(0, 1).contiguous()
256 +
257 + output_query, lse_query = self._new_tokens.run(
258 + prefill_query,
259 + key,
260 + value,
261 + return_lse=True,
262 + )
263 + lse_query = lse_query.transpose(0, 1).contiguous()
264 +
265 + merge_attn_states(
266 + out,
267 + output_context,
268 + lse_context,
269 + output_query,
270 + lse_query,
271 + )
272 + return out
273 +
274 +
275 class FlashInferBackend(AttentionBackend):
276 accept_output_buffer: bool = True
277 supported_dtypes: ClassVar[list[torch.dtype]] = [torch.float16, torch.bfloat16]
@@ -281,7 +393,9 @@ class FlashInferMetadata:
393 # For cascade attention (CPU for planning).
394 use_cascade: bool
395
284 - prefill_wrapper: BatchPrefillWithPagedKVCacheWrapper | None = None
396 + prefill_wrapper: (
397 + BatchPrefillWithPagedKVCacheWrapper | BatchDCPPrefillWrapper | None
398 + ) = None
399 decode_wrapper: BatchDecodeWithPagedKVCacheWrapper | None = None
400 cascade_wrapper: MultiLevelCascadeAttentionWrapper | None = None
401
@@ -303,7 +417,9 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
417 self.cache_config = vllm_config.cache_config
418 self.model_config = vllm_config.model_config
419 self._workspace_buffer = None
306 - self._prefill_wrapper = None # Wrapper for prefill/append
420 + self._prefill_wrapper: (
421 + BatchPrefillWithPagedKVCacheWrapper | BatchDCPPrefillWrapper | None
422 + ) = None # Wrapper for prefill/append
423 self._decode_wrapper = None # Wrapper for decode (general shape)
424
425 if vllm_is_batch_invariant():
@@ -341,9 +457,23 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
457 self.compilation_config.max_cudagraph_capture_size,
458 )
459
344 - self.num_qo_heads = self.model_config.get_num_attention_heads(
345 - self.vllm_config.parallel_config
460 + try:
461 + self.dcp_world_size = get_dcp_group().world_size
462 + self.dcp_rank = get_dcp_group().rank_in_group
463 + self.dcp_kv_cache_interleave_size = (
464 + vllm_config.parallel_config.dcp_kv_cache_interleave_size
465 + )
466 + except AssertionError:
467 + # DCP might not be initialized in testing
468 + self.dcp_world_size = 1
469 + self.dcp_rank = 0
470 + self.dcp_kv_cache_interleave_size = 1
471 +
472 + self.num_qo_heads = (
473 + self.model_config.get_num_attention_heads(self.vllm_config.parallel_config)
474 + * self.dcp_world_size
475 )
476 +
477 self.num_kv_heads = self.kv_cache_spec.num_kv_heads
478 self.head_dim = self.kv_cache_spec.head_size
479 self.page_size = self.kv_cache_spec.block_size
@@ -455,11 +585,19 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
585 )
586 return self._workspace_buffer
587
458 - def _get_prefill_wrapper(self):
588 + def _get_prefill_wrapper(
589 + self,
590 + ) -> BatchPrefillWithPagedKVCacheWrapper | BatchDCPPrefillWrapper:
591 if self._prefill_wrapper is None:
460 - self._prefill_wrapper = BatchPrefillWithPagedKVCacheWrapper(
461 - self._get_workspace_buffer(), get_kv_cache_layout()
462 - )
592 + if self.dcp_world_size > 1:
593 + self._prefill_wrapper = BatchDCPPrefillWrapper(
594 + workspace_buffer=self._get_workspace_buffer(),
595 + )
596 + else:
597 + self._prefill_wrapper = BatchPrefillWithPagedKVCacheWrapper(
598 + self._get_workspace_buffer(), get_kv_cache_layout()
599 + )
600 + assert self._prefill_wrapper is not None
601 return self._prefill_wrapper
602
603 def _get_decode_wrapper(self, batch_size: int, use_cudagraph: bool = False):
@@ -526,9 +664,29 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
664 max_seq_len = common_attn_metadata.max_seq_len
665 seq_lens = common_attn_metadata.seq_lens
666 seq_lens_cpu = common_attn_metadata.seq_lens_cpu
529 - seq_lens_np = seq_lens_cpu.numpy()
667 block_table_tensor = common_attn_metadata.block_table_tensor
668 + qo_indptr_cpu = common_attn_metadata.query_start_loc_cpu
669
670 + if self.dcp_world_size > 1:
671 + if num_prefills > 0:
672 + qo_indptr_prefill_cpu = (
673 + qo_indptr_cpu[num_decodes:] - qo_indptr_cpu[num_decodes]
674 + )
675 + query_lens_prefill_cpu = (
676 + qo_indptr_prefill_cpu[1:] - qo_indptr_prefill_cpu[:-1]
677 + )
678 + seq_lens_cpu[num_decodes:] = (
679 + seq_lens_cpu[num_decodes:] - query_lens_prefill_cpu
680 + )
681 +
682 + seq_lens_cpu = get_dcp_local_seq_lens(
683 + seq_lens_cpu,
684 + self.dcp_world_size,
685 + self.dcp_rank,
686 + self.dcp_kv_cache_interleave_size,
687 + )
688 +
689 + seq_lens_np = seq_lens_cpu.numpy()
690 num_blocks_np = (seq_lens_np + (page_size - 1)) // page_size
691
692 use_cascade = common_prefix_len > 0
@@ -589,7 +747,7 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
747 # write self.paged_kv_last_page_len_cpu inplace
748 paged_kv_last_page_len_np = seq_lens_np % page_size
749 self.paged_kv_last_page_len_np[:num_reqs] = np.where(
592 - paged_kv_last_page_len_np == 0,
750 + (paged_kv_last_page_len_np == 0) & (seq_lens_np != 0),
751 page_size,
752 paged_kv_last_page_len_np,
753 )
@@ -600,13 +758,16 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
758 self.num_kv_heads,
759 num_prefill_tokens,
760 max_seq_len,
761 + self.dcp_world_size,
762 self.cache_dtype,
763 self.q_data_type,
764 is_prefill=True,
765 has_sinks=self.has_sinks,
766 has_spec=uses_spec_reorder,
767 )
609 - decode_use_trtllm = self.use_trtllm_decode_attention
768 + decode_use_trtllm = (
769 + self.use_trtllm_decode_attention and self.dcp_world_size <= 1
770 + )
771
772 if not (prefill_use_trtllm and decode_use_trtllm):
773 if self.has_sinks:
@@ -651,7 +812,6 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
812 use_cascade=use_cascade,
813 )
814
654 - qo_indptr_cpu = common_attn_metadata.query_start_loc_cpu
815 paged_kv_indptr_cpu = self.paged_kv_indptr_cpu[: 1 + num_reqs]
816 paged_kv_last_page_len_cpu = self.paged_kv_last_page_len_cpu[:num_reqs]
817
@@ -703,24 +863,52 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
863 attn_metadata.max_q_len_prefill = int(query_lens_prefill.max().item())
864
865 if not attn_metadata.prefill_use_trtllm:
706 - attn_metadata.prefill_wrapper.plan(
707 - qo_indptr_cpu,
708 - paged_kv_indptr_cpu,
709 - paged_kv_indices,
710 - paged_kv_last_page_len_cpu[prefill_start:],
711 - self.num_qo_heads,
712 - self.num_kv_heads,
713 - self.head_dim,
714 - self.page_size,
715 - causal=True,
716 - sm_scale=self.sm_scale,
717 - window_left=self.window_left,
718 - logits_soft_cap=self.logits_soft_cap,
719 - q_data_type=self.q_data_type,
720 - kv_data_type=self.kv_cache_dtype,
721 - fixed_split_size=self.prefill_fixed_split_size,
722 - disable_split_kv=self.disable_split_kv,
723 - )
866 + if self.dcp_world_size > 1:
867 + assert isinstance(
868 + attn_metadata.prefill_wrapper, BatchDCPPrefillWrapper
869 + )
870 + attn_metadata.prefill_wrapper.plan(
871 + qo_indptr_cpu=qo_indptr_cpu,
872 + paged_kv_indptr_cpu=paged_kv_indptr_cpu,
873 + paged_kv_indices=paged_kv_indices,
874 + paged_kv_last_page_len_cpu=paged_kv_last_page_len_cpu,
875 + prefill_start=prefill_start,
876 + page_size=self.page_size,
877 + num_qo_heads=self.num_qo_heads,
878 + dcp_world_size=self.dcp_world_size,
879 + num_kv_heads=self.num_kv_heads,
880 + head_dim=self.head_dim,
881 + sm_scale=self.sm_scale,
882 + window_left=self.window_left,
883 + logits_soft_cap=self.logits_soft_cap,
884 + q_data_type=self.q_data_type,
885 + kv_cache_dtype=self.kv_cache_dtype,
886 + prefill_fixed_split_size=self.prefill_fixed_split_size,
887 + disable_split_kv=self.disable_split_kv,
888 + )
889 + else:
890 + assert isinstance(
891 + attn_metadata.prefill_wrapper,
892 + BatchPrefillWithPagedKVCacheWrapper,
893 + )
894 + attn_metadata.prefill_wrapper.plan(
895 + qo_indptr_cpu,
896 + paged_kv_indptr_cpu,
897 + paged_kv_indices,
898 + paged_kv_last_page_len_cpu[prefill_start:],
899 + self.num_qo_heads,
900 + self.num_kv_heads,
901 + self.head_dim,
902 + self.page_size,
903 + causal=True,
904 + sm_scale=self.sm_scale,
905 + window_left=self.window_left,
906 + logits_soft_cap=self.logits_soft_cap,
907 + q_data_type=self.q_data_type,
908 + kv_data_type=self.kv_cache_dtype,
909 + fixed_split_size=self.prefill_fixed_split_size,
910 + disable_split_kv=self.disable_split_kv,
911 + )
912 else:
913 attn_metadata.qo_indptr_gpu = qo_indptr_cpu.to(
914 self.device, non_blocking=True
@@ -770,7 +958,7 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
958 paged_kv_indices,
959 self.paged_kv_last_page_len_cpu[:num_input_tokens],
960 seq_lens_cpu[:num_input_tokens],
773 - self.num_qo_heads,
961 + self.num_qo_heads * self.dcp_world_size,
962 self.num_kv_heads,
963 self.head_dim,
964 self.page_size,
@@ -797,6 +985,8 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
985
986
987 class FlashInferImpl(AttentionImpl):
988 + can_return_lse_for_decode: bool = True
989 +
990 def __init__(
991 self,
992 num_heads: int,
@@ -989,6 +1179,8 @@ class FlashInferImpl(AttentionImpl):
1179
1180 # Inputs and outputs may be padded for CUDA graphs
1181 query = query[:num_actual_tokens]
1182 + key = key[:num_actual_tokens]
1183 + value = value[:num_actual_tokens]
1184 output_padded = output
1185 output = output[:num_actual_tokens]
1186
@@ -1015,17 +1207,46 @@ class FlashInferImpl(AttentionImpl):
1207 assert prefill_wrapper is not None
1208
1209 if not attn_metadata.prefill_use_trtllm:
1018 - assert prefill_wrapper._causal
1019 - assert prefill_wrapper._window_left == self.window_left
1020 - assert prefill_wrapper._logits_soft_cap == (self.logits_soft_cap or 0.0)
1021 - assert prefill_wrapper._sm_scale == self.scale
1022 - prefill_wrapper.run(
1023 - prefill_query,
1024 - kv_cache_permute,
1025 - k_scale=layer._k_scale_float,
1026 - v_scale=layer._v_scale_float,
1027 - out=output[num_decode_tokens:],
1028 - )
1210 + if self.dcp_world_size > 1:
1211 + assert isinstance(prefill_wrapper, BatchDCPPrefillWrapper)
1212 + assert prefill_wrapper._context._window_left == self.window_left
1213 + assert prefill_wrapper._context._logits_soft_cap == (
1214 + self.logits_soft_cap or 0.0
1215 + )
1216 + assert prefill_wrapper._context._sm_scale == self.scale
1217 + assert not prefill_wrapper._context._causal
1218 + assert prefill_wrapper._new_tokens._window_left == self.window_left
1219 + assert prefill_wrapper._new_tokens._logits_soft_cap == (
1220 + self.logits_soft_cap or 0.0
1221 + )
1222 + assert prefill_wrapper._new_tokens._sm_scale == self.scale
1223 + assert prefill_wrapper._new_tokens._causal
1224 +
1225 + prefill_wrapper.run(
1226 + layer,
1227 + prefill_query,
1228 + kv_cache_permute,
1229 + key[num_decode_tokens:],
1230 + value[num_decode_tokens:],
1231 + out=output[num_decode_tokens:],
1232 + )
1233 + else:
1234 + assert isinstance(
1235 + prefill_wrapper, BatchPrefillWithPagedKVCacheWrapper
1236 + )
1237 + assert prefill_wrapper._window_left == self.window_left
1238 + assert prefill_wrapper._logits_soft_cap == (
1239 + self.logits_soft_cap or 0.0
1240 + )
1241 + assert prefill_wrapper._sm_scale == self.scale
1242 + assert prefill_wrapper._causal
1243 + prefill_wrapper.run(
1244 + prefill_query,
1245 + kv_cache_permute,
1246 + k_scale=layer._k_scale_float,
1247 + v_scale=layer._v_scale_float,
1248 + out=output[num_decode_tokens:],
1249 + )
1250 else:
1251 # prefill_query may be non-contiguous
1252 prefill_query = prefill_query.contiguous()
@@ -1101,13 +1322,37 @@ class FlashInferImpl(AttentionImpl):
1322 assert decode_wrapper._window_left == self.window_left
1323 assert decode_wrapper._logits_soft_cap == (self.logits_soft_cap or 0.0)
1324 assert decode_wrapper._sm_scale == self.scale
1104 - decode_wrapper.run(
1105 - decode_query,
1106 - kv_cache_permute,
1107 - k_scale=layer._k_scale_float,
1108 - v_scale=layer._v_scale_float,
1109 - out=output[:num_decode_tokens],
1110 - )
1325 +
1326 + if self.dcp_world_size > 1:
1327 + decode_query = get_dcp_group().all_gather(
1328 + decode_query.contiguous(), dim=-2
1329 + )
1330 + output_tmp = torch.empty_like(decode_query)
1331 + lse = torch.empty(
1332 + (decode_query.size(0), decode_query.size(1)),
1333 + dtype=torch.float32,
1334 + device=decode_query.device,
1335 + )
1336 + decode_wrapper.run(
1337 + decode_query,
1338 + kv_cache_permute,
1339 + k_scale=layer._k_scale_float,
1340 + v_scale=layer._v_scale_float,
1341 + out=output_tmp,
1342 + lse=lse,
1343 + return_lse=True,
1344 + )
1345 + output[:num_decode_tokens] = cp_lse_ag_out_rs(
1346 + output_tmp, lse, get_dcp_group()
1347 + )
1348 + else:
1349 + decode_wrapper.run(
1350 + decode_query,
1351 + kv_cache_permute,
1352 + k_scale=layer._k_scale_float,
1353 + v_scale=layer._v_scale_float,
1354 + out=output[:num_decode_tokens],
1355 + )
1356 else:
1357 # decode_query may be non-contiguous
1358 decode_query = decode_query.contiguous()
vllm/v1/executor/multiproc_executor.py
+5
@@ -31,6 +31,7 @@ from vllm.distributed import destroy_distributed_environment, destroy_model_para
31 from vllm.distributed.device_communicators.shm_broadcast import Handle, MessageQueue
32 from vllm.distributed.kv_transfer.kv_connector.utils import KVOutputAggregator
33 from vllm.distributed.parallel_state import (
34 + get_dcp_group,
35 get_dp_group,
36 get_ep_group,
37 get_pp_group,
@@ -726,6 +727,8 @@ class WorkerProc:
727 pp_rank = get_pp_group().rank_in_group
728 tp_size = get_tp_group().world_size
729 tp_rank = get_tp_group().rank_in_group
730 + dcp_size = get_dcp_group().world_size
731 + dcp_rank = get_dcp_group().rank_in_group
732 process_name = "Worker"
733 if dp_size > 1:
734 process_name += f"_DP{dp_rank}"
@@ -733,6 +736,8 @@ class WorkerProc:
736 process_name += f"_PP{pp_rank}"
737 if tp_size > 1:
738 process_name += f"_TP{tp_rank}"
739 + if dcp_size > 1:
740 + process_name += f"_DCP{dcp_rank}"
741 if enable_ep:
742 ep_rank = get_ep_group().rank_in_group
743 process_name += f"_EP{ep_rank}"