본문 바로가기
개발 가이드/AI 개발

[AI 개발] 3. PyTorch 완전 가이드

by 플로거 2026. 7. 19.

Python 딥러닝 프레임워크 가이드

PyTorch 완전 가이드

PyTorch로 딥러닝 모델을 만들고 학습하는 방법을 정리합니다. Tensor, Autograd, Dataset과 DataLoader, 학습 루프, GPU 실행, 모델 저장과 추론까지 실무 흐름에 맞춰 살펴봅니다.

  • Tensor
  • Autograd
  • DataLoader
  • GPU
  • 모델 학습
  • 추론
반응형
이 글의 핵심
PyTorch 학습의 기본 흐름은 데이터를 Tensor로 준비하고, 모델의 forward 연산을 수행한 뒤 loss를 계산하고, backward와 optimizer step을 반복하는 것입니다. 운영 단계에서는 재현성, checkpoint, GPU 사용률과 데이터 로딩 병목까지 함께 관리해야 합니다.

1. PyTorch란?

PyTorch는 Python 생태계에서 널리 사용되는 딥러닝 프레임워크입니다. 직관적인 Tensor 연산, 동적 계산 그래프, 풍부한 연구 및 실무 예제를 기반으로 모델 실험에서 서비스 적용까지 빠르게 이어갈 수 있습니다.

영역 주요 활용
연구와 실험 빠른 프로토타이핑, 동적 계산 그래프, 풍부한 커뮤니티 예제
컴퓨터 비전 torchvision, CNN, ResNet, 이미지 분류와 객체 탐지
NLP와 LLM Transformers, LoRA, 파인튜닝, 임베딩 모델
운영 ONNX 변환, 배치 추론, GPU 서버, 모델 서빙

2. 설치와 환경 설정

프로젝트별 가상환경을 만든 뒤 CPU 또는 CUDA 환경에 맞는 PyTorch 패키지를 설치합니다. GPU를 사용할 때는 운영체제, NVIDIA 드라이버, CUDA 호환성을 함께 확인해야 합니다.

Bash
# uv 기반 가상환경 생성
uv venv
source .venv/bin/activate

# Windows PowerShell
# .venv\Scripts\Activate.ps1

# 기본 패키지 설치
uv pip install torch torchvision torchaudio

# 설치 확인
python - <<'PY'
import torch

print("torch:", torch.__version__)
print("cuda available:", torch.cuda.is_available())
print("cuda version:", torch.version.cuda)
PY
설치 팁
CUDA 환경은 PyTorch 공식 설치 안내에서 운영체제와 CUDA 버전에 맞는 명령을 확인하는 것이 안전합니다. 프로젝트에서는 requirements.txtpyproject.toml로 패키지 버전을 고정하세요.

3. Tensor 기본

Tensor는 PyTorch의 핵심 데이터 구조입니다. NumPy 배열처럼 다룰 수 있으며 GPU 이동과 자동 미분을 지원합니다. 모델 학습에서는 shape, dtype, device가 맞지 않아 오류가 발생하는 경우가 많으므로 세 값을 항상 함께 확인하는 습관이 중요합니다.

Python
import torch

x = torch.tensor([
    [1.0, 2.0],
    [3.0, 4.0],
])

w = torch.randn(2, 3)

print("x.shape:", x.shape)
print("w.shape:", w.shape)
print("matrix product:")
print(x @ w)

if torch.cuda.is_available():
    x = x.to("cuda")
    print("device:", x.device)

자주 확인할 Tensor 속성

  • tensor.shape: 차원과 각 축의 크기
  • tensor.dtype: float32, float16, int64 등의 데이터 형식
  • tensor.device: CPU 또는 CUDA 장치
  • tensor.requires_grad: gradient 추적 여부

4. Autograd

Autograd는 Tensor 연산 그래프를 추적하여 역전파에 필요한 gradient를 자동으로 계산합니다. 학습 대상 파라미터에는 requires_grad=True가 설정되고, loss에 대해 backward()를 실행하면 gradient가 누적됩니다.

Python
import torch

x = torch.tensor([2.0], requires_grad=True)
y = x ** 2 + 3 * x + 1

y.backward()

print(x.grad)  # dy/dx = 2x + 3, x=2이면 7
주의
PyTorch의 gradient는 기본적으로 누적됩니다. 일반적인 학습 루프에서는 매 반복마다 optimizer.zero_grad()를 호출해 이전 gradient를 초기화해야 합니다.

