AI & Machine Learning

GPU 활용률: 결과인가, 원인인가

그 97%라는 달콤한 GPU 활용률 수치, 그거 다 거짓말입니다. GPU가 바쁘게 돌아가고 있는 것처럼 보여도, 아마 쓸모없는 짓을 하고 있을 가능성이 높아요.

그래프는 높은 GPU 활용률(녹색)과 급격히 떨어진 토큰 처리량(빨간색 구간)을 보여주는 타임라인을 나타내며, 이 둘의 불일치를 설명합니다.

Key Takeaways

  • NVIDIA의 GPU 활용률 지표(예: nvidia-smi)는 커널이 실행된 시간을 측정할 뿐, 유효한 작업량은 측정하지 않아 성능 진단에 오해를 불러일으킵니다.
  • 프리필/디코드 불균형, 분산 학습 대기, I/O 스톨, CPU 경합, 메모리 대역폭 포화와 같은 일반적인 실패 사례는 모두 높은 GPU 활용률과 낮은 처리량으로 나타납니다.
  • 정확한 병목 현상 탐지는 단순히 집계된 활용률이 아니라, CUDA API 호출, 드라이버 이벤트, 커널 실행 추적, 호스트 측 CPU 활동과 같은 저수준 데이터를 상관시켜야 합니다.

vLLM 서버에서 nvidia-smi를 보면 8분 동안 97%라는 놀라운 GPU 활용률을 찍습니다. 그런데 동시에 토큰 처리량은 바닥을 기어요. 이 두 가지 말도 안 되는 상황이 동시에 벌어지고 있다는 겁니다. 이게 바로 우리가 흔히 속는 지점이죠. NVIDIA의 GPU 활용률 지표는 생산적인 작업량을 측정하는 게 아닙니다. 천만에요. 이건 그냥 ‘얼마나 시간 동안 GPU가 켜져 있었는지’를 알려주는 카운터일 뿐입니다. GPU 위에서 ‘무언가’가 실행되고 있었다는 사실은 알려주지만, 그 ‘무언가’가 실행될 가치가 있었는지는 알려주지 않죠.

저희도 vLLM의 레이턴시 급증 현상을 내부적으로 재현하다가 이 황당한 사실을 마주했습니다. 하드웨어는 TensorDock RTX 4090이었고, 소프트웨어는 vLLM 0.18.0에 Qwen2.5-0.5B-Instruct 모델을 사용했습니다. 8분 동안 대시보드는 완벽해 보였습니다. Nvidia-smi는 92-99% 사이를 오가며 평균 97%를 기록했죠. 팬은 윙윙거리고, 메모리 사용량은 안정적이며, 전력 소모는 320W를 유지했습니다. 모든 게 정상인 것처럼 보였죠.

하지만 아니었습니다.

범인은 의외로 단순한 요청이었습니다: n_completions=8logprobs=20을 조합한 요청이었죠. 이 조합은 디코드 단계마다 8개의 독립적인 시퀀스를 생성해야 했고, 각 시퀀스는 전체 어휘 집합에 대한 소프트맥스를 필요로 했습니다. 무려 10만 5천 토큰씩 말이죠. 이렇게 생성된 거대한 결과물들은 스케줄링된 다른 모든 요청들을 9-11초씩이나 기다리게 만들었습니다. GPU는 분명 바빴지만, 사용자의 눈에는 보이지 않는 쓰레기를 처리하느라 바빴던 겁니다. 처리량은요? 박살 났습니다.

이건 정말 드문 예외적인 상황이 아닙니다. 그냥 ‘만능 시계’에 불과한 진단 도구만 가지고 있을 때 나올 수 있는 예측 가능한 결과입니다.

NVIDIA 자체 문서에서도 GPU-Util을 이렇게 정의하고 있습니다: “지난 샘플 기간 동안 하나 이상의 커널이 GPU에서 실행되었던 시간의 비율.” 이걸로 끝입니다. 커널이 효율적인지, 병목 현상이 있는지, 아니면 다른 작업을 방해하고 있는지에 대한 통찰력은 전혀 제공하지 않죠. 마치 헬스장에 얼마나 오래 있었는지 자랑하면서, 웨이트 트레이닝을 했는지 아니면 그냥 천장을 멍하니 바라봤는지 언급하지 않는 것과 같습니다.

NVIDIA의 좀 더 고급 도구인 DCGM은 SM_ACTIVEMEM_COPY_UTIL 같은 지표를 통해 더 세밀한 정보를 제공하긴 합니다. 물론 도움이 되긴 하지만, 그렇다고 완벽하진 않습니다. 피크 성능의 5%밖에 안 되는 커널이 100밀리초 동안 실행되어도, 해당 시간 동안은 100% SM_ACTIVE로 기록됩니다. 대시보드는 여전히 아무것도 모릅니다.

우리는 다양한 워크로드에서 이 패턴을 분석했습니다. 높은 활용률, 급감하는 처리량, 그리고 마치 ‘매직 8볼’처럼 아무 의미 없는 대시보드. 공통점이요? 근본적인 원인은 그 아래 깊숙한 곳에 숨어 있습니다.

