본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 6장: 학습 파이프라인 구축과 하이퍼파라미터 최적화
2026년 1월 24일·AI / ML·

6장: 학습 파이프라인 구축과 하이퍼파라미터 최적화

파인튜닝 학습 파이프라인의 전체 구조를 설계하고, 학습률, 배치 크기, 스케줄링 등 핵심 하이퍼파라미터를 최적화하는 전략을 다룹니다.

18분1,035자10개 섹션
llmtrainingmlopsdata-engineering
공유
fine-tuning6 / 10
12345678910
이전5장: QLoRA로 소비자 GPU에서 파인튜닝하기다음7장: 파인튜닝 모델 평가와 벤치마킹

학습 파이프라인의 전체 구조

파인튜닝 학습 파이프라인은 단순히 모델을 학습시키는 것 이상의 체계적인 과정입니다. 데이터 로딩, 전처리, 모델 설정, 학습 루프, 평가, 체크포인트 관리, 실험 추적까지 모든 요소가 유기적으로 연결되어야 합니다.

text
학습 파이프라인 전체 흐름:
 
  설정 로드 (Config)
       |
  데이터 로드 및 전처리
       |
  모델 로드 및 PEFT 설정
       |
  학습 루프
    |-- 순전파 (Forward Pass)
    |-- 손실 계산 (Loss)
    |-- 역전파 (Backward Pass)
    |-- 그래디언트 클리핑
    |-- 옵티마이저 스텝
    |-- 학습률 스케줄링
    |-- 로깅 (Wandb/TensorBoard)
    |-- 평가 (주기적)
    |-- 체크포인트 저장 (주기적)
       |
  최종 모델 저장
       |
  평가 및 보고서 생성

설정 관리

재현 가능한 실험을 위해 모든 설정을 코드가 아닌 설정 파일로 관리하는 것이 중요합니다.

python
# config.py
from dataclasses import dataclass, field
 
 
@dataclass
class ModelConfig:
    model_name: str = "meta-llama/Llama-3.1-8B-Instruct"
    use_4bit: bool = True
    bnb_4bit_quant_type: str = "nf4"
    use_flash_attention: bool = True
 
 
@dataclass
class LoraConfig:
    r: int = 32
    lora_alpha: int = 64
    lora_dropout: float = 0.05
    target_modules: list[str] = field(default_factory=lambda: [
        "q_proj", "k_proj", "v_proj", "o_proj",
        "gate_proj", "up_proj", "down_proj"
    ])
 
 
@dataclass
class TrainingConfig:
    output_dir: str = "./output"
    num_train_epochs: int = 3
    per_device_train_batch_size: int = 2
    gradient_accumulation_steps: int = 8
    learning_rate: float = 2e-4
    lr_scheduler_type: str = "cosine"
    warmup_ratio: float = 0.1
    weight_decay: float = 0.01
    max_seq_length: int = 2048
    max_grad_norm: float = 0.3
    save_steps: int = 200
    eval_steps: int = 200
    logging_steps: int = 10
    bf16: bool = True
    gradient_checkpointing: bool = True
    optim: str = "paged_adamw_8bit"
    seed: int = 42
 
 
@dataclass
class DataConfig:
    train_file: str = "data/train.jsonl"
    val_file: str = "data/val.jsonl"
    packing: bool = True
 
 
@dataclass
class ExperimentConfig:
    model: ModelConfig = field(default_factory=ModelConfig)
    lora: LoraConfig = field(default_factory=LoraConfig)
    training: TrainingConfig = field(default_factory=TrainingConfig)
    data: DataConfig = field(default_factory=DataConfig)
    experiment_name: str = "baseline"

YAML 기반 설정 관리도 실무에서 널리 사용됩니다.

yaml
# configs/experiment_v1.yaml
model:
  model_name: meta-llama/Llama-3.1-8B-Instruct
  use_4bit: true
  bnb_4bit_quant_type: nf4
 
lora:
  r: 32
  lora_alpha: 64
  lora_dropout: 0.05
 
training:
  num_train_epochs: 3
  per_device_train_batch_size: 2
  gradient_accumulation_steps: 8
  learning_rate: 0.0002
  lr_scheduler_type: cosine
  warmup_ratio: 0.1
  max_seq_length: 2048
 
experiment_name: v1-baseline

학습률 (Learning Rate) 전략

