생산 환경에서 LLM 추론 모니터링(2026): vLLM, TGI, llama.cpp용 Prometheus 및 Grafana

프로메테우스와 그라파나를 사용하여 LLM 모니터링하기

LLM 추론은 “단순한 API처럼” 보일 수 있지만, 지연 시간이 급격히 증가하고 대기열이 다시 쌓이기 시작하며, GPU가 95% 메모리 사용률에 도달하면서도 명확한 설명이 없을 때 문제가 발생합니다.

단일 노드 설정을 벗어나거나 처리량 최적화를 시작하는 순간 모니터링은 미션 크리티컬이 됩니다. 그 시점에서 전통적인 API 메트릭만으로는 충분하지 않습니다. 토큰, 배치 행동, 대기 시간, KV 캐시 압력과 같은 현대 LLM 시스템의 실제 병목 현상에 대한 가시성이 필요합니다.

이 기사는 제가 작성한 **관측 가능성 및 모니터링 가이드**의 일부입니다. 여기서는 모니터링 대 관측 가능성의 기초, Prometheus 아키텍처, 그리고 생산성 최고 실천 방법을 다룹니다. 여기서는 특히 LLM 추론 작업량 모니터링에 초점을 맞춥니다.

(인프라 선택을 고려 중이라면, 제 2026년 LLM 호스팅 가이드를 참조하세요. 배치 메커니즘, VRAM 제한, 처리량 대 지연 시간의 트레이드오프에 대한 심층 분석이 필요하다면, LLM 성능 공학 가이드를 참조하세요.)

일반적인 REST 서비스와 달리 LLM 서빙은 토큰, 지속적인 배치, KV 캐시 활용, GPU/CPU 포화, 대기열 동역학에 의해 형성됩니다. 동일한 페이로드 크기의 두 요청은 max_new_tokens, 병렬 처리, 캐시 재사용에 따라 지연 시간이 크게 달라질 수 있습니다.

이 가이드는 Prometheus와 Grafana를 활용한 LLM 추론 모니터링을 위한 실용적이고 생산성 중심의 단계별 가이드입니다:

  • 측정해야 할 항목 (p95/p99 지연 시간, 토큰/초, 대기 시간, 캐시 활용, 오류율)
  • 일반적인 서버에서 /metrics를 스크래핑하는 방법 (vLLM, Hugging Face TGI, llama.cpp)
  • 백분위, 포화, 처리량에 대한 PromQL 예시
  • Docker ComposeKubernetes와 함께 사용되는 배포 패턴
  • 실제 부하 하에서만 나타나는 문제를 해결하는 방법

예제는 제조사 중립적입니다. 나중에 OpenTelemetry 추적, 자동 확장, 서비스 메시지가 추가되더라도 동일한 메트릭 모델이 적용됩니다.


monitoging llm with prometheus and grafana

왜 LLM 추론을 다르게 모니터링해야 하는가

전통적인 API 모니터링(RPS, p95 지연 시간, 오류율)은 필수적이지만 충분하지 않습니다. LLM 서빙은 추가적인 축을 더합니다:

1) 지연 시간에는 두 가지 의미가 있습니다

  • E2E 지연 시간: 요청이 수신된 시간부터 최종 토큰이 반환된 시간까지.
  • 토큰 간 지연 시간: 디코딩 중 토큰당 시간 (스트리밍 UX에 중요).

일부 서버는 두 가지 모두를 노출합니다. 예를 들어, TGI는 요청 지속 시간과 토큰당 평균 시간을 히스토그램으로 노출합니다.

2) 처리량은 토큰 수, 요청 수가 아닙니다

5개의 토큰을 반환하는 “빠른” 서비스는 500개의 토큰을 반환하는 서비스와 비교할 수 없습니다. 대부분의 경우, “RPS"는 “토큰/초“가 되어야 합니다.

3) 대기열은 제품입니다

지속적인 배치를 실행할 경우, 대기열 깊이는 판매하는 것입니다. 대기열 지속 시간대기열 크기를 감시하면 사용자 기대치를 충족하는지 알 수 있습니다.

