GPU
GPU는 training과 inference 뒤의 dense linear algebra를 가속합니다. 반복해서 문제가 되는 제약은 raw FLOPs만이 아니라 memory capacity, memory bandwidth, interconnect입니다.
공개 research-engineering note에서는 GPU 작업을 resource diagnosis 문제로 봅니다.
유용한 질문은 현재 workflow를 제한하는 항이 무엇인가입니다.
진단 지도
Bottleneck taxonomy
GPU bottleneck taxonomy는 capacity, bandwidth, compute, input pipeline, synchronization, communication, scheduler limit를 분리합니다. 이렇게 해야 “GPU utilization이 낮다”는 말이 모호한 진단으로 끝나지 않습니다.
Training 또는 inference step은 아래처럼 분해할 수 있습니다.
| 유형 | 증상 | 일반적인 evidence |
|---|---|---|
| Capacity | OOM 또는 너무 작은 batch size | memory allocation, batch/context sensitivity |
| Bandwidth | 높은 memory traffic, 낮은 FLOP utilization | profiler memory bandwidth, tensor shape pattern |
| Compute | kernel이 wall time을 지배 | 높은 GPU utilization과 안정적인 input pipeline |
| Input pipeline | GPU가 data를 기다림 | CPU usage, data-loader timing, storage IO |
| Synchronization | 잦은 stall | host sync call, logging, metric aggregation |
| Communication | multi-GPU scaling 저하 | all-reduce time, interconnect saturation |
| Scheduler | 긴 wait, preemption, allocation mismatch | queue time, walltime, resource request mismatch |
Memory
GPU memory는 training과 inference에서 보통 가장 먼저 만나는 hard limit입니다. Workload가 compute-light하더라도 weight, activation, optimizer state, gradient, KV cache가 device memory를 넘으면 실패합니다.
Training memory는 대략 아래처럼 분해할 수 있습니다.
Autoregressive inference에서는 KV cache가 지배적인 경우가 많습니다.
여기서 은 layer 수, 는 attention head 수, 는 context length, 는 value 하나의 byte 수입니다.
핵심 check:
- memory가 parameter, activation, optimizer state, batch size, KV cache 중 어디에 쓰이는가?
- 매 step memory가 증가해서 graph retention이나 logging leakage를 의심해야 하는가?
- mixed precision, gradient checkpointing, smaller batch size, sharded optimizer, shorter context가 bottleneck을 해결하는가?
- memory가 primary bottleneck인가, 아니면 input, synchronization, communication stall의 증상인가?
Utilization
GPU utilization은 증상이지 완전한 진단이 아닙니다. Low utilization은 data loading, CPU preprocessing, synchronization, communication, small batch size, memory stall, 또는 compute-heavy하지 않은 workload에서 나올 수 있습니다.
단순한 utilization 관점은 아래와 같습니다.
High utilization만으로 좋은 throughput이 증명되지는 않습니다. 유용한 metric은 고정된 quality와 memory budget 아래에서 초당 완료한 work입니다.
실전 진단:
- step time, GPU utilization, GPU memory, CPU usage, I/O wait를 측정합니다.
- data loading이 compute를 따라오는지 확인합니다.
- batch size, precision, tensor shape를 확인합니다.
- synchronization point와 distributed communication을 확인합니다.
- code를 바꾸기 전에 짧고 대표적인 run을 profile합니다.
Driver and CUDA
Shared machine에서 “GPU가 안 된다”는 실패는 대부분 NVIDIA driver, framework가 빌드된 CUDA runtime, host toolkit 사이의 mismatch에서 나옵니다. Driver는 지원 가능한 최대 CUDA version을 제한하고, driver가 지원하지 않는 더 새로운 runtime은 initialize에 실패합니다.
Compatibility chain은 아래와 같습니다.
처음부터 project dependency를 바꾸기보다 host layer에서 위로 올라가며 debug합니다.
실전 check:
- framework를 의심하기 전에 driver가 GPU를 보는지 확인합니다.
- GPU Xid나 PCI/UUID mapping은 raw log와 asset inventory를 그대로 공개하지 말고 sanitized command pattern으로만 남깁니다.
- system toolkit만 보지 말고 framework에 bundled된 CUDA runtime을 확인합니다.
- driver가 보고하는 CUDA version은 runtime compatibility의 상한으로 봅니다.
- driver upgrade 뒤에는 test 전에 reboot하거나 kernel module을 reload합니다.
- clean environment에서 재현해 host 문제와 project 문제를 분리합니다.
- private node name이나 project path 대신 error class와 compatibility layer를 기록합니다.
Device Mapping
GPU index는 재부팅, driver 상태, visibility setting, scheduler allocation에 따라 사람이 기대한 물리 GPU와 다르게 보일 수 있습니다. Slurm GRES, CUDA_VISIBLE_DEVICES, /dev/nvidia*, PCI bus ID, UUID를 구분해서 봐야 합니다.
nvidia-smi --query-gpu=index,uuid,pci.bus_id,name --format=csv필요하면 private runbook에서 minor number까지 매핑합니다. Public note에는 raw output을 붙이지 않고 mapping logic만 남깁니다.
for i in $(nvidia-smi --query-gpu=index --format=csv,noheader); do
nvidia-smi -q -i "$i" | awk -v idx="$i" '
/Product Name/ {sub(/.*: /,""); name=$0}
/GPU UUID/ {sub(/.*: /,""); uuid=$0}
/Bus Id/ {sub(/.*: /,""); bus=$0}
/Minor Number/ {sub(/.*: /,""); minor=$0}
END {printf("index=%s minor=%s dev=/dev/nvidia%s bus=%s uuid=%s name=%s\n", idx, minor, minor, bus, uuid, name)}
'
donePublish only the conclusion, such as scheduler-visible GPU mapping was checked. Do not publish private bus topology, node inventory, serial-like identifiers, or per-node device layout.
Xid Triage
Xid log entries are not a full root cause by themselves. Treat them as the first classification step.
journalctl -k | grep -i xid
grep -i xid /var/log/kern.log| Evidence | Next Question |
|---|---|
| repeated Xid on one device | same physical GPU, same job type, or same time window? |
| Xid after driver update | driver/runtime compatibility or reboot/module state? |
| Xid during high utilization | power, thermal, memory pressure, or workload-specific kernel? |
| Xid across many devices | host, driver, PCIe, power, or scheduler-wide event? |
Public notes should report the class of issue and the diagnostic route, not the raw kernel log.
진단 축
- Capacity: model, activation, optimizer state, cache가 들어가는가?
- Bandwidth: kernel이 arithmetic보다 memory movement에 제한되는가?
- Compute: tensor core 또는 GPU kernel이 wall time을 지배하는가?
- Input pipeline: CPU preprocessing이나 storage가 GPU를 굶기는가?
- Communication: multi-GPU synchronization이 scaling을 지배하는가?
- Scheduler: resource request나 walltime이 code보다 run을 더 크게 좌우하는가?
First Measurements
GPU note는 추측보다 작은 측정값에서 시작합니다.
| 측정값 | 이유 |
|---|---|
| step time | throughput 변화의 기본 단위 |
| allocated / reserved memory | true capacity pressure와 fragmentation 구분 |
| GPU utilization | compute work가 있는지 보는 rough signal |
| dataloader wait | input pipeline starvation 확인 |
| host CPU and RAM | preprocessing, pin memory, worker pressure 확인 |
| communication time | distributed scaling 병목 확인 |
실전 check
- model weight, activation, optimizer state, KV cache의 memory headroom을 추적합니다.
- precision을 hardware와 numerical tolerance에 맞춥니다.
- optimize 전에 profile합니다.
- model code를 바꾸기 전에 GPU bottleneck taxonomy로 bottleneck을 분류합니다.
- public note는 generic하게 유지하고 private host나 allocation을 공개하지 않습니다.