학습률은 파인튜닝에서 가장 중요한 하이퍼파라미터입니다. 너무 높으면 사전 학습된 지식이 파괴(Catastrophic Forgetting)되고, 너무 낮으면 학습이 진행되지 않습니다.

권장 학습률 범위

text
파인튜닝 방법별 권장 학습률:
 
  방법              권장 범위           일반적인 값
  Full Fine-Tuning  1e-6 ~ 5e-5       2e-5
  LoRA              1e-4 ~ 5e-4       2e-4
  QLoRA             1e-4 ~ 5e-4       2e-4
  DPO               1e-6 ~ 5e-6       5e-7
Info

LoRA/QLoRA의 학습률이 Full Fine-Tuning보다 10배 이상 높은 것은 의외로 느껴질 수 있습니다. 이는 LoRA 어댑터의 파라미터 수가 훨씬 적고, 스케일링 팩터(alpha/r)가 적용되기 때문입니다. 원본 모델의 가중치는 고정되어 있으므로 더 큰 학습률을 사용해도 안전합니다.

학습률 스케줄러

학습률을 학습 과정에서 동적으로 조절하는 스케줄러의 선택도 중요합니다.

text
주요 학습률 스케줄러:
 
  Cosine:
    특징: 코사인 함수를 따라 학습률이 점진적으로 감소
    장점: 부드러운 감소, 학습 후반부 안정적
    용도: 대부분의 파인튜닝 작업에 권장
 
  Linear:
    특징: 선형으로 학습률 감소
    장점: 단순하고 예측 가능
    용도: 짧은 학습에 적합
 
  Cosine with Restarts:
    특징: 주기적으로 학습률을 재시작
    장점: 지역 최적점 탈출 가능
    용도: 긴 학습이나 다중 태스크 학습
 
  Constant with Warmup:
    특징: 워밍업 후 일정한 학습률 유지
    장점: 구현 간단
    용도: 짧은 학습이나 탐색 단계
python
from transformers import get_scheduler
import torch
 
optimizer = torch.optim.AdamW(model.parameters(), lr=2e-4)
total_steps = 1000
 
# Cosine 스케줄러 (워밍업 포함)
scheduler = get_scheduler(
    name="cosine",
    optimizer=optimizer,
    num_warmup_steps=100,  # 전체의 10%
    num_training_steps=total_steps,
)

워밍업 (Warmup)

학습 초기에 학습률을 0에서 목표 값까지 점진적으로 올리는 기법입니다. 초기 불안정한 그래디언트로 인한 발산을 방지합니다.

text
워밍업 비율 가이드:
 
  데이터셋 크기     권장 워밍업 비율
  1,000개 이하      5% ~ 10%
  1,000 ~ 10,000    3% ~ 5%
  10,000 이상       1% ~ 3%

배치 크기 전략

배치 크기(Batch Size)는 한 번의 그래디언트 업데이트에 사용되는 데이터 수입니다. GPU 메모리 제약 하에서 효과적인 배치 크기를 달성하기 위해 그래디언트 누적(Gradient Accumulation)을 활용합니다.

text
실효 배치 크기 계산:
 
  실효 배치 크기 = per_device_batch_size
                   x gradient_accumulation_steps
                   x num_gpus
 
  예시:
    per_device_batch_size = 2
    gradient_accumulation_steps = 8
    num_gpus = 1
    실효 배치 크기 = 2 x 8 x 1 = 16

배치 크기에 따른 학습 역학

text
배치 크기의 영향:
 
  작은 배치 (4~8):
    - 그래디언트 노이즈가 높아 정규화 효과
    - 지역 최적점 탈출에 유리
    - 학습 불안정할 수 있음
    - 더 많은 업데이트 스텝 필요
 
  중간 배치 (16~32):
    - 노이즈와 안정성의 균형
    - 대부분의 파인튜닝에 적합
    - 권장 시작점
 
  큰 배치 (64 이상):
    - 안정적인 그래디언트
    - 학습률을 비례하여 높일 수 있음
    - 일반화 성능이 떨어질 수 있음
    - 메모리 요구량 증가

실험 추적과 모니터링

학습 과정을 체계적으로 추적하고 모니터링하는 것은 반복적인 실험의 핵심입니다.

Weights & Biases (wandb) 통합

python
import wandb
 