4) 캐시 압력은 장애 사전 지표입니다

KV 캐시 고갈 (또는 분할)은 일반적으로 갑작스러운 지연 시간 증가 및 타임아웃으로 나타납니다. vLLM은 KV 캐시 사용량을 게이지로 노출합니다.


LLM 추론 모니터링을 위한 메트릭 체크리스트

이를 당신의 북마크로 사용하세요. 처음에는 모든 항목이 필요하지 않지만, 결국에는 대부분을 사용하게 될 것입니다.

골든 신호 (LLM 스타일)

  • 트래픽: 요청/초, 토큰/초
  • 오류: 오류율, 타임아웃, OOM, 429 (레이트 제한)
  • 지연 시간: p50/p95/p99 요청 지속 시간; 사전 처리 vs 디코딩 지연 시간; 토큰 간 지연 시간
  • 포화: GPU 사용률, 메모리 사용, KV 캐시 사용, 대기열 크기

Prometheus 외부에서 GPU 메모리 사용, 온도, 사용량에 대한 저수준 가시성이 필요하다면 (디버깅 또는 단일 노드 설정을 위해), 제 Linux / Ubuntu에서의 GPU 모니터링 애플리케이션 가이드를 참조하세요.

LLM 관측 가능성에 대한 보다 넓은 시야 - 추적, 구조화된 로그, 합성 테스트, GPU 프로파일링, SLO 설계를 포함하여 - 제 LLM 시스템을 위한 관측 가능성 가이드를 참조하세요.

유용한 차원 (레이블)

레이블 카디널리티를 낮추세요. 좋은 레이블:

  • 모델, 엔드포인트, 메서드 (사전 처리/디코딩), 상태 (성공/오류), 인스턴스

피해야 할 레이블:

  • 원시 프롬프트, 원시 사용자 ID, 요청 ID - 이들은 시리즈 수를 폭증시킵니다.

메트릭 노출: 내장된 /metrics 엔드포인트 (vLLM, TGI, llama.cpp)

가장 쉬운 방법은: 서버가 이미 노출하는 메트릭을 사용하는 것입니다.

vLLM: Prometheus 호환 /metrics

vLLM은 Prometheus 호환 /metrics 엔드포인트를 노출하고 (Prometheus 메트릭 로거를 통해) vllm: 접두사로 서버/요청 메트릭을 출판합니다. 실행 중인 요청 및 KV 캐시 사용량과 같은 게이지도 포함됩니다.

보통 볼 수 있는 예시 메트릭:

  • vllm:num_requests_running
  • vllm:num_requests_waiting
  • vllm:kv_cache_usage_perc

Hugging Face TGI: 대기열 + 요청 히스토그램을 포함한 /metrics

TGI는 /metrics에서 대기열 크기, 요청 지속 시간, 대기열 지속 시간, 토큰당 평균 시간을 포함한 많은 생산용 메트릭을 노출합니다.

주목할 만한 항목:

  • tgi_queue_size (게이지)
  • tgi_request_duration (히스토그램, E2E 지연 시간)
  • tgi_request_queue_duration (히스토그램)
  • tgi_request_mean_time_per_token_duration (히스토그램)

llama.cpp 서버: 메트릭 엔드포인트 활성화

llama.cpp 서버는 Prometheus 호환 메트릭 엔드포인트를 지원하지만, 이는 플래그로 활성화되어야 합니다 (예: --metrics).

llama.cpp가 프록시 뒤에 실행 중이라면, 가능한 한 서버를 직접 스크래핑하세요 (프록시 수준의 지연 시간이 실제 추론 행동을 숨기는 것을 피하기 위해).


Prometheus 구성: 추론 서버 스크래핑

이 예제는 다음과 가정합니다:

  • vLLM: http://vllm:8000/metrics
  • TGI: http://tgi:8080/metrics
  • llama.cpp: http://llama:8080/metrics
  • 빠른 피드백을 위해 스크래핑 간격이 조정됨

