> EulerStack > 튜토리얼 > 6. Sanity 훈련 루프

6. Sanity 훈련 루프

⚠️ 범위 경고 — 본 훈련은 다른 도구로 하세요

EulerStack 은 훈련 프레임워크가 아닙니다. 이 장에서 소개하는 "Sanity 훈련" 은 "새 mixer / 새 primitive 를 추가했을 때 아키텍처가 구조적으로 무너지지 않았는지 30 초 안에 확인하는 회귀 스모크 테스트" 입니다. 그 이상이 아닙니다.

실제 LLM 훈련 — 즉 수 시간~수 주 단위 pretrain, SFT, RLHF — 에 절대 이 헬퍼를 쓰지 마세요. 이유는 여기에 누락된 것들이 너무 많기 때문입니다.

EulerStack Sanity 훈련에 없는 것들

기능 없는 이유
Distributed training (DDP / FSDP / TP / PP) 전용 런처가 필요 → accelerate / Megatron
Gradient accumulation, mixed precision scaler GradScaler 표준 구현 없음
LR scheduler (warmup + cosine, WSD 등) 한 AdamW + 고정 LR 뿐
Gradient clipping, weight decay 세부 튜닝 프로덕션 레시피 없음
Checkpointing, resume, best-model 선택 20-step 만 돌고 끝
Eval 루프, validation loss, perplexity 트래킹 최소 로그만 출력
Data sampling 가중치, curriculum, multi-dataset 혼합 단일 JSONL 만
RLHF (PPO/DPO/GRPO), SFT 특화 포맷팅 전부 없음
WandB / TensorBoard / MLflow 통합 없음
HPO (Optuna, Ray Tune) 없음
모델 merging, pruning, quantisation-aware training 없음

이 목록을 보면 알 수 있듯, "훈련이 된다" 는 말은 두 가지 매우 다른 의미를 갖습니다.

이 장은 오직 전자입니다.

실제 훈련에 권장하는 도구

EulerStack YAML 로 export 한 모델은 표준 HF PreTrainedModel 이므로 아래 어떤 도구와도 그대로 연동됩니다. 목적별 권장:

사용 사례 도구 한 줄 설명
Pretraining (단일~수노드) HF Trainer, Composer, Levanter DDP / FSDP / mixed precision 표준
Pretraining (HPC, 수백~수천 GPU) TorchTitan, Megatron-LM, GPT-NeoX 3D parallelism, activation checkpointing, ZeRO
SFT / Fine-tune Axolotl, LLaMA-Factory, torchtune chat template, packing, QLoRA 지원
Parameter-efficient PEFT, bitsandbytes, Unsloth LoRA / QLoRA / IA³ / adapters
RLHF / 선호도 학습 TRL, OpenRLHF, Axolotl-GRPO PPO / DPO / IPO / GRPO / RLOO
실전 HPO Optuna, Ray Tune bayesian / multi-objective
실험 추적 Weights & Biases, MLflow, ClearML metrics + artifact + run compare

권장 워크플로:

YAML 스펙 (EulerStack)
    │  compile → save_pretrained
    ▼
HF 모델 디렉토리 (표준)
    │  AutoModelForCausalLM.from_pretrained(..., trust_remote_code=True)
    ▼
Axolotl / Megatron / HF Trainer / TRL / torchtune / ... (선택)
    │
    ▼
훈련된 모델

EulerStack 은 맨 위 칸 만 맡습니다.

자세한 포지셔닝은 튜토리얼 0: EulerStack 의 자리 를 참조.


여기서부터는 — 내부 Sanity 회귀 테스트 설명

아래의 내용은 EulerStack 저장소 자체의 CI 에서만 쓰이는 스모크 테스트 설명 입니다. 새 mixer 나 primitive 를 추가했을 때 다음 질문에 빠르게 답하기 위한 헬퍼입니다.

  1. 구조가 이어지는가 — forward 가 shape-consistent 하게 끝나는가.
  2. grad 가 유한한가 — backward 후 NaN/Inf 가 나오지 않는가.
  3. loss 가 감소하는 신호를 보이는가 — 20 step 기준 monotone 은 아니어도 descent trend 가 있는가.

이 세 가지만 확인되면 "이 YAML 이 HF 트레이너에 붙을 자격이 있다" 는 선언 가능. 이 이상 의 질문 (실제 품질, 수렴 후 지표, scale-up 안정성) 은 이 루프로 답하지 않습니다.

두 가지 Sanity 모드

EulerStack 은 두 가지 Sanity 모드를 제공합니다. 상황에 따라 골라 씁니다.

CPU 기반 빠른 Sanity

GPU 가 없거나 CI 환경에서 돌리는 용도입니다. 모델 크기를 축소한 sanity 변형 으로 같은 토폴로지를 유지하되 파라미터 수만 ~50K 수준으로 줄여 CPU 에서 수 초 안에 끝나게 만듭니다.

from eulerstack.training.sanity import build_sanity_model, run_sanity_training
from eulerstack.data.prepare import TokenizedDataset
import torch

# 같은 topology, 작은 스케일 모델
model = build_sanity_model(
    vocab_size=256, d_model=64, n_heads=4, n_layers=4, max_seq_len=64,
)

# 간단한 패턴 데이터 (실제 텍스트 대신)
data = TokenizedDataset(torch.arange(0, 32).unsqueeze(0).repeat(128, 1))

result = run_sanity_training(
    model, data, batch_size=16, max_steps=50, seed=42,
)
print(result.summary())

정상 출력 예시는 다음과 같습니다.

