gpumode · 강의 아카이브
《GPU Mode》 L098 2025 · GPU Observability Mid priority transcript · failed

GPU Observability

NVIDIA 의 CUPTI / NVTX / Nsight 가 채워주는 자리 위에, eBPF 기반의 third-party observability 가 어떻게 끼어들 수 있는가. Yusheng Zheng 의 bpftime · gpu_ext 라인을 따라 — kernel launch 부터 UVM page fault 까지 GPU 위에서 일어나는 일을 production-grade 로 들여다보는 새로운 stack 의 위치를 정리한 학습 노트. 강의 자체의 자막은 실패했고, 여기서는 발표자의 공개 repo · 블로그 · 관련 paper 를 근거로 같은 토픽을 시각적으로 재구성한다.

eBPF CUPTI NVTX bpftime UVM page fault tracing PTX injection production observability
Y
Speaker
Yusheng (郑昱笙) Zheng
eunomia-bpf · bpftime maintainer · eBPF on GPU
강의 번호
L098
스피커
Yusheng Zheng
자막
failed · 재구성
근거
repo · 블로그 · paper
§ 01강의가 풀려는 문제· Why this lecture exists

“GPU 위에서 무슨 일이 벌어지는지” 를 production 에서 본다는 것

개발자의 desktop 에서 Nsight Compute 한 번 띄우면 보이는 정보 — kernel duration, occupancy, memory throughput — 를 production cluster 에서 실시간으로 streaming 으로, workload 를 멈추지 않고, 그리고 다른 사용자의 코드에 대해서도 보고 싶다. 이 욕구가 GPU observability 의 출발점이다.

강의가 던지는 두 개의 질문은 이렇다.

  1. NVIDIA 가 이미 깔아둔 telemetry stack (CUPTI, NVTX, DCGM, Nsight) 위에 무엇이 더 필요한가 — 그리고 왜 production 에서는 그것들만으로 부족한가.
  2. eBPF 라는 Linux 의 검증된 사용자공간/커널 hook 메커니즘이 GPU 에 어떻게 옮겨갈 수 있는가 — driver 내부를 바꾸지 않으면서.

Yusheng 의 입장은 실용주의다. CUDA driver 의 internals 를 다 이해하지 않아도, 올바른 hook point 를 잡으면 production 에서 의미 있는 신호를 뽑을 수 있다. 그 hook point 가 어디인지, 그리고 어떤 hook 이 어떤 질문에 답하는지를 정리하는 것이 이 강의의 본론이다.

강의의 인지적 frame

이 강의의 모든 도구는 같은 질문에 답한다 — “이 production GPU job 에서 방금 무슨 일이 벌어졌는가, 그리고 그게 왜 느렸거나 왜 OOM 됐는가?” Nsight 는 개발자 desktop 의 답이고, eBPF 기반 stack 은 같은 질문을 production 에서 streaming 으로 답하는 길이다.

“Observability 는 metric 이 아니라 를 답해주는 신호다. CPU 쪽은 eBPF 가 이걸 풀었고, GPU 는 아직 비어 있다.”노트 · Yusheng 의 OSDI / ATC 발표 정리

그래서 이 강의의 끝에서 손에 잡혀 있어야 하는 건 4개 layer 의 observability stack(driver hook, CUPTI activity, NVTX range, application metric)과, 각 layer 가 어떤 질문에 답하는지의 매핑이다.

§ 02기존 GPU 모니터링의 한계· CUPTI · Nsight 가 못 보는 자리

“nvidia-smi 만으로는 죽을 수 있다”

대부분의 production GPU 모니터링은 세 단계로 끝난다 — nvidia-smi, DCGM, 그리고 가끔 Nsight Systems. 이 셋이 각자 어디까지 보여주고 어디서부터 보이지 않는지를 정리하면 빈 자리가 자연스럽게 드러난다.