prometheus.yml

global:
  scrape_interval: 5s
  evaluation_interval: 15s

scrape_configs:
  - job_name: "vllm"
    metrics_path: /metrics
    static_configs:
      - targets: ["vllm:8000"]

  - job_name: "tgi"
    metrics_path: /metrics
    static_configs:
      - targets: ["tgi:8080"]

  - job_name: "llama_cpp"
    metrics_path: /metrics
    static_configs:
      - targets: ["llama:8080"]

Prometheus가 새로운 사람이라면, 스크래핑 구성, 엑спор터, 레이블 재설정, 경고 규칙에 대한 보다 깊은 설명이 필요하다면, 제 Prometheus 모니터링 설정 가이드를 참조하세요.

프로 팁: “서비스 레이블” 추가

여러 모델/리플리카를 실행 중이라면, 대시보드에 안정적인 service 레이블을 추가하기 위해 레이블 재설정을 포함하세요.

relabel_configs:
  - target_label: service
    replacement: "llm-inference"

복사/붙여넣기 가능한 PromQL 예시

요청률 (RPS)

sum(rate(tgi_request_count[5m]))

vLLM의 경우, 요청 카운터를 사용하세요 (버전에 따라 이름이 다를 수 있음), 하지만 패턴은 동일합니다: sum(rate(<counter>[5m])).

오류율 (%)

*_success 카운터가 있다면, 실패 비율을 계산하세요:

1 - (
  sum(rate(tgi_request_success[5m]))
  /
  sum(rate(tgi_request_count[5m]))
)

히스토그램 메트릭의 p95 지연 시간 (Prometheus)

Prometheus 히스토그램은 버킷 수를 기반으로 합니다. histogram_quantile()를 사용하여 rate()의 버킷에 대해 계산하세요. Prometheus는 이 모델과 히스토그램 대 요약의 차이점을 문서화합니다.

histogram_quantile(
  0.95,
  sum by (le) (rate(tgi_request_duration_bucket[5m]))
)

p99 대기 시간

histogram_quantile(
  0.99,
  sum by (le) (rate(tgi_request_queue_duration_bucket[5m]))
)

토큰당 평균 시간 (토큰 간 지연 시간)

histogram_quantile(
  0.95,
  sum by (le) (rate(tgi_request_mean_time_per_token_duration_bucket[5m]))
)

토큰 간 지연 시간은 종종 디코딩 병목 현상과 메모리 대역폭에 의해 제한됩니다. 이는 LLM 성능 최적화 가이드에서 상세히 다룹니다.

대기열 깊이 (즉시)

max(tgi_queue_size)

vLLM KV 캐시 사용률 (즉시)

max(vllm:kv_cache_usage_perc)

Grafana 대시보드: 실시간 알림에 도움이 되는 패널

Grafana는 히스토그램을 여러 가지 방식으로 시각화할 수 있습니다 (백분위, 히트맵, 버킷 분포). Grafana Labs는 Prometheus 히스토그램 시각화에 대한 상세한 가이드를 제공합니다.

최소한의, 고신호 대시보드 레이아웃:

행 1 — 사용자 경험

  1. p95 요청 지연 시간 (시간 시리즈)
  2. p95 토큰 간 지연 시간 (시간 시리즈)
  3. 오류율 (시간 시리즈 + 통계)

행 2 — 용량 및 포화

  1. 대기열 크기 (시간 시리즈)
  2. 실행 중 vs 대기 중 요청 (스택)
  3. KV 캐시 사용 % (게이지)

행 3 — 처리량

  1. 요청/초
  2. 생성된 토큰/요청 (p50/p95)

스트리밍이 있다면, “첫 번째 토큰 지연 시간” (TTFT) 패널을 추가하세요.

예시 Grafana 쿼리

  • p95 지연 시간 패널: 위에서 언급한 histogram_quantile(0.95, …) 쿼리
  • 히트맵 패널: 버킷 레이트 (*_bucket)를 히트맵으로 그래프 (Grafana는 이 접근법을 지원합니다)