# wandb 초기화
wandb.init(
    project="fine-tuning-guide",
    name="qlora-llama3-8b-v1",
    config={
        "model": "meta-llama/Llama-3.1-8B-Instruct",
        "method": "QLoRA",
        "lora_r": 32,
        "lora_alpha": 64,
        "learning_rate": 2e-4,
        "batch_size": 16,
        "epochs": 3,
        "dataset_size": 5000,
    }
)
 
# TrainingArguments에 wandb 연동
training_args = TrainingArguments(
    report_to="wandb",
    run_name="qlora-llama3-8b-v1",
    logging_steps=10,
    # ...
)

모니터링해야 할 핵심 지표

text
학습 중 모니터링 지표:
 
  손실 관련:
    - train_loss: 학습 손실 (감소해야 함)
    - eval_loss: 검증 손실 (과적합 감지)
    - train_loss - eval_loss: 과적합 갭
 
  학습 역학:
    - learning_rate: 현재 학습률
    - grad_norm: 그래디언트 노름 (폭발/소실 감지)
    - epoch: 현재 에포크
 
  시스템 자원:
    - GPU 메모리 사용량
    - GPU 활용률
    - 학습 속도 (samples/sec)

조기 종료 (Early Stopping)

검증 손실이 더 이상 개선되지 않으면 학습을 중단하여 과적합을 방지합니다.

python
from transformers import EarlyStoppingCallback
 
trainer = SFTTrainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=val_dataset,
    callbacks=[
        EarlyStoppingCallback(
            early_stopping_patience=3,
            early_stopping_threshold=0.01
        )
    ],
)
text
조기 종료 설정 가이드:
 
  patience (인내심):
    - 검증 손실이 개선되지 않는 연속 평가 횟수
    - 너무 작으면 학습이 조기에 중단될 수 있음
    - 권장: 3~5회
 
  threshold (임계값):
    - 개선으로 인정하는 최소 변화량
    - 너무 높으면 미세한 개선을 놓침
    - 권장: 0.001~0.01

하이퍼파라미터 탐색 전략

최적의 하이퍼파라미터 조합을 찾기 위한 체계적인 탐색 방법을 소개합니다.

수동 탐색 가이드

text
하이퍼파라미터 탐색 순서:
 
  1단계: 학습률 탐색 (가장 중요)
    - 후보: [5e-5, 1e-4, 2e-4, 5e-4]
    - 1 에포크만 학습하여 빠르게 비교
    - train_loss 감소 속도와 eval_loss 확인
 
  2단계: LoRA 랭크 결정
    - 후보: [8, 16, 32, 64]
    - 최적 학습률에서 비교
    - 성능과 메모리의 균형점 선택
 
  3단계: 배치 크기 조정
    - 후보: [8, 16, 32]
    - 학습률을 배치 크기에 비례하여 조정
 
  4단계: 에포크 수 결정
    - 후보: [1, 2, 3, 5]
    - 검증 손실의 수렴 시점 확인

Optuna를 활용한 자동 탐색

python
import optuna
from transformers import TrainingArguments
from trl import SFTTrainer
 
 
def objective(trial):
    """Optuna 목적 함수"""
 
    # 탐색 공간 정의
    lr = trial.suggest_float("learning_rate", 5e-5, 5e-4, log=True)
    lora_r = trial.suggest_categorical("lora_r", [8, 16, 32, 64])
    lora_alpha = lora_r * 2  # alpha = 2 * r 규칙
    batch_size = trial.suggest_categorical("batch_size", [8, 16, 32])
    warmup_ratio = trial.suggest_float("warmup_ratio", 0.03, 0.15)
    weight_decay = trial.suggest_float("weight_decay", 0.0, 0.1)
 
    # LoRA 설정
    from peft import LoraConfig as PeftLoraConfig
    lora_config = PeftLoraConfig(
        r=lora_r,
        lora_alpha=lora_alpha,
        target_modules="all-linear",
        lora_dropout=0.05,
        task_type="CAUSAL_LM",
    )
 
    # 모델 로드 및 설정 (매 trial마다)
    model = load_base_model()
    model = get_peft_model(model, lora_config)
 
    # 학습 실행
    training_args = TrainingArguments(
        output_dir="./optuna-trial-" + str(trial.number),
        num_train_epochs=1,  # 탐색 시에는 1 에포크
        per_device_train_batch_size=batch_size // 8,
        gradient_accumulation_steps=8,
        learning_rate=lr,
        warmup_ratio=warmup_ratio,
        weight_decay=weight_decay,
        eval_strategy="epoch",
        logging_steps=50,
        bf16=True,
    )
 
    trainer = SFTTrainer(
        model=model,
        args=training_args,
        train_dataset=train_dataset,
        eval_dataset=val_dataset,
    )
 
    result = trainer.train()
    eval_result = trainer.evaluate()
 
    return eval_result["eval_loss"]
 
 