5. Dataset과 DataLoader

Dataset은 개별 샘플에 접근하는 방법을 정의하고, DataLoader는 배치 구성, 셔플, 병렬 데이터 로딩을 담당합니다. 데이터 전처리와 모델 코드를 분리하면 재현성과 유지보수성이 좋아집니다.

Python
import torch
from torch.utils.data import Dataset, DataLoader


class ToyDataset(Dataset):
    def __init__(self):
        self.x = torch.randn(100, 4)
        self.y = (self.x.sum(dim=1) > 0).long()

    def __len__(self):
        return len(self.x)

    def __getitem__(self, index):
        return self.x[index], self.y[index]


dataset = ToyDataset()
loader = DataLoader(
    dataset,
    batch_size=16,
    shuffle=True,
)

for xb, yb in loader:
    print("x batch:", xb.shape)
    print("y batch:", yb.shape)
    break

DataLoader 성능 확인 항목

  • batch_size가 GPU 메모리와 처리량에 적절한지 확인합니다.
  • num_workers를 조절해 데이터 로딩 병목을 측정합니다.
  • GPU 사용 시 pin_memory=True가 도움이 되는지 확인합니다.
  • 학습과 검증 데이터의 transform을 분리합니다.
  • 데이터 순서와 split 과정에서 누수가 없는지 점검합니다.

6. 학습 루프

모델, 손실 함수, 옵티마이저를 정의한 뒤 forward, loss 계산, gradient 초기화, backward, optimizer step 순서로 반복합니다.

1. Batch
불러오기
2. Forward
예측
3. Loss
계산
4. Backward
미분
5. Step
가중치 갱신
train.py
import torch
from torch import nn
from torch.utils.data import DataLoader, TensorDataset

x = torch.randn(512, 8)
y = (x.sum(dim=1, keepdim=True) > 0).float()

loader = DataLoader(
    TensorDataset(x, y),
    batch_size=32,
    shuffle=True,
)

model = nn.Sequential(
    nn.Linear(8, 16),
    nn.ReLU(),
    nn.Linear(16, 1),
)

loss_fn = nn.BCEWithLogitsLoss()
optimizer = torch.optim.AdamW(
    model.parameters(),
    lr=1e-3,
)

for epoch in range(5):
    model.train()
    total_loss = 0.0

    for xb, yb in loader:
        prediction = model(xb)
        loss = loss_fn(prediction, yb)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        total_loss += loss.item()

    average_loss = total_loss / len(loader)
    print(f"epoch={epoch}, loss={average_loss:.4f}")

GPU 실행 형태

Python
import torch

device = torch.device(
    "cuda" if torch.cuda.is_available() else "cpu"
)

model = model.to(device)

for xb, yb in loader:
    xb = xb.to(device)
    yb = yb.to(device)

    prediction = model(xb)
    loss = loss_fn(prediction, yb)
모델과 입력 Tensor는 같은 device에 있어야 합니다. 모델은 CUDA에 있고 입력이 CPU에 있으면 device mismatch 오류가 발생합니다.

7. 저장과 추론

학습한 모델은 일반적으로 state_dict를 저장합니다. 추론할 때는 동일한 모델 구조를 생성한 뒤 파라미터를 로드하고, eval()torch.no_grad()를 함께 사용합니다.

Python
# 모델 파라미터 저장
torch.save(
    model.state_dict(),
    "model.pt",
)

# 모델 파라미터 로드
state_dict = torch.load(
    "model.pt",
    map_location="cpu",
)

model.load_state_dict(state_dict)
model.eval()

with torch.no_grad():
    sample = torch.randn(1, 8)
    logits = model(sample)
    probability = torch.sigmoid(logits)

print(probability.item())

Checkpoint에 함께 저장할 정보

Python
checkpoint = {
    "epoch": epoch,
    "model_state_dict": model.state_dict(),
    "optimizer_state_dict": optimizer.state_dict(),
    "loss": average_loss,
}

torch.save(checkpoint, "checkpoint.pt")
  • 현재 epoch와 global step
  • 모델 및 옵티마이저 state
  • 학습률 스케줄러 state
  • 평가 metric과 best score
  • 모델 및 데이터 설정

8. PyTorch 실무 설계