배포 옵션 1: Docker Compose (빠른 로컬 + 단일 노드)

로컬, 자가 호스팅, 클라우드 기반 추론 아키텍처 사이의 선택을 고려 중이라면, 제 LLM 호스팅 비교 가이드에서 전체 분석을 참조하세요.

다음과 같은 폴더를 생성하세요:

monitoring/
  docker-compose.yml
  prometheus/
    prometheus.yml
  grafana/
    provisioning/
      datasources/datasource.yml
      dashboards/dashboards.yml
    dashboards/
      llm-inference.json

docker-compose.yml

services:
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana:latest
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - ./grafana/provisioning:/etc/grafana/provisioning
      - ./grafana/dashboards:/var/lib/grafana/dashboards
    ports:
      - "3000:3000"
    depends_on:
      - prometheus

Docker 대신 수동 Grafana 설치를 선호한다면, 제 Ubuntu에서 Grafana 설치 및 사용 가이드의 단계별 가이드를 참조하세요.

Grafana 데이터소스 제공 (grafana/provisioning/datasources/datasource.yml)

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true

대시보드 제공 (grafana/provisioning/dashboards/dashboards.yml)

apiVersion: 1
providers:
  - name: "LLM"
    folder: "LLM"
    type: file
    disableDeletion: true
    options:
      path: /var/lib/grafana/dashboards

배포 옵션 2: Kubernetes (Prometheus Operator + ServiceMonitor)

kube-prometheus-stack (Prometheus Operator)를 사용하는 경우, ServiceMonitor를 통해 스크래핑 대상으로 지정하세요.

Kubernetes, 단일 노드 Docker, 관리형 추론 제공업체 간의 인프라 트레이드오프에 대해, 제 2026년 LLM 호스팅 가이드를 참조하세요.

1) 인프라 배포를 Service로 노출

apiVersion: v1
kind: Service
metadata:
  name: tgi
  labels:
    app: tgi
spec:
  selector:
    app: tgi
  ports:
    - name: http
      port: 8080
      targetPort: 8080

2) ServiceMonitor 생성

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: tgi
  labels:
    release: kube-prometheus-stack
spec:
  selector:
    matchLabels:
      app: tgi
  endpoints:
    - port: http
      path: /metrics
      interval: 5s

vLLM 및 llama.cpp 서비스에 대해 반복하세요. 리플리카를 추가할 때 깔끔하게 확장됩니다.

3) 경고: SLO 스타일 규칙 (예시)

다음은 좋은 시작 경고입니다:

  • 높은 p95 지연 시간 (연소율)
  • 대기 시간 p99 너무 높음 (사용자가 대기 중)
  • 오류율 > 1%
  • KV 캐시 사용률 > 90% 지속 (용량 경계)

예시 규칙 (p95 요청 지속 시간):

- alert: LLMHighP95Latency
  expr: histogram_quantile(0.95, sum by (le) (rate(tgi_request_duration_bucket[5m]))) > 3
  for: 10m
  labels:
    severity: page
  annotations:
    summary: "TGI p95 latency > 3s (10m)"

디버깅: LLM 스택에서 일반적인 Prometheus + Grafana 실패 사례

1) Prometheus 대상이 “DOWN”

증상

  • Prometheus UI → 대상이 DOWN 표시
  • “context deadline exceeded” 또는 연결 거부

체크리스트

  • 서버가 실제로 /metrics를 노출하고 있습니까?
  • 잘못된 포트? 잘못된 스키마 (http 대 https)?
  • Kubernetes: Service가 pod를 선택하고 있습니까? ServiceMonitor의 release 라벨이 올바른가요?

빠른 테스트

curl -sS http://tgi:8080/metrics | head

2) 메트릭을 스크래핑할 수 있지만 패널이 비어 있음

가장 흔한 원인

  • 잘못된 메트릭 이름 (서버 버전 변경)
  • 대시보드가 _bucket을 기대하지만 게이지/카운터만 가지고 있음
  • Prometheus 스크래핑 간격이 짧은 윈도우에 너무 길음 (예: [1m]에 30초 스크래핑은 노이즈가 많음)