# Optuna 스터디 실행
study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=20)
 
print("최적 하이퍼파라미터: " + str(study.best_params))
print("최적 검증 손실: " + str(study.best_value))

분산 학습 기초

다중 GPU 환경에서 학습 속도를 높이는 기본적인 분산 학습 설정을 소개합니다.

Accelerate 활용

python
# accelerate_config.yaml
# accelerate config 명령으로 생성 가능
bash
# 단일 GPU 학습
python train.py
 
# 다중 GPU 학습 (DDP)
accelerate launch --multi_gpu --num_processes 4 train.py
 
# DeepSpeed ZeRO Stage 2
accelerate launch --use_deepspeed \
    --deepspeed_config_file ds_config.json \
    train.py
text
분산 학습 전략:
 
  DDP (DistributedDataParallel):
    - 각 GPU에 모델 복사본을 두고 데이터 병렬 처리
    - 간단하고 안정적
    - 모델이 단일 GPU에 올라갈 때 적합
 
  FSDP (Fully Sharded Data Parallel):
    - 모델 파라미터, 그래디언트, 옵티마이저 상태를 GPU 간 분할
    - 큰 모델에 적합
    - 설정이 복잡
 
  DeepSpeed ZeRO:
    - Stage 1: 옵티마이저 상태 분할
    - Stage 2: 옵티마이저 + 그래디언트 분할
    - Stage 3: 전체 분할 (FSDP와 유사)
    - Offloading: CPU/NVMe로 데이터 이전 가능

체크포인트 관리

학습 도중 모델 상태를 저장하여 학습 재개, 최적 모델 선택 등을 가능하게 합니다.

python
training_args = TrainingArguments(
    save_strategy="steps",
    save_steps=200,
    save_total_limit=3,           # 최근 3개만 유지
    load_best_model_at_end=True,  # 최적 모델 자동 로드
    metric_for_best_model="eval_loss",
    greater_is_better=False,
)
text
체크포인트 전략:
 
  save_strategy="steps" + save_steps=200:
    - 200 스텝마다 저장
    - 긴 학습에서 중간 상태 보존에 유용
 
  save_strategy="epoch":
    - 에포크 완료마다 저장
    - 짧은 학습에 적합
 
  save_total_limit=3:
    - 디스크 공간 절약
    - 최근 N개만 유지
 
  load_best_model_at_end=True:
    - 학습 종료 시 최적 체크포인트 자동 로드
    - eval_loss 기준으로 최적 모델 선택

학습 재개

python
# 체크포인트에서 학습 재개
trainer.train(resume_from_checkpoint="./output/checkpoint-400")

전체 학습 스크립트

지금까지의 모든 요소를 통합한 완성된 학습 스크립트입니다.

