SGLang Tracing: Improve root span attributes (#17008)
Signed-off-by: zhanghaotong <zhanghaotong.zht@antgroup.com>
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import copy
|
import copy
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
@@ -90,6 +91,7 @@ from sglang.srt.server_args import (
|
|||||||
)
|
)
|
||||||
from sglang.srt.speculative.spec_info import SpeculativeAlgorithm
|
from sglang.srt.speculative.spec_info import SpeculativeAlgorithm
|
||||||
from sglang.srt.tracing.trace import (
|
from sglang.srt.tracing.trace import (
|
||||||
|
SpanAttributes,
|
||||||
extract_trace_headers,
|
extract_trace_headers,
|
||||||
trace_get_proc_propagate_context,
|
trace_get_proc_propagate_context,
|
||||||
trace_req_finish,
|
trace_req_finish,
|
||||||
@@ -1593,7 +1595,11 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi
|
|||||||
if self.enable_metrics:
|
if self.enable_metrics:
|
||||||
self._calculate_timing_metrics(meta_info, state, recv_obj, i)
|
self._calculate_timing_metrics(meta_info, state, recv_obj, i)
|
||||||
|
|
||||||
trace_req_finish(rid, ts=int(state.finished_time * 1e9))
|
trace_req_finish(
|
||||||
|
rid,
|
||||||
|
ts=int(state.finished_time * 1e9),
|
||||||
|
attrs=self.convert_to_span_attrs(state, recv_obj, i),
|
||||||
|
)
|
||||||
|
|
||||||
del self.rid_to_state[rid]
|
del self.rid_to_state[rid]
|
||||||
|
|
||||||
@@ -2284,6 +2290,98 @@ class TokenizerManager(TokenizerCommunicatorMixin, TokenizerManagerMultiItemMixi
|
|||||||
):
|
):
|
||||||
self.mm_receiver.send_encode_request(obj)
|
self.mm_receiver.send_encode_request(obj)
|
||||||
|
|
||||||
|
def convert_to_span_attrs(
|
||||||
|
self,
|
||||||
|
state: ReqState,
|
||||||
|
recv_obj: Union[
|
||||||
|
BatchStrOutput,
|
||||||
|
BatchEmbeddingOutput,
|
||||||
|
BatchMultimodalOutput,
|
||||||
|
BatchTokenIDOutput,
|
||||||
|
],
|
||||||
|
i: int,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""Convert attributes to span attributes."""
|
||||||
|
span_attrs = {}
|
||||||
|
|
||||||
|
if not self.enable_trace:
|
||||||
|
return span_attrs
|
||||||
|
|
||||||
|
# Token usage attributes
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_USAGE_COMPLETION_TOKENS] = (
|
||||||
|
recv_obj.completion_tokens[i]
|
||||||
|
)
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_USAGE_PROMPT_TOKENS] = recv_obj.prompt_tokens[
|
||||||
|
i
|
||||||
|
]
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_USAGE_CACHED_TOKENS] = recv_obj.cached_tokens[
|
||||||
|
i
|
||||||
|
]
|
||||||
|
|
||||||
|
# Request identifiers
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_REQUEST_ID] = (
|
||||||
|
str(state.obj.rid) if state.obj.rid else None
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sampling parameters
|
||||||
|
sampling_params = state.obj.sampling_params or {}
|
||||||
|
|
||||||
|
if max_new_tokens := sampling_params.get("max_new_tokens"):
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] = max_new_tokens
|
||||||
|
|
||||||
|
if top_p := sampling_params.get("top_p"):
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_REQUEST_TOP_P] = top_p
|
||||||
|
|
||||||
|
if temperature := sampling_params.get("temperature"):
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] = temperature
|
||||||
|
|
||||||
|
if top_k := sampling_params.get("top_k"):
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_REQUEST_TOP_K] = top_k
|
||||||
|
|
||||||
|
if n := sampling_params.get("n"):
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_REQUEST_N] = n
|
||||||
|
|
||||||
|
# Response attributes
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_RESPONSE_MODEL] = self.served_model_name
|
||||||
|
|
||||||
|
finish_reason = (
|
||||||
|
recv_obj.finished_reasons[i].get("type")
|
||||||
|
if recv_obj.finished_reasons[i]
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
if finish_reason:
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_RESPONSE_FINISH_REASONS] = json.dumps(
|
||||||
|
[finish_reason]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Latency attributes
|
||||||
|
if state.first_token_time and state.created_time:
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_LATENCY_TIME_TO_FIRST_TOKEN] = (
|
||||||
|
state.first_token_time - state.created_time
|
||||||
|
)
|
||||||
|
|
||||||
|
if state.finished_time and state.created_time:
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_LATENCY_E2E] = (
|
||||||
|
state.finished_time - state.created_time
|
||||||
|
)
|
||||||
|
|
||||||
|
if state.first_token_time_perf and state.finished_time_perf:
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_LATENCY_TIME_IN_MODEL_DECODE] = (
|
||||||
|
state.finished_time_perf - state.first_token_time_perf
|
||||||
|
)
|
||||||
|
|
||||||
|
if state.request_sent_to_scheduler_ts and state.finished_time:
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_LATENCY_TIME_IN_MODEL_INFERENCE] = (
|
||||||
|
state.finished_time - state.request_sent_to_scheduler_ts
|
||||||
|
)
|
||||||
|
|
||||||
|
if state.request_sent_to_scheduler_ts and state.first_token_time:
|
||||||
|
span_attrs[SpanAttributes.GEN_AI_LATENCY_TIME_IN_MODEL_PREFILL] = (
|
||||||
|
state.first_token_time - state.request_sent_to_scheduler_ts
|
||||||
|
)
|
||||||
|
|
||||||
|
return span_attrs
|
||||||
|
|
||||||
|
|
||||||
class ServerStatus(Enum):
|
class ServerStatus(Enum):
|
||||||
Up = "Up"
|
Up = "Up"
|
||||||
|
|||||||
@@ -737,3 +737,25 @@ def trace_event_batch(
|
|||||||
|
|
||||||
for req in reqs:
|
for req in reqs:
|
||||||
trace_event(name, req.rid, ts=ts, attrs=_attrs)
|
trace_event(name, req.rid, ts=ts, attrs=_attrs)
|
||||||
|
|
||||||
|
|
||||||
|
class SpanAttributes:
|
||||||
|
# Attribute names copied from here to avoid version conflicts:
|
||||||
|
# https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md
|
||||||
|
GEN_AI_USAGE_COMPLETION_TOKENS = "gen_ai.usage.completion_tokens"
|
||||||
|
GEN_AI_USAGE_PROMPT_TOKENS = "gen_ai.usage.prompt_tokens"
|
||||||
|
GEN_AI_USAGE_CACHED_TOKENS = "gen_ai.usage.cached_tokens"
|
||||||
|
GEN_AI_REQUEST_MAX_TOKENS = "gen_ai.request.max_tokens"
|
||||||
|
GEN_AI_REQUEST_TOP_P = "gen_ai.request.top_p"
|
||||||
|
GEN_AI_REQUEST_TOP_K = "gen_ai.request.top_k"
|
||||||
|
GEN_AI_REQUEST_TEMPERATURE = "gen_ai.request.temperature"
|
||||||
|
GEN_AI_RESPONSE_MODEL = "gen_ai.response.model"
|
||||||
|
GEN_AI_RESPONSE_FINISH_REASONS = "gen_ai.response.finish_reasons"
|
||||||
|
GEN_AI_REQUEST_ID = "gen_ai.request.id"
|
||||||
|
GEN_AI_REQUEST_N = "gen_ai.request.n"
|
||||||
|
GEN_AI_LATENCY_TIME_IN_QUEUE = "gen_ai.latency.time_in_queue"
|
||||||
|
GEN_AI_LATENCY_TIME_TO_FIRST_TOKEN = "gen_ai.latency.time_to_first_token"
|
||||||
|
GEN_AI_LATENCY_E2E = "gen_ai.latency.e2e"
|
||||||
|
GEN_AI_LATENCY_TIME_IN_MODEL_PREFILL = "gen_ai.latency.time_in_model_prefill"
|
||||||
|
GEN_AI_LATENCY_TIME_IN_MODEL_DECODE = "gen_ai.latency.time_in_model_decode"
|
||||||
|
GEN_AI_LATENCY_TIME_IN_MODEL_INFERENCE = "gen_ai.latency.time_in_model_inference"
|
||||||
|
|||||||
Reference in New Issue
Block a user