FIG · 4 layer GPU observability stack각 layer 가 답하는 질문
L0 · ApplicationNVTX range · python decorator 사용자가 직접 코드에 박는 marker. nvtx.annotate("attention") 한 줄. 가장 의미론적으로 풍부하지만, 손이 닿는 코드에서만 가능. In-app
L1 · CUPTI activity / callbackcuLaunchKernel · cuMemcpyAsync CUDA driver 가 직접 emit 하는 event. kernel name, duration, stream, grid/block. NVIDIA 의 공식 path. 전제: CUDA app 안에서 callback library 가 attach. Driver API
L2 · eBPF on driver / userspaceuprobe on libcuda · syscall · ioctl CUPTI 를 못 거는 상황 (다른 사용자의 binary, 이미 도는 process) 에서도 hook 가능. bpftime 의 핵심 영역. eBPF
L3 · Kernel hooks (UVM, sched)nvidia-uvm · nvidia driver page fault, eviction, scheduler. gpu_ext 가 NVIDIA Open GPU Kernel Modules 에 eBPF struct_ops hook 을 박아서 노출. Kernel
위로 갈수록 의미론적 풍부함이 커지고, 아래로 갈수록 커버리지가 커진다. NVTX 는 “attention 이 느렸다” 까지 알 수 있고, kernel hook 은 “모든 process 의 page fault” 를 다 잡는다. 두 끝 사이를 메우는 게 eBPF L2 이다.

nvidia-smi 와 DCGM 이 보여주는 것은 본질적으로 aggregate metric 이다 — GPU 전체의 SM utilization, memory utilization, power. 한 process 가 점유한 만큼 다른 process 가 비어 있는지, 어떤 kernel 이 SM 을 점유했는지는 알 수 없다. “GPU 가 80% 바쁘다” 는 사실로부터 “내 코드의 어디가 80% 를 만드는가” 까지의 거리가 production 에서 가장 흔한 빈 자리다.

실전 가설

“OOM 이 났는데 nvidia-smi 의 memory 그래프는 한가하다” — UVM oversubscription 이 일으키는 page eviction 때문. 이 케이스는 L3 (kernel UVM hook) 만이 직접 답할 수 있다. CUPTI/NVTX 만으로는 증상은 보이지만 원인까지 안 잡힌다.

또 하나의 한계 — multi-tenant 환경. cluster 안에서 다른 팀의 binary 가 도는 경우, 그 binary 에 NVTX 도 없고 CUPTI callback library 도 안 attach 돼 있다. 외부에서 그 process 를 들여다봐야 하는데, 이건 본질적으로 OS-level instrumentation 의 영역이다 — eBPF 가 CPU 쪽에서 풀던 문제와 같다.

§ 03eBPF on GPU· PTX injection · 사용자공간 VM

리눅스의 검증된 hook 추상을 GPU 로 옮긴다

eBPF 는 Linux 커널 안에서 안전하게 검증된 작은 프로그램을 hook point 마다 실행하게 해주는 frame. 그 추상을 GPU 로 옮기는 두 갈래가 있다 — 사용자공간 VM (bpftime) 과 driver 내부 struct_ops hook (gpu_ext).

bpftime — userspace eBPF runtime

kernel eBPF 와 달리 사용자공간 process 안에 VM 을 띄우고 uprobe / syscall / USDT 같은 hook 점에서 eBPF bytecode 를 실행한다. CUDA app 의 libcuda.so 의 함수 심볼에 attach 가 가능하다는 점이 핵심.

그리고 강의의 가장 흥미로운 contribution — eBPF → PTX 변환. eBPF bytecode 를 PTX 로 컴파일해서 GPU kernel 안에 inject 하면, 사용자가 짠 device function 안에서 정해진 hook point 에 도달했을 때 추가 로깅을 수행할 수 있다. CPU 쪽 uprobe 의 GPU 판.

의미

“이미 도는 다른 process 의 GPU kernel 에 — 코드 수정 없이 — instrumentation 을 박는다.” 이게 production 에서 가장 큰 unlock. CUPTI 는 process 시작 전에 attach 해야 하고, NVTX 는 코드에 손이 닿아야 한다. eBPF 는 이미 떠 있는 binary 에 attach.

gpu_ext — driver 내부 struct_ops

