본문으로 건너뛰기
김신건의 로그

GPU: 그래픽/ML 병렬 프로세서

· 수정 · 📖 약 3분 · 1,047자/단어 #ml #hardware #gpu #cuda #tensor-core #simt
GPU, Graphics Processing Unit, CUDA, 그래픽 카드, Tensor Core, SM, Streaming Multiprocessor

정의

GPU (Graphics Processing Unit) 는 원래 3D 그래픽 렌더링을 위해 설계됐지만, massively parallel 아키텍처가 딥러닝의 행렬 연산과 완벽히 맞아 현재 AI 컴퓨팅의 표준 하드웨어가 됐다. NVIDIA, AMD, Intel 이 3대 제조사.

언제 쓰이나

  • 딥러닝 모델 학습 / 추론
  • LLM inference serving (vLLM, TGI 등)
  • 3D 그래픽 렌더링, 영상 처리
  • 과학 시뮬레이션 (HPC), 암호화폐 채굴
  • CUDA 에코시스템이 필요한 모든 병렬 워크로드

아키텍처 개요

전체 계층 구조

flowchart TB
    GPU["GPU 칩"] --> GPC["GPC\n(Graphics Processing Cluster)"]
    GPC --> SM["SM (Streaming Multiprocessor)\n× 132개 (H100)"]
    SM --> CUDA["CUDA Core × 128\n(FP32 ALU)"]
    SM --> TC["Tensor Core × 4\n(행렬곱 전용)"]
    SM --> Shared["Shared Memory\n+ L1 Cache (256KB)"]
    SM --> Reg["Register File\n(65536 × 32bit)"]
    GPU --> L2["L2 Cache (50MB)"]
    GPU --> HBM["HBM3 (80GB, 3.35 TB/s)"]

SM (Streaming Multiprocessor)

NVIDIA GPU 의 핵심 실행 단위. 각 SM 은 독립적인 연산 블록.

H100 (Hopper 아키텍처) SM 구성:

  • 128개 FP32 CUDA 코어 (일반 연산)
  • 4개 Tensor Core (3세대 Hopper TC: FP8/FP16/BF16/FP32 지원)
  • 256KB L1 cache + Shared Memory (프로그래머 제어 가능)
  • Register file 65,536 × 32bit (스레드 간 공유 없음)
  • Warp Scheduler 4개 (32스레드 warp 관리)
H100 SXM5: 132 SM × (128 FP32 + 4 Tensor Core) = 16,896 CUDA cores

SIMT: GPU 실행 모델

SIMT (Single Instruction Multiple Thread) 는 GPU 의 병렬 실행 모델.

Warp 실행

Warp = 32개 스레드의 묶음 (하드웨어 실행 단위)
 ┌──────────────────────────────────┐
 │ Thread 0  Thread 1  ... Thread 31│   ← 동일 명령 동시 실행
 └──────────────────────────────────┘
           Warp 0 (32T)

SM 은 최대 64 warp (2048 스레드) 를 동시에 관리
활성 warp 중 하나가 메모리 대기 → 즉시 다른 warp 전환 (zero-cost context switch)

Branch Divergence (분기 발산)

// SIMT 의 함정: if-else 분기
if (threadIdx.x % 2 == 0) {
    do_A();  // 짝수 스레드만
} else {
    do_B();  // 홀수 스레드만
}
// Warp 내 분기 → 두 경로 순차 실행 (SIMD 효율 50% 낙하)

Warp 내 스레드가 다른 분기를 탈 경우, 두 경로를 순차적으로 실행하고 비활성 스레드는 마스킹. 성능 반감.

메모리 계층

flowchart TB
    subgraph "빠름 (작음)"
        Reg["Register\n(스레드 전용, ~1 cycle)"]
        Shared["Shared Memory\n(SM 내 공유, ~1 cycle, 128-256KB)"]
        L1["L1 Cache\n(SM 내, ~10 cycle, Shared 와 공유)"]
    end
    subgraph "느림 (큼)"
        L2["L2 Cache\n(전체 GPU 공유, ~200 cycle, 50MB)"]
        HBM["HBM (Global Memory)\n(~500 cycle, 80GB, 3.35 TB/s H100)"]
    end
    Reg --> Shared --> L1 --> L2 --> HBM
