LabHub
学习 学习路径 课程

PCA — Prometheus 认证助理

GPU 与推理服务指标 — DCGM 说了什么、没说什么

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

한 줄 요약

GPU 지표에서 가장 자주 틀리는 판정은 "이 카드는 논다" 이다. 사용률은 0 인데 메모리 13.7 GiB 를 잡고 있는 카드를 어느 쪽으로 셀 것인가 — 답은 지표 하나가 아니라 사용률·메모리·전력을 창 전체로 함께 보는 것이다.

概念图: 창 전체로 · 카드가 놀아도 자리는 비어 있지 않다. · 같은 것을 카운터로도 게이지로도 잴 수 있다 · 귀속(attribution) 라벨은 보장되지 않는다.

왜 이게 필요했나

GPU 는 비싸고 잘 안 늘어난다. 그래서 "몇 장이 필요한가" 를 판정할 일이 자주 생기는데, 이때 대시보드의 사용률 하나만 보면 반드시 틀린다. 이 클러스터의 실측이 그 예다.

RTX 3090 한 장이 세 시간 내내 사용률 0 인데 프레임버퍼 14 기가바이트를 잡고 있었다. 전력도 21와트로 바닥이다

계산은 정말로 하지 않는다. 그런데 그 13.7 GiB 는 다른 워크로드가 쓸 수 없다. 카드가 놀아도 자리는 비어 있지 않다. 이 상태를 "노는 GPU" 로 세면 용량 계획이 틀리고, "쓰는 GPU" 로 세면 낭비를 못 찾는다. 둘 다 적어야 한다.

어떻게 동작하나

dcgm-exporter 는 DCGM 라이브러리의 필드를 그대로 지표로 낸다. 자주 쓰는 것들이다.

지표 종류 단위·뜻
DCGM_FI_DEV_GPU_UTIL gauge GPU 사용률(%)
DCGM_FI_DEV_FB_USED · FB_FREE gauge 프레임버퍼 사용·여유 (MiB)
DCGM_FI_DEV_POWER_USAGE gauge 전력(W)
DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION counter 누적 에너지(mJ)
DCGM_FI_DEV_SM_CLOCK gauge SM 클럭(MHz)
DCGM_FI_PROF_SM_ACTIVE gauge 워프가 얹혀 있던 시간 비율(기본 비활성)

에너지가 카운터라는 점이 재미있다. rate(...[30m]) / 1000 으로 미분하면 와트가 나오고, 같은 시각 POWER_USAGE 게이지와 견주면 거의 같은 값이 된다(실측: 54.7 W 대 55.3 W). 같은 것을 카운터로도 게이지로도 잴 수 있다는 것을 눈으로 확인할 수 있는 드문 자리다.

GPU_UTIL 에 대해 DCGM 공식 필드 설명은 "GPU Utilization." 한 줄뿐이다. 무엇을 어떻게 재는지 더 알고 싶으면 프로파일링 지표 쪽을 봐야 한다. 공식 문서는 PROF_SM_ACTIVE 를 "적어도 하나의 워프가 SM 에 얹혀 있던 시간의 비율을 모든 SM 에 대해 평균한 값" 으로 정의하고, "여기서 active 가 반드시 계산 중을 뜻하지는 않는다 — 메모리 요청을 기다리는 워프도 active 로 센다" 고 덧붙인다. 커널 하나가 GPU 의 1/5 만 써도 사용률이 100% 로 보일 수 있는 이유가 여기 있다. 다만 이 exporter 의 기본 설정에서 PROF_* 는 꺼져 있고, 데이터센터급(Volta 이상) 제한도 있다.

귀속(attribution) 라벨은 보장되지 않는다. dcgm-exporter 는 kubelet 에 물어 exported_namespace·exported_pod·exported_container 를 붙여 주는데, 노드 구성에 따라 이 라벨이 통째로 비어 있을 수 있다. 이 클러스터에서도 네 장 중 한 장이 그렇다. 귀속이 없는 GPU 는 "누가 쓰는지 모르는 자원" 이고, 비용 배분과 회수 판정이 거기서 멈춘다.

현장에서 만나는 모습 — 서빙 지표

추론 서버는 GPU 지표만으로 판정할 수 없다. 대기열이 쌓여 첫 토큰이 늦어지는 동안에도 GPU 사용률은 100% 로 보이기 때문이다. 그래서 vLLM 은 서빙 쪽 지표를 따로 낸다.

지표 종류
vllm:num_requests_running · vllm:num_requests_waiting gauge 실행 중·대기 중 요청 수
vllm:time_to_first_token_seconds histogram 첫 토큰까지 걸린 시간
vllm:inter_token_latency_seconds histogram 토큰 사이 간격
vllm:prompt_tokens_total · vllm:generation_tokens_total counter 처리한 토큰 수
vllm:kv_cache_usage_perc gauge KV 캐시 점유(1 이 100%)
vllm:request_success_total counter 끝난 요청 수, finished_reason 라벨

v1 엔진에서 이름이 몇 개 바뀌었다는 것도 알아 두면 좋다. gpu_cache_usage_perckv_cache_usage_perc 가 되었고, 라벨이 model_name 하나에서 model_name·engine 둘로 늘었다. 소스에서는 카운터가 접미사 없이 선언되고 클라이언트 라이브러리가 _total 을 붙인다 — 그래서 소스를 grep 해서 이름을 옮겨 적으면 틀린다.

다음 실습의 서빙 지표는 실측이 아니다. 이 클러스터의 vLLM 배포는 지금 복제본 0 으로 꺼져 있어 지표가 하나도 없다. 없는 것을 있는 척하지 않기 위해, 형식만 본뜬 합성 표본을 쓰고 모든 계열에 source="synthetic" 라벨을 붙여 두었다. GPU·컨테이너·노드 지표는 전부 실측이고, vllm: 계열만 표본이다.

다음 실습에서 할 것

GPU 넉 장의 3시간치 실측으로 "노는 카드" 를 판정하고, 귀속 라벨이 빠진 카드를 찾고, 누적 에너지 카운터에서 평균 전력을 끌어내 게이지와 견주고, 마지막으로 합성 표본의 첫 토큰 지연 p95 를 히스토그램에서 구한다. 끝에는 무엇이 실측이고 무엇이 표본인지 구분해 보고서에 적는다.