실험 코드와 학습 파이프라인을 분리하는 것이 중요합니다. Dataset, transform, model, loss, trainer, evaluator, configuration을 독립 모듈로 두면 재현성과 확장성이 좋아집니다.

결정 지점 확인 질문 실무 기준
경계 자주 바뀌는 부분과 핵심 모델 코드가 섞여 있는가? 입출력, 설정, 데이터, 모델, 평가 로직을 분리합니다.
상태 모델, optimizer, checkpoint 상태는 누가 소유하는가? Trainer가 학습 상태와 수명 주기를 명확히 관리하게 합니다.
설정 실험 조건을 다시 재현할 수 있는가? 하이퍼파라미터와 데이터 버전을 설정 파일로 관리합니다.
장애 중단된 학습을 어디서부터 다시 시작할 수 있는가? 주기적인 checkpoint와 resume 절차를 준비합니다.

권장 프로젝트 구조

Directory
pytorch-project/
├── configs/
│   └── train.yaml
├── data/
├── src/
│   ├── datasets.py
│   ├── models.py
│   ├── trainer.py
│   ├── evaluator.py
│   └── utils.py
├── tests/
├── train.py
└── infer.py

9. PyTorch 운영 기준

학습 성능은 GPU utilization뿐 아니라 데이터 로딩 병목, mixed precision, gradient accumulation, checkpoint 저장 비용을 함께 봐야 합니다. 장시간 학습은 실패 후 재시작할 수 있는 checkpoint 전략이 필수입니다.

운영 전 확인 목록
  • Python, NumPy, PyTorch와 CUDA seed를 관리합니다.
  • 학습 데이터, 코드, 설정, 모델 버전을 연결해 기록합니다.
  • GPU utilization과 GPU memory를 모니터링합니다.
  • DataLoader 병목과 CPU 사용률을 함께 확인합니다.
  • checkpoint 저장 및 resume 절차를 실제로 검증합니다.
  • AMP 사용 시 loss scale과 수치 안정성을 확인합니다.
  • 학습 로그와 metric을 외부 저장소에 기록합니다.

Seed 설정 예제

Python
import random
import numpy as np
import torch


def set_seed(seed: int = 42) -> None:
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)


set_seed(42)

10. PyTorch 검증 전략

모델 품질은 validation metric 하나만으로 판단하면 안 됩니다. 데이터 누수, class imbalance, seed 고정, overfit smoke test, 추론 입력 검증과 성능 회귀를 함께 확인해야 합니다.

품질 축 검증 방법 완료 기준
정확성 Tensor shape, dtype, device와 정상·실패 케이스 자동화 핵심 시나리오가 반복 실행되어도 동일하게 통과합니다.
회귀 방지 버그 수정 시 동일 케이스를 테스트로 유지 같은 장애가 다시 배포되지 않습니다.
데이터 품질 데이터 누수, 중복, class imbalance 점검 학습·검증·테스트 데이터 분리 기준이 확인됩니다.
학습 가능성 작은 데이터셋에 대한 overfit smoke test 모델과 학습 루프가 손실을 충분히 줄일 수 있습니다.
성능 처리량, latency, GPU memory, 데이터 로딩 시간 측정 기준 모델 대비 허용 범위를 넘는 회귀가 없습니다.
운영성 로그, metric, 알림, checkpoint resume 검증 문제가 발생했을 때 원인 추적과 복구 경로가 있습니다.

마무리

PyTorch 학습의 핵심은 Tensor, Autograd, Dataset과 DataLoader, 모델과 loss, optimizer로 이어지는 기본 흐름을 정확히 이해하는 것입니다. 실제 프로젝트에서는 여기에 GPU 사용, 재현성, checkpoint, 데이터 품질과 운영 모니터링까지 포함해야 안정적인 학습 파이프라인을 만들 수 있습니다.

핵심 정리
  • Tensor의 shape, dtype, device를 함께 확인합니다.
  • 학습 루프는 forward, loss, zero_grad, backward, step 순서로 구성합니다.
  • Dataset과 DataLoader를 모델 코드와 분리합니다.
  • 추론 시 eval()torch.no_grad()를 사용합니다.
  • 재현성, checkpoint, 데이터 누수와 성능 회귀를 함께 검증합니다.

원문: AI DevOps Korea PyTorch 가이드

반응형

댓글