python
# train.py
import torch
from datasets import load_dataset
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    TrainingArguments,
    EarlyStoppingCallback,
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from trl import SFTTrainer
import wandb
 
 
def main():
    # 1. wandb 초기화
    wandb.init(project="fine-tuning-guide")
 
    # 2. 모델 로드
    bnb_config = BitsAndBytesConfig(
        load_in_4bit=True,
        bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=torch.bfloat16,
        bnb_4bit_use_double_quant=True,
    )
 
    model = AutoModelForCausalLM.from_pretrained(
        "meta-llama/Llama-3.1-8B-Instruct",
        quantization_config=bnb_config,
        device_map="auto",
        attn_implementation="flash_attention_2",
    )
    model = prepare_model_for_kbit_training(
        model, use_gradient_checkpointing=True
    )
 
    tokenizer = AutoTokenizer.from_pretrained(
        "meta-llama/Llama-3.1-8B-Instruct"
    )
    if tokenizer.pad_token is None:
        tokenizer.pad_token = tokenizer.eos_token
 
    # 3. LoRA 설정
    lora_config = LoraConfig(
        r=32,
        lora_alpha=64,
        target_modules="all-linear",
        lora_dropout=0.05,
        task_type="CAUSAL_LM",
    )
    model = get_peft_model(model, lora_config)
    model.print_trainable_parameters()
 
    # 4. 데이터 로드
    dataset = load_dataset("json", data_files={
        "train": "data/train.jsonl",
        "validation": "data/val.jsonl",
    })
 
    # 5. 학습 설정
    training_args = TrainingArguments(
        output_dir="./output",
        num_train_epochs=3,
        per_device_train_batch_size=2,
        gradient_accumulation_steps=8,
        learning_rate=2e-4,
        lr_scheduler_type="cosine",
        warmup_ratio=0.1,
        weight_decay=0.01,
        max_grad_norm=0.3,
        logging_steps=10,
        save_strategy="steps",
        save_steps=200,
        eval_strategy="steps",
        eval_steps=200,
        save_total_limit=3,
        load_best_model_at_end=True,
        metric_for_best_model="eval_loss",
        bf16=True,
        gradient_checkpointing=True,
        gradient_checkpointing_kwargs={"use_reentrant": False},
        optim="paged_adamw_8bit",
        report_to="wandb",
        seed=42,
    )
 
    # 6. 트레이너 설정 및 학습
    trainer = SFTTrainer(
        model=model,
        args=training_args,
        train_dataset=dataset["train"],
        eval_dataset=dataset["validation"],
        tokenizer=tokenizer,
        max_seq_length=2048,
        packing=True,
        callbacks=[
            EarlyStoppingCallback(early_stopping_patience=3)
        ],
    )
 
    trainer.train()
 
    # 7. 최적 모델 저장
    trainer.save_model("./best-adapter")
    wandb.finish()
 
 
if __name__ == "__main__":
    main()

정리

이번 장에서는 학습 파이프라인의 전체 구조와 하이퍼파라미터 최적화 전략을 다루었습니다.

  • 설정 관리, 실험 추적, 체크포인트 관리 등 재현 가능한 학습 파이프라인의 핵심 요소를 설계했습니다.
  • 학습률, 배치 크기, 워밍업 등 주요 하이퍼파라미터의 역할과 권장 값을 정리했습니다.
  • wandb를 활용한 모니터링과 Optuna를 활용한 자동 탐색 방법을 소개했습니다.
  • 전체 요소를 통합한 완성된 학습 스크립트를 제공했습니다.

다음 장에서는 파인튜닝된 모델의 성능을 객관적으로 평가하고 벤치마킹하는 방법을 다룹니다. 자동 평가 메트릭, 인간 평가, A/B 비교 등 다각적인 평가 전략을 체계적으로 안내합니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#llm#training#mlops#data-engineering

관련 글

AI / ML

7장: 파인튜닝 모델 평가와 벤치마킹

파인튜닝된 모델의 성능을 자동 메트릭, LLM 평가, 인간 평가를 통해 다각적으로 측정하고 벤치마킹하는 체계적인 방법을 다룹니다.

2026년 1월 26일·16분
AI / ML

5장: QLoRA로 소비자 GPU에서 파인튜닝하기

4비트 양자화와 LoRA를 결합한 QLoRA의 원리를 이해하고, 단일 소비자 GPU에서 대규모 모델을 파인튜닝하는 실전 방법을 다룹니다.

2026년 1월 22일·14분
AI / ML

8장: 모델 레지스트리와 버전 관리

파인튜닝된 모델을 체계적으로 관리하기 위한 모델 레지스트리 구축, 버전 관리, 메타데이터 추적, 아티팩트 저장 전략을 다룹니다.

2026년 1월 28일·15분
이전 글5장: QLoRA로 소비자 GPU에서 파인튜닝하기
다음 글7장: 파인튜닝 모델 평가와 벤치마킹

댓글

목차

약 18분 남음
  • 학습 파이프라인의 전체 구조
  • 설정 관리
  • 학습률 (Learning Rate) 전략
    • 권장 학습률 범위
    • 학습률 스케줄러
    • 워밍업 (Warmup)
  • 배치 크기 전략
    • 배치 크기에 따른 학습 역학
  • 실험 추적과 모니터링
    • Weights & Biases (wandb) 통합
    • 모니터링해야 할 핵심 지표
    • 조기 종료 (Early Stopping)
  • 하이퍼파라미터 탐색 전략
    • 수동 탐색 가이드
    • Optuna를 활용한 자동 탐색
  • 분산 학습 기초
    • Accelerate 활용
  • 체크포인트 관리
    • 학습 재개
  • 전체 학습 스크립트
  • 정리