계층크기지연대역폭접근
Register스레드별 64KB~1 cycle최고스레드 전용
Shared MemorySM당 최대 228KB~1 cycle매우 높음SM 내 블록 공유
L1 CacheSM당 128KB~28 cycle높음자동
L2 Cache50MB (H100)~200 cycle중간자동
HBM (Global)80GB (H100)~500 cycle3.35 TB/s전체 커널

IMPORTANT

메모리 대역폭이 병목인 커널(bandwidth-bound)을 컴퓨트 집약 커널(compute-bound)로 바꾸는 것이 GPU 최적화의 핵심. Shared Memory 활용과 메모리 coalescing 이 주요 기법.

Tensor Core: 딥러닝 특화 유닛

CUDA 코어가 scalar(단일 FP32) 연산을 하는 반면, Tensor Core 는 4×4 행렬 연산을 1 클럭에 처리.

Tensor Core (Hopper, 3세대):
  D = A × B + C
  A: [16×16], B: [16×8], C/D: [16×8]
  지원 형식: FP8, FP16, BF16, FP32, INT8, INT4

CUDA Core (FP32):
  d = a * b + c   (scalar)
  1개 연산/clock

Tensor Core 성능 (H100 SXM5)

정밀도피크 TFLOPS
FP6466.9
FP32 (CUDA Core)133.8
TF32 (Tensor Core)989
FP16/BF16 (Tensor Core)1,979
FP8 (Tensor Core)3,958
INT8 (Tensor Core)3,958

세대 비교

flowchart LR
    V100["V100 (Volta 2017)\nTensor Core 1세대\n125 TFLOPS FP16\n16-32GB HBM2"] --> A100["A100 (Ampere 2020)\nTensor Core 3세대\nSparse 지원\n312 TFLOPS FP16\n40-80GB HBM2e"]
    A100 --> H100["H100 (Hopper 2022)\nTensor Core 4세대\nFP8 지원\n1,979 TFLOPS BF16\n80GB HBM3"]
    H100 --> B200["B200 (Blackwell 2024)\nFP4 지원\n9 PFLOPS FP8\n192GB HBM3e"]
GPU아키텍처BF16 TFLOPSHBMNVLink
V100Volta (2017)12532GBNVLink 2
A100Ampere (2020)31280GBNVLink 3
H100Hopper (2022)1,97980GBNVLink 4
H200Hopper (2024)1,979141GB HBM3eNVLink 4
B200Blackwell (2024)4,500192GBNVLink 5

소프트웨어 스택

flowchart TB
    App["PyTorch / TensorFlow / JAX"] --> Lib["cuDNN / cuBLAS / NCCL"]
    Lib --> CUDA["CUDA Runtime / Driver"]
    CUDA --> HW["NVIDIA GPU HW"]
    App2["OpenCL / ROCm (AMD)"] --> HW2["AMD GPU"]
    Triton["OpenAI Triton\n(Python CUDA 커널)"] --> CUDA
라이브러리역할
CUDANVIDIA 독점 GPU 프로그래밍 API
cuDNNCNN, Transformer 최적화 커널
cuBLASGEMM 최적화
NCCL멀티 GPU 통신 (all-reduce 등)
TritonPython 에서 CUDA 커널 작성 (OpenAI)
ROCmAMD GPU 대응 오픈소스 스택

실전: CUDA / PyTorch 최적화

기본 행렬곱 (CUDA)

// naive: global memory 직접 접근 (느림)
__global__ void matmul_naive(float *A, float *B, float *C, int N) {
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;
    float sum = 0.0f;
    for (int k = 0; k < N; k++) {
        sum += A[row * N + k] * B[k * N + col];
    }
    C[row * N + col] = sum;
}

// shared memory tiling: L1 활용 (빠름)
__global__ void matmul_tiled(float *A, float *B, float *C, int N) {
    __shared__ float As[TILE][TILE];
    __shared__ float Bs[TILE][TILE];
    // ... tiling 로직
}

PyTorch 에서 Tensor Core 활용

import torch

# Tensor Core 활성화: AMP (Automatic Mixed Precision)
from torch.cuda.amp import autocast, GradScaler

scaler = GradScaler()

with autocast(dtype=torch.bfloat16):  # BF16 → Tensor Core 자동 사용
    output = model(input)
    loss = criterion(output, target)

scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()

Flash Attention: 메모리 효율 Attention

# standard: O(seq^2) HBM 접근
# flash attention: HBM 접근 최소화, Shared Memory 활용
import torch.nn.functional as F