NVIDIA 의 Open GPU Kernel Modules 를 fork 해서 eBPF struct_ops hook 을 박는다. 무엇을 hook 하는가 — UVM 의 page fault handler, eviction policy, scheduler timeslice 결정. 이 자리들은 사용자공간에서 절대 보이지 않는 driver internal 결정점이다.

  • memory eviction policy — FIFO / LFU / MRU / PID-quota 같은 plug-in.
  • prefetch strategy — adaptive-sequential / stride / PID-tree.
  • scheduler — process 별 priority 와 timeslice 직접 통제.

학습 차원에서 더 중요한 건 그 hook 점들을 tracing 으로 켜둘 수 있다는 사실이다 — repo 안의 chunk_trace, prefetch_trace, gpu_sched_trace 가 그 예시.

FIG · 같은 GPU job 위에서 4개 layer 가 보는 신호timeline view
L0 NVTX
attention.fwd
mlp.fwd
loss
L1 CUPTI
flash
softmax
flash
gemm
act
gemm
ce
L2 eBPF
launch
launch
launch
launch
launch
launch
launch
L3 UVM
fault
fault
evict batch
같은 시간 축 위에 — 같은 학습 step 위에 — 4개 layer 가 다른 차원의 신호를 emit. NVTX 의 “mlp.fwd 가 길었다” 가 CUPTI 의 “gemm 두 번이 길었다” 와, eBPF 의 “launch 직후 stall”, UVM 의 “evict batch 가 끼어들었다” 와 자연스럽게 연결된다.
§ 04NVTX / CUPTI 기반· in-app instrumentation

“코드에 한 줄 박을 수 있을 때” 가장 풍부한 신호가 나온다

eBPF 가 강력하다고 해서 NVTX/CUPTI 를 대체하지 않는다. 강의의 메시지는 합치는 쪽이다 — 가장 풍부한 의미론은 application 이 알고, 가장 넓은 커버리지는 eBPF 가 준다. 둘을 같은 timeline 위에 정렬해야 production 의 “왜” 가 풀린다.

# 학습 step 마다 의미 있는 region 을 찍는 표준 패턴
import nvtx
import torch

@nvtx.annotate("train.step")
def step(batch):
    with nvtx.annotate("forward"):
        loss = model(batch)
    with nvtx.annotate("backward"):
        loss.backward()
    with nvtx.annotate("optim"):
        opt.step(); opt.zero_grad()
    return loss

이 NVTX range 가 trace 에 박히면 — Nsight Systems 의 GUI 든, 직접 만든 dashboard 든 — 같은 timeline 위에서 “attention 이 차지한 % vs mlp 가 차지한 %” 같은 분해가 즉시 가능해진다. 의미론은 코드만 알 수 있다.

CUPTI activity API — 모든 launch event

CUDA driver 에 callback library (libcupti.so) 를 attach 하면 — kernel launch, memcpy, memset, stream sync 등이 event 로 흘러나온다. 각 event 에 실제 GPU 시간이 박혀 있어 launch 와 실제 실행 사이의 gap (host-side latency) 도 측정 가능.

핵심 limitation 두 가지.

  • process 시작 전 attachLD_PRELOAD 또는 init 시점에 hook. 이미 도는 process 에는 못 붙는다.
  • 한 process 에 한 callback — Nsight 와 동시에 못 쓴다.
eBPF 와 합치는 자리

NVTX/CUPTI 가 잡지 못하는 “이미 도는 production process” 에 대해서는 eBPF 가 cuLaunchKernel uprobe 로 같은 신호를 잡는다. 의미론(NVTX) 은 빈약하지만 attach 가 자유롭다.

§ 05분산 환경 trace· multi-GPU · multi-node

NCCL collectives 가 들어가면 한 노드의 trace 만으로는 답이 안 나온다

대규모 학습은 거의 항상 multi-GPU + multi-node. 한 노드의 GPU profile 만 봐서는 — 어느 NCCL allreduce 가 다른 rank 의 stragger 때문에 길어졌는지 결정이 안 난다. 분산 환경의 observability 는 cross-rank correlation 이 추가되는 새 차원.

