- 들어가며 — DCGM과 exporter의 관계
- 기본으로 켜져 있는 메트릭
- GPU 이용률이라는 말의 함정
- 그럼 무엇을 같이 봐야 하나
- 커스텀 메트릭 설정하기
- 파드와 컨테이너 라벨 붙이기
- 마치며 — 이름을 믿지 말고 정의를 읽는다
- 직접 해보기
- 시리즈
- 참고 자료
들어가며 — DCGM과 exporter의 관계
GPU 대시보드를 만들라는 요청을 받으면 대부분 같은 곳에서 시작합니다. DCGM Exporter를 띄우고, 기본 대시보드를 가져오고, 큰 게이지에 GPU 이용률을 꽂습니다. 그 게이지가 95퍼센트를 가리키면 모두가 만족합니다. 문제는 그 숫자가 사람들이 기대하는 것을 재지 않는다는 점입니다.
구조부터 정리하면 이렇습니다. GPU에서 값을 실제로 읽는 것은 DCGM이고, exporter는 그 값을 프로메테우스 노출 형식으로 옮기는 얇은 층입니다. GPU Operator의 차트 기본값에서 dcgm.enabled가 거짓인 이유도 여기 있습니다. 주석이 그대로 말하듯 exporter에 내장된 nv-hostengine을 쓰기 때문에 별도 DCGM 데몬셋이 필요 없습니다.
메트릭 이름과 설정은 2026-08-12에 공식 문서·저장소에서 확인했습니다. 버전에 따라 다를 수 있으니 사용 중인 버전에서 다시 확인하세요.
기본으로 켜져 있는 메트릭
무엇이 노출되는지는 저장소의 etc/default-counters.csv가 결정합니다. 이 주제의 유일한 권위 있는 출처이며, 형식은 DCGM 필드 이름, 프로메테우스 메트릭 타입, 도움말 문자열의 세 칸입니다. 먼저 실제 출력을 봅니다.
kubectl -n gpu-operator port-forward svc/nvidia-dcgm-exporter 9400:9400
curl -s localhost:9400/metrics | grep -E '^DCGM_FI_(DEV|PROF)' | head -20
저장소 README가 보여 주는 출력 형태는 이렇습니다.
DCGM_FI_DEV_SM_CLOCK{gpu="0", UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52",container="",namespace="",pod=""} 139
DCGM_FI_DEV_MEM_CLOCK{gpu="0", UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52",container="",namespace="",pod=""} 405
기본 CSV에서 주석 처리되지 않은, 즉 실제로 켜져 있는 필드를 성격별로 묶으면 다음과 같습니다. 괄호 안은 CSV의 도움말 문자열입니다.
- 클럭:
DCGM_FI_DEV_SM_CLOCK(SM clock frequency (in MHz)),DCGM_FI_DEV_MEM_CLOCK - 온도와 전력:
DCGM_FI_DEV_GPU_TEMP,DCGM_FI_DEV_MEMORY_TEMP,DCGM_FI_DEV_POWER_USAGE(Power draw (in W)),DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION(counter, since boot, in mJ) - 메모리:
DCGM_FI_DEV_FB_USED,DCGM_FI_DEV_FB_FREE,DCGM_FI_DEV_FB_RESERVED— 모두 MiB 단위 - 이용률:
DCGM_FI_DEV_GPU_UTIL,DCGM_FI_DEV_MEM_COPY_UTIL,DCGM_FI_DEV_ENC_UTIL,DCGM_FI_DEV_DEC_UTIL - 오류:
DCGM_FI_DEV_XID_ERRORS(Value of the last XID error encountered),DCGM_FI_DEV_PCIE_REPLAY_COUNTER - 행 리맵:
DCGM_FI_DEV_UNCORRECTABLE_REMAPPED_ROWS,DCGM_FI_DEV_CORRECTABLE_REMAPPED_ROWS,DCGM_FI_DEV_ROW_REMAP_FAILURE - 프로파일링:
DCGM_FI_PROF_GR_ENGINE_ACTIVE,DCGM_FI_PROF_PIPE_TENSOR_ACTIVE,DCGM_FI_PROF_DRAM_ACTIVE,DCGM_FI_PROF_PCIE_TX_BYTES,DCGM_FI_PROF_PCIE_RX_BYTES
여기서 이미 중요한 사실이 하나 나옵니다. 이 목록에 DCGM_FI_PROF_SM_ACTIVE와 DCGM_FI_PROF_SM_OCCUPANCY가 없습니다. 두 필드는 CSV에 존재하지만 주석 처리되어 있습니다. 즉 기본 설정만으로는 지금 이야기할 진짜 지표들이 아예 수집되지 않습니다.
GPU 이용률이라는 말의 함정
DCGM_FI_DEV_GPU_UTIL의 CSV 도움말은 한 줄입니다. GPU utilization (in %). 이 이름과 이 설명만 보면 GPU 성능의 몇 퍼센트를 쓰고 있다는 뜻으로 읽힙니다. 그런데 CSV의 섹션 주석은 조용히 다른 힌트를 줍니다. 표본 구간이 제품마다 다르다고 적혀 있습니다.
같은 이름의 값을 NVIDIA의 NVML API 문서는 훨씬 노골적으로 정의합니다. nvmlUtilization_t의 gpu 필드는 지난 표본 구간 동안 GPU에서 하나 이상의 커널이 실행되고 있던 시간의 비율입니다. 문장을 그대로 뜯어보면 무엇을 재지 않는지가 보입니다. 커널이 몇 개인지, SM을 몇 개나 쓰는지, 텐서 코어를 건드리는지, 메모리 대역폭을 얼마나 쓰는지는 전혀 들어 있지 않습니다. 재는 것은 오직 시간입니다. 커널이 하나라도 얹혀 있었느냐 아니냐입니다.
그래서 이런 일이 벌어집니다. 블록 하나짜리 커널을 끊임없이 돌리는 파드가 있다고 합시다. SM이 108개인 카드에서 그 커널은 SM 하나만 씁니다. 나머지 107개는 놀고 있습니다. 그런데 커널은 계속 실행 중이므로 이용률 게이지는 100퍼센트를 가리킵니다. 대시보드는 초록색이고, 카드는 사실상 1퍼센트도 안 쓰고 있습니다.
DCGM 문서가 이 간극을 메우는 지표로 제시하는 것이 DCGM_FI_PROF_SM_ACTIVE입니다. 필드 아이디는 1002이고, 정의는 "적어도 하나의 워프가 멀티프로세서에서 활성이었던 시간의 비율을 전체 멀티프로세서에 대해 평균한 값"입니다. 같은 문서가 붙여 놓은 계산 예시가 이 지표의 성격을 정확히 드러냅니다. GPU에 SM이 N개일 때, N개의 블록을 쓰는 커널이 구간 전체에 걸쳐 돌면 활동률은 1이 됩니다. N/5개의 블록을 쓰는 커널이 구간 전체에 걸쳐 돌면 0.2입니다. 그리고 N개의 블록을 쓰지만 구간의 5분의 1 동안만 돌고 나머지는 SM이 놀았다면 그 값도 0.2입니다.
앞의 예로 돌아가면 답이 나옵니다. 이용률은 100퍼센트인데 DCGM_FI_PROF_SM_ACTIVE는 0.01 근처입니다. 두 숫자가 같은 상황을 설명하고 있고, 진실을 말하는 쪽은 후자입니다.
그럼 무엇을 같이 봐야 하나
DCGM 문서는 DCGM_FI_PROF_SM_ACTIVE에 해석 기준까지 붙여 두었습니다. 0.8 이상은 GPU를 효과적으로 쓰기 위한 필요조건이지 충분조건은 아니며, 0.5 미만이면 비효율적인 사용일 가능성이 높다는 것입니다. 필요조건이라는 표현이 핵심입니다. SM이 바쁘다는 것과 유용한 일을 하고 있다는 것은 다릅니다.
그래서 최소 네 개를 함께 봐야 합니다.
DCGM_FI_PROF_SM_ACTIVE (1002)로 얼마나 넓게 퍼져 있는지를 봅니다. DCGM_FI_PROF_SM_OCCUPANCY (1003)는 멀티프로세서에 상주하는 워프 수를 그 멀티프로세서가 지원하는 최대 동시 워프 수로 나눈 비율로, SM 안이 얼마나 채워져 있는지를 말합니다. 다만 문서가 직접 경고하듯 점유율이 높다고 반드시 GPU를 더 잘 쓰는 것은 아닙니다. 메모리 대역폭 제한 워크로드에서는 그렇지만 연산 제한 워크로드에서는 그렇지 않습니다.
DCGM_FI_PROF_PIPE_TENSOR_ACTIVE (1004)는 텐서 파이프가 활성이었던 사이클의 비율로 텐서 코어가 실제로 도는지를, DCGM_FI_PROF_DRAM_ACTIVE (1005)는 장치 메모리로 데이터가 오가던 사이클의 비율로 메모리가 병목인지를 말합니다. LLM 추론 서버에서 앞이 바닥이면 행렬 연산이 텐서 코어로 가지 않는다는 뜻이고, 디코드 위주 구간에서 뒤가 높고 앞이 낮은 것은 정상적인 모습입니다.
쿼리로 쓰면 이런 모양이 됩니다. 프로메테우스 표현식은 라벨 셀렉터에 중괄호를 쓰기 때문에 반드시 코드 블록 안에 둡니다.
# 노드별 평균 SM 활동률
avg by (hostname) (DCGM_FI_PROF_SM_ACTIVE)
# 이용률은 높은데 SM은 비어 있는 GPU 찾기
DCGM_FI_DEV_GPU_UTIL > 90 and on(gpu, UUID) DCGM_FI_PROF_SM_ACTIVE < 0.3
# 프레임버퍼 사용 비율
DCGM_FI_DEV_FB_USED / (DCGM_FI_DEV_FB_USED + DCGM_FI_DEV_FB_FREE)
# 그라파나 변수는 달러 기호를 쓰므로 반드시 코드 블록 안에서만
avg by (gpu) (rate(DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION{hostname=~"$node"}[$__rate_interval]))
한 가지 더 있습니다. 프로파일링 메트릭은 하드웨어 제약으로 특정 그룹만 함께 읽을 수 있어 DCGM이 통계적 표본 추출로 자동 다중화합니다. 그래서 문서는 수집 주기를 지나치게 짧게 잡으면 메트릭을 묶는 과정에서 0이 반환된다고 경고합니다. 대시보드에 이유 없는 0이 찍힌다면 이 이야기를 떠올릴 필요가 있습니다.
커스텀 메트릭 설정하기
기본 CSV를 바꾸는 방법은 세 가지입니다.
첫째, CSV 파일을 직접 지정합니다. -f 또는 --collectors 플래그이고, 환경 변수는 DCGM_EXPORTER_COLLECTORS, 기본값은 /etc/dcgm-exporter/default-counters.csv입니다.
둘째, YAML 설정 파일을 씁니다. --config-file 또는 DCGM_EXPORTER_CONFIG_FILE입니다. README가 보여 주는 구조는 이렇습니다.
version: 1
metrics:
file: /etc/dcgm-exporter/default-counters.csv
collection:
interval: 30s
인라인으로 필드를 나열할 수도 있으며 이때 각 항목의 키는 name, prometheusType, help입니다. 쿠버네티스에서는 커스텀 메트릭 ConfigMap을 파일로 마운트하고 metrics.file을 그 경로로 지정하라고 README가 안내합니다. YAML은 시작 시점에만 읽히므로 수정하면 재시작이 필요합니다.
셋째, GPU Operator를 쓴다면 차트 값으로 지정합니다. dcgmExporter.config 블록에 name, create, data가 있고, 차트 주석이 중요한 제약을 명시합니다. 기존 ConfigMap을 가리키는 경우 그 ConfigMap은 릴리스와 같은 네임스페이스에 있어야 하며, 메트릭 목록은 dcgm-metrics.csv라는 키 아래에 있어야 합니다.
# helm values 예시
dcgmExporter:
config:
name: custom-dcgm-exporter-metrics
create: true
data: |-
DCGM_FI_DEV_GPU_UTIL, gauge, GPU utilization (in %).
DCGM_FI_DEV_FB_USED, gauge, Framebuffer memory used (in MiB).
DCGM_FI_PROF_SM_ACTIVE, gauge, The ratio of cycles an SM has at least 1 warp assigned.
DCGM_FI_PROF_SM_OCCUPANCY, gauge, The ratio of number of warps resident on an SM.
DCGM_FI_PROF_PIPE_TENSOR_ACTIVE, gauge, Ratio of cycles the tensor (HMMA) pipe is active.
DCGM_FI_PROF_DRAM_ACTIVE, gauge, Ratio of cycles the device memory interface is active sending or receiving data.
수집 주기는 -c 또는 --collect-interval, 환경 변수는 DCGM_EXPORTER_INTERVAL, 단위는 밀리초로 기본값 30000입니다. 리스닝 주소는 -a 또는 DCGM_EXPORTER_LISTEN이고 기본값은 9400 포트입니다. 차트는 ServiceMonitor를 기본으로 켜며 스크레이프 간격이 15초인데, 수집 주기 30초와 어긋나 같은 값을 두 번 긁는 구간이 생깁니다.
파드와 컨테이너 라벨 붙이기
기본 상태의 시계열에는 GPU 식별 라벨만 붙습니다. 소스에서 확인한 라벨은 gpu, UUID, pci_bus_id, device, modelName, hostname이고, MIG 인스턴스에서는 GPU_I_PROFILE과 GPU_I_ID가 추가됩니다. 이것만으로는 어느 팀이 카드를 먹고 있는지 알 수 없습니다.
쿠버네티스 매핑을 켜는 플래그가 --kubernetes 또는 -k이고 환경 변수는 DCGM_EXPORTER_KUBERNETES, 기본값은 거짓입니다. 켜면 pod, namespace, container 라벨이 붙습니다. 파드 UID를 원하면 --kubernetes-enable-pod-uid를 켜서 pod_uid 라벨을 얻고, 파드 라벨까지 원하면 --kubernetes-enable-pod-labels를 켭니다. 이때 라벨 키에는 pod_label_ 접두어가 붙습니다.
파드 라벨을 통째로 넣으면 카디널리티가 폭발하므로 --kubernetes-pod-label-allowlist-regex로 걸러야 합니다. 환경 변수는 DCGM_EXPORTER_KUBERNETES_POD_LABEL_ALLOWLIST_REGEX이고 비워 두면 모든 라벨이 들어갑니다. 차트에서는 이렇게 노출됩니다.
dcgmExporter:
enablePodLabels: true
enablePodUID: true
podLabelAllowlistRegex:
- '^app$'
- '^team$'
차트 주석이 경고를 덧붙입니다. 둘 중 하나라도 켜면 오퍼레이터가 파드에 대한 get, list, watch 권한을 가진 클러스터 범위 ClusterRole과 바인딩을 만듭니다. 권한이 넓어지는 변경이니 알고 켜야 합니다.
덧붙일 것이 셋 있습니다. GPU와 파드를 매칭하는 식별자는 --kubernetes-gpu-id-type으로 고르며 값은 uid와 device-name, 기본은 uid입니다. time-slicing이나 MPS에서 나오는 가상 GPU 메트릭을 잡으려면 --kubernetes-virtual-gpus가 필요하고 이때 vgpu 라벨이 붙습니다. 그리고 -o 또는 DCGM_EXPORTER_USE_OLD_NAMESPACE를 켜면 라벨 이름이 옛 방식인 pod_name, pod_namespace, container_name으로 바뀝니다. 오래된 대시보드에서 쿼리가 안 맞는 흔한 이유입니다.
파드 라벨이 붙으면 이런 질문에 답할 수 있게 됩니다.
# 네임스페이스별 프레임버퍼 사용량 합계
sum by (namespace) (DCGM_FI_DEV_FB_USED)
# 파드별 SM 활동률 (SM_ACTIVE를 CSV에 추가한 뒤에만 동작)
avg by (namespace, pod) (DCGM_FI_PROF_SM_ACTIVE)
# GPU를 잡고 있으면서 SM은 거의 안 쓰는 파드
avg by (namespace, pod) (DCGM_FI_PROF_SM_ACTIVE) < 0.2
and on(namespace, pod) (avg by (namespace, pod) (DCGM_FI_DEV_FB_USED) > 1024)
마치며 — 이름을 믿지 말고 정의를 읽는다
실질적으로 지켜야 할 것은 두 가지입니다. 첫째, 대시보드에 이용률 게이지 하나만 두지 않는 것입니다. 그 숫자는 커널이 얹혀 있었는지만 말하고 카드가 얼마나 쓰이는지는 말하지 않습니다. 최소한 SM 활동률과 프레임버퍼 사용량을 옆에 붙여야 그림이 완성됩니다.
둘째, 필요한 필드를 CSV에 직접 넣는 것입니다. 기본 CSV에서 DCGM_FI_PROF_SM_ACTIVE와 DCGM_FI_PROF_SM_OCCUPANCY가 주석 처리되어 있다는 사실을 모르면, 쿼리를 아무리 잘 써도 데이터가 없어 빈 그래프만 봅니다.
다음 글에서는 층을 하나 올라가 애플리케이션 쪽 메트릭을 봅니다. vLLM이 노출하는 시계열은 지금 몇 개가 기다리고 있고 첫 토큰까지 얼마나 걸리는지 같은, GPU 메트릭이 답하지 못하는 질문에 답합니다.
직접 해보기
- SLO 에러 버짓 계산기 — 지금 보고 있는 지표로 목표를 세우면 여유가 얼마나 되는지 계산해 보세요.
- LLM GPU 메모리(VRAM) 계산기 — 프레임버퍼 사용량이 예상과 맞는지 대조해 보세요.
- kubectl 명령어 찾기 — 포트 포워딩과 로그 확인 명령을 상황별로 찾아보세요.
시리즈
참고 자료
- dcgm-exporter 기본 카운터 CSV: https://github.com/NVIDIA/dcgm-exporter/blob/main/etc/default-counters.csv
- dcgm-exporter README: https://github.com/NVIDIA/dcgm-exporter/blob/main/README.md
- DCGM Feature Overview (프로파일링 메트릭 정의): https://docs.nvidia.com/datacenter/dcgm/latest/user-guide/feature-overview.html
- NVML nvmlUtilization_t: https://docs.nvidia.com/deploy/nvml-api/structnvmlUtilization__t.html
- gpu-operator 저장소 values.yaml: https://github.com/NVIDIA/gpu-operator/blob/main/deployments/gpu-operator/values.yaml
현재 단락 (1/84)
GPU 대시보드를 만들라는 요청을 받으면 대부분 같은 곳에서 시작합니다. DCGM Exporter를 띄우고, 기본 대시보드를 가져오고, 큰 게이지에 GPU 이용률을 꽂습니다. 그 ...