해결 방법

  • Grafana Explore에서 메트릭 접두사를 검색하세요 (예: tgi_ / vllm:)
  • 범위 윈도우를 [1m][5m]으로 증가하세요

3) 히스토그램 백분위가 “평평"하거나 잘못됨

Prometheus 히스토그램은 올바른 집계가 필요합니다:

  • rate(metric_bucket[5m]) 사용
  • sum by (le) (및 선택적으로 다른 안정적인 레이블)
  • histogram_quantile() 사용

Prometheus는 버킷 모델과 서버 측 백분위 계산을 문서화합니다.
Grafana의 히스토그램 시각화 가이드는 실용적인 패널 패턴을 포함합니다.

4) 카디널리티 폭증 (Prometheus 메모리 증가)

증상

  • Prometheus RAM 사용량 증가
  • “too many series” 오류

일반적인 근본 원인

  • 사용자 정의 엑спор터에서 프롬프트, 사용자 ID, 요청 ID를 레이블로 추가했습니다.

해결 방법

  • 고카디널리티 레이블 제거
  • 낮은 카디널리티 레이블로 사전 집계 (모델, 엔드포인트, 상태)
  • 요청별 디버깅을 위해 레이블 대신 로그/트레이스 사용 고려

5) “메트릭은 있으나 왜 느린지 알 수 없음”

메트릭은 필수적이지만, 때로는 상관 관계가 필요합니다:

  • 요청 메타데이터 (모델, 토큰 수, TTFT)와 함께 구조화된 로그 추가
  • 게이트웨이 및 추론 서버 주변의 트레이싱 (OpenTelemetry) 추가
  • 지원되는 경우, 예제를 사용하여 지연 시간 급증에서 트레이스로 이동

좋은 워크플로우: Grafana 대시보드 급증 → Explore 클릭 → 인스턴스/모델로 좁히기 → 해당 기간의 로그/트레이스 확인

이것은 관측 가능성 및 모니터링 아키텍처 가이드에서 설명한 고전적인 메트릭 → 로그 → 트레이스 모델을 따릅니다.

6) vLLM / 다프로세스 메트릭 특이점

서빙 스택이 여러 프로세스에서 실행 중이라면, Prometheus 다프로세스 구성이 필요할 수 있습니다 (프로세스가 메트릭을 노출하는 방식에 따라 다름). vLLM 문서는 Prometheus polling을 위해 /metrics를 노출하는 것을 강조하며, 배포 시 서버의 메트릭 모드를 확인하세요.


실용적인 “Day-1” 대시보드 및 경고 설정

생산성에 적합한 가벼운 설정을 원한다면, 다음과 같이 시작하세요:

대시보드 패널

  1. p95 요청 지연 시간
  2. p95 토큰당 평균 시간
  3. 대기열 크기
  4. p95 대기열 지속 시간
  5. 오류율
  6. KV 캐시 사용 %

경고

  • p95 요청 지연 시간 > X 10분 동안
  • p99 대기열 지속 시간 > Y 10분 동안
  • 오류율 > 1% 5분 동안
  • KV 캐시 사용률 > 90% 15분 동안
  • Prometheus 대상이 다운 (항상)

관련 관측 가능성 가이드

관련 LLM 인프라스트럭처 가이드


마무리 메모

Prometheus + Grafana는 추론 건강에 대한 “상시 활동” 뷰를 제공합니다. 기본 사항을 갖춘 후, 일반적으로 다음 큰 성공은 다음과 같은 것에서 옵니다:

  • 모델/테넌트별 SLO
  • 요청 형성 (최대 토큰, 병렬 처리 제한)
  • 대기열 시간KV 캐시 여유 공간에 따라 자동 확장

모니터링 대 관측 가능성, Prometheus 기초, 생산성 패턴에 대한 보다 넓은 설명이 필요하다면, 제 관측 가능성 가이드를 참조하세요.