강의에서 정리되는 패턴은 두 단계.

  1. 각 rank 가 같은 schema 의 trace 를 emit — NVTX range, CUPTI event, eBPF event 가 모두 동일한 timestamp epoch 와 동일한 metric 이름을 쓰도록 통일.
  2. 중앙에서 collective op 단위로 align — 같은 NCCL allreduce 의 시작 / 끝 marker 를 모든 rank 에서 모아 비교. 가장 늦게 도착한 rank 가 stragger.
다른 강의들과 잇는 자리

L064 — Optimizing Communication for MLL058 — Tracing for distributed 같은 강의들이 같은 문제를 다른 각도에서 본다. L098 의 contribution 은 collection layer 자체를 eBPF 로 통일하자는 제안.

구체적인 실현은 보통 — 각 노드에서 bpftime agent 가 돌면서 launch / NCCL ioctl / NVTX 를 수집, OpenTelemetry 또는 Prometheus 로 export, 중앙 dashboard 에서 rank 별 lane 으로 시각화. 이 stack 의 어느 부분이든 NVIDIA 가 직접 제공하지 않는다는 점이 강의의 큰 메시지 — third-party tooling 의 자리가 진짜로 비어 있다.

“single-node profiling 은 풀린 문제다. 분산 학습에서 ‘straggler 가 누구냐’ 와 ‘network 인지 compute 인지’ 를 production 에서 답하는 stack 은 아직 만들어지는 중이다.”학습 노트 · 확인 필요
§ 06production tooling· bpftime · gpu_ext · agentsight

같은 작가의 repo 들이 어떻게 한 stack 을 이루는가

Yusheng 이 maintain 하는 eunomia-bpf org 안의 repo 들은 무작위가 아니라 한 stack 의 다른 layer들이다. 어떤 repo 가 어디 위치하는지를 정리하면 강의 본문이 절반은 풀린다.

bpftime
사용자공간 eBPF runtime. uprobe / syscall / USDT / GPU PTX injection 을 지원하는 framework. backbone.
llvmbpf
eBPF VM 의 LLVM JIT/AOT 컴파일러. PTX 로의 컴파일 path 가 여기서 만들어진다.
gpu_ext
NVIDIA Open GPU Kernel Modules 에 eBPF struct_ops hook 을 박은 fork. UVM eviction · prefetch · scheduler 의 plug-in 자리.
agentsight
LLM agent 의 zero-instrument observability. eBPF 로 syscall 과 stdout 을 잡아 LLM agent 의 행동을 trace.
wasm-bpf
WebAssembly 안에서 eBPF 를 돌리는 toolchain. cluster operator / CRD 형태로 배포할 때의 패키징.
eunomia-bpf
eBPF 프로그램의 build · run 을 단순화한 tool. bpftrace 의 다음 단계 같은 위치.

이 repo 들의 관계를 한 문장으로 — “llvmbpf 가 컴파일하고, bpftime 이 사용자공간에서 실행하고, gpu_ext 가 driver 안 hook 점을 노출하고, agentsight 가 LLM 시대의 새 application”. observability stack 의 기반과 응용을 같은 author 가 한 묶음으로 깔고 있다.

§ 07대표 사례· UVM page fault · kernel attribution

실제로 잡아낸 production 문제 두 가지

stack 의 가치를 검증하는 가장 좋은 방법은 — 이 stack 이 없었다면 어떻게 풀었을까 를 물어보는 것. 두 개의 대표적 case.

CASE 01
UVM 에서 silent page eviction
큰 모델을 single GPU 에 oversubscribe 시키면 — UVM 이 자동으로 host 로 evict 한다. nvidia-smi 의 memory 그래프는 정상으로 보이지만 throughput 이 절반. L3 (gpu_ext UVM hook) 의 page fault tracing 으로 어떤 tensor 의 page 가 얼마나 자주 evict 되는지 직접 본다.
CASE 02
Multi-tenant cluster 의 kernel attribution
다른 팀의 binary 가 같은 GPU 위에 도는데, 어느 process 가 SM 을 점유했는지가 안 보인다. L2 (bpftime uprobe on libcuda) 로 모든 process 의 launch event 를 잡고 PID 별로 attribution.
CASE 03
불규칙한 NCCL stragger
학습 throughput 이 갑자기 1초 뚝 떨어지는 패턴. 어느 rank 가 늦었는가? L2 + L0 합쳐서 — eBPF 로 NCCL ioctl 을 모든 rank 에서 잡고 NVTX range 와 align 해서 시각화. 가장 늦게 도착한 rank 의 직전 NVTX 가 원인 단서.
CASE 04
LLM agent 의 모델 호출 pattern
LLM agent 가 어느 step 에서 어떤 tool 을 부르는지를 observability 로 보고 싶다. agentsight 가 stdout/syscall 만 가지고 — agent 의 코드를 수정하지 않고 — 이걸 추적. eBPF stack 의 LLM 시대 응용.

