PCA — 프로메테우스 인증 어소시에이트 · GPU 와 서빙 지표 — DCGM 이 말하는 것과 말하지 않는 것 · 이론
GPU 와 서빙 지표 — DCGM 이 말하는 것과 말하지 않는 것
한 줄 요약
GPU 지표에서 가장 자주 틀리는 판정은 "이 카드는 논다" 이다. 사용률은 0 인데
메모리 13.7 GiB 를 잡고 있는 카드를 어느 쪽으로 셀 것인가 — 답은 지표 하나가
아니라 사용률·메모리·전력을 창 전체로 함께 보는 것이다.
왜 이게 필요했나
GPU 는 비싸고 잘 안 늘어난다. 그래서 "몇 장이 필요한가" 를 판정할 일이 자주 생기는데,
이때 대시보드의 사용률 하나만 보면 반드시 틀린다. 이 클러스터의 실측이 그 예다.
계산은 정말로 하지 않는다. 그런데 그 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_perc 는kv_cache_usage_perc 가 되었고, 라벨이 model_name 하나에서 model_name·engine
둘로 늘었다. 소스에서는 카운터가 접미사 없이 선언되고 클라이언트 라이브러리가_total 을 붙인다 — 그래서 소스를 grep 해서 이름을 옮겨 적으면 틀린다.
다음 실습의 서빙 지표는 실측이 아니다. 이 클러스터의 vLLM 배포는 지금 복제본
0 으로 꺼져 있어 지표가 하나도 없다. 없는 것을 있는 척하지 않기 위해, 형식만
본뜬 합성 표본을 쓰고 모든 계열에 source="synthetic" 라벨을 붙여 두었다.
GPU·컨테이너·노드 지표는 전부 실측이고, vllm: 계열만 표본이다.
다음 실습에서 할 것
GPU 넉 장의 3시간치 실측으로 "노는 카드" 를 판정하고, 귀속 라벨이 빠진 카드를
찾고, 누적 에너지 카운터에서 평균 전력을 끌어내 게이지와 견주고, 마지막으로
합성 표본의 첫 토큰 지연 p95 를 히스토그램에서 구한다. 끝에는 무엇이 실측이고
무엇이 표본인지 구분해 보고서에 적는다.