Support EPLB balancedness prometheus metric without GPU->CPU synchronize (#15401)
This commit is contained in:
@@ -2221,6 +2221,7 @@ class Scheduler(
|
||||
if result.copy_done is not None:
|
||||
result.copy_done.synchronize()
|
||||
|
||||
self.log_batch_result_stats(batch, result)
|
||||
self.maybe_send_health_check_signal()
|
||||
|
||||
def maybe_send_health_check_signal(self):
|
||||
|
||||
@@ -4,7 +4,7 @@ import logging
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from contextlib import contextmanager
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from typing import TYPE_CHECKING, List, Optional, Union
|
||||
|
||||
from sglang.srt.disaggregation.kv_events import EventPublisherFactory, KVEventBatch
|
||||
from sglang.srt.disaggregation.utils import DisaggregationMode
|
||||
@@ -12,12 +12,13 @@ from sglang.srt.environ import envs
|
||||
from sglang.srt.managers.io_struct import GetLoadReqInput, GetLoadReqOutput
|
||||
from sglang.srt.managers.schedule_policy import PrefillAdder
|
||||
from sglang.srt.managers.scheduler import Req, ScheduleBatch
|
||||
from sglang.srt.managers.utils import GenerationBatchResult
|
||||
from sglang.srt.metrics.collector import SchedulerMetricsCollector, SchedulerStats
|
||||
from sglang.srt.utils import get_bool_env_var
|
||||
from sglang.srt.utils.device_timer import DeviceTimer
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sglang.srt.managers.scheduler import Scheduler
|
||||
from sglang.srt.managers.scheduler import EmbeddingBatchResult, Scheduler
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -395,6 +396,22 @@ class SchedulerMetricsMixin:
|
||||
self._emit_kv_metrics()
|
||||
self._publish_kv_events()
|
||||
|
||||
def log_batch_result_stats(
|
||||
self: Scheduler,
|
||||
batch: ScheduleBatch,
|
||||
result: Union[GenerationBatchResult, EmbeddingBatchResult],
|
||||
):
|
||||
if not self.enable_metrics:
|
||||
return
|
||||
if not isinstance(result, GenerationBatchResult):
|
||||
return
|
||||
|
||||
if (m := result.expert_distribution_metrics) is not None:
|
||||
self.metrics_collector.increment_eplb_balancedness(
|
||||
forward_mode=batch.forward_mode.name.lower(),
|
||||
balancedness=m.eplb_balancedness.item(),
|
||||
)
|
||||
|
||||
def _emit_kv_metrics(self: Scheduler):
|
||||
if not self.enable_kv_cache_events:
|
||||
return
|
||||
|
||||
@@ -406,6 +406,7 @@ class TpModelWorker(BaseTpWorker):
|
||||
batch_result = GenerationBatchResult(
|
||||
logits_output=logits_output,
|
||||
can_run_cuda_graph=can_run_cuda_graph,
|
||||
expert_distribution_metrics=out.expert_distribution_metrics,
|
||||
)
|
||||
|
||||
if is_verify:
|
||||
@@ -460,6 +461,7 @@ class TpModelWorker(BaseTpWorker):
|
||||
return GenerationBatchResult(
|
||||
pp_hidden_states_proxy_tensors=pp_proxy_tensors,
|
||||
can_run_cuda_graph=can_run_cuda_graph,
|
||||
expert_distribution_metrics=out.expert_distribution_metrics,
|
||||
)
|
||||
|
||||
def forward_batch_split_prefill(self, batch: ScheduleBatch):
|
||||
@@ -482,6 +484,7 @@ class TpModelWorker(BaseTpWorker):
|
||||
batch_result = GenerationBatchResult(
|
||||
logits_output=logits_output,
|
||||
can_run_cuda_graph=can_run_cuda_graph,
|
||||
expert_distribution_metrics=out.expert_distribution_metrics,
|
||||
)
|
||||
batch_result.next_token_ids = next_token_ids
|
||||
return batch_result
|
||||
|
||||
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, List, Optional
|
||||
|
||||
import torch
|
||||
|
||||
from sglang.srt.eplb.expert_distribution import ExpertDistributionMetrics
|
||||
from sglang.srt.layers.logits_processor import LogitsProcessorOutput
|
||||
from sglang.srt.managers.overlap_utils import FutureIndices
|
||||
from sglang.srt.managers.schedule_batch import Req
|
||||
@@ -44,6 +45,9 @@ class GenerationBatchResult:
|
||||
# relay path: forward stream -> next step forward
|
||||
next_draft_input: Optional[EagleDraftInput] = None
|
||||
|
||||
# metrics
|
||||
expert_distribution_metrics: Optional[ExpertDistributionMetrics] = None
|
||||
|
||||
def copy_to_cpu(self, return_logprob: bool):
|
||||
"""Copy tensors to CPU in overlap scheduling.
|
||||
Only the tensors which are needed for processing results are copied,
|
||||
@@ -67,6 +71,9 @@ class GenerationBatchResult:
|
||||
if self.accept_lens is not None:
|
||||
self.accept_lens = self.accept_lens.to("cpu", non_blocking=True)
|
||||
|
||||
if (x := self.expert_distribution_metrics) is not None:
|
||||
x.copy_to_cpu()
|
||||
|
||||
self.copy_done.record()
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user