네 case 의 공통점 — 코드를 수정하지 않고도 답이 나오는 자리. 이 “zero instrument” 가 production observability 의 진짜 가치다. 개발자가 손을 댈 수 있는 자리에서는 NVTX 가 가장 풍부하지만, 손이 안 닿는 자리에서는 eBPF 가 유일한 답.

§ 08다른 도구와의 비교· Nsight · DCGM · Prometheus exporter

각 도구가 진짜 잘 하는 것 — 그리고 어디서 한계가 시작되는가

eBPF stack 이 모든 것을 대체하지 않는다. 도구 별로 강점과 한계를 표로 정리해두면 어느 자리에 어떤 도구를 쓸지 결정이 빨라진다.

FIG · 도구 별 capability matrix각 도구가 답하는 질문의 차원
도구
production 안전
attach 자유도
의미론적 깊이
nvidia-smi
YES
free
aggregate only
DCGM
YES
free
metric only
Nsight Systems
dev
pre-attach
deep timeline
Nsight Compute
slow
pre-attach
SASS-level
CUPTI activity
prod-ish
pre-attach
launch+memcpy
NVTX range
YES
code 안
앱 의미론
bpftime uprobe
YES
live attach
launch level
gpu_ext UVM hook
struct fork
free
page-level
이 표 한 장의 메시지 — “live attach × deep semantics” 라는 자리는 NVTX 와 eBPF 의 합집합으로만 채워진다. NVIDIA 의 단일 도구로는 안 채워지는 빈 자리.

실전 결정의 한 가지 트릭 — “dev 에서 reproduce 가 되는가” 를 첫 분기로 쓴다. 된다면 Nsight Systems 한 번 띄우는 게 항상 최선. 안 된다면 (production-only 버그) eBPF stack 으로 넘어간다. 두 stack 을 같은 schema 로 emit 하도록 정렬해두면 dev 에서의 직관이 production 으로 이전된다.

§ 09한계와 함정· limits · permissions · overhead

“다 보인다” 는 광고 너머의 현실

eBPF GPU stack 은 실제 production 에 깔아보면 몇 개의 만성적 문제가 있다. 강의에서 명시되지 않았더라도 — repo 의 issue / paper limitations 에서 일관되게 언급되는 것들.

현재 상태 · 확인 필요

이 강의가 발표된 시점의 정확한 driver/CUDA 버전 매핑, B200 / Blackwell 에서의 PTX injection 실증 여부, 그리고 strugger detection 의 수치적 결과 — 자막 실패로 직접 확인 어려움. 강의 비디오를 다시 보고 채워야 할 항목들이다.

§ 10기억할 메모· key takeaways · repo

다시 열었을 때 5분 안에 손에 잡혀야 할 것

자막이 실패한 강의이지만 — 발표자의 repo 와 paper 가 stack 의 모양을 충분히 드러낸다. 다시 돌아왔을 때 빠르게 복원해야 하는 사실들.

