Clarify the meaning of cpu_group / entry_rank when dp + tp is enabled. (#16876)
This commit is contained in:
@@ -603,7 +603,7 @@ class SchedulerDisaggregationPrefillMixin:
|
|||||||
"""
|
"""
|
||||||
polls = poll_and_all_reduce(
|
polls = poll_and_all_reduce(
|
||||||
[req.disagg_kv_sender for req in self.disagg_prefill_inflight_queue],
|
[req.disagg_kv_sender for req in self.disagg_prefill_inflight_queue],
|
||||||
self.tp_worker.get_attention_tp_cpu_group(),
|
self.attn_tp_cpu_group,
|
||||||
)
|
)
|
||||||
|
|
||||||
transferred_rids: List[str] = []
|
transferred_rids: List[str] = []
|
||||||
|
|||||||
@@ -60,10 +60,14 @@ from sglang.srt.disaggregation.utils import (
|
|||||||
prepare_abort,
|
prepare_abort,
|
||||||
)
|
)
|
||||||
from sglang.srt.distributed import get_pp_group, get_world_group
|
from sglang.srt.distributed import get_pp_group, get_world_group
|
||||||
|
from sglang.srt.distributed.parallel_state import get_tp_group
|
||||||
from sglang.srt.dllm.config import DllmConfig
|
from sglang.srt.dllm.config import DllmConfig
|
||||||
from sglang.srt.environ import envs
|
from sglang.srt.environ import envs
|
||||||
from sglang.srt.eplb.expert_distribution import get_global_expert_distribution_recorder
|
from sglang.srt.eplb.expert_distribution import get_global_expert_distribution_recorder
|
||||||
from sglang.srt.layers.dp_attention import compute_dp_attention_world_info
|
from sglang.srt.layers.dp_attention import (
|
||||||
|
compute_dp_attention_world_info,
|
||||||
|
get_attention_tp_group,
|
||||||
|
)
|
||||||
from sglang.srt.layers.moe import initialize_moe_config
|
from sglang.srt.layers.moe import initialize_moe_config
|
||||||
from sglang.srt.layers.quantization.fp8_utils import initialize_fp8_gemm_config
|
from sglang.srt.layers.quantization.fp8_utils import initialize_fp8_gemm_config
|
||||||
from sglang.srt.managers.io_struct import (
|
from sglang.srt.managers.io_struct import (
|
||||||
@@ -546,25 +550,24 @@ class Scheduler(
|
|||||||
self.max_running_requests // self.pp_size, 1
|
self.max_running_requests // self.pp_size, 1
|
||||||
)
|
)
|
||||||
|
|
||||||
self.tp_group = self.tp_worker.get_tp_group()
|
self.tp_group = get_tp_group()
|
||||||
self.tp_cpu_group = self.tp_group.cpu_group
|
self.tp_cpu_group = self.tp_group.cpu_group
|
||||||
self.attn_tp_group = self.tp_worker.get_attention_tp_group()
|
self.attn_tp_group = get_attention_tp_group()
|
||||||
self.attn_tp_cpu_group = self.tp_worker.get_attention_tp_cpu_group()
|
self.attn_tp_cpu_group = self.attn_tp_group.cpu_group
|
||||||
self.pp_group = get_pp_group()
|
self.pp_group = get_pp_group()
|
||||||
self.world_group = get_world_group()
|
self.world_group = get_world_group()
|
||||||
|
|
||||||
# With DP attention enabled, the entry rank is attn_tp_rank==0;
|
# NOTE: dp_tp_* are request/data-plane coordination groups (not tensor collectives).
|
||||||
# otherwise the entry rank is TP group local rank 0.
|
# When DP attention is enabled, scope to the attention-TP group; otherwise use
|
||||||
# For #11910, use the CPU communication group to broadcast VLM Python objects,
|
# the base TP group. Entry rank is the local rank 0 in that group.
|
||||||
# avoiding any coupling with CUDA streams/devices.
|
# Use the CPU (gloo) group to broadcast VLM Python objects and avoid CUDA
|
||||||
if self.server_args.enable_dp_attention:
|
# stream/device coupling (#11910).
|
||||||
self.cpu_group = self.attn_tp_cpu_group
|
self.dp_tp_group = (
|
||||||
self.entry_rank = self.attn_tp_group.first_rank
|
self.attn_tp_group
|
||||||
self.is_entry_rank = self.attn_tp_rank == 0
|
if self.server_args.enable_dp_attention
|
||||||
else:
|
else self.tp_group
|
||||||
self.cpu_group = self.tp_cpu_group
|
)
|
||||||
self.entry_rank = self.tp_group.first_rank
|
self.dp_tp_cpu_group = self.dp_tp_group.cpu_group
|
||||||
self.is_entry_rank = self.tp_group.rank_in_group == 0
|
|
||||||
|
|
||||||
self.pad_input_ids_func = self.tp_worker.get_pad_input_ids_func()
|
self.pad_input_ids_func = self.tp_worker.get_pad_input_ids_func()
|
||||||
set_random_seed(self.random_seed)
|
set_random_seed(self.random_seed)
|
||||||
@@ -1358,10 +1361,10 @@ class Scheduler(
|
|||||||
if (
|
if (
|
||||||
torch.distributed.is_available()
|
torch.distributed.is_available()
|
||||||
and torch.distributed.is_initialized()
|
and torch.distributed.is_initialized()
|
||||||
and self.cpu_group is not None
|
and self.dp_tp_cpu_group is not None
|
||||||
):
|
):
|
||||||
group_world_size = torch.distributed.get_world_size(
|
group_world_size = torch.distributed.get_world_size(
|
||||||
group=self.cpu_group
|
group=self.dp_tp_cpu_group
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
@@ -1374,14 +1377,16 @@ class Scheduler(
|
|||||||
# Since the Scheduler is single-threaded, any large CPU cost will impact
|
# Since the Scheduler is single-threaded, any large CPU cost will impact
|
||||||
# handling of other messages. For example, CPU hits 99.9% can significantly
|
# handling of other messages. For example, CPU hits 99.9% can significantly
|
||||||
# increase the CUDA kernel launch time.
|
# increase the CUDA kernel launch time.
|
||||||
if self.is_entry_rank:
|
if self.dp_tp_group.rank_in_group == 0:
|
||||||
# Only the entry rank materializes once from dict.
|
# Only the entry rank materializes once from dict.
|
||||||
image_inputs = MultimodalInputs.from_dict(raw_mm_inputs)
|
image_inputs = MultimodalInputs.from_dict(raw_mm_inputs)
|
||||||
# Broadcast to other TP ranks (use src=0 within the group).
|
# Broadcast to other TP ranks (use src=0 within the group).
|
||||||
if group_world_size > 1:
|
if group_world_size > 1:
|
||||||
obj_list = [image_inputs]
|
obj_list = [image_inputs]
|
||||||
torch.distributed.broadcast_object_list(
|
torch.distributed.broadcast_object_list(
|
||||||
obj_list, src=self.entry_rank, group=self.cpu_group
|
obj_list,
|
||||||
|
src=self.dp_tp_group.first_rank,
|
||||||
|
group=self.dp_tp_cpu_group,
|
||||||
)
|
)
|
||||||
image_inputs = obj_list[0]
|
image_inputs = obj_list[0]
|
||||||
else:
|
else:
|
||||||
@@ -1389,7 +1394,9 @@ class Scheduler(
|
|||||||
if group_world_size > 1:
|
if group_world_size > 1:
|
||||||
obj_list = [None]
|
obj_list = [None]
|
||||||
torch.distributed.broadcast_object_list(
|
torch.distributed.broadcast_object_list(
|
||||||
obj_list, src=self.entry_rank, group=self.cpu_group
|
obj_list,
|
||||||
|
src=self.dp_tp_group.first_rank,
|
||||||
|
group=self.dp_tp_cpu_group,
|
||||||
)
|
)
|
||||||
image_inputs = obj_list[0]
|
image_inputs = obj_list[0]
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1079,7 +1079,7 @@ class SchedulerPPMixin:
|
|||||||
"""
|
"""
|
||||||
polls = poll_and_all_reduce(
|
polls = poll_and_all_reduce(
|
||||||
[req.disagg_kv_sender if is_send else req.kv_receiver for req in req_queue],
|
[req.disagg_kv_sender if is_send else req.kv_receiver for req in req_queue],
|
||||||
self.tp_worker.get_attention_tp_cpu_group(),
|
self.attn_tp_cpu_group,
|
||||||
)
|
)
|
||||||
rids: List = []
|
rids: List = []
|
||||||
for poll_statuses in poll_statuses_group:
|
for poll_statuses in poll_statuses_group:
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class SchedulerProfilerMixin:
|
|||||||
if envs.SGLANG_PROFILE_V2.get():
|
if envs.SGLANG_PROFILE_V2.get():
|
||||||
self._profile_manager = ProfileManager(
|
self._profile_manager = ProfileManager(
|
||||||
tp_rank=self.tp_rank,
|
tp_rank=self.tp_rank,
|
||||||
cpu_group=self.cpu_group,
|
cpu_group=self.dp_tp_cpu_group,
|
||||||
gpu_id=self.gpu_id,
|
gpu_id=self.gpu_id,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@@ -180,7 +180,7 @@ class SchedulerProfilerMixin:
|
|||||||
schema.writeSchema(connection)
|
schema.writeSchema(connection)
|
||||||
connection.commit()
|
connection.commit()
|
||||||
del connection
|
del connection
|
||||||
torch.distributed.barrier(self.cpu_group)
|
torch.distributed.barrier(self.dp_tp_cpu_group)
|
||||||
|
|
||||||
self.rpd_profiler = rpdTracerControl()
|
self.rpd_profiler = rpdTracerControl()
|
||||||
self.rpd_profiler.setPythonTrace(True)
|
self.rpd_profiler.setPythonTrace(True)
|
||||||
@@ -291,14 +291,14 @@ class SchedulerProfilerMixin:
|
|||||||
self.torch_profiler.export_chrome_trace(
|
self.torch_profiler.export_chrome_trace(
|
||||||
os.path.join(self.torch_profiler_output_dir, filename)
|
os.path.join(self.torch_profiler_output_dir, filename)
|
||||||
)
|
)
|
||||||
torch.distributed.barrier(self.cpu_group)
|
torch.distributed.barrier(self.dp_tp_cpu_group)
|
||||||
|
|
||||||
if self.rpd_profiler is not None:
|
if self.rpd_profiler is not None:
|
||||||
self.rpd_profiler.rangePop()
|
self.rpd_profiler.rangePop()
|
||||||
self.rpd_profiler.stop()
|
self.rpd_profiler.stop()
|
||||||
self.rpd_profiler.flush()
|
self.rpd_profiler.flush()
|
||||||
|
|
||||||
torch.distributed.barrier(self.cpu_group)
|
torch.distributed.barrier(self.dp_tp_cpu_group)
|
||||||
if self.tp_rank == 0:
|
if self.tp_rank == 0:
|
||||||
from sglang.srt.utils.rpd_utils import rpd_to_chrome_trace
|
from sglang.srt.utils.rpd_utils import rpd_to_chrome_trace
|
||||||
|
|
||||||
|
|||||||
@@ -83,15 +83,6 @@ class BaseTpWorker(ABC):
|
|||||||
def get_pad_input_ids_func(self):
|
def get_pad_input_ids_func(self):
|
||||||
return getattr(self.model_runner.model, "pad_input_ids", None)
|
return getattr(self.model_runner.model, "pad_input_ids", None)
|
||||||
|
|
||||||
def get_tp_group(self):
|
|
||||||
return self.model_runner.tp_group
|
|
||||||
|
|
||||||
def get_attention_tp_group(self):
|
|
||||||
return self.model_runner.attention_tp_group
|
|
||||||
|
|
||||||
def get_attention_tp_cpu_group(self):
|
|
||||||
return getattr(self.model_runner.attention_tp_group, "cpu_group", None)
|
|
||||||
|
|
||||||
def get_memory_pool(self):
|
def get_memory_pool(self):
|
||||||
return (
|
return (
|
||||||
self.model_runner.req_to_token_pool,
|
self.model_runner.req_to_token_pool,
|
||||||
|
|||||||
Reference in New Issue
Block a user