diff --git a/python/sglang/srt/managers/tokenizer_manager.py b/python/sglang/srt/managers/tokenizer_manager.py index a22ea08c4..468947e85 100644 --- a/python/sglang/srt/managers/tokenizer_manager.py +++ b/python/sglang/srt/managers/tokenizer_manager.py @@ -2218,6 +2218,14 @@ class TokenizerManager(TokenizerControlMixin, TokenizerManagerScoreMixin): ): cached_tokens_details = recv_obj.cached_tokens_details[i] + spec_verify_ct = ( + recv_obj.spec_verify_ct[i] + if hasattr(recv_obj, "spec_verify_ct") + and recv_obj.spec_verify_ct + and len(recv_obj.spec_verify_ct) > i + else 0 + ) + self.metrics_collector.observe_one_finished_request( labels, recv_obj.prompt_tokens[i], @@ -2226,6 +2234,7 @@ class TokenizerManager(TokenizerControlMixin, TokenizerManagerScoreMixin): state.time_stats.get_e2e_latency(), self._request_has_grammar(state.obj), cached_tokens_details, + spec_verify_ct=spec_verify_ct, ) def dump_requests(self, state: ReqState, out_dict: dict): diff --git a/python/sglang/srt/observability/metrics_collector.py b/python/sglang/srt/observability/metrics_collector.py index f71fe1d99..d82b7eeb9 100644 --- a/python/sglang/srt/observability/metrics_collector.py +++ b/python/sglang/srt/observability/metrics_collector.py @@ -1342,6 +1342,11 @@ class TokenizerMetricsCollector: documentation="Number of generation tokens processed.", labelnames=labels.keys(), ) + self.spec_verify_calls_total = Counter( + name="sglang:spec_verify_calls_total", + documentation="Number of speculative decoding verification calls.", + labelnames=labels.keys(), + ) default_bucket_prompt_tokens = [ 100, @@ -1542,9 +1547,12 @@ class TokenizerMetricsCollector: e2e_latency: float, has_grammar: bool, cached_tokens_details: Optional[Dict[str, Any]] = None, + spec_verify_ct: int = 0, ): self.prompt_tokens_total.labels(**labels).inc(prompt_tokens) self.generation_tokens_total.labels(**labels).inc(generation_tokens) + if spec_verify_ct > 0: + self.spec_verify_calls_total.labels(**labels).inc(spec_verify_ct) # Report cached tokens with detailed source breakdown if cached_tokens > 0: