๋ฉํ ๋ ํผ๋๋ฐฑ: "llama-ccp + GGUF Qunatization"
LoRA ๋ณํฉ -> llama-ccp ๋น๋ -> GGUF (f16) ๋ณํ -> Unsloth ์ถ์ฒ ์์ํ UD-Q4_K_XL ๋๋ Q4_K_M -> mmproj Unsloth ๊ณต์์์ ๊ฐ์ ธ์ด LoRA ๊ฐ ๋น์ ๋ ์ด์ด ๊ฑด๋ค์ด์ง์์ -> ์๋น
ํ๊ตญ ์๋ฌผ ํด์ถฉ ํ์ง๊ธฐ โ Qwen3.5-9B LoRA
unsloth/Qwen3.5-9B์ ํ์ธํ๋ํ ๋น์ -์ธ์ด LoRA ์ด๋ํฐ๋ก, ์๋ฌผ ์ฌ์ง์์ ํ๊ตญ ๋์๋ฌผ ํด์ถฉ์ ์๋ณํฉ๋๋ค. ์, ๊ณผ์ค, ์๋ฌผ ์ ์ฒด ์ฌ์ง์ ๋ฃ์ผ๋ฉด ํด์ถฉ์ ํ๊ตญ์ด ์ด๋ฆ์ ์ถ๋ ฅํ๊ณ , ํด์ถฉ์ด ์์ผ๋ฉด ์ ์์ ์ถ๋ ฅํฉ๋๋ค.
- 19๊ฐ ํด๋์ค ๋ถ๋ฅ๊ธฐ: ํด์ถฉ 18์ข + "์ ์"(ํด์ถฉ ์์)
- ๋ฒ ์ด์ค ๋ชจ๋ธ:
unsloth/Qwen3.5-9B(๋น์ -์ธ์ด, ํ์ด๋ธ๋ฆฌ๋ linear + self attention) - ์ด๋ํฐ ์ ํ: LoRA (PEFT), rank 64, alpha 128
- ์ธ์ด: ํ๊ตญ์ด
- ํฌ๊ธฐ: ์ด๋ํฐ ๊ฐ์ค์น 660 MB
์ฑ๋ฅ
Himedia-AI-01/pest-detection-korean์ ๊ฒ์ฆ ์ธํธ ์ ์ฒด 1,595๊ฐ ์ํ๋ก ํ๊ฐํ ๊ฒฐ๊ณผ์ ๋๋ค.
| ์งํ | ์ ์ |
|---|---|
| ์ ํ๋ (Accuracy) | 91.36% |
| F1 (๋งคํฌ๋ก) | 90.32% |
| F1 (๊ฐ์ค) | 91.34% |
| ์ ๋ฐ๋ (๋งคํฌ๋ก) | 90.88% |
| ์ฌํ์จ (๋งคํฌ๋ก) | 91.01% |
| ์ ๋ฐ๋ (๊ฐ์ค) | 92.40% |
| ์ฌํ์จ (๊ฐ์ค) | 91.36% |
ํผ๋ ํ๋ ฌ
ํด๋์ค๋ณ ์ฑ๋ฅ
| ํด๋์ค | ์ ๋ฐ๋ | ์ฌํ์จ | F1 | ์ํ ์ |
|---|---|---|---|---|
| ๋ฌด์๋ฒ | 1.0000 | 1.0000 | 1.0000 | 22 |
| ๋ด๋ฐฐ๊ฑฐ์ธ๋ฏธ๋๋ฐฉ | 0.9787 | 0.9787 | 0.9787 | 47 |
| ๋จน๋ ธ๋ฆฐ์ฌ | 0.9888 | 0.9670 | 0.9778 | 91 |
| ๋ฐฐ์ถํฐ๋๋น | 0.9658 | 0.9658 | 0.9658 | 117 |
| ๋ด๋ฐฐ๋๋ฐฉ | 0.9429 | 0.9851 | 0.9635 | 67 |
| ์๋ฝ์์ผ๋ ธ๋ฆฐ์ฌ | 0.9741 | 0.9417 | 0.9576 | 120 |
| ํฑ๋ค๋ฆฌ๊ฐ๋ฏธํ๋ฆฌ๋ ธ๋ฆฐ์ฌ | 1.0000 | 0.9078 | 0.9517 | 141 |
| ๊ฝ๋ ธ๋์ด์ฑ๋ฒ๋ | 0.9524 | 0.9302 | 0.9412 | 43 |
| ํ๋ฐค๋๋ฐฉ | 0.9500 | 0.9194 | 0.9344 | 124 |
| ํฐ28์ ๋ฐ์ด๋ฌด๋น๋ฒ๋ | 0.9375 | 0.9184 | 0.9278 | 49 |
| ์ฉ๋ฉ๋๋ฌด๋ ธ๋ฆฐ์ฌ | 0.8341 | 0.9884 | 0.9048 | 173 |
| ์ ์ | 0.8295 | 0.9932 | 0.9040 | 147 |
| ๋ด๋ฐฐ๊ฐ๋ฃจ์ด | 0.9730 | 0.8182 | 0.8889 | 44 |
| ๋ฐฐ์ถ์ข๋๋ฐฉ | 0.8675 | 0.8889 | 0.8780 | 81 |
| ๋น๋จ๋ ธ๋ฆฐ์ฌ | 0.8333 | 0.8824 | 0.8571 | 34 |
| ๋ฒผ๋ฃฉ์๋ฒ๋ | 0.9726 | 0.7136 | 0.8232 | 199 |
| ๋๋๋๋ฐฉ | 1.0000 | 0.6923 | 0.8182 | 13 |
| ๋ชฉํ๋ฐ๋๋ช ๋๋ฐฉ | 0.6667 | 0.9444 | 0.7816 | 36 |
| ๊ฒ๊ฑฐ์ธ๋ฏธ๋ฐค๋๋ฐฉ | 0.6000 | 0.8571 | 0.7059 | 14 |
๐ ๋ฒ ์ด์ค๋ผ์ธ ๋น๊ต: LoRA ์ด๋ํฐ ์ ๋ฌด์ ๋ฐ๋ฅธ ์ฐจ์ด
LoRA ํ์ธํ๋์ด ๋ชจ๋ธ์ ์ค์ ๋ก ๋ฌด์์ ๊ฐ๋ฅด์ณ ์ฃผ๋์ง ์ ๋์ ์ผ๋ก ํ์ธํ๊ธฐ ์ํด, ๋๊ฐ์ ํ๊ฐ ํ์ดํ๋ผ์ธ์ LoRA ์ด๋ํฐ ์์ด ์๋ณธ unsloth/Qwen3.5-9B ๋ฒ ์ด์ค ๋ชจ๋ธ์๋ ๊ทธ๋๋ก ๋๋ ค ๋ดค์ต๋๋ค โ ๊ฐ์ 1,595๊ฐ ๊ฒ์ฆ ์ํ(Himedia-AI-01/pest-detection-korean), ๊ฐ์ ์ ์ฒ๋ฆฌ(letterbox 512ร512), ๊ฐ์ ์์คํ
ํ๋กฌํํธ, ๊ฐ์ ๋์ฝ๋ฉ ์ค์ .
19๊ฐ ํด๋์ค ๋ผ๋ฒจ ์ค ์ด๋์๋ ํด๋นํ์ง ์๋ ์์ธก์ UNKNOWN(off-vocabulary, OOV)์ผ๋ก ๋ถ๋ฅํ๊ณ ์ค๋ต์ผ๋ก ์ฒ๋ฆฌํ์ต๋๋ค. ์ฆ "์ด ๋ชจ๋ธ์ด ์ค์ ๋ก ์ ๋ต ํด์ถฉ ์ด๋ฆ์ ์ถ๋ ฅํด ๋ด๋๊ฐ?"๋ฅผ ์๋ ๊ทธ๋๋ก ๋ณด์ฌ ์ฃผ๋ ํ๊ฐ์ ๋๋ค.
ํต์ฌ ๊ฒฐ๊ณผ
| ์งํ | ๋ฒ ์ด์ค Qwen3.5-9B (LoRA ์์) |
LoRA ์ ์ฉ (pest-detector-final) |
ฮ |
|---|---|---|---|
| ์ ํ๋ (Accuracy) | 9.47% | 89.47% | +80.00%p |
| F1 (๋งคํฌ๋ก) | 4.32% | 89.44% | +85.12%p |
| F1 (๊ฐ์ค) | 7.37% | 90.38% | +83.01%p |
| ์ ๋ฐ๋ (๋งคํฌ๋ก) | 8.00% | 90.88% | +82.88%p |
| ์ฌํ์จ (๋งคํฌ๋ก) | 5.47% | 89.28% | +83.81%p |
| OOV ์ถ๋ ฅ | 1,183 / 1,595 (74.2%) | 33 / 1,595 (2.1%) | โ72.1%p |
ํผ๋ ํ๋ ฌ ๋น๊ต
๋ฒ ์ด์ค ๋ชจ๋ธ (LoRA ์์) โ ๊ฑฐ์ ๋ชจ๋ ํ์ด ์ค๋ฅธ์ชฝ ๋ UNKNOWN ์ด๋ก ๋ชฐ๋ฆฝ๋๋ค:
LoRA ์ด๋ํฐ ์ ์ฉ โ ์์ธก์ด ๋๊ฐ์ ์ ์ง์ค๋๊ณ UNKNOWN ์ด์ ๊ฑฐ์ ๋น์ด ์์ต๋๋ค:
๋ฒ ์ด์ค ๋ชจ๋ธ์ ์ถ๋ ฅ ๋ถ์
๋ฒ ์ด์ค ๋ชจ๋ธ์ด ๋ด๋์ 1,183๊ฐ์ OOV ์์ธก์ ์์ธํ ๋ฏ์ด๋ณด๋ฉด ์ฌ๋ฏธ์๋ ์ฌ์ค์ด ๋ณด์ ๋๋ค: ์ด๊ฒ๋ค์ ์๋ฏธ ์๋ ๋ฌธ์์ด์ด ์๋๋๋ค. ๋๋ถ๋ถ ํ๊ตญ์ด๋ก ๋ถ๋ช ํ๊ฒ ์ฐ์ธ, ์ค์ฌํ๋ ํด์ถฉ ์ด๋ฆ๋ค์ ๋๋ค โ ๋ฒ ์ด์ค ๋ชจ๋ธ์ด ๊ณค์ถฉ ์ฌ์ง์์ ์ด๋ฏธ ์์๋ณด๊ณ ์ด๋ฆ๊น์ง ๋ถ์ด๋๋ฐ, ๊ทธ ์ด๋ฆ์ด ์ฐ๋ฆฌ๊ฐ ํ์ต์ ์ด 19๊ฐ ํด๋์ค์ ๋ค์ด ์์ง ์์ ๋ฟ์ ๋๋ค.
๋ฒ ์ด์ค ๋ชจ๋ธ์ ์์ 20๊ฐ OOV "๋จ์ด" (์ฒซ ํ ํฐ ๊ธฐ์ค์ผ๋ก ๋ฌถ์):
| ๋น๋ | ํ๊ตญ์ด | ์ค๋ช | ์ค์ฌ ์ฌ๋ถ |
|---|---|---|---|
| 143 | ๋ฐฉ์๋ฒ๋ | wireworm / click beetle | โ ์ค์ฌ ํด์ถฉ (19๊ฐ ๋ชฉ๋ก ์ธ) |
| 125 | ํฐ๋ฐฐ๋๋ฐฉ | white-bellied moth | โ ์ค์ฌ ๋๋ฐฉ ๊ณ์ด |
| 115 | ๋ฐฉ์ ์ถฉ | nematode (์ ์ถฉ) | โ ์ค์ฌ ์๋ฌผ ํด์ถฉ |
| 94 | ๋ฒผ๋ฉธ๊ตฌ | rice planthopper | โ ์ค์ฌ ๋ฒผ ํด์ถฉ |
| 76 | ๋ฐค๋๋ฐฉ | noctuid (๋ฐค๋๋ฐฉ๊ณผ) | โ ์ค์ฌ ๋๋ฐฉ ๊ณ์ด |
| 61 | ๋๋ฐฉ | "๋๋ฐฉ" (์ผ๋ฐ๋ช ) | โ ๏ธ ์ผ๋ฐ๋ช , ์ข ๋ฏธ์ง์ |
| 49 | ๋ฐฐ์ถ๋ฐฉ์๋ฒ๋ | "๋ฐฐ์ถ click beetle" | โ ์ฐฝ์ ์กฐ์ด |
| 32 | ์ ๊ธฐ๋ฐฐ์ถ๋ฐฉ์๋ฒ๋ | "์๊ธฐ ๋ฐฐ์ถ click beetle" | โ ์ฐฝ์ ์กฐ์ด |
| 30 | ํฐ๋ ๊ฐ๋๋ฐฉ | "ํฐ ๋ ๊ฐ ๋๋ฐฉ" | โ ๊ทธ๋ด๋ฏํ ์กฐํฉ์ด |
| 25 | ๋ฐฉ์์ ๋๋ฐฉ | "๋ฐฉ์์ ๋๋ฐฉ" | โ ์ฐฝ์ ์กฐ์ด |
| 21 | ํฐ๊ฐ๋ฃจ๋ณ | powdery mildew (ํฐ๊ฐ๋ฃจ๋ณ) | โ ์ค์ฌ (๋ณํด, ํด์ถฉ ์๋) |
| 20 | ์ง๋ง๋ฌผ | aphid (์ง๋ง๋ฌผ) | โ ์ค์ฌ ํด์ถฉ โ 19๊ฐ ์ธ |
| 20 | ์ ๋ฒ๋ | "์ ๋ฒ๋ " (์ผ๋ฐ๋ช ) | โ ๏ธ ์ผ๋ฐ๋ช |
| 19 | ํฐ์ ๋ฐ์ด๊ฝ๋ฌด์ง | white-spotted flower chafer | โ ์ค์ฌ ๋ฑ์ ๋ฒ๋ |
| 18 | ์๋ฒ๋ | leaf beetle (์๋ฒ๋ ๊ณผ) | โ ๏ธ ๊ณผ๋ช , ์ข ๋ฏธ์ง์ |
| 15 | ๋ฐฉ์ ์ | ๋ฐฉ์ ์ถฉ์ ๋ณํ | โ ์ฐฝ์ ์กฐ์ด |
| 11 | ๋ฒผ์๋ฒ๋ | rice leaf beetle | โ ์ค์ฌ ํด์ถฉ |
| 10 | ไธๆ็ข่ซ | "์น ์ฑ๋ฌด๋น๋ฒ๋ " (์ค๊ตญ์ด) | โ ์ค๊ตญ์ด ํผ์ |
| 6 | ๋๋๋๋ฐฉ | "๋๋ ๋๋ฐฉ" | โ ๊ทธ๋ด๋ฏํ ์กฐํฉ์ด |
| 6 | ๋๋์๋ฒ๋ | soybean leaf beetle | โ ์ค์ฌ ํด์ถฉ |
์ ์ฒด 1,183๊ฐ OOV ์๋ฌธ ๋ชฉ๋ก์ evaluation/baseline_off_vocab_list.json์ ์์ต๋๋ค.
LoRA๊ฐ ์ค์ ๋ก ํ๋ ์ผ
๋ฒ ์ด์ค ๋ชจ๋ธ์ ํ๊ตญ ํด์ถฉ์ ๋ํ ์ฌ์ ์ง์์ด ์ด๋ฏธ ์ถฉ๋ถํฉ๋๋ค โ ๊ณค์ถฉ ์ฌ์ง์ ๋ณด๊ณ ํด๋ถํ์ ์ผ๋ก ๊ทธ๋ด๋ฏํ ์ด๋ฆ์ ๊ฝค ์์ ์๊ฒ ๋ด๋์ต๋๋ค. ๋ชจ๋ธ์ด ๋ชจ๋ฅด๋ ๊ฑด ์ด๋ฒ ๊ณผ์ ์ ์ ๋ต ๋ชฉ๋ก์ ๋ค์ด๊ฐ๋ 19๊ฐ ์ด๋ฆ์ด ๋ฌด์์ธ์ง์ ๋๋ค.
๊ทธ๋์ LoRA์ ์ญํ ์ "ํด์ถฉ์ด ์ด๋ป๊ฒ ์๊ฒผ๋์ง"๋ฅผ ๊ฐ๋ฅด์ณ ์ฃผ๋ ๊ฒ ์๋๋๋ค. ๊ทธ๋ฐ ์ง์์ ์ด๋ฏธ ์์ต๋๋ค. LoRA๊ฐ ์ค์ ๋ก ํ๋ ์ผ์ vocabulary-locking (์ดํ ๊ณ ์ ) โ ๋ชจ๋ธ์ ์ถ๋ ฅ ๋ถํฌ๋ฅผ "19์ง์ ๋ค ๋ฉ๋ด"๋ก ์ขํ ์ฃผ๋ ์ผ์ ๋๋ค.
| ๋์ | ๋ฒ ์ด์ค ๋ชจ๋ธ | + LoRA ์ด๋ํฐ |
|---|---|---|
| ํด์ถฉ ์ธ์ | ์ด๋ฏธ ์ถฉ๋ถ (์ค์ฌ ํด์ถฉ ์ด๋ฆ ์์ฑ) | ์ฌ์ ํ ์ถฉ๋ถ |
| ์ถ๋ ฅ ์ดํ | ๊ฐ๋ฐฉํ โ ๋ชจ๋ ํ๊ตญ์ด ํด์ถฉ ์ด๋ฆ | ํ์ต๋ 19๊ฐ ํด๋์ค๋ก ๊ณ ์ |
| OOV ์ถ๋ ฅ ๋น์จ | 74.2% | 2.1% |
| CoT(์ฌ๊ณ ์ฐ์) ํ ํฐ ์ถ๋ ฅ | ์ฆ์ (<think>โฆ</think>) |
์ ๊ฑฐ๋จ |
| ํด๋์ค๋ณ F1 | ๋๋ถ๋ถ 0.00 (์ถ์ธก์ด ๊ฑฐ์ ์ ๋ง์) | ๋ชจ๋ ํด๋์ค โฅ 0.70, ๋๋ถ๋ถ โฅ 0.90 |
๋ฐ๋ก ์ด๊ฒ์ด 9B ํ๋ผ๋ฏธํฐ ๋ฒ ์ด์ค ๋ชจ๋ธ์ 660 MB์ง๋ฆฌ LoRA ๊ฐ์ค์น๋ง์ผ๋ก ์ ํ๋๊ฐ 9%์์ 91%๋ก ๋ด ์ด์ ์ ๋๋ค. 90์ต ๊ฐ ํ๋ผ๋ฏธํฐ์ ํด์ถฉ์ ๋ํ ์ง์์ ์๋ก ์๊ฒจ ๋ฃ๋ ๊ฒ ์๋๋ผ, 19๊ฐ ์ค ํ๋๋ฅผ ๊ณ ๋ฅด๋ ์ข์ ์ ํธ๋ง ํ์ต์ํค๋ ๊ฒ์ ๋๋ค. ์ด๊ฑด vocabulary alignment ๋ฌธ์ ์ด๊ณ , low-rank adaptation(LoRA)์ด ๊ฐ์ฅ ์ ํด๋ด๋ ์ข ๋ฅ์ ์ผ์ ๋๋ค.
๋ฐฉ๋ฒ๋ก ์ฃผ์
์์ ๋ฒ ์ด์ค๋ผ์ธ ์์น๋ 1,595๊ฐ ์ํ ์ ์ฒด๋ฅผ ๋์์ผ๋ก ๊ณ์ฐํ ๊ฐ์ด๋ฉฐ, OOV ์์ธก์ ์ค๋ต์ผ๋ก ์ฒ๋ฆฌํ์ต๋๋ค. ์ผ๋ถ๋ฌ ์ด๋ ๊ฒ ๋ง์ถ ๊ฒ์ ๋๋ค โ "์๋ณธ ๋ฒ ์ด์ค ๋ชจ๋ธ์ด ์ค์ ๋ก ์ ๋ต์ ์ผ๋ง๋ ์์ฃผ ๋ด๋๋๊ฐ?"๋ฅผ ์๋ ๊ทธ๋๋ก ๋ณด์ฌ ์ฃผ๊ธฐ ์ํด์์ ๋๋ค.
์ฐธ๊ณ ๋ก OOV ์ํ์ ์ ์ ๊ณ์ฐ์์ ์ ์ธํ๋ฉด(๋ฒ ์ด์ค ๋ชจ๋ธ์ด ์ ํจํ ํด๋์ค ์ด๋ฆ์ ๋ฑ์ 412๊ฐ ์ํ๋ง ๋จ๊ธฐ๋ฉด) ๋ฒ ์ด์ค ๋ชจ๋ธ๋ ์ ํ๋ 36.65% / F1 ๊ฐ์ค 27.13%๊น์ง ์ฌ๋ผ๊ฐ๋๋ค. ๋ค๋ง ์ด ์์น๋ "๋ชจ๋ธ์ด ์ดํ ์์์ ๋ต์ ๋ธ ๊ฒฝ์ฐ"๋ง ๋ฐ๋ก ๋ผ์ด ๋ธ ๊ฒ์ด๋ฉฐ, ์ ์ด์ 74%๋ ์ดํ ์์์ ๋ต์ ๋ด์ง๋ ๋ชปํฉ๋๋ค.
์ฌํ
git clone https://github.com/pfox1995/pest-hyperparameter-search.git
cd pest-hyperparameter-search
# ๋ฒ ์ด์ค๋ผ์ธ (LoRA ์์)
python eval_baseline.py --save-dir ./hf_eval_baseline --label baseline
# LoRA ์ด๋ํฐ ์ ์ฉ (์ด ๋ชจ๋ธ)
python eval_v8.py --adapter pfox1995/pest-detector-final \
--save-dir ./hf_eval_v8 --label v8
๋ชจ๋ ํ๊ฐ ์ํฐํฉํธ โ ํผ๋ ํ๋ ฌ PNG, metrics.json, ํด๋์ค๋ณ ๋ถ์, ์ ์ฒด ์๋ณธ ์์ธก, OOV ๋ชฉ๋ก โ ์ github.com/pfox1995/pest-hyperparameter-search/tree/main/evaluation์ ์์ต๋๋ค.
ํด๋์ค ๋ชฉ๋ก
๋ชจ๋ธ์ด ์ธ์ํ๋ 19๊ฐ ํ๊ตญ์ด ๋ผ๋ฒจ(ํด์ถฉ 18์ข + "์ ์"):
๊ฒ๊ฑฐ์ธ๋ฏธ๋ฐค๋๋ฐฉ, ๊ฝ๋ ธ๋์ด์ฑ๋ฒ๋ , ๋ด๋ฐฐ๊ฐ๋ฃจ์ด, ๋ด๋ฐฐ๊ฑฐ์ธ๋ฏธ๋๋ฐฉ, ๋ด๋ฐฐ๋๋ฐฉ, ๋๋๋๋ฐฉ, ๋จน๋ ธ๋ฆฐ์ฌ, ๋ชฉํ๋ฐ๋๋ช ๋๋ฐฉ, ๋ฌด์๋ฒ, ๋ฐฐ์ถ์ข๋๋ฐฉ, ๋ฐฐ์ถํฐ๋๋น, ๋ฒผ๋ฃฉ์๋ฒ๋ , ๋น๋จ๋ ธ๋ฆฐ์ฌ, ์ฉ๋ฉ๋๋ฌด๋ ธ๋ฆฐ์ฌ, ์๋ฝ์์ผ๋ ธ๋ฆฐ์ฌ, ์ ์, ํฐ28์ ๋ฐ์ด๋ฌด๋น๋ฒ๋ , ํฑ๋ค๋ฆฌ๊ฐ๋ฏธํ๋ฆฌ๋ ธ๋ฆฐ์ฌ, ํ๋ฐค๋๋ฐฉ
ํ์ต ์ธ๋ถ ์ฌํญ
- ๋ฒ ์ด์ค ๋ชจ๋ธ:
unsloth/Qwen3.5-9B(Qwen3-Next ๋น์ -์ธ์ด, ํ์ด๋ธ๋ฆฌ๋ Gated DeltaNet + self-attention) - ์ด๋ํฐ: LoRA, rank
r=64, alpha128. ํ๊ฒ ์ ๊ท์์model.layers.*์language_model.layers.*๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ๋ชจ๋ ํฌํจํฉ๋๋ค (self_attn,linear_attn,mlpโq/k/v/o/gate/up/down/in_proj_*/out_proj). - ๋ฐ์ดํฐ์
:
Himedia-AI-01/pest-detection-koreanโ ํ๊ตญ ๋์๋ฌผ ํด์ถฉ ์ด๋ฏธ์ง, 19๊ฐ ํด๋์ค (ํด์ถฉ 18์ข + "์ ์") - ์ต์ ์ฒดํฌํฌ์ธํธ: step 850, eval_loss = 0.0232
- ํ์ดํผํ๋ผ๋ฏธํฐ ํ์: ์ต์ข ํ์ต ์ ์ Optuna TPE๋ก proxy 50 trial + full 10 trial ์ํ
- ํ๋์จ์ด: RunPod A6000 (48 GB VRAM)
- ํ๋ ์์ํฌ: Unsloth + PEFT + TRL/SFTTrainer, bf16
ํ์ต ์ฝ๋์ ํ์ดํผํ๋ผ๋ฏธํฐ ํ์ ์ฝ๋๋ pfox1995/pest-hyperparameter-search์ ์์ต๋๋ค.
๐ก๏ธ ํ์ต ์์ ์ฑ๊ณผ ์ฒดํฌํฌ์ธํธ ์ ํ
์ด ์ด๋ํฐ๋ ํ ๋ฒ์ ํ์ต ์ค eval_loss๊ฐ ๊ฐ์ฅ ๋ฎ์๋ step 850 ์ง์ ์ LoRA ๊ฐ์ค์น์
๋๋ค. ๋ฐ๋ก ์ด์ด์ง step 940~950 ๊ตฌ๊ฐ์์ gradient๊ฐ ํญ๋ฐํด eval_loss๊ฐ 0.023์์ 0.58๊น์ง ํ์ด ์ค๋ฅด๊ธด ํ์ง๋ง, HuggingFace Trainer์ load_best_model_at_end=True ๋๋ถ์ ํ์ต์ด ๋๋ ๋ ์๋์ผ๋ก step 850 ๊ฐ์ค์น๋ก ๋๋์์์ต๋๋ค. ๊ณต๊ฐ๋ ์ด๋ํฐ๋ 'ํญ๋ฐ ์ดํ'๊ฐ ์๋๋ผ **'ํญ๋ฐ ์ง์ , eval_loss๊ฐ ๊ฐ์ฅ ๋ฎ์๋ ์๊ฐ'**์ ์ค๋
์ท์
๋๋ค.
ํ์ต ๊ถค์ (์ฃผ์ ์คํ )
์ค์ ํ์ต ๋ก๊ทธ(training_artifacts/checkpoint-950/trainer_state.json)์์ ๋ฝ์๋ธ ๊ด์ธก๊ฐ์
๋๋ค.
| Step | eval_loss | grad_norm | ์ํ |
|---|---|---|---|
| 25 | 0.0465 | 3.20 | warmup ๋๋ ์งํ (์ฒซ ํ๊ฐ) |
| 125 | 0.0332 | โ | ์๋ ด ๊ตฌ๊ฐ ์ง์ |
| 200 | 0.0305 | 10.84 | ์ ์ ๋ฒ์ (clipping ๋ฐ๋) |
| 325 | 0.0254 | 0.36 | ๊ฐ์ฅ ์์ ์ ์ธ ๊ตฌ๊ฐ |
| 450 | 0.0282 | โ | ์์ ์ ์ผ๋ก ์๋ ด ์ค |
| 850 | 0.0232 | โ | ๐ eval_loss ์ต์ ์ โ ์ด ์ฒดํฌํฌ์ธํธ๊ฐ ์ต์ข ์ด๋ํฐ๋ก ์ฑํ๋จ |
| 900 | 0.0239 | 2,710 | grad_norm ๊ธ๋ฑ ์กฐ์ง |
| 920 | โ | 2,333 | ๋ถ์์ ํ ์ํ ์ง์ |
| 925 | 0.0358 | โ | eval_loss ๋ฐ๋ฑ ์์ |
| 940 | โ | 505,148 | ๐ฅ gradient ํญ๋ฐ ๋ณธ๊ฒฉํ |
| 950 | 0.5803 | โ | ๐ฅ ํ์ต ๋ฐ์ฐ (์ต์ข ์คํ ) |
best_metric: 0.023164400830864906, best_global_step: 850
(trainer_state.json ์๋จ ํ๋์ Trainer๊ฐ ์์ฒด ๊ธฐ๋กํ ๊ณต์ ๊ฐ)
ํ์ต ์คํฌ๋ฆฝํธ๊ฐ ๊ฑธ์ด ๋ 7๋จ ์์ ์ฅ์น
train_final.py๋ ํ์ต์ด ๋ถ์์ ํด์ง ๊ฐ๋ฅ์ฑ์ ์ฒ์๋ถํฐ ์ผ๋์ ๋๊ณ ์ง ์คํฌ๋ฆฝํธ์
๋๋ค. ๋ค์ 7๊ฐ ์์ ์ฅ์น๊ฐ ๋์์ ๊ฑธ๋ ค ์์ต๋๋ค:
| # | ์ค์ | ๊ฐ | ์ญํ |
|---|---|---|---|
| 1 | max_grad_norm |
1.0 | ๋งค ์คํ ๋ง๋ค gradient L2 norm์ 1.0์ผ๋ก clipping. ํญ๋ฐ์ด backprop์ ์ค๋ฆฌ์ง ๋ชปํ๊ฒ ๋ง์. |
| 2 | warmup_ratio |
0.03 | ์ ์ฒด ์คํ ์ 3%๋ฅผ warmup์ผ๋ก ์จ์ ์ด๊ธฐ LR์ด ํ๋ ์ถฉ๊ฒฉ์ ์ํ. |
| 3 | lr_scheduler_type |
linear | LR์ ์ ํ์ผ๋ก ์ค์ฌ ๋๊ฐ โ ํ๋ฐ์ผ๋ก ๊ฐ์๋ก ์์ฐ์ค๋ฝ๊ฒ ์์์ง. |
| 4 | optim |
adamw_torch | adamw_8bit๋ณด๋ค ์์น์ ์ผ๋ก ์์ (์ด์ ์คํ์์ 8bit optimizer๊ฐ step 29์์ ๋ฐ์ฐํ ์ด๋ ฅ์ด ์์). |
| 5 | use_rslora |
True | rank-stabilized LoRA โ ์ค์ผ์ผ์ alpha/โr๋ก ์ ๊ทํํด rank-64์์๋ ์๋ ด์ด ์์ ์ . |
| 6 | save_steps / eval_steps |
25 / 25 | 25 ์คํ ๋ง๋ค ์ฒดํฌํฌ์ธํธ + ํ๊ฐ. ํญ๋ฐ ์ง์ ์ ์์ ๊ตฌ๊ฐ์ ์ด์ดํ๊ฒ ๋จ๊ฒจ ์ค. |
| 7 | load_best_model_at_end |
True | ํ์ต์ด ๋๋ ๋ eval_loss๊ฐ ๊ฐ์ฅ ๋ฎ์๋ ์ฒดํฌํฌ์ธํธ๋ก ์๋ ๋ณต์. |
์ด ์ค #1๊ณผ #7์ด ์ด๋ฒ ํ์ต์ ๊ฒฐ์ ์ ์์ ๋ง์ผ๋ก ์๋ํ์ต๋๋ค.
- #1 (
max_grad_norm=1.0) โ step 940์์ gradient๊ฐ 505,148๊น์ง ํ์ด ์ฌ๋์ ๋, ์ค์ ๊ฐ์ค์น ์ ๋ฐ์ดํธ์ ๋ฐ์๋๋ norm์ 1.0์ผ๋ก ๋๋ฌ ์คฌ์ต๋๋ค. ๋๋ถ์ eval_loss๊ฐ 0.58 ์ ์์ ๋ฉ์ถ ๊ฒ์ด๋ฉฐ, clipping์ด ์์๋ค๋ฉด ๊ฐ์ค์น ์์ฒด๊ฐ NaN์ผ๋ก ๋ฐ์ฐํ์ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค. - #7 (
load_best_model_at_end=True) โtrainer.train()์ด ๋๋๋ ์๊ฐ Trainer๊ฐ ๋ด๋ถlog_history๋ฅผ ํ์ด์metric_for_best_model="eval_loss"๊ฐ ๊ฐ์ฅ ๋ฎ์๋ step 850 ์ฒดํฌํฌ์ธํธ๋ฅผ ์๋์ผ๋ก ๋ค์ ๋ถ๋ฌ์ต๋๋ค. ํ์ต ์คํฌ๋ฆฝํธ์์ ๋ณ๋ ์์ ์ ํ์ง ์์๋ ์๋์ผ๋ก ๋ณต์๋ฉ๋๋ค.
์ ํ๋ฐ์ ํญ๋ฐํ๋๊ฐ โ ๋ฒ๊ทธ๊ฐ ์๋๋ผ ์ด ์ธํ ์ ํน์ฑ
LoRA rank=64์ dropout=0.0์ผ๋ก 9B์ง๋ฆฌ ๋ฒ ์ด์ค ๋ชจ๋ธ์ ํ์ธํ๋ํ๋ฉด, ์ํญ ํ๋ฐ๋ถ์ eval_loss๊ฐ ํ ๋ฒ ์๋ ดํ ๋ค ๋ค์ ๋ฌด๋์ง๋ ํจํด์ด ๊ฑฐ์ ๊ท์น์ ์ผ๋ก ๋ํ๋ฉ๋๋ค. ์ฃผ์ ์์ธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- loss๊ฐ ๊ทน๋๋ก ์์์ง โ step 850 ๋ถ๊ทผ์์ train loss๊ฐ 0.024 ์์ค์ด๋ผ๋ ๊ฑด ์ฌ์ค์ ํ์ต ๋ฐ์ดํฐ๋ฅผ ๊ฑฐ์ ๋ค ์ธ์ด ์ํ์ ๋๋ค. ์ด ๊ตฌ๊ฐ์์๋ Adam์ 2์ฐจ ๋ชจ๋ฉํธ(๋ถ์ฐ ์ถ์ ์น)๊ฐ ๋งค์ฐ ์์์ง๋๋ฐ, ์ด๋ ๋ฐฐ์น ํ๋๋ผ๋ ๊ธฐ์กด ๋ถํฌ์ ๋ค๋ฅธ ๋ฐฉํฅ์ ๊ฐ๋ฆฌํค๋ฉด ์คํจ LR(effective LR)์ด ํญ๋ฐ์ ์ผ๋ก ์ปค์ง๋๋ค.
- LoRA rank-64 + dropout 0 ์กฐํฉ์ capacity ์ฌ์ ๊ฐ ํผ โ ๋จ์ capacity๊ฐ "์ด๋ฏธ ์ ๋ง์ถ ์ํ์ ๋ ์ ๋ฐํ๊ฒ ๋ง์ถ๋ ค๋" ์ชฝ์ผ๋ก ์ ๋ฆฌ๋ฉด์ overfit ๋ฐฉํฅ์ gradient๋ฅผ ๋ง๋ค์ด ๋ ๋๋ค.
- linear ์ค์ผ์ค๋ฌ์ ํ๊ณ โ step 940 ์์ ์๋ LR์ด 4.24e-5๋ก ์ฌ์ ํ ๊ฝค ๋๊ณ , cosine ์ค์ผ์ค์ฒ๋ผ ํ๋ฐ์ ๊ธ๊ฒฉํ ๋จ์ด์ง์ง ์์ต๋๋ค.
๊ทธ๋์ ์ ๋ต์ "gradient ํญ๋ฐ ์์ฒด๋ฅผ ๋ง๋ ๊ฒ"์ด ์๋๋ผ **"ํญ๋ฐ์ด ์ผ์ด๋๊ธฐ ์ ์ ์ต์ ์ง์ ์ ์ก์ ๋๋ ๊ฒ"**์ด์ด์ผ ํฉ๋๋ค. ์ด ์ด๋ํฐ๋ ์ ํํ ๊ทธ๋ฐ ์์น์ผ๋ก ๋ง๋ค์ด์ก์ต๋๋ค.
์ ์ฅ๋ ์ฒดํฌํฌ์ธํธ๊ฐ "์์ฑ๋" ์ด๋ํฐ๋ก ํ๋นํ ์ด์
- โ
eval_loss ์ต์ ์ง์ โ step 850์ ์ ์ฒด
log_history์คeval_loss๊ฐ ์ต์(0.02316)๋ฅผ ๊ธฐ๋กํ ์คํ ์ ๋๋ค. - โ ์ถฉ๋ถํ ์๋ ด๋ ์ํ โ step 300๋ถํฐ step 900๊น์ง ์ฝ 600 ์คํ ๋์ eval_loss๊ฐ 0.023~0.030 ๊ตฌ๊ฐ์์ ์์ ์ ์ผ๋ก ์ง๋ํ์ต๋๋ค โ ๊ณผ์ ํฉ ์ง์ ์ ์ ๋ฌด๋ฅด์ต์ ์๋ ด ๊ตฌ๊ฐ์ ๋๋ค.
- โ
๊ฒ์ฆ ์ฑ๋ฅ์ผ๋ก ๊ต์ฐจ ํ์ธ โ 1,595๊ฐ ๊ฒ์ฆ ์ํ ์ ์ฒด์์ 89.47% ์ ํ๋, F1 macro 89.44% (
evaluation/metrics.json์ฐธ์กฐ). - โ ๋ฒ ์ด์ค๋ผ์ธ ๋๋น +80%p โ LoRA ์์ด ๋๋ฆฐ ๋์ผ ๋ชจ๋ธ์ 9.47%์ ๊ทธ์นฉ๋๋ค (์์ธํ ๋น๊ต๋ ์์ "๋ฒ ์ด์ค๋ผ์ธ ๋น๊ต" ์น์ ์ฐธ๊ณ ).
"ํ์ต์ด ์ค๊ฐ์ ๊ผฌ์์ผ๋ ์ด ์ด๋ํฐ๋ ๋ถ์คํ ๊ฒ ์๋๊ฐ?"๋ผ๋ ์๋ฌธ์ด ๋ค ์ ์์ง๋ง, ์ค์ ๊ทธ ๋ฐ๋์
๋๋ค. ์คํ๋ ค load_best_model_at_end๊ฐ ๊ฑธ๋ ค ์๋ ์ํฉ์์ ํญ๋ฐ์ด ๋ฐ์ํ๋ค๋ ์ฌ์ค ์์ฒด๊ฐ ์ด์ ์์ ๋ง์ด ์ค๊ณ๋๋ก ์๋ํ๋ค๋ ์ฆ๊ฑฐ์
๋๋ค. "ํ์ต์ ๋๊น์ง ๋๋ฆฐ ์ด๋ํฐ"๊ฐ ๋ ์ข์ ์ด๋ํฐ๋ผ๋ ๋ณด์ฅ๋ ์์ต๋๋ค โ ์คํ๋ ค eval_loss๊ฐ ๋ค์ ์ฌ๋ผ๊ฐ ๋ฒ๋ฆฐ overfit ์ํ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
ํฅํ ๊ฐ์ โ ๋ ๊น๋ํ๊ฒ ์ข ๋ฃํ๋ ค๋ฉด
๋ค์ ํ์ต์์๋ transformers.EarlyStoppingCallback์ ๋ถ์ด๋ฉด ํญ๋ฐ์ด ์ผ์ด๋๊ธฐ ์ ์ ํ์ต์ ์กฐ๊ธฐ ์ข
๋ฃ์ํฌ ์ ์์ต๋๋ค:
from transformers import EarlyStoppingCallback
trainer = SFTTrainer(
...,
callbacks=[EarlyStoppingCallback(
early_stopping_patience=3, # 3ํ ์ฐ์ eval_loss ๊ฐ์ ์ด ์์ผ๋ฉด ์ข
๋ฃ
early_stopping_threshold=0.001, # ๊ฐ์ ์ผ๋ก ์ธ์ ํ ์ต์ ๋ณํ๋
)],
)
์ด๋ฒ ํ์ต์ ์ด ์ฝ๋ฐฑ์ด ๊ฑธ๋ ค ์์๋ค๋ฉด step 900์ฏค์์ ํ์ต์ด ์๋์ผ๋ก ๋๋์ step 940์ ํญ๋ฐ์ ์์ ์ผ์ด๋์ง ์์์ ๊ฒ๋๋ค. ์ ์ฅ๋๋ ์ต์ข ์ด๋ํฐ ์์ฒด๋ ๊ฐ์ง๋ง(step 850) GPU ์๊ฐ๊ณผ ์ ๋ ฅ์ ์ฝ 6% ์๋ ์ ์์ต๋๋ค.
ํ๋์ ์ ๋ฆฌ
| ์ง๋ฌธ | ๋ต |
|---|---|
| gradient clipping์ด ๊ฑธ๋ ค ์์๋๊ฐ? | โ
max_grad_norm=1.0 |
| ์ค์ ๋ก ํญ๋ฐ์ด ์ผ์ด๋ฌ๋๊ฐ? | โ step 940, grad_norm 505,148 |
| ํญ๋ฐํ ์ํ์ ์ด๋ํฐ๊ฐ ์ ๋ก๋๋๋๊ฐ? | โ load_best_model_at_end=True ๋๋ถ์ step 850 ๋ฒ์ ์ผ๋ก ๋ณต์๋จ |
| ์ ๋ก๋๋ ์ด๋ํฐ์ ์ฑ๋ฅ์? | โ 89.47% ์ ํ๋ / F1 macro 89.44% (1,595๊ฐ ๊ฒ์ฆ ์ํ ์ ์ฒด) |
| ํ์ต์ ๋๊น์ง ๋๋ ค์ผ ํ๋๊ฐ? | โ ์ด๋ฏธ step 850์ด eval_loss ์ต์ ์ . ๊ทธ ์ดํ๋ overfit ๋ฐ ํญ๋ฐ ๊ตฌ๊ฐ |
์ฌ์ฉ๋ฒ
๋น ๋ฅธ ์์ (์ถ๋ก )
import torch
from transformers import AutoModelForImageTextToText, AutoProcessor
from peft import PeftModel
from PIL import Image
BASE = "unsloth/Qwen3.5-9B"
ADAPTER = "pfox1995/pest-detector-final"
# ๋ฒ ์ด์ค ๋ชจ๋ธ ๋ก๋ + ์ด๋ํฐ ์ฐ๊ฒฐ
model = AutoModelForImageTextToText.from_pretrained(
BASE, dtype=torch.bfloat16, device_map="cuda",
).eval()
model = PeftModel.from_pretrained(model, ADAPTER)
processor = AutoProcessor.from_pretrained(BASE)
# ์ด๋ฏธ์ง ์ค๋น
image = Image.open("pest.jpg").convert("RGB")
# ํ์ต ์ ์ฌ์ฉํ ์์คํ
ํ๋กฌํํธ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉ
SYSTEM_MSG = (
"๋น์ ์ ์๋ฌผ ํด์ถฉ ์๋ณ ์ ๋ฌธ๊ฐ์
๋๋ค. "
"์ฌ์ง์ ๋ณด๊ณ ํด์ถฉ์ ์ด๋ฆ๋ง ํ๊ตญ์ด๋ก ๋ตํ์ธ์. "
'ํด์ถฉ์ด ์์ผ๋ฉด "์ ์"์ด๋ผ๊ณ ๋ง ๋ตํ์ธ์. '
"๋ถ๊ฐ ์ค๋ช
์์ด ์ด๋ฆ๋ง ์ถ๋ ฅํ์ธ์."
)
messages = [
{"role": "system", "content": [{"type": "text", "text": SYSTEM_MSG}]},
{"role": "user", "content": [
{"type": "image", "image": image},
{"type": "text", "text": "์ด ์ฌ์ง์ ์๋ ํด์ถฉ์ ์ด๋ฆ์ ์๋ ค์ฃผ์ธ์."},
]},
]
tmpl = processor.apply_chat_template(messages, add_generation_prompt=True)
inputs = processor(image, tmpl, add_special_tokens=False, return_tensors="pt").to("cuda")
with torch.inference_mode():
out = model.generate(
**inputs,
max_new_tokens=16,
do_sample=False,
use_cache=True,
stop_strings=["\n", "<|im_end|>"],
tokenizer=processor.tokenizer,
)
prediction = processor.decode(
out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True
).strip()
print(prediction) # ์: "๋ฐฐ์ถํฐ๋๋น"
๋น ๋ฅธ ์๋น์ ์ํ ์ด๋ํฐ ๋ณํฉ
ํ๋ก๋์ ํ๊ฒฝ์์๋ LoRA ๊ฐ์ค์น๋ฅผ ๋ฒ ์ด์ค ๋ชจ๋ธ์ ํ ๋ฒ๋ง ๋ณํฉํด ๋๋ฉด, ์ถ๋ก ์ PEFT๋ฅผ ๊ฑฐ์น์ง ์๊ฒ ๋์ด forward pass๊ฐ ์ฝ 20% ๋นจ๋ผ์ง๋๋ค.
from transformers import AutoModelForImageTextToText, AutoProcessor
from peft import PeftModel
import torch
model = AutoModelForImageTextToText.from_pretrained(
"unsloth/Qwen3.5-9B", dtype=torch.bfloat16, device_map="cuda",
)
model = PeftModel.from_pretrained(model, "pfox1995/pest-detector-final")
model = model.merge_and_unload() # LoRA๋ฅผ ๋ฒ ์ด์ค ๊ฐ์ค์น์ ๋ณํฉ
model.save_pretrained("./pest-detector-merged", safe_serialization=True)
AutoProcessor.from_pretrained("unsloth/Qwen3.5-9B").save_pretrained("./pest-detector-merged")
๋ณํฉ ํ์๋ ์๋น ์ peft ์์ด ์์ transformers๋ง์ผ๋ก ๋ก๋ํ ์ ์์ต๋๋ค.
HTTP API๋ก ์๋นํ๊ธฐ
๋ฐ๋ก ์ธ ์ ์๋ FastAPI ์๋ฒ๊ฐ pfox1995/pest-hyperparameter-search/serving/์ ์ค๋น๋์ด ์์ต๋๋ค.
์ต์ ๋ฐฐํฌ ์ ์ฐจ
git clone https://github.com/pfox1995/pest-hyperparameter-search.git
cd pest-hyperparameter-search/serving
pip install -r requirements.txt
python merge_adapter.py # ์ฝ 2๋ถ, 1ํ๋ง ์คํ
uvicorn serve:app --host 0.0.0.0 --port 8000 # ์๋ฐ์
์ด ๋๋๋ฉด ์ค๋น ์๋ฃ
ํ๋์จ์ด ๊ถ์ฅ ์ฌํญ
| GPU | VRAM | ๋น๊ณ |
|---|---|---|
| RTX A40 | 48 GB | ๊ถ์ฅ. RunPod ์คํ ๊ธฐ์ค $0.22/์. bf16 ์คํ๊ณผ ๋์ ์์ฒญ ์ฒ๋ฆฌ์ ์ถฉ๋ถํ ์ฌ์ ๊ฐ ์์. |
| RTX A6000 | 48 GB | VRAM์ ๋์ผ, ํด๋ญ์ด ์ฝ 20% ๋น ๋ฆ, ๊ฐ๊ฒฉ์ ๋ ๋น์. |
| RTX A5000 | 24 GB | bf16์ด ๋น ๋ฏํ๊ฒ ๋ค์ด๊ฐ, ๋จ์ผ ์คํธ๋ฆผ ์ ์ฉ. |
| A100 80 GB | 80 GB | 9B ๋ชจ๋ธ์๋ ๊ณผํ ์ฌ์ โ ๊ฑด๋๋ฐ์๋ฉด ๋ฉ๋๋ค. |
API ํธ์ถ
curl -X POST http://your-pod:8000/predict \
-H "Content-Type: application/json" \
-d '{"image_base64": "'$(base64 -w0 pest.jpg)'"}'
์๋ต ์์:
{
"pest": "๋ฐฐ์ถํฐ๋๋น",
"raw": "๋ฐฐ์ถํฐ๋๋น",
"known_class": true,
"latency_ms": 980
}
์๋ฒ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์ ํ๋ก๋์ ์ฉ ์ต์ ํ๋ฅผ ์ ์ฉํฉ๋๋ค:
stop_strings=["\n"]๋ก ์ฒซ ์ค๋ฐ๊ฟ์์ generate๋ฅผ ์ค๋จ (chat template์ trailing ํ ํฐ ๋ฐฉ์ง)- ์ฌํ์ฑ๊ณผ ์บ์ ํจ์จ์ ์ํ greedy decoding + ์ด๋ฏธ์ง ํด์ ๊ธฐ๋ฐ LRU ์บ์
- ํ์ต ์ ์ ๋ ฅ ๋ถํฌ์ ๋ง์ถ๊ธฐ ์ํ 768 px letterbox resize
- no-grad ์ถ๋ก ์ ์ํ
torch.inference_mode()
Dockerfile๊ณผ ์ค์ผ์ผ๋ง ๊ฐ์ด๋๋ฅผ ํฌํจํ ์ ์ฒด ๋ฐฐํฌ ๋ฌธ์๋ ์๋น README๋ฅผ ์ฐธ๊ณ ํ์ธ์.
์ฌํ (์ฐธ๊ณ ์ฉ)
git clone https://github.com/pfox1995/pest-hyperparameter-search.git
cd pest-hyperparameter-search
# 7๋จ ์์ ์ฅ์น๊ฐ ๋ชจ๋ ๊ฑธ๋ฆฐ ํ์ต
python3 train_final.py \
--epochs 1 \
--save-strategy steps --save-steps 25 --eval-steps 25
training_artifacts/final_train.log์ ํ์ต ๋ก๊ทธ ์๋ณธ์ด ๊ทธ๋๋ก ๋จ์ ์๊ณ , training_artifacts/checkpoint-{850,925,950}/trainer_state.json์์ ๊ฐ ๊ตฌ๊ฐ์ loss / grad_norm / ํ์ต๋ฅ ๊ถค์ ์ ์ง์ ํ์ธํ ์ ์์ต๋๋ค.
ํ๊ณ ๋ฐ ์ฃผ์ ์ฌํญ
- ํ๊ตญ์ด ์ ์ฉ ์ถ๋ ฅ. ์์คํ ํ๋กฌํํธ๊ฐ ๋ชจ๋ธ์๊ฒ ํ๊ตญ์ด ํด์ถฉ ์ด๋ฆ๋ง ์ถ๋ ฅํ๋๋ก ์ง์ํฉ๋๋ค. ๋ค๋ฅธ ์์คํ ํ๋กฌํํธ๋ฅผ ์ฐ๋ฉด ์ถ๋ ฅ ํ์์ด ๋ฌ๋ผ์ง ์ ์์ต๋๋ค.
- ๊ณ ์ ๋ 19๊ฐ ํด๋์ค ์ดํ. ๋ชจ๋ธ์ ํ์ต ์ธํธ์ ์๋ ๋ผ๋ฒจ๋ง ์ถ๋ ฅํฉ๋๋ค. 19๊ฐ ํด๋์ค๋ฅผ ๋ฒ์ด๋ ๋๋ฌธ ํด์ถฉ์ ์๋ ค์ง 19๊ฐ ์ค ํ๋๋ก ์๋ชป ๋ถ๋ฅ๋ฉ๋๋ค.
- ๋ฒ ์ด์ค ๋ชจ๋ธ ํน์ด์ โ ์์ฑ์ด EOS์์ ํญ์ ๋ฉ์ถ์ง ์์. ์ถ๋ก ์ ๋ชจ๋ธ์ด ํด์ถฉ ์ด๋ฆ ๋ค์ chat template ํ ํฐ(์:
\nassistant)์ ๋ง๋ถ์ด๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.generate()์stop_strings=["\n"]์ธ์๋ฅผ ์ฃผ๋ฉด ๋ฐฉ์งํ ์ ์์ผ๋ฉฐ, ์ ๊ณต๋ ์๋น ์๋ฒ๋ ์ด๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. - ๋น์ ํ์ ๋ฏผ๊ฐ๋. ์ฅ๋ณ ๊ธฐ์ค 768 px ์ดํ ์ด๋ฏธ์ง๋ก ํ์ตํ ๋ชจ๋ธ์ ๋๋ค. ๋๋ฌด ํฐ ์ด๋ฏธ์ง๋ ๋๋ฌด ์์ ์ด๋ฏธ์ง๋ ์ฑ๋ฅ์ด ๋จ์ด์ง ์ ์์ผ๋ 512~768 px ๋ฒ์๋ก letterbox resizeํด์ ์ฐ์๊ธธ ๊ถ์ฅํฉ๋๋ค.
์ธ์ฉ
์ด ๋ชจ๋ธ์ ์ฌ์ฉํ์ค ๊ฒฝ์ฐ ๋ค์์ ์ธ์ฉํด ์ฃผ์ธ์:
@misc{pest-detector-final-2026,
author = {pfox1995},
title = {Korean Pest Detector โ Qwen3.5-9B LoRA Adapter},
year = {2026},
publisher = {Hugging Face},
url = {https://huggingface.co/pfox1995/pest-detector-final},
}
๋งํฌ
- ๋ชจ๋ธ: https://huggingface.co/pfox1995/pest-detector-final
- ํ์ต + ์๋น ์ฝ๋: https://github.com/pfox1995/pest-hyperparameter-search
- ์ ์ฒด ํ๊ฐ ์ํฐํฉํธ (CM PNG, ํด๋์ค๋ณ ์งํ, ์๋ณธ ์์ธก ๊ฒฐ๊ณผ, OOV ๋ชฉ๋ก): github.com/pfox1995/pest-hyperparameter-search/tree/main/evaluation
- ๋ฐ์ดํฐ์ : https://huggingface.co/datasets/Himedia-AI-01/pest-detection-korean
Unsloth๋ก 2๋ฐฐ ๋น ๋ฅด๊ฒ, VRAM์ 70% ์๊ปด์ ํ์ตํ์ต๋๋ค. PEFT ๊ธฐ๋ฐ์ LoRA ์ด๋ํฐ์ ๋๋ค.
- Downloads last month
- 131
Model tree for pfox1995/pest-detector-final
Evaluation results
- Accuracy on Himedia-AI-01/pest-detection-koreanself-reported0.914
- F1 (macro) on Himedia-AI-01/pest-detection-koreanself-reported0.903
- F1 (weighted) on Himedia-AI-01/pest-detection-koreanself-reported0.913
- Precision (macro) on Himedia-AI-01/pest-detection-koreanself-reported0.909
- Recall (macro) on Himedia-AI-01/pest-detection-koreanself-reported0.910


