프로덕션 메트릭
프로덕션 메트릭 (Production Metrics)
이 페이지는 SGLang이 Prometheus를 통해 노출하는 메트릭을 설명해요. 서버 실행 시 --enable-metrics를 추가하면 활성화할 수 있어요. 언어 모델 메트릭과 확산(diffusion) 메트릭, 모니터링 스택(Prometheus + Grafana) 설정 방법, MFU 관련 추정 성능 메트릭까지 다뤄요.
출처: 문서
본문
SGLang은 Prometheus를 통해 다음 메트릭을 노출해요. 서버 실행 시 --enable-metrics를 추가하면 활성화할 수 있어요.
모니터링 대시보드의 예시는 examples/monitoring/grafana.json에서 확인할 수 있어요.
언어 모델 메트릭 (Language model metrics)
메트릭의 예시는 다음과 같아요:
$ curl http://localhost:30000/metrics
# HELP sglang:prompt_tokens_total Number of prefill tokens processed.
# TYPE sglang:prompt_tokens_total counter
sglang:prompt_tokens_total{model_name="meta-llama/Llama-3.1-8B-Instruct"} 8.128902e+06
# HELP sglang:generation_tokens_total Number of generation tokens processed.
# TYPE sglang:generation_tokens_total counter
sglang:generation_tokens_total{model_name="meta-llama/Llama-3.1-8B-Instruct"} 7.557572e+06
# HELP sglang:token_usage The token usage
# TYPE sglang:token_usage gauge
sglang:token_usage{model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.28
# HELP sglang:cache_hit_rate The cache hit rate
# TYPE sglang:cache_hit_rate gauge
sglang:cache_hit_rate{model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.007507552643049313
# HELP sglang:time_to_first_token_seconds Histogram of time to first token in seconds.
# TYPE sglang:time_to_first_token_seconds histogram
sglang:time_to_first_token_seconds_sum{model_name="meta-llama/Llama-3.1-8B-Instruct"} 2.3518979474117756e+06
sglang:time_to_first_token_seconds_bucket{le="0.001",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
sglang:time_to_first_token_seconds_bucket{le="0.005",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
sglang:time_to_first_token_seconds_bucket{le="0.01",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
sglang:time_to_first_token_seconds_bucket{le="0.02",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
sglang:time_to_first_token_seconds_bucket{le="0.04",model_name="meta-llama/Llama-3.1-8B-Instruct"} 1.0
sglang:time_to_first_token_seconds_bucket{le="0.06",model_name="meta-llama/Llama-3.1-8B-Instruct"} 3.0
sglang:time_to_first_token_seconds_bucket{le="0.08",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:time_to_first_token_seconds_bucket{le="0.1",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:time_to_first_token_seconds_bucket{le="0.25",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:time_to_first_token_seconds_bucket{le="0.5",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:time_to_first_token_seconds_bucket{le="0.75",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:time_to_first_token_seconds_bucket{le="1.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 27.0
sglang:time_to_first_token_seconds_bucket{le="2.5",model_name="meta-llama/Llama-3.1-8B-Instruct"} 140.0
sglang:time_to_first_token_seconds_bucket{le="5.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 314.0
sglang:time_to_first_token_seconds_bucket{le="7.5",model_name="meta-llama/Llama-3.1-8B-Instruct"} 941.0
sglang:time_to_first_token_seconds_bucket{le="10.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 1330.0
sglang:time_to_first_token_seconds_bucket{le="15.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 1970.0
sglang:time_to_first_token_seconds_bucket{le="20.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 2326.0
sglang:time_to_first_token_seconds_bucket{le="25.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 2417.0
sglang:time_to_first_token_seconds_bucket{le="30.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 2513.0
sglang:time_to_first_token_seconds_bucket{le="+Inf",model_name="meta-llama/Llama-3.1-8B-Instruct"} 11008.0
sglang:time_to_first_token_seconds_count{model_name="meta-llama/Llama-3.1-8B-Instruct"} 11008.0
# HELP sglang:e2e_request_latency_seconds Histogram of End-to-end request latency in seconds
# TYPE sglang:e2e_request_latency_seconds histogram
sglang:e2e_request_latency_seconds_sum{model_name="meta-llama/Llama-3.1-8B-Instruct"} 3.116093850019932e+06
sglang:e2e_request_latency_seconds_bucket{le="0.3",model_name="meta-llama/Llama-3.1-8B-Instruct"} 0.0
sglang:e2e_request_latency_seconds_bucket{le="0.5",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:e2e_request_latency_seconds_bucket{le="0.8",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:e2e_request_latency_seconds_bucket{le="1.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:e2e_request_latency_seconds_bucket{le="1.5",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:e2e_request_latency_seconds_bucket{le="2.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:e2e_request_latency_seconds_bucket{le="2.5",model_name="meta-llama/Llama-3.1-8B-Instruct"} 6.0
sglang:e2e_request_latency_seconds_bucket{le="5.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 7.0
sglang:e2e_request_latency_seconds_bucket{le="10.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 10.0
sglang:e2e_request_latency_seconds_bucket{le="15.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 11.0
sglang:e2e_request_latency_seconds_bucket{le="20.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 14.0
sglang:e2e_request_latency_seconds_bucket{le="30.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 247.0
sglang:e2e_request_latency_seconds_bucket{le="40.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 486.0
sglang:e2e_request_latency_seconds_bucket{le="50.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 845.0
sglang:e2e_request_latency_seconds_bucket{le="60.0",model_name="meta-llama/Llama-3.1-8B-Instruct"} 1513.0
sglang:e2e_request_latency_seconds_bucket{le="+Inf",model_name="meta-llama/Llama-3.1-8B-Instruct"} 11228.0
sglang:e2e_request_latency_seconds_count{model_name="meta-llama/Llama-3.1-8B-Instruct"} 11228.0
# HELP sglang:time_per_output_token_seconds Histogram of time per output token in seconds.
# TYPE sglang:time_per_output_token_seconds histogram
sglang:time_per_output_token_seconds_sum{model_name="meta-llama/Llama-3.1-8B-Instruct"} 866964.5791549598
sglang:time_per_output_token_seconds_bucket{le="0.005",model_name="meta-llama/Llama-3.1-8B-Instruct"} 1.0
sglang:time_per_output_token_seconds_bucket{le="0.01",model_name="meta-llama/Llama-3.1-8B-Instruct"} 73.0
# ... (히스토그램 버킷 생략) ...
sglang:func_latency_seconds_count{name="generate_request"} 14007.0
# HELP sglang:num_running_reqs The number of running requests
# TYPE sglang:num_running_reqs gauge
sglang:num_running_reqs{model_name="meta-llama/Llama-3.1-8B-Instruct"} 162.0
# HELP sglang:num_used_tokens The number of used tokens
# TYPE sglang:num_used_tokens gauge
sglang:num_used_tokens{model_name="meta-llama/Llama-3.1-8B-Instruct"} 123859.0
# HELP sglang:gen_throughput The generate throughput (token/s)
# TYPE sglang:gen_throughput gauge
sglang:gen_throughput{model_name="meta-llama/Llama-3.1-8B-Instruct"} 86.50814177726902
# HELP sglang:num_queue_reqs The number of requests in the waiting queue
# TYPE sglang:num_queue_reqs gauge
sglang:num_queue_reqs{model_name="meta-llama/Llama-3.1-8B-Instruct"} 2826.0
# HELP sglang:spec_num_steps Currently active speculative_num_steps.
# TYPE sglang:spec_num_steps gauge
sglang:spec_num_steps{model_name="meta-llama/Llama-3.1-8B-Instruct"} 3.0
# HELP sglang:spec_num_draft_tokens Currently active speculative_num_draft_tokens (decouples from steps under topk>1).
# TYPE sglang:spec_num_draft_tokens gauge
sglang:spec_num_draft_tokens{model_name="meta-llama/Llama-3.1-8B-Instruct"} 4.0
확산 메트릭 (Diffusion metrics)
SGLang Diffusion은 --enable-metrics로 요청, 큐, 단계 및 LoRA 메트릭을 노출해요. 메트릭 참조, 카운팅 의미, 분리 스크레이프 설정은 Diffusion production metrics를 참고해 주세요.
설정 가이드 (Setup Guide)
이 섹션은 examples/monitoring 디렉터리에 제공된 모니터링 스택(Prometheus + Grafana)을 설정하는 방법을 설명해요.
전제 조건 (Prerequisites)
- Docker와 Docker Compose 설치
- 메트릭이 활성화된 SGLang 서버 실행
사용법 (Usage)
-
메트릭을 활성화해 SGLang 서버 시작:
python -m sglang.launch_server \ --model-path <your_model_path> \ --port 30000 \ --enable-metrics \ --enable-mfu-metrics<your_model_path>를 실제 모델 경로(예:meta-llama/Meta-Llama-3.1-8B-Instruct)로 바꿔 주세요. 모니터링 스택에서 서버에 접근할 수 있는지 확인하세요(Docker에서 실행한다면--host 0.0.0.0이 필요할 수 있어요). 기본적으로 메트릭 엔드포인트는http://<sglang_server_host>:30000/metrics에서 사용할 수 있어요. -
모니터링 예시 디렉터리로 이동:
cd examples/monitoring -
모니터링 스택 시작:
docker compose up -d이 명령은 Prometheus와 Grafana를 백그라운드에서 시작해요.
-
모니터링 인터페이스 접근:
- Grafana: 웹 브라우저에서 http://localhost:3000으로 이동.
- Prometheus: 웹 브라우저에서 http://localhost:9090으로 이동.
-
Grafana 로그인:
- 기본 사용자명:
admin - 기본 비밀번호:
admin첫 로그인 시 비밀번호 변경을 요청받을 거예요.
- 기본 사용자명:
-
대시보드 보기: SGLang 대시보드는 사전 구성되어 자동으로 사용 가능해야 해요.
Dashboards→Browse→SGLang Monitoring폴더 →SGLang Dashboard로 이동하세요.
문제 해결 (Troubleshooting)
- 포트 충돌: "port is already allocated" 같은 오류가 발생하면 다른 서비스(이전 Prometheus/Grafana 인스턴스 포함)가
9090또는3000포트를 사용 중인지 확인하세요.docker ps로 실행 중인 컨테이너를 찾고docker stop <container_id>로 중지하거나,lsof -i :<port>로 포트를 사용 중인 다른 프로세스를 찾으세요. 포트가 시스템의 다른 필수 서비스와 영구적으로 충돌한다면docker-compose.yaml파일에서 포트를 조정해야 할 수 있어요.
Docker Compose 파일에서 Grafana의 포트를 다른 포트(예: 3090)로 변경하려면 grafana 서비스 아래에 포트 매핑을 명시적으로 지정해야 해요.
옵션 1: environment 섹션에 GF_SERVER_HTTP_PORT 추가:
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_SERVER_HTTP_PORT=3090 # <-- Add this line
옵션 2: 포트 매핑 사용:
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3090:3000" # <-- Host:Container port mapping
- 연결 문제:
- Prometheus와 Grafana 컨테이너가 모두 실행 중인지 확인(
docker ps). - Grafana의 Prometheus 데이터 소스 구성을 확인(보통
grafana/datasources/datasource.yaml로 자동 구성).Connections→Data sources→Prometheus로 이동. URL이 Prometheus 서비스(예:http://prometheus:9090)를 가리켜야 해요. - SGLang 서버가 실행 중이고 메트릭 엔드포인트(
http://<sglang_server_host>:30000/metrics)가 Prometheus 컨테이너에서 접근 가능한지 확인. SGLang이 호스트 머신에서 실행 중이고 Prometheus가 Docker 안에 있다면prometheus.yaml스크레이프 구성에서localhost대신host.docker.internal(Docker Desktop) 또는 머신의 네트워크 IP를 사용해요.
- Prometheus와 Grafana 컨테이너가 모두 실행 중인지 확인(
- 대시보드에 데이터 없음:
- 메트릭을 만들기 위해 SGLang 서버에 트래픽을 생성해요. 예를 들어 벤치마크 실행:
python3 -m sglang.bench_serving --backend sglang --dataset-name random --num-prompts 100 --random-input 128 --random-output 128 - Prometheus UI(
http://localhost:9090)의Status→Targets에서 SGLang 엔드포인트가 성공적으로 스크레이프되는지 확인. - Prometheus 메트릭의
model_name및instance라벨이 Grafana 대시보드에 사용된 변수와 일치하는지 확인. Grafana 대시보드 변수나 Prometheus 구성의 라벨을 조정해야 할 수 있어요.
- 메트릭을 만들기 위해 SGLang 서버에 트래픽을 생성해요. 예를 들어 벤치마크 실행:
구성 파일 (Configuration Files)
모니터링 설정은 examples/monitoring 디렉터리 내부의 다음 파일들로 정의돼요:
docker-compose.yaml: Prometheus와 Grafana 서비스를 정의.prometheus.yaml: 스크레이프 대상을 포함한 Prometheus 구성.grafana/datasources/datasource.yaml: Grafana용 Prometheus 데이터 소스를 구성.grafana/dashboards/config/dashboard.yaml: Grafana가 지정된 경로에서 대시보드를 로드하도록 지시.grafana/dashboards/json/sglang-dashboard.json: JSON 형식의 실제 Grafana 대시보드 정의.
이 파일들을 수정해 구성을 커스터마이즈할 수 있어요. 예를 들어 SGLang 서버가 다른 호스트나 포트에서 실행된다면 prometheus.yaml의 static_configs 대상을 업데이트해야 할 수 있어요.
메트릭이 수집되는지 확인 (Check if the metrics are being collected)
다음을 실행해 요청을 생성해요:
python3 -m sglang.bench_serving \
--backend sglang \
--dataset-name random \
--num-prompts 3000 \
--random-input 1024 \
--random-output 1024 \
--random-range-ratio 0.5
그러면 Grafana 대시보드에서 메트릭을 볼 수 있어야 해요.
추정 성능 메트릭 (Estimated Performance Metrics, MFU 관련)
SGLang은 Model FLOPs Utilization(MFU) 관련 신호를 유도하는 데 사용할 수 있는 다음 추정 GPU별 카운터를 내보내요:
sglang:estimated_flops_per_gpu_total: 추정 부동소수점 연산 수.sglang:estimated_read_bytes_per_gpu_total: 메모리에서 읽은 추정 바이트 수.sglang:estimated_write_bytes_per_gpu_total: 메모리에 쓴 추정 바이트 수.
이 메트릭은 --enable-metrics와 --enable-mfu-metrics가 모두 활성화됐을 때 사용할 수 있어요.
이는 누적 카운터(cumulative counters)예요. 초당 값을 얻으려면 Prometheus rate(...)를 사용해요.
PromQL 예시
GPU당 평균 TFLOPS:
rate(sglang:estimated_flops_per_gpu_total[1m]) / 1e12
GB/s 단위의 평균 추정 메모리 대역폭:
(rate(sglang:estimated_read_bytes_per_gpu_total[1m]) +
rate(sglang:estimated_write_bytes_per_gpu_total[1m])) / 1e9
참고 사항 (Notes)
- 이 메트릭들은 관찰 가능성과 추세 분석을 위한 추정치예요.
- 추정 메모리 바이트는 모델링된 트래픽을 반영하며 GPU 프로파일러의 직접적인 하드웨어 카운터가 아니에요.