# PyTorch 2.0+ 기본 내장 (SDPA)
with torch.backends.cuda.sdp_kernel(
    enable_flash=True,
    enable_math=False,
    enable_mem_efficient=True
):
    output = F.scaled_dot_product_attention(q, k, v)

CPU 와 비교

flowchart LR
    subgraph "CPU (Intel Xeon)"
        c_core["8-64 코어\n복잡한 ALU\n분기 예측, OoO 실행"]
        c_mem["DDR5 ~200 GB/s"]
        c_core --> c_mem
    end
    subgraph "GPU (H100)"
        g_sm["132 SM\n16,896 CUDA Core\n528 Tensor Core"]
        g_hbm["HBM3 3.35 TB/s"]
        g_sm --> g_hbm
    end
항목CPU (Xeon)GPU (H100)
코어 수8-6416,896 CUDA
클럭3-5 GHz~1.98 GHz
메모리 BW~200 GB/s3.35 TB/s
분기 처리최적화 (예측)비효율 (warp divergence)
단일 스레드 성능높음낮음
병렬 스루풋낮음극도로 높음
딥러닝 행렬곱낮음 (~2 TFLOPS)1,979 TFLOPS (BF16)

다중 GPU 연결

flowchart TB
    subgraph "단일 서버 (DGX H100)"
        GPU0 <-->|"NVLink 4\n900 GB/s"| GPU1
        GPU1 <-->|"NVLink 4"| GPU2
        GPU2 <-->|"NVLink 4"| GPU3
        GPU0 <-->|"NVLink 4"| GPU3
    end
    subgraph "서버 간"
        Server1 <-->|"InfiniBand NDR\n400 Gb/s"| Server2
        Server2 <-->|"InfiniBand"| Server3
    end
  • NVLink: 노드 내 GPU 간 고속 상호연결 (단방향 900 GB/s, H100)
  • NVSwitch: NVLink 스위치 패브릭, 8-16 GPU 완전 연결
  • InfiniBand: 노드 간 연결, NCCL all-reduce 에 활용

흔한 함정

WARNING

  1. 메모리 coalescing 무시 = warp 32 스레드가 연속 주소 접근 안 하면 실효 BW 1/32. 메모리 레이아웃 설계 중요.
  2. 작은 커널 남발 = 커널 launch overhead 누적. 여러 op 을 하나로 fusion (torch.compile / Triton).
  3. CPU-GPU 동기화 남발 = .item(), print(tensor) 호출 시 CPU 동기화 발생. 학습 루프에서 최소화.
  4. Host-Device 전송 병목 = CPU 에서 GPU 로 데이터 복사(PCIe 16-64 GB/s)가 병목. DataLoader 의 pin_memory=True, num_workers 활용.
  5. AMP 미사용 = FP32 로 학습 시 Tensor Core 를 사용하지 못함. torch.autocast('cuda') 로 BF16/FP16 전환.

관련 위키

이 글의 용어 (7개)
[Voice AI] LLM Serving: vLLM, PagedAttention, continuous batchingai
정의 LLM Serving = 자체 호스팅 LLM 을 낮은 TTFT + 높은 throughput 으로 제공. 음성 에이전트의 LLM 단계 지연 결정. | 도구 | 특징 | |--…
모델 양자화ml
정의 양자화 (Quantization) 는 신경망 모델의 가중치/활성화를 높은 정밀도 (FP32, FP16) 에서 낮은 정밀도 (INT8, INT4 등) 로 변환하여 메모리와 연…
분산 학습ml
정의 분산 학습 (Distributed Training) 은 한 또는 에 들어가지 않는 큰 모델을 여러 가속기에 나눠서 학습시키는 기법. 현대 LLM (Llama 405B, GP…
HBMml
정의 HBM (High Bandwidth Memory)는 DRAM die 를 수직으로 적층해 매우 높은 대역폭을 제공하는 메모리 패키지. AI 시대 GPU/TPU 의 메모리 병목…
SIMTml
정의 SIMT (Single Instruction, Multiple Threads) 는 NVIDIA 가 정립한 GPU 의 실행 모델이다. 한 명령(instruction) 을 한 …
Systolic Arrayml
정의 Systolic Array 는 격자 형태로 배치된 다수의 Processing Element (PE) 가, 입력 데이터가 박동(systolic)처럼 격자를 가로질러 흐르는 동…
TPU (Tensor Processing Unit): Google 의 ML ASICml
정의 TPU (Tensor Processing Unit) 는 Google 이 딥러닝 워크로드 전용으로 설계한 ASIC (Application-Specific Integrated …

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기