Sanity training: PASS
  Steps: 50
  Initial loss: 5.5432
  Final loss: 3.1201
  Loss decreased: True

이 모드는 아키텍처 구현이 근본적으로 깨지지 않았는지 를 확인하는 smoke test 입니다. 새로 믹서나 블록을 추가했을 때 가장 먼저 돌려보는 단계라고 생각하면 됩니다.

GPU 기반 E2E Sanity (실제 프리셋)

실제 프리셋(0.8B 이상)을 GPU 에 올려 dolma 데이터로 짧게 훈련하는 모드입니다. 프로덕션 설정에 가장 가까운 검증입니다.

import yaml, torch
from eulerstack.ir.normalizer import normalize_to_ir
from eulerstack.training.sanity import build_model_from_ir, run_e2e_training
from eulerstack.data.prepare import tokenize_jsonl, TokenizedDataset

# 프리셋 로드
with open("configs/presets/arch_advanced_jamba.yml") as f:
    ir = normalize_to_ir(yaml.safe_load(f))

# GPU 에 모델 빌드
model = build_model_from_ir(ir, device="cuda:1", dtype=torch.bfloat16)

# 데이터 준비 (캐시 활용)
raw = tokenize_jsonl(
    jsonl_path="data/dolma_10k.jsonl",
    tokenizer_name="gpt2",
    max_seq_len=512,
    num_rows=1000,
)
dataset = TokenizedDataset(raw.input_ids, vocab_size=ir.model.vocab_size)

# 20 스텝 훈련
result = run_e2e_training(
    model, dataset,
    batch_size=2, lr=1e-4, max_steps=20,
    device="cuda:1", use_amp=True, seed=42,
)
print(result.summary())

이 모드가 통과하면 해당 프리셋은 본 훈련에 들어갈 준비가 됐다고 볼 수 있습니다.

pytest 로 통합 실행

위 두 모드를 스크립트가 아닌 pytest 테스트로 실행할 수도 있습니다. 게이트 환경변수와 옵션이 함께 준비되어 있어 CI 나 개발 중 회귀 테스트에 바로 쓸 수 있습니다.

# 0.8B 이하 llm_ 프리셋 전체 (simple / mistral / jamba / moe × 2 크기 = 8개)
RUN_LLM_E2E=1 python -m pytest tests/integration/llm_e2e/ --llm-presets=all -v -s

# 17 개 arch_ 프리셋 전체
RUN_ARCH_E2E=1 python -m pytest tests/integration/arch_e2e/ --arch-presets=all -v -s

# 6 개 expert_mini 프리셋 전체
RUN_EXPERT_MINI_E2E=1 python -m pytest tests/integration/expert_mini_e2e/ --mini-presets=all -v -s

# 커스텀 스텝 수와 학습률
RUN_ARCH_E2E=1 python -m pytest tests/integration/arch_e2e/ \
    --arch-steps=50 --arch-lr=1e-4 -v -s

# GPU 지정 (기본값은 cuda:1)
RUN_ARCH_E2E=1 EULERSTACK_DEVICE=cuda:0 python -m pytest tests/integration/arch_e2e/ -v -s

각 게이트 변수(RUN_LLM_E2E, RUN_ARCH_E2E, RUN_EXPERT_MINI_E2E)가 설정되어 있어야 테스트가 실행됩니다. 미설정 시에는 SKIPPED 로 표시되며, 이유 메시지에 어떤 변수를 설정해야 하는지 나옵니다.

각 통합 테스트의 자세한 설명은 별도 문서에서 다룹니다.

풀 프리셋과 Sanity 변형 비교

두 모드의 차이를 한 표로 요약하면 다음과 같습니다.

항목 풀 프리셋 Sanity 변형
d_model 1024–2048 64
vocab_size 32000 256
파라미터 0.8B–2B 이상 약 50K
하드웨어 GPU 필수 CPU, 5 초 이내
목적 프로덕션 검증 아키텍처 smoke 테스트

개발 주기로 보자면, 코드를 수정한 직후에는 CPU sanity 로 빠르게 확인하고, 그 다음에 GPU E2E sanity 를 한 번 돌린 뒤, 마지막으로 본 훈련에 들어가는 것이 합리적인 순서 입니다.

Sanity 통과 후 — 실제 훈련으로 가는 경로

Sanity 가 통과하면 EulerStack 의 일은 끝납니다. 여기서부터는 외부 훈련 도구의 영역입니다.

# Step 1: EulerStack YAML 을 표준 HF 디렉토리로 export
eulerstack compile \
    --preset configs/presets/arch_advanced_jamba.yml \
    --output-dir ./my_model

# Step 2: 이제부터는 외부 트레이너 사용 — 예시 몇 가지:

# (A) Axolotl 로 SFT
accelerate launch -m axolotl.cli.train axolotl_config.yaml
# axolotl_config.yaml 안에 base_model: ./my_model

# (B) HF Trainer 로 간단한 pretrain
python train_with_hf_trainer.py \
    --model_name_or_path ./my_model \
    --dataset_name wikitext \
    --dataset_config wikitext-2-raw-v1 \
    --do_train --per_device_train_batch_size 2

# (C) TRL 로 DPO
python train_dpo.py --model ./my_model --dataset anthropic/hh-rlhf

# (D) TorchTitan / Megatron 분산 사전학습은 각 도구의 공식 레시피 참고

export 된 모델은 표준 HuggingFace PreTrainedModel 이므로 PEFT, TRL, vLLM, TGI, SGLang, TensorRT-LLM 등 HF 계약을 소비하는 모든 도구 에 그대로 들어갑니다.

다음 단계