흔한 용의자들: GPU는 왜 자신이 바쁘다고 착각할까

  1. Prefill/Decode 탱고: vLLM, SGLang, TGI와 같은 프레임워크는 동일한 하드웨어에서 프리필(입력 처리)과 디코드(출력 생성)를 배치로 처리하려고 합니다. 프리필이 디코드보다 기하급수적으로 많은 컴퓨팅 성능을 요구하는 경우(긴 컨텍스트에서 흔히 발생), 긴 컨텍스트 요청 하나가 다른 짧은 요청들의 교통 체증을 유발합니다. 프리필 커널이 셰이더 코어를 독점하기 때문에 GPU는 100% SM_ACTIVE 상태를 유지합니다. 그동안 대기 중인 요청들의 디코드 지연 시간은 무한대로 늘어납니다.

  2. 분산 학습 그리드록: 4개 GPU의 올 리듀스(all-reduce) 연산을 상상해 보세요. 만약 한 GPU가 지연되면, 나머지 GPU들은 기다립니다. 이 기다리는 GPU들은 커널이 대기 자체를 조정하는 커널이기 때문에 100% 활용률을 보입니다. 전체 처리량은 효율적인 GPU가 아닌, 가장 느린 GPU에 의해 결정됩니다.

  3. 데이터 로더 데드락: PyTorch의 DataLoader는 메인 프로세스에서 인덱스 순서를 섞는 동안 단일 스레드 병목 현상이 발생할 수 있습니다. GPU는 동일한 순방향 커널을 반복해서 충실히 실행하지만, 다음 배치의 실행은 cudaStreamSync에 의해 차단됩니다. 커널은 열심히 작동하지만, 다음 작업은 진입로에서 꽉 막혀 있습니다.

  4. CPU 코어 혼돈: vLLM의 엔진 루프는 단일 스레드입니다. OS 컨텍스트 스위치(이웃 코어의 커널 작업, 성가신 인터럽트, 제대로 관리되지 않은 cgroup 등)가 cudaLaunchKernel 호출을 중단시킬 수 있습니다. P99 cudaLaunchKernel 시간이 일반적인 p50의 16.7us에서 13.1ms로 엄청나게 늘어나는 것을 목격했습니다. 이 모든 것이 스케줄러 문제 때문입니다. GPU는 정지되기 에 실행 중이던 커널을 계속 실행하여 활용률이 정상으로 보이게 합니다.

  5. 메모리 대역폭 멜트다운: SM(스트리밍 멀티프로세서)이 처리할 수 있는 것보다 훨씬 빠른 속도로 시스템에 데이터를 쏟아붓는 커널은 100% SM_ACTIVE를 보고합니다. 하지만 실제 제약 조건은 무엇일까요? DRAM 대역폭입니다. 활용률은 헛다리 짚기이고, 병목은 메모리 처리량입니다.

이 모든 시나리오에서 증상은 매우 익숙합니다: 높은 활용률, 낮은 처리량. 하지만 원인은 그 아래 계층에 숨어 있습니다.

실제 병목 현상 찾기

그렇다면 어떻게 해야 이 복잡한 문제를 파헤칠 수 있을까요? 집계된 활용률은 잊으세요. 어려운 질문을 던져야 합니다: “GPU는 초당 실제로 무엇을 기다리고 있었는가?”

이 질문에 답하려면 동일한 호스트의 여러 소스에서 가져온 데이터를 타임스탬프로 동기화하여 상관시켜야 합니다:

  • CUDA Runtime API 호출: libcudart.so에 대한 uprobe를 통해 cudaLaunchKernel, cudaMemcpyAsync, cudaStreamSynchronize, cudaDeviceSynchronize와 같은 이벤트를 모니터링합니다.
  • CUDA Driver API 호출: libcuda.so에 대한 uprobe를 사용하여 cuLaunchKernel 및 관련 드라이버 수준 작업을 추적합니다.
  • 커널 실행 추적: 실제로 실행되는 커널을 자세히 살펴봅니다. CUPTI 또는 NVIDIA Nsight와 같은 도구는 커널 자체 내의 커널 실행 시간, 점유율 및 리소스 활용률에 대한 자세한 프로파일을 제공할 수 있습니다.
  • 호스트 측 활동: CPU를 무시하지 마세요. GPU 드라이버 상호 작용과 관련된 CPU 스레드 활동, 컨텍스트 스위치 및 시스템 호출을 모니터링합니다.
  • 메모리 대역폭: DRAM 대역폭 사용량을 직접 측정합니다. 이는 종종 DCGM 또는 특정 프로파일링 도구를 통해 노출됩니다.

이러한 정보들을 엮어내면, 생산적인 계산을 처리하는 GPU와 단순히 바퀴만 굴리고 있는 GPU의 차이를 마침내 볼 수 있게 됩니다. 97% 활용률이 편리하게 은폐해 버리는 바로 그 차이 말이죠.

이것은 단순한 이론적인 문제가 아닙니다. 고성능 컴퓨팅에서 지속적이고 좌절스러운 현실입니다. AI 워크로드가 더욱 복잡해짐에 따라, 단순한 활용률 카운터를 넘어 볼 수 있는 능력은 단순한 이점을 넘어 절대적으로 필수적인 것이 될 것입니다.


🧬 관련 인사이트

Written by
Open Source Beat Editorial Team

Curated insights, explainers, and analysis from the editorial team.

Worth sharing?

Get the best Open Source stories of the week in your inbox — no noise, no spam.

Originally reported by Dev.to