| # SFT ํ์ต ์์ธ ์ํฉ ํ๋ ์ด๋ถ | |
| **ํ๋ก์ ํธ:** Korean 1B SFT ์ฌํ์ต | |
| **์๋ฒ:** 8ร B200 183GB, Driver 580.95.05, CUDA 13.1, PyTorch 2.10 | |
| **์์ฑ์ผ:** 2026-02-26 | |
| **์ค์ :** bs=4 ร 8GPU ร grad_accum=2 = effective batch 64, max_steps=10000, lr=2e-5, FP8 | |
| --- | |
| ## ์๋๋ฆฌ์ค 1: Loss๊ฐ 0์ผ๋ก ๋จ์ด์ง๋ ๊ฒฝ์ฐ | |
| ### ๊ฐ์ง ๊ธฐ์ค | |
| - **์ฆ๊ฐ ๊ฒฝ๊ณ :** loss < 0.01์ด 3 step ์ฐ์ ๋ฐ์ | |
| - **์ฃผ์:** loss < 0.1์ด 10 step ์ด์ ์ง์ | |
| - **์ ์ ๋ฒ์:** 1B SFT์์ ์๋ ด ์ loss โ 1.5~2.0. 0์ ๊ฐ๊น์ฐ๋ฉด 100% ๋น์ ์ | |
| ### ์ฆ๊ฐ ๋์ | |
| 1. ํ์ต ์ฆ์ ์ค๋จ (Ctrl+C ๋๋ `kill -SIGINT <PID>`) | |
| 2. ๊ฐ์ฅ ์ต๊ทผ ์ ์ ์ฒดํฌํฌ์ธํธ ํ์ธ: | |
| ```bash | |
| ls -lt checkpoints/korean_1b_sft/checkpoint-* | head -5 | |
| ``` | |
| ### ์์ธ๋ณ ์ง๋จ ๋ฐ ๋์ | |
| #### 1-A. Labels Shift ๋ฒ๊ทธ ์ฌ๋ฐ | |
| **ํ์ธ ๋ฐฉ๋ฒ:** | |
| ```python | |
| # ๋ฐ์ดํฐ์์ ์ํ ํ๋ ๋ก๋ ํ labels ๊ฒ์ฆ | |
| from data.sft_dataset import SFTDataset | |
| from tokenizers import Tokenizer | |
| tok = Tokenizer.from_file("tokenizer/korean_sp/tokenizer.json") | |
| ds = SFTDataset("data/sft/train.jsonl", tok, max_seq_len=4096) | |
| ids, labels = ds[0] | |
| # labels์์ -1์ด ์๋ ๋ถ๋ถ์ด input_ids์ ๋ค์ ํ ํฐ๊ณผ ์ผ์นํ๋์ง ํ์ธ | |
| mask = labels != -1 | |
| print(f"์ ํจ labels ์: {mask.sum()}") | |
| print(f"์ฒซ ์ ํจ label ์์น: {mask.nonzero()[0].item() if mask.any() else 'NONE'}") | |
| # labels[i]๋ input_ids[i+1]๊ณผ ๊ฐ์์ผ ํจ (autoregressive) | |
| # ๋ง์ฝ labels == input_ids ์ด๋ฉด shift ์ ๋จ โ ๋ฒ๊ทธ | |
| ``` | |
| **์์ :** `sft_dataset.py`์์ `labels = input_ids[1:]`, `input_ids = input_ids[:-1]` shift ํ์ธ | |
| #### 1-B. ๋ฐ์ดํฐ ์ค์ผ | |
| **ํ์ธ ๋ฐฉ๋ฒ:** | |
| ```python | |
| # ๋๋ค ๋ฐฐ์น์์ ์ค์ ํ์ต ํ ํฐ ๊ฒ์ฌ | |
| for batch in train_loader: | |
| ids, labels, mask = batch | |
| valid = (labels != -1) | |
| print(f"์ ํจ ํ ํฐ ๋น์จ: {valid.float().mean():.4f}") | |
| # ์ ํจ ํ ํฐ์ด 0์ด๋ฉด ๋ชจ๋ labels๊ฐ -1 โ loss=0 | |
| if valid.sum() == 0: | |
| print("๐ด ๋ชจ๋ labels๊ฐ ignore_index! ๋ฐ์ดํฐ ๋ฌธ์ ") | |
| break | |
| ``` | |
| **๋์:** ๋ฐ์ดํฐ ์ฌ์์ฑ, `prepare_sft_data.py` ์ฌ์คํ | |
| #### 1-C. Learning Rate ๋ฌธ์ | |
| **ํ์ธ:** loss๊ฐ ๊ฐ์๊ธฐ 0์ด๋ฉด lr ๋ฌธ์ ๋ณด๋ค๋ labels ๋ฒ๊ทธ์ผ ๊ฐ๋ฅ์ฑ์ด ํจ์ฌ ๋์. ๊ทธ๋๋ ํ์ธ: | |
| ```bash | |
| grep "lr " checkpoints/korean_1b_sft/train.log | tail -20 | |
| # lr์ด ๋น์ ์์ ์ผ๋ก ๋์ผ๋ฉด (>1e-3) ์์ | |
| ``` | |
| --- | |
| ## ์๋๋ฆฌ์ค 2: Loss Spike (๊ธ๋ฑ) | |
| ### ๊ฐ์ง ๊ธฐ์ค | |
| - **Spike ์ ์:** ์ด์ log_interval ํ๊ท ๋๋น **3๋ฐฐ ์ด์** ๊ธ๋ฑ | |
| - **์:** ํ๊ท loss 1.9์์ ๊ฐ์๊ธฐ 5.7 ์ด์ | |
| - **GNorm ๊ธฐ์ค:** grad_norm > 10.0์ด๋ฉด ์ฃผ์, > 50.0์ด๋ฉด ์ฌ๊ฐ | |
| ### ์์ธ๋ณ ๋์ | |
| | ์์ธ | ์ง๋จ | ๋์ | | |
| |------|------|------| | |
| | Bad batch (์ด์ ๋ฐ์ดํฐ) | ํด๋น step์ ๋ฐฐ์น ๋ด์ฉ ํ์ธ | 1~2ํ spike ํ ์์ฐ ๋ณต๊ตฌ๋๋ฉด ๋ฌด์ | | |
| | LR ๋ฌธ์ | warmup ์งํ spike โ lr ๋๋ฌด ๋์ | lr์ 1e-5๋ก ๋ฎ์ถ๊ณ ์ฌ์์ | | |
| | GNorm ํญ๋ฐ | gnorm > 50 | max_grad_norm์ 0.5๋ก ๊ฐํ | | |
| | FP8 ์์น ๋ถ์์ | FP8 ๊ด๋ จ warning ํ์ธ | `--use_fp8` ์ ๊ฑฐํ๊ณ BF16์ผ๋ก ์ ํ | | |
| ### ๋์ ์ ์ฐจ | |
| 1. **1ํ spike:** ๋ฌด์ (๋จ๋ฐ์ฑ bad batch). ๋ค์ log์์ ๋ณต๊ตฌ ํ์ธ | |
| 2. **์ฐ์ 3ํ spike:** ํ์ต ์ค๋จ | |
| 3. **๋ณต๊ตฌ ๋ฐฉ๋ฒ:** | |
| ```bash | |
| # ๋ง์ง๋ง ์ ์ ์ฒดํฌํฌ์ธํธ์์ ์ฌ์์, lr ๋ฎ์ถ๊ธฐ | |
| bash scripts/launch_sft.sh --resume checkpoints/korean_1b_sft/checkpoint-XXXX --lr 1e-5 | |
| ``` | |
| ### ํ์ฌ ์ฝ๋์ ๋ณดํธ ์ฅ์น | |
| - โ `max_grad_norm=1.0` (gradient clipping ํ์ฑํ) | |
| - โ Non-finite loss ๊ฐ์ง โ RuntimeError ๋ฐ์ (trainer.py `_step()`) | |
| - โ Loss spike ์๋ ๊ฐ์ง/skip์ ๋ฏธ๊ตฌํ โ `monitor_training.sh`๋ก ๋ณด์ | |
| --- | |
| ## ์๋๋ฆฌ์ค 3: ๊ณผ์ ํฉ (val_loss > train_loss ์ง์) | |
| ### ๊ฐ์ง ๊ธฐ์ค | |
| - **์ฃผ์:** val_loss - train_loss > 0.15 (์๋๊ฐญ 8% ์ด์) | |
| - **์ฌ๊ฐ:** val_loss๊ฐ 3ํ ์ฐ์ eval์์ ์์น (train_loss๋ ํ๊ฐ ์ค) | |
| - **eval_interval:** ํ์ฌ 250 steps โ ๋งค 250 step๋ง๋ค val_loss ๊ธฐ๋ก๋จ | |
| ### ํ์ฌ ์ฝ๋ ์ํ | |
| - โ `val_loader` ์ง์ (sft.py์์ `--val_data` ์ธ์ ์์) | |
| - โ `_run_validation()` ๊ตฌํ๋จ (trainer.py) | |
| - โ Best checkpoint ์๋ ์ ์ฅ (`val_loss < self._best_val_loss`) | |
| - โ **Early stopping ๋ฏธ๊ตฌํ** โ val_loss๊ฐ ์ฌ๋ผ๋ max_steps๊น์ง ํ์ต ๊ณ์ | |
| ### ๋์ | |
| #### ์ฆ์ ๊ฐ๋ฅํ ์กฐ์น | |
| 1. **์๋ early stop:** ๋ชจ๋ํฐ๋ง ์คํฌ๋ฆฝํธ๊ฐ ๊ฒฝ๊ณ โ ์๋ ์ค๋จ | |
| 2. **Best checkpoint ์ฌ์ฉ:** `checkpoint-best` ๋๋ ํ ๋ฆฌ์ ์๋ ์ ์ฅ๋จ | |
| ```bash | |
| ls checkpoints/korean_1b_sft/checkpoint-best/ | |
| ``` | |
| #### ๊ณผ์ ํฉ ํด์ ๋ฐฉ๋ฒ (์ฌํ์ต ์) | |
| | ๋ฐฉ๋ฒ | ์ค์ ๋ณ๊ฒฝ | | |
| |------|-----------| | |
| | LR ๋ฎ์ถ๊ธฐ | `--lr 1e-5` | | |
| | Weight decay ๋์ด๊ธฐ | `--weight_decay 0.05` | | |
| | ๋ฐ์ดํฐ augmentation | NEFTune ์ด๋ฏธ ํ์ฑํ (noise_alpha=10.0) โ | | |
| | Steps ์ค์ด๊ธฐ | `--max_steps 7000` (๊ณผ์ ํฉ ์์ ์ step์์ ๋ฉ์ถค) | | |
| | Dropout | ๋ชจ๋ธ ๊ตฌ์กฐ ์์ ํ์ (ํ์ฌ ์ฝ๋์์ ์ฝ์ง ์์) | | |
| #### Early Stopping ์ถ๊ฐ ๋ฐฉ๋ฒ (trainer.py ์์ ) | |
| ```python | |
| # trainer.py์ train() ๋ฉ์๋์์ validation ํ: | |
| if val_loss > self._best_val_loss: | |
| self._patience_counter += 1 | |
| if self._patience_counter >= 5: # 5ํ ์ฐ์ ๊ฐ์ ์์ผ๋ฉด ์ค๋จ | |
| self._log("Early stopping triggered") | |
| break | |
| else: | |
| self._patience_counter = 0 | |
| self._best_val_loss = val_loss | |
| ``` | |
| --- | |
| ## ์๋๋ฆฌ์ค 4: OOM (Out of Memory) | |
| ### ํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์ถ์ | |
| | ํญ๋ชฉ | ์ถ์ | | |
| |------|------| | |
| | ๋ชจ๋ธ ํ๋ผ๋ฏธํฐ (1.19B, BF16) | ~2.4 GB | | |
| | ์ตํฐ๋ง์ด์ ์ํ (AdamW, fp32) | ~9.5 GB | | |
| | Gradient (BF16) | ~2.4 GB | | |
| | Activation (bs=4, seq=4096, gradient checkpointing ON) | ~8-15 GB | | |
| | **Peak ์ดํฉ (per GPU)** | **~25-35 GB** | | |
| | **B200 ์ฌ์ ** | **183 - 35 = ~148 GB ์ฌ์ ** | | |
| โ 1B ๋ชจ๋ธ์์ OOM ๊ฐ๋ฅ์ฑ **๊ทนํ ๋ฎ์** | |
| ### ๋ง์ฝ ๋ฐ์ํ๋ค๋ฉด | |
| 1. **์ฆ์:** `torch.cuda.OutOfMemoryError` โ trainer.py์์ ์ด๋ฏธ catchํ์ฌ ์์ธ ๋ฉ์์ง ์ถ๋ ฅ | |
| 2. **์ฆ์ ๋์:** | |
| ```bash | |
| # batch_size ์ค์ด๊ธฐ (4โ2), grad_accum ๋๋ฆฌ๊ธฐ (2โ4) โ effective batch ๋์ผ | |
| bash scripts/launch_sft.sh --batch_size 2 --grad_accum 4 --resume <last_ckpt> | |
| ``` | |
| 3. **Gradient checkpointing:** | |
| - โ **์ด๋ฏธ ํ์ฑํ๋จ** (sft.py์์ `model.gradient_checkpointing_enable()`) | |
| 4. **์ถ๊ฐ ์กฐ์น:** | |
| ```bash | |
| # ๋ฉ๋ชจ๋ฆฌ fragmentation ๋ฐฉ์ง | |
| export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True | |
| ``` | |
| ### ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ํฐ๋ง | |
| ```bash | |
| watch -n 5 nvidia-smi # ์ค์๊ฐ ํ์ธ | |
| # ๋๋ monitor_training.sh ์ฌ์ฉ (์๋ ์ฐธ์กฐ) | |
| ``` | |
| --- | |
| ## ์๋๋ฆฌ์ค 5: GPU Hang / NCCL ํต์ ์ฅ์ | |
| ### ๊ฐ์ง ๋ฐฉ๋ฒ | |
| - **์ฆ์:** ํ์ต ๋ก๊ทธ๊ฐ ๋ฉ์ถค (์ step์ด N๋ถ ์ด์ ์ ๋์ด) | |
| - **NCCL timeout:** ๊ธฐ๋ณธ 30๋ถ ํ ์๋ฌ ๋ฐ์ | |
| - `nvidia-smi`์์ ํน์ GPU utilization 0% | |
| ### ์ง๋จ | |
| ```bash | |
| # 1. GPU ์ํ ํ์ธ | |
| nvidia-smi | |
| # 2. NCCL ๋๋ฒ๊ทธ ํ์ฑํํ์ฌ ์ฌ์์ | |
| export NCCL_DEBUG=INFO | |
| export NCCL_DEBUG_SUBSYS=ALL | |
| # 3. ํ๋ก์ธ์ค ์ํ ํ์ธ | |
| ps aux | grep torchrun | |
| ``` | |
| ### ๋ณต๊ตฌ ๋ฐฉ๋ฒ | |
| ```bash | |
| # 1. ๊ธฐ์กด ํ๋ก์ธ์ค ์ ๋ฆฌ | |
| pkill -f torchrun | |
| sleep 5 | |
| # 2. ๊ฐ์ฅ ์ต๊ทผ ์ฒดํฌํฌ์ธํธ ์๋ ๊ฐ์ง | |
| LATEST_CKPT=$(ls -d checkpoints/korean_1b_sft/checkpoint-* 2>/dev/null \ | |
| | grep -v best | sort -t- -k2 -n | tail -1) | |
| echo "Latest checkpoint: ${LATEST_CKPT}" | |
| # 3. ์ฌ์์ | |
| bash scripts/launch_sft.sh --resume "${LATEST_CKPT}" | |
| ``` | |
| ### ์ต๊ทผ ์ฒดํฌํฌ์ธํธ ์๋ ๊ฐ์ง ์คํฌ๋ฆฝํธ | |
| ```bash | |
| #!/bin/bash | |
| # find_latest_checkpoint.sh | |
| CKPT_DIR="${1:-checkpoints/korean_1b_sft}" | |
| LATEST=$(ls -d "${CKPT_DIR}"/checkpoint-[0-9]* 2>/dev/null \ | |
| | sort -t- -k2 -n | tail -1) | |
| if [[ -z "$LATEST" ]]; then | |
| echo "No checkpoint found in ${CKPT_DIR}" >&2 | |
| exit 1 | |
| fi | |
| echo "$LATEST" | |
| ``` | |
| ### ์๋ฐฉ | |
| - `save_interval=500` (ํ์ฌ ์ค์ ) โ ์ต๋ 500 step ์์ค | |
| - NCCL timeout ์กฐ์ : `export NCCL_TIMEOUT=1800` (30๋ถ โ ํ์ ์ ์ค์ด๊ธฐ) | |
| --- | |
| ## ์๋๋ฆฌ์ค 6: ํ์ต ์๋ฃ ํ ๋ฐ๋ณต๋ฅ >15% | |
| ### ํ๋จ ๊ธฐ์ค | |
| | ๋ฐ๋ณต๋ฅ | ํ๋จ | ๋์ | | |
| |--------|------|------| | |
| | <5% (rep_penalty ์์ด) | โ ์ฑ๊ณต | ๋ฐฐํฌ ๊ฐ๋ฅ | | |
| | 5-10% | ๐ก OK | rep_penalty=1.1๋ก ๋ฐฐํฌ | | |
| | 10-20% | ๐ ๊ฒฝ๊ณ | ์๋ ํ๋ผ๋ฏธํฐ ์กฐ์ ์๋ | | |
| | >20% | ๐ด ์คํจ | ์ฌํ์ต ํ์ | | |
| ### ํ๋ผ๋ฏธํฐ ์กฐ์ ์ผ๋ก ํด๊ฒฐ ์๋ (์ฌํ์ต ์์ด) | |
| ```python | |
| # ์ถ๋ก ์ ์ ์ฉ | |
| generate_kwargs = { | |
| "repetition_penalty": 1.1, # 1.05~1.2 ๋ฒ์ ํ์ | |
| "no_repeat_ngram_size": 3, # 3-gram ๋ฐ๋ณต ์ฐจ๋จ | |
| "temperature": 0.7, # ์ฝ๊ฐ ๋ฎ์ถ๋ฉด ๋ฐ๋ณต ๊ฐ์ | |
| "top_p": 0.9, | |
| } | |
| ``` | |
| ### ์ฌํ์ต์ด ํ์ํ ๊ฒฝ์ฐ | |
| - rep_penalty=1.2 + no_repeat_3gram์์๋ >10% | |
| - ์์ธ ๋ถ์: | |
| 1. **๋ฐ์ดํฐ ๋ด ๋ฐ๋ณต ํจํด:** `data_quality_audit.py`๋ก ์ฌํ์ธ | |
| 2. **Epoch ๊ณผ๋ค:** 5+ epoch์ ๋ฐ๋ณต ํจํด ์๊ธฐ ์ ๋ฐ โ 3-4 epoch์ด ์ ์ | |
| 3. **EOS ํ์ต ๋ถ์กฑ:** truncation ์ EOS ์์ค ์ฌ๋ถ ํ์ธ | |
| ### ๊ณ ๊ธ ๋์ (์ถ๊ฐ ํ์ต ๋ฐฉ๋ฒ) | |
| | ๋ฐฉ๋ฒ | ์ค๋ช | ์์ | | |
| |------|------|------| | |
| | ORPO | Preference optimization, ๋ฐ๋ณต ํจํด ์ง์ penalize | +3-6์๊ฐ | | |
| | DPO | Chosen(๋น๋ฐ๋ณต) vs Rejected(๋ฐ๋ณต) ์ ํ์ | +4-8์๊ฐ | | |
| | rep_penalty fine-tuning | ์ถ๋ก ์ penalty ๊ฒฐ๊ณผ๋ฅผ reward๋ก RL | ๋ณต์ก | | |
| --- | |
| ## ์๋๋ฆฌ์ค 7: ko_ifeval ๊ธฐ๋์น ๋ฏธ๋ฌ (<15%) | |
| ### ์์ธ ๋ถ์ ๋ฐฉ๋ฒ | |
| #### Step 1: ๋ชจ๋ธ ์ถ๋ ฅ ์ง์ ํ์ธ | |
| ```bash | |
| # ko_ifeval ์คํจ ์ํ ๋ถ์ | |
| python -c " | |
| # lm_eval ๊ฒฐ๊ณผ์์ ์คํจ ์ผ์ด์ค ์ถ์ถ | |
| # ์ง์๋ฌธ ์ดํด ๋ถ์กฑ vs ํฌ๋งท ์ค๋ฅ vs ํ๊ตญ์ด ๋ฅ๋ ฅ ๋ถ์กฑ ๊ตฌ๋ถ | |
| " | |
| ``` | |
| #### Step 2: ์นดํ ๊ณ ๋ฆฌ๋ณ ๋ถ์ | |
| | ์คํจ ์ ํ | ์๋ฏธ | ๋์ | | |
| |-----------|------|------| | |
| | ์ง์ ๋ฌด์ (wrong format) | instruction following ์ฝํจ | SFT ๋ฐ์ดํฐ์ format-constrained ์ํ ์ถ๊ฐ | | |
| | ํ๊ตญ์ด ์ดํด ์คํจ | ํ๊ตญ์ด ๋ฅ๋ ฅ ๋ถ์กฑ | ํ๊ตญ์ด ๋น์จ ๋์ด๊ธฐ (ํ์ฌ ~70%) | | |
| | ์ถ๋ก ์ค๋ฅ | 1B ๋ชจ๋ธ ํ๊ณ | ๋ชจ๋ธ ํฌ๊ธฐ ํ๊ณ โ 3B ์ ํ | | |
| #### Step 3: ๋ชจ๋ธ ํ๊ณ vs ๋ฐ์ดํฐ ๋ฌธ์ ๊ตฌ๋ถ | |
| ``` | |
| 1B ๋ชจ๋ธ ko_ifeval ํ์ค์ ๋ฒ์: 15-30% | |
| - <15%: ๋ฐ์ดํฐ/ํ์ต ๋ฌธ์ ๊ฐ๋ฅ์ฑ ๋์ | |
| - 15-25%: ์ ์ ๋ฒ์, ๋ฐ์ดํฐ๋ก ๊ฐ์ ์ฌ์ง ์์ | |
| - 25-30%: 1B ํ๊ณ์ ๊ทผ์ , 3B ์ ํ ํ์ | |
| - >30%: 1B์์ ๋ฌ์ฑํ๊ธฐ ์ด๋ ค์ | |
| ``` | |
| ### ๋ฐ์ดํฐ ์ถ๊ฐ ์์ง ๋ฐฉํฅ | |
| 1. **Korean instruction-following ๋ฐ์ดํฐ:** KoAlpaca, KULLM ๋ฑ์์ format-constrained ์ํ | |
| 2. **Multi-turn ํ๊ตญ์ด ๋ํ:** ์ง์ ๋ฐ๋ฅด๊ธฐ ๋ฅ๋ ฅ ๊ฐํ | |
| 3. **ko_ifeval๊ณผ ์ ์ฌํ ํฌ๋งท ๋ฐ์ดํฐ:** "~ํ์์ผ๋ก ๋ตํ์์ค" ์ ํ | |
| --- | |
| ## ์๋๋ฆฌ์ค 8: ๋์คํฌ ๊ณต๊ฐ ๋ถ์กฑ | |
| ### ํ์ฌ ์ํ | |
| ``` | |
| /PROJECT: 3.5TB ์ด, 1.4TB ์ฌ์ฉ, 2.2TB ๊ฐ์ฉ (39% ์ฌ์ฉ) | |
| ``` | |
| ### ์ฒดํฌํฌ์ธํธ ํฌ๊ธฐ ์ถ์ | |
| | ํญ๋ชฉ | ํฌ๊ธฐ | | |
| |------|------| | |
| | model.pt (1.19B BF16) | ~2.4 GB | | |
| | optimizer.pt (AdamW states) | ~9.5 GB | | |
| | scheduler + meta | ~1 MB | | |
| | **์ฒดํฌํฌ์ธํธ 1๊ฐ** | **~12 GB** | | |
| | 10,000 steps / 500 save = 20๊ฐ | **~240 GB** | | |
| | + best checkpoint | +12 GB | | |
| | + tensorboard logs | ~100 MB | | |
| | **์ด ์์** | **~252 GB** | | |
| โ 2.2TB ๊ฐ์ฉ ๋๋น ์ถฉ๋ถํ์ง๋ง, ์ฌ๋ฌ ์คํ ์ ๋์ ์ฃผ์ | |
| ### ์ฒดํฌํฌ์ธํธ ๊ด๋ฆฌ ์ ๋ต | |
| #### ์ ์ฅ ์ฃผ๊ธฐ ์ต์ ํ | |
| - **ํ์ฌ:** 500 step๋ง๋ค (์ถ์ฒ ์ ์ง) | |
| - ๋์คํฌ ๋ถ์กฑ ์: 1000 step์ผ๋ก ๋ณ๊ฒฝ โ 120 GB๋ก ์ ๋ฐ ๊ฐ์ | |
| - `train_config.save_interval = 1000` | |
| #### ์ค๋๋ ์ฒดํฌํฌ์ธํธ ์๋ ์ญ์ | |
| ```bash | |
| #!/bin/bash | |
| # cleanup_checkpoints.sh โ ์ต์ N๊ฐ๋ง ์ ์ง, best๋ ํญ์ ๋ณด์กด | |
| CKPT_DIR="${1:-checkpoints/korean_1b_sft}" | |
| KEEP="${2:-5}" # ์ต์ 5๊ฐ ์ ์ง | |
| CKPTS=$(ls -d "${CKPT_DIR}"/checkpoint-[0-9]* 2>/dev/null | sort -t- -k2 -n) | |
| TOTAL=$(echo "$CKPTS" | wc -l) | |
| DELETE=$((TOTAL - KEEP)) | |
| if [[ $DELETE -gt 0 ]]; then | |
| echo "$CKPTS" | head -n "$DELETE" | while read ckpt; do | |
| echo "Removing: $ckpt" | |
| rm -rf "$ckpt" | |
| done | |
| echo "Kept latest $KEEP checkpoints + checkpoint-best" | |
| else | |
| echo "Only $TOTAL checkpoints, nothing to delete (keep=$KEEP)" | |
| fi | |
| ``` | |
| ### ๋์คํฌ ๋ชจ๋ํฐ๋ง | |
| ```bash | |
| # ํ์ต ์ค ์ฃผ๊ธฐ์ ํ์ธ | |
| df -h /PROJECT | awk 'NR==2 {if ($5+0 > 80) print "๐ด DISK >80%: "$5}' | |
| ``` | |
| --- | |
| ## ํ์ต ์ฌ์์ ๊ฐ์ด๋ | |
| ### ํ์ฌ ์ฝ๋์ Resume ์ง์ | |
| โ **์์ ์ง์๋จ:** | |
| - `sft.py`์ `--resume` ์ธ์ ์์ | |
| - `load_checkpoint()`์ผ๋ก model, optimizer, scheduler ์ํ ๋ชจ๋ ๋ณต์ | |
| - `start_step` ๋ฐํ โ ์ด์ด์ ํ์ต | |
| ### ์ฌ์์ ๋ช ๋ น์ด | |
| ```bash | |
| # ๋ฐฉ๋ฒ 1: ์ต์ ์ฒดํฌํฌ์ธํธ์์ ์๋ ์ฌ์์ | |
| LATEST=$(ls -d checkpoints/korean_1b_sft/checkpoint-[0-9]* 2>/dev/null \ | |
| | sort -t- -k2 -n | tail -1) | |
| bash scripts/launch_sft.sh --resume "${LATEST}" | |
| # ๋ฐฉ๋ฒ 2: ํน์ ์ฒดํฌํฌ์ธํธ ์ง์ | |
| bash scripts/launch_sft.sh --resume checkpoints/korean_1b_sft/checkpoint-0003000 | |
| # ๋ฐฉ๋ฒ 3: LR ๋ณ๊ฒฝํ๋ฉฐ ์ฌ์์ (๊ณผ์ ํฉ/spike ๋์) | |
| bash scripts/launch_sft.sh --resume "${LATEST}" --lr 1e-5 | |
| ``` | |
| ### ์ฃผ์์ฌํญ | |
| - **cosine schedule:** resume ์ scheduler๊ฐ ์ค๊ฐ step์์ ๋ณต์๋จ โ LR์ด ์ฌ๋ฐ๋ฅธ ์์น์์ ์ฌ๊ฐ | |
| - **max_steps ๋ณ๊ฒฝ ์:** ์๋ 5000 step ๊ธฐ์ค schedule์ธ๋ฐ 10000์ผ๋ก ๋ณ๊ฒฝํ๋ฉด LR curve๊ฐ ๋ฌ๋ผ์ง โ ์ฒ์๋ถํฐ ์ฌํ์ต ๊ถ์ฅ | |
| - **DDP seed:** resume ์ ๋์ผ seed ์ฌ์ฉํด์ผ ๋ฐ์ดํฐ ์์ ์ฌํ (ํ์ฌ ์ฝ๋์์ ์๋ ์ฒ๋ฆฌ) | |
| --- | |
| ## ๋ชจ๋ํฐ๋ง ์๋ํ | |
| ๋ณ๋ ์คํฌ๋ฆฝํธ: `scripts/monitor_training.sh` ์ฐธ์กฐ | |
| ### ๊ฐ์ ํญ๋ชฉ ์์ฝ | |
| | ํญ๋ชฉ | ์๊ณ๊ฐ | ์๋ฏธ | | |
| |------|--------|------| | |
| | loss = 0.0000 (3 step ์ฐ์) | ๐ด Critical | Labels ๋ฒ๊ทธ | | |
| | loss spike (3ร ํ๊ท ) | ๐ Warning | Bad batch / LR | | |
| | gnorm > 10.0 | ๐ Warning | ๋ถ์์ | | |
| | gnorm > 50.0 | ๐ด Critical | ๋ฐ์ฐ ์ง์ | | |
| | GPU util < 50% | ๐ก Info | ๋ณ๋ชฉ (data loading?) | | |
| | ๋ก๊ทธ 5๋ถ ์ด์ ๋ฉ์ถค | ๐ด Critical | Hang / NCCL ์ฅ์ | | |
| | ๋์คํฌ ์ฌ์ฉ > 80% | ๐ Warning | ์ฒดํฌํฌ์ธํธ ์ ๋ฆฌ ํ์ | | |
| --- | |
| ## ์ํ๋ ์์ (๋์ โ ๋ฎ์) | |
| | ์์ | ์๋๋ฆฌ์ค | ์ํ๋ | ์๋ฐฉ | | |
| |------|----------|--------|------| | |
| | 1 | **Loss โ 0 (Labels ๋ฒ๊ทธ)** | ๐ด๐ด๐ด | ํ์ต ์ labels shift ๊ฒ์ฆ ์คํฌ๋ฆฝํธ ์คํ | | |
| | 2 | **GPU Hang (NCCL)** | ๐ด๐ด | save_interval=500, NCCL ํ๊ฒฝ๋ณ์ ์ค์ | | |
| | 3 | **๊ณผ์ ํฉ** | ๐ด | val_data ํ์, ๋ชจ๋ํฐ๋ง | | |
| | 4 | **๋ฐ๋ณต๋ฅ >15%** | ๐ ๐ | ๊นจ๋ํ ๋ฐ์ดํฐ, ์ ์ epoch | | |
| | 5 | **Loss Spike** | ๐ | grad_clip=1.0, ์ด๋ฏธ ์ค์ ๋จ | | |
| | 6 | **ko_ifeval ๋ฏธ๋ฌ** | ๐ | 1B ํ๊ณ ์ธ์ง, ๋ฐ์ดํฐ ๋ค์์ฑ | | |
| | 7 | **๋์คํฌ ๋ถ์กฑ** | ๐ก | 2.2TB ์ฌ์ , ์๋ ์ ๋ฆฌ | | |
| | 8 | **OOM** | ๐ข | 183GB์ 1B ๋ชจ๋ธ, ๊ฑฐ์ ๋ถ๊ฐ๋ฅ | | |
| --- | |
| ## ํ์ต ์ ์ฒดํฌ๋ฆฌ์คํธ | |
| ``` | |
| โก ๋ฐ์ดํฐ ํํฐ๋ง ์๋ฃ (data_quality_audit.py) | |
| โก Val split ์์ฑ (90/10) | |
| โก Labels shift ๊ฒ์ฆ (์ ์ฝ๋ ์ค๋ํซ ์คํ) | |
| โก sft_dataset.py ์์ ํ์ธ (dynamic padding, EOS ๋ณด์กด) | |
| โก launch_sft.sh ์ค์ ํ์ธ (max_steps, val_data, lr) | |
| โก ๋์คํฌ ๊ณต๊ฐ ํ์ธ (df -h /PROJECT) | |
| โก GPU ์ํ ํ์ธ (nvidia-smi) | |
| โก monitor_training.sh ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ | |
| โก tensorboard ์คํ: tensorboard --logdir checkpoints/korean_1b_sft/tensorboard | |
| ``` | |