| # SFT ๋ฐ์ดํฐ ํ์ง ๊ฐ์ฌ ๋ณด๊ณ ์ |
|
|
| **๋ ์ง:** 2026-02-26 |
| **๋ฐ์ดํฐ:** `data/sft/train.jsonl` (159,125 ์ํ) |
| **์์ค:** 6๊ฐ HuggingFace ๋ฐ์ดํฐ์
(KOR-OpenOrca-Platypus-v3, kullm-v2, ko-alpaca-12k, korean_safe_conversation, evol-instruct-korean, kovast) |
|
|
| --- |
|
|
| ## 1. ๋ฐ์ดํฐ ๊ธฐ๋ณธ ํต๊ณ |
|
|
| | ํญ๋ชฉ | ๊ฐ | |
| |------|-----| |
| | ์ด ์ํ ์ | 159,125 | |
| | Output ํ๊ท ๊ธธ์ด | 608 chars | |
| | Output ์ค์๊ฐ | 468 chars | |
| | Output ์ต์/์ต๋ | 10 / 7,393 chars | |
| | ์ค๋ณต (instruction+output) | 0 (dedup ์ ์ฉ๋จ) | |
| | ์ค๋ณต (instruction only) | 0 | |
|
|
| ### Output ๊ธธ์ด ๋ถํฌ |
|
|
| | ๊ตฌ๊ฐ | ์๋ | ๋น์จ | |
| |------|------|------| |
| | < 50 chars | 16,519 | 10.4% | |
| | 50-100 | 11,112 | 7.0% | |
| | 100-500 | 55,550 | 34.9% | |
| | 500-1000 | 47,023 | 29.6% | |
| | 1000-2000 | 23,731 | 14.9% | |
| | 2000-4000 | 5,049 | 3.2% | |
| | > 4000 | 141 | 0.1% | |
|
|
| --- |
|
|
| ## 2. ๋ฐ๊ฒฌ๋ ํ์ง ๋ฌธ์ |
|
|
| ### ๐ด ์ฌ๊ฐ (๋ฐ๋ณต ๋ฃจํ ์ง์ ์์ธ ๊ฐ๋ฅ์ฑ) |
|
|
| #### ๋ฌธ์ 1: ํน์ ํ ํฐ ์ค์ผ โ `</s>` 113๊ฑด |
| - Output ํ
์คํธ ์์ `</s>` ๋ฌธ์์ด์ด ๋ฆฌํฐ๋ด๋ก ํฌํจ๋ ์ํ 113๊ฑด |
| - **์ํฅ:** ํ์ต ์ chat template์ด `{output}</s>`๋ฅผ ๋ถ์ด๋ฏ๋ก, output ๋ด๋ถ์ `</s>`๋ premature EOS๋ฅผ ํ์ต์ํด. ์ดํ ๋ชจ๋ธ์ด EOS๋ฅผ ์ ๋๋ก ์์ฑํ์ง ๋ชปํ๊ฑฐ๋, EOS ์ดํ์๋ ๊ณ์ ์์ฑํ๋ ํจํด์ ํ์ต |
| - ๊ธฐํ: `<|endoftext|>` 1๊ฑด, `EOS` 44๊ฑด, `[PAD]` 3๊ฑด |
|
|
| #### ๋ฌธ์ 2: Output ๋ด ์ง๋ฌธ/๋ต๋ณ ๋ง์ปค โ ์ฝ 550๊ฑด |
| - `"์ง๋ฌธ:"` 503๊ฑด, `"๋ต๋ณ:"` 430๊ฑด (output ๋ด๋ถ) |
| - `"### ๋ต๋ณ:"` 141๊ฑด, `"### ์ง๋ฌธ:"` 10๊ฑด |
| - `"### Instruction:"` 4๊ฑด, `"### Response:"` 2๊ฑด |
| - **์ํฅ:** ๋ชจ๋ธ์ด ๋ต๋ณ ์ค์ "์ง๋ฌธ:" โ "๋ต๋ณ:" ํจํด์ ํ์ตํ์ฌ ์์ฒด์ ์ผ๋ก Q/A ๋ฃจํ๋ฅผ ์์ฑ |
|
|
| #### ๋ฌธ์ 3: Self-repetition ํจํด โ 57๊ฑด |
| - 10-gram ๊ธฐ์ค 50% ์ด์ ๋ฐ๋ณต๋๋ output 57๊ฑด |
| - **์ํฅ:** ๋ฐ๋ณต ์์ฑ ํจํด์ ์ง์ ํ์ต |
|
|
| ### ๐ก ์ค๊ฐ (ํ์ง ์ ํ) |
|
|
| #### ๋ฌธ์ 4: ์งง์ Output โ 16,519๊ฑด (10.4%) |
| - 50์ ๋ฏธ๋ง output์ด ์ ์ฒด์ 10.4% |
| - 30์ ๋ฏธ๋ง์ 8,833๊ฑด |
| - **์ํฅ:** ๋ชจ๋ธ์ด ์ถฉ๋ถํ ๊ธด ๋ต๋ณ์ ์์ฑํ๋ ๋ฅ๋ ฅ ์ ํ. ์งง๊ฒ ๋๋ด์ผ ํ ๊ณณ์์ EOS๋ฅผ ๋ฐฐ์ฐ์ง๋ง, ๋๋ถ๋ถ์ ์ง๋ฌธ์์๋ ๋๋ฌด ์งง์ ๋ต๋ณ โ EOS ๋ฏธ์์ฑ โ ๊ณ์ ์์ฑ โ ๋ฃจํ |
|
|
| #### ๋ฌธ์ 5: ๋ฎ์ ํ๊ตญ์ด ๋น์จ โ 21,774๊ฑด (13.7%) |
| - ํ๊ธ ๋ฌธ์ ๋น์จ 30% ๋ฏธ๋ง์ธ ์ํ (์ฝ๋, ์์ด, ์ค๊ตญ์ด ๋ฑ ํผ์ฌ) |
| - `prepare_sft_data.py`์ ํํฐ๊ฐ ์ด๋ฏธ 30% ๊ธฐ์ค์ ์ ์ฉํ์ง๋ง, ๊ฐ์ค์น ์ํ๋ง ์ดํ ์ ์ฉ ์์ ๋ฌธ์ ๊ฐ๋ฅ์ฑ |
| - **์ํฅ:** ํ๊ตญ์ด LLM์ผ๋ก์์ ์ผ๊ด์ฑ ์ ํ |
|
|
| --- |
|
|
| ## 3. ๊ฐ์ค ๊ฒ์ฆ ๊ฒฐ๊ณผ |
|
|
| ### ๊ฐ์ค A: Output์ Q/A ๋ฃจํ ํจํด ์กด์ฌ โ โ ๏ธ ๋ถ๋ถ ํ์ธ |
| - `### ์ง๋ฌธ: ... ### ๋ต๋ณ:` ์ ํํ ํจํด: **4๊ฑด** (0.003%) |
| - `์ง๋ฌธ: ... ๋ต๋ณ:` ๋น๊ณต์ ํจํด: **119๊ฑด** (0.07%) |
| - ๋จ์ "์ง๋ฌธ:" ๋๋ "๋ต๋ณ:" ํฌํจ: **~550๊ฑด** |
| - **๊ฒฐ๋ก :** ์ ํํ ๋ฃจํ ํจํด์ ๊ทน์์์ด๋, "์ง๋ฌธ/๋ต๋ณ" ํค์๋๊ฐ output์ ํฌํจ๋ ์ํ์ด ์๋ฐฑ ๊ฑด ์กด์ฌ. ์ด๊ฒ๋ง์ผ๋ก ๋ฃจํ์ ์ฃผ ์์ธ์ด๋ผ ๋ณด๊ธฐ ์ด๋ ค์. |
|
|
| ### ๊ฐ์ค B: ์งง์ Output โ โ
์ ๋ ฅ ์์ธ |
| - 50์ ๋ฏธ๋ง 16,519๊ฑด (10.4%)์ด output ๋ถํฌ์ ์๋น ๋ถ๋ถ |
| - ๋ชจ๋ธ์ด ์งง์ ๋ต๋ณ ํ EOS๋ฅผ ์์ฑํ์ง ๋ชปํ๊ณ ๊ณ์ ํ ํฐ์ ์์ฑํ ๊ฐ๋ฅ์ฑ |
| - **ํนํ `</s>` ํ ํฐ ์ค์ผ(113๊ฑด)๊ณผ ๊ฒฐํฉํ๋ฉด:** ๋ชจ๋ธ์ด EOS ๊ฒฝ๊ณ๋ฅผ ์ ํํ ํ์ตํ์ง ๋ชปํจ |
|
|
| ### ๊ฐ์ค C: ์์ค๋ณ ํ์ง ํธ์ฐจ โ โ
ํ์ธ (๊ฐ์ ) |
| - `prepare_sft_data.py` ๊ธฐ์ค: KOR-OpenOrca-Platypus-v3 **5๋ฐฐ ์
์ํ๋ง**, kovast **0.8๋ฐฐ ๋ค์ด์ํ๋ง** |
| - ๊ฐ์ค์น๊ฐ ๋งค์ฐ ๊ณต๊ฒฉ์ (5.0๋ฐฐ๋ ๋์ผ ๋ฐ์ดํฐ 5ํ ๋ฐ๋ณต = ๊ณผ์ ํฉ ์ํ) |
| - kovast๋ ๋ฉํฐํด ๋ํ์์ ์ฒซ ํด๋ง ์ถ์ถ โ ๋ฌธ๋งฅ ๋ถ์กฑ์ผ๋ก ์ด์ํ output ๊ฐ๋ฅ |
| - **๊ฒฐ๋ก :** 5๋ฐฐ ์
์ํ๋ง๋ OpenOrca-Platypus๊ฐ ์ฃผ ํ์ต ๋ฐ์ดํฐ๋ฅผ ์ง๋ฐฐ. ํด๋น ์์ค์ ๋ฌธ์ ๊ฐ ์์ผ๋ฉด ์ ์ฒด ๋ชจ๋ธ์ ์ง์ ์ํฅ. |
|
|
| ### ๐ ์ถ๊ฐ ๋ฐ๊ฒฌ: ๋ฐ๋ณต ๋ฃจํ์ ์ง์ง ์์ธ ์ถ์ |
| **EOS ํ์ต ์คํจ๊ฐ ํต์ฌ.** ์์ธ ์กฐํฉ: |
| 1. Output ๋ด `</s>` ๋ฆฌํฐ๋ด (113๊ฑด) โ EOS ๊ฒฝ๊ณ ํผ๋ |
| 2. ์งง์ output 10.4% โ EOS ํ์ด๋ฐ ํ์ต ๋ถ์์ |
| 3. 5000 steps๋ก 159K ๋ฐ์ดํฐ ํ์ต โ ๊ฐ ์ํ ํ๊ท 1.6 epoch๋ ์ ๋จ โ underfitting ๊ฐ๋ฅ |
| 4. **inference ์ repetition_penalty ๋ฏธ์ ์ฉ** (eval ์ฝ๋์๋ top_p/top_k๋ง ์๊ณ repetition_penalty ์์) |
| |
| --- |
| |
| ## 4. ์ฆ์ ์ ์ฉ ๊ฐ๋ฅํ ๋ฐ์ดํฐ ํํฐ๋ง ์ฝ๋ |
| |
| ```python |
| """ |
| enhanced_quality_filter.py โ SFT ๋ฐ์ดํฐ ํ์ง ๊ฐํ ํํฐ |
| Usage: python enhanced_quality_filter.py data/sft/train.jsonl data/sft/train_cleaned.jsonl |
| """ |
| import json |
| import re |
| import sys |
| |
| def enhanced_filter(sample: dict) -> bool: |
| instruction = sample.get("instruction", "").strip() |
| output = sample.get("output", "").strip() |
| |
| # 1. ๊ธฐ๋ณธ ๊ธธ์ด ํํฐ (๊ฐํ) |
| if len(output) < 80: # 50 โ 80์ผ๋ก ์ํฅ |
| return False |
| if len(output) > 3000: # 4000 โ 3000์ผ๋ก ํํฅ |
| return False |
| if len(instruction) < 15: |
| return False |
| |
| # 2. ํน์ ํ ํฐ ์ ๊ฑฐ |
| BAD_TOKENS = ["</s>", "<|endoftext|>", "<|end|>", "<s>", "<pad>", "[PAD]", "<unk>"] |
| for tok in BAD_TOKENS: |
| if tok in output: |
| return False |
| |
| # 3. Q/A ๋ง์ปค ์ค์ผ ์ ๊ฑฐ |
| QA_PATTERNS = [ |
| r"###\s*(์ง๋ฌธ|๋ต๋ณ|Instruction|Response|Input|Output)\s*:", |
| r"^(์ง๋ฌธ|๋ต๋ณ)\s*:", # ์ค ์์์์ "์ง๋ฌธ:" "๋ต๋ณ:" |
| ] |
| for pat in QA_PATTERNS: |
| if re.search(pat, output, re.MULTILINE): |
| return False |
| |
| # 4. ํ๊ตญ์ด ๋น์จ ๊ฐํ (30% โ 40%) |
| ko_chars = sum(1 for c in output if '\uac00' <= c <= '\ud7a3') |
| if len(output) > 0 and ko_chars / len(output) < 0.4: |
| return False |
| |
| # 5. N-gram ๋ฐ๋ณต ํํฐ (๊ฐํ) |
| words = output.split() |
| if len(words) > 15: |
| # 5-gram ๋ฐ๋ณต ์ฒดํฌ |
| fivegrams = [tuple(words[i:i+5]) for i in range(len(words) - 4)] |
| if fivegrams: |
| unique_ratio = len(set(fivegrams)) / len(fivegrams) |
| if unique_ratio < 0.7: # 30% ์ด์ ๋ฐ๋ณต์ด๋ฉด ์ ๊ฑฐ |
| return False |
| |
| # 6. "EOS" ๋ฆฌํฐ๋ด ์ ๊ฑฐ |
| if re.search(r'\bEOS\b', output): |
| return False |
| |
| return True |
| |
| |
| def main(): |
| input_path = sys.argv[1] |
| output_path = sys.argv[2] |
| |
| kept, dropped = 0, 0 |
| with open(input_path) as fin, open(output_path, "w") as fout: |
| for line in fin: |
| sample = json.loads(line) |
| if enhanced_filter(sample): |
| fout.write(line) |
| kept += 1 |
| else: |
| dropped += 1 |
| |
| print(f"Kept: {kept:,} | Dropped: {dropped:,} | Drop rate: {dropped/(kept+dropped)*100:.1f}%") |
| |
| |
| if __name__ == "__main__": |
| main() |
| ``` |
| |
| --- |
| |
| ## 5. ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ๊ฐ์ ๊ถ์ฅ์ฌํญ |
| |
| ### 5.1 ๊ฐ์ค์น ์ฌ์กฐ์ |
| |
| ํ์ฌ ๊ฐ์ค์น๊ฐ ๋๋ฌด ๊ณต๊ฒฉ์ . ๊ถ์ฅ ๋ณ๊ฒฝ: |
| |
| ```python |
| DATASET_WEIGHTS = { |
| "KOR-OpenOrca-Platypus-v3": 2.0, # 5.0 โ 2.0 (๊ณผ์ ํฉ ๋ฐฉ์ง) |
| "kullm-v2": 1.0, |
| "ko-alpaca-12k": 1.5, # 2.0 โ 1.5 |
| "korean_safe_conversation": 1.0, # 1.5 โ 1.0 |
| "evol-instruct-korean": 1.5, |
| "kovast": 0.5, # 0.8 โ 0.5 (ํ์ง ์ด์) |
| } |
| ``` |
| |
| ### 5.2 ํ์ต ์ค์ ์์ |
| |
| ```bash |
| # ํ์ฌ: 5000 steps, batch 4ร8ร2 = 64 |
| # 159K samples / 64 = 2,486 steps/epoch โ ํ์ฌ ์ฝ 2 epochs |
| |
| # ๊ถ์ฅ: ํํฐ๋ง ํ ~120K ๋ฐ์ดํฐ๋ก 3 epochs |
| MAX_STEPS=6000 |
| ``` |
| |
| ### 5.3 Inference ์ repetition_penalty ์ถ๊ฐ |
| |
| ```python |
| # eval/comprehensive_eval.py ์์ |
| repetition_penalty = 1.2 # ๋ฐ๋ณต ์ต์ |
| ``` |
| |
| --- |
| |
| ## 6. ์ถ์ฒ ๊ณ ํ์ง ๋ฐ์ดํฐ์
(HuggingFace) |
| |
| | ๋ฐ์ดํฐ์
| URL | ์ค๋ช
| ์์ ํฌ๊ธฐ | |
| |----------|-----|------|-----------| |
| | Open-Orca Korean | `kyujinpy/KOR-OpenOrca-Platypus-v3` | ์ด๋ฏธ ์ฌ์ฉ ์ค | - | |
| | ShareGPT Korean | `junelee/sharegpt_deepl_ko` | ShareGPT ํ๊ตญ์ด ๋ฒ์ญ | ~90K | |
| | KoAlpaca v1.1 | `beomi/KoAlpaca-v1.1a` | ๊ณ ํ์ง ํ๊ตญ์ด Alpaca | ~21K | |
| | LIMA Korean | `HAERAE-HUB/KMMLU` | ํ๊ตญ์ด ๋ฒค์น๋งํฌ (ํ๊ฐ์ฉ) | - | |
| | Korean HC3 | `heegyu/korean_chatgpt_corpus` | ChatGPT ํ๊ตญ์ด ๋ํ | ~12K | |
| | Orca DPO Korean | `kyujinpy/orca_dpo_pairs_ko` | DPO ํ์ด (SFT+DPO ๊ฐ๋ฅ) | ~12K | |
| | OpenHermes 2.5 Ko | `maywell/ko_Ultrafeedback_binarized` | ํ๊ตญ์ด Ultrafeedback | ~60K | |
| | KOpen-platypus | `kyujinpy/KOpen-platypus` | ํ๊ตญ์ด Platypus | ~25K | |
| |
| **๊ฐ์ฅ ์ถ์ฒํ๋ ์ถ๊ฐ ๋ฐ์ดํฐ:** |
| 1. `junelee/sharegpt_deepl_ko` โ ๋ค์ํ ์ฃผ์ ์ ๋ฉํฐํด ๋ํ, ์ถฉ๋ถํ ๊ธด output |
| 2. `heegyu/korean_chatgpt_corpus` โ ChatGPT ํ์ง ํ๊ตญ์ด ๋ต๋ณ |
| 3. `beomi/KoAlpaca-v1.1a` โ ๊ฒ์ฆ๋ ํ๊ตญ์ด instruction ๋ฐ์ดํฐ |
| |
| --- |
| |
| ## 7. ์์ฝ: ์ฆ์ ์กฐ์น ์ฌํญ |
| |
| | ์ฐ์ ์์ | ์กฐ์น | ์์ ํจ๊ณผ | |
| |----------|------|-----------| |
| | ๐ด P0 | `</s>`, `<|endoftext|>`, `EOS` ํฌํจ ์ํ ์ ๊ฑฐ (161๊ฑด) | EOS ํ์ต ํผ๋ ํด์ | |
| | ๐ด P0 | Output ์ต์ ๊ธธ์ด 80์๋ก ์ํฅ | ์งง์ ๋ต๋ณ์ผ๋ก ์ธํ EOS ๋ฏธํ์ต ๋ฐฉ์ง | |
| | ๐ด P0 | Inference์ `repetition_penalty=1.2` ์ถ๊ฐ | ์ฆ์ ๋ฐ๋ณต ๋ฃจํ ์ํ | |
| | ๐ก P1 | Q/A ๋ง์ปค ํฌํจ ์ํ ์ ๊ฑฐ (~550๊ฑด) | ์์ฒด Q/A ๋ฃจํ ํจํด ํ์ต ๋ฐฉ์ง | |
| | ๐ก P1 | OpenOrca ๊ฐ์ค์น 5.0 โ 2.0 | ๊ณผ์ ํฉ ๋ฐฉ์ง, ๋ค์์ฑ ํ๋ณด | |
| | ๐ก P1 | ํ๊ตญ์ด ๋น์จ ํํฐ 40%๋ก ๊ฐํ | ํ๊ตญ์ด ์ผ๊ด์ฑ ํฅ์ | |
| | ๐ข P2 | ์ถ๊ฐ ๊ณ ํ์ง ๋ฐ์ดํฐ์
์์ง | ์ ๋ฐ์ ํ์ง ํฅ์ | |
| | ๐ข P2 | Self-repetition ํํฐ ๊ฐํ (5-gram, 70% threshold) | ๋ฐ๋ณต ํจํด ์์ฒ ์ฐจ๋จ | |
| |
| **์์ ํํฐ๋ง ํ ๋ฐ์ดํฐ:** ~120,000-130,000 ์ํ (ํ์ฌ ๋๋น 18-25% ์ ๊ฑฐ) |
|
|