4 layer stack
L0 NVTX (앱 의미론), L1 CUPTI (driver event), L2 eBPF userspace (launch / syscall hook), L3 kernel UVM hook (page fault). 위로 갈수록 의미론, 아래로 갈수록 커버리지.
eBPF on GPU 의 두 갈래
bpftime = 사용자공간 VM + uprobe/PTX injection. gpu_ext = NVIDIA OGKM fork 에 struct_ops hook. 두 layer 가 다른 자리를 채운다.
live attach
CUPTI 와 Nsight 는 process 시작 전에 attach 해야 한다. eBPF 는 이미 도는 binary 에 attach 가능. production 의 가장 큰 unlock.
production 안전성
NVTX 와 DCGM 은 항상 안전. Nsight Compute 는 느려서 production 부적합. eBPF 는 sampling 모드로 안전, kernel-launch 마다 hook 박는 모드는 overhead 주의.
silent UVM eviction
대표적 production 함정. nvidia-smi 가 한가해 보여도 throughput 이 깎이는 패턴. gpu_ext 의 page fault tracing 만 직접 답.
cross-rank align
분산 학습에서는 모든 rank 의 trace 를 같은 epoch 에 정렬해야 stragger 가 보인다. NCCL collective marker 를 anchor 로 쓰는 게 표준.
agentsight
LLM agent 의 zero-instrument observability. eBPF stack 의 LLM 시대 응용. 같은 author repo.
의사결정 default
dev 에서 reproduce → Nsight Systems. production-only → eBPF stack. NVTX 는 항상 박아둔다. CUPTI 는 단일 process 가 알려진 환경에서 추가.
YouTube youtube.com/watch?v=-6FlMJ-AP74 · transcript failed
bpftime github.com/eunomia-bpf/bpftime · userspace eBPF runtime + GPU PTX injection
gpu_ext github.com/eunomia-bpf/gpu_ext · eBPF struct_ops hooks for NVIDIA OGKM
eunomia-bpf github.com/eunomia-bpf · org with all related repos
CUPTI ref docs.nvidia.com/cuda/cupti · official CUDA Profiling Tools Interface
NVTX ref github.com/NVIDIA/NVTX · NVIDIA Tools Extension Library

손에 새기기 — 실습 시퀀스

  1. NVTX baseline — 자기 학습 루프에 nvtx.annotate 를 forward / backward / optim 에 박고 Nsight Systems 로 한 step 의 timeline 을 본다. 의미론적 분해가 timeline 위에서 보이는지 확인.
  2. CUPTI 만의 시점 — 같은 코드에 NVTX 를 빼고 CUPTI 만으로 같은 trace 를 떠본다. “어디가 mlp 인지”가 안 보인다는 사실을 직접 체감.
  3. bpftime 설치 — 데스크탑 환경에서 bpftime 을 설치하고 단순한 uprobe 로 cuLaunchKernel 의 호출 횟수를 기록. CUDA app 를 수정하지 않고 신호가 나오는지 검증.
  4. UVM oversubscribe 재현 — 작은 GPU 에 큰 모델을 올려 OOM 직전까지 가는 toy scenario. nvidia-smigpu_ext trace 를 동시에 보고 page fault 패턴 비교.
  5. cross-rank align — 2 rank 학습에서 NCCL allreduce 의 시작/끝을 양쪽 rank 에서 모아 같은 epoch 으로 정렬. 더 늦게 도착하는 rank 가 어느 단계에 묶여 있었는지 분석.
§ 11다른 강의로 이어지는 길· connections

이 강의의 도구가 다른 강의에서 어떻게 다시 등장하는가

L098 의 4-layer stack 은 다른 GPU Mode 강의들의 도구를 모두 한 timeline 위로 끌어올 수 있는 frame. 어느 강의가 어느 layer 와 매핑되는지를 묶어둔다.

§ 12열린 질문· open questions

다음에 다시 들었을 때 직접 검증해야 할 것들

자막이 실패한 강의라 노트의 많은 부분이 발표자의 repo 와 관련 paper 로부터 재구성됐다. 채워야 할 빈 자리들을 명시.

검증 메모

이 노트의 모든 capability matrix 항목과 case 예시는 발표자의 공개 repo (eunomia-bpf, bpftime, gpu_ext) 와 관련 paper (OSDI/ATC) 의 description 으로부터 재구성한 것이다. 강의 영상에서 직접 다룬 demo 와 수치는 자막 실패로 확인되지 않았다.

← Lecture 097 HipKittens — AMD GPU 위 tile 추상 Lecture 099 → Distributed ML on consumer devices — Matt Beton