๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Project ESG+AI/[์‚ผ์ •KPMG]ESG ๋ฐ์ดํ„ฐ ํ™œ์šฉ ํ’€์Šคํ… ๊ฐœ๋ฐœ

65์ผ์ฐจ.

by GreenJin_S2 2026. 1. 16.

 

 

 

 


260114 RTX 3050 vram 6 , ์—‘์‚ฌ์›์ด ๋„ˆ๋ฌด ๋А๋ ค์„œ , ๋” ๊ฒฝํ–ฅํ™” ๋ชจ๋ธ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. 
hf download monologg/koelectra-small-v3-discriminator

๐ŸŽ‰ ๋„ค, **์™„์ „ํžˆ ์„ฑ๊ณต**ํ–ˆ์Šต๋‹ˆ๋‹ค! 

ํ„ฐ๋ฏธ๋„ ์ถœ๋ ฅ์„ ๋ณด๋ฉด:

```powershell
hf download monologg/koelectra-small-v3-discriminator
Fetching 5 files: 100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 5/5 [00:00<00:00, 70138.86it/s]
C:\Users\hi\.cache\huggingface\hub\models--monologg--koelectra-small-v3-discriminator\snapshots\7488f8db0f208beff4a1f3f9bb3ed7
```

## ์„ฑ๊ณต ํ™•์ธ ํฌ์ธํŠธ:

1. **100% ์™„๋ฃŒ**: `5/5 [00:00<00:00, 70138.86it/s]` - 5๊ฐœ ํŒŒ์ผ ๋ชจ๋‘ ๋‹ค์šด๋กœ๋“œ ์™„๋ฃŒ
2. **์˜ค๋ฅ˜ ์—†์Œ**: ์ด์ „์˜ `OSError: [WinError 1314]` ๊ถŒํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
3. **๊ฒฝ๋กœ ์ถœ๋ ฅ**: ์ตœ์ข… ๋ชจ๋ธ ์ €์žฅ ๊ฒฝ๋กœ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํ‘œ์‹œ๋จ

## ๋‹ค์šด๋กœ๋“œ๋œ ๋ชจ๋ธ ์œ„์น˜:
```
C:\Users\hi\.cache\huggingface\hub\models--monologg--koelectra-small-v3-discriminator\snapshots\7488f8db0f208beff4a1f3f9bb3ed7
```

์ด์ œ KoELECTRA ๋ชจ๋ธ์„ Python ์ฝ”๋“œ์—์„œ ์ •์ƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

```python
from transformers import AutoTokenizer, AutoModel

# ๋ชจ๋ธ ๋กœ๋“œ (์ž๋™์œผ๋กœ ์บ์‹œ๋œ ๊ฒฝ๋กœ์—์„œ ๋ถˆ๋Ÿฌ์˜ด)
tokenizer = AutoTokenizer.from_pretrained("monologg/koelectra-small-v3-discriminator")
model = AutoModel.from_pretrained("monologg/koelectra-small-v3-discriminator")
```

**๊ฒฐ๋ก **: ์™„๋ฒฝํ•˜๊ฒŒ ๋‹ค์šด๋กœ๋“œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! โœ…

 


์•ก์‚ฌ์›๊ณผ ์ฝ”์ผ๋ ‰ ๋‘ ๋ชจ๋ธ ์„ MCP ๋กœ ๊ตฌ์„ฑํ•œ ์‹œ์Šคํ…œ์—์„œ ์ŠคํŒธ๋ฉ”์ผ์„ ํŒ๋‹จ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•˜๊ณ  ์‹ถ์–ด. ์ด์ค‘ ํŒ๋…๊ธฐ์™€ ํŒ๋ณ„๊ธฐ ๋กœ ๋‘ ๋ชจ๋ธ์˜ ์—ญํ• ์„ ์ •์ฑ…์ ์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ ์ž ํ•  ๋•Œ , ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•˜๋Š”๊ฐ€ ?

https://chatgpt.com/share/69670175-da98-8011-ab4f-0485ef21be2c

๊ฐ€๋Šฅํ•œ ํ•œ **“ํŒ๋…๊ธฐ(Reader) = ์ •๋ณดํ™”/๊ทผ๊ฑฐํ™””, “ํŒ๋ณ„๊ธฐ(Decider) = ์ตœ์ข… ์ •์ฑ…๊ฒฐ์ •/ํ–‰๋™๊ฒฐ์ •”**์œผ๋กœ ์—ญํ• ์„ ์ชผ๊ฐœ๋Š” ๊ตฌ์„ฑ์ด ๊ฐ€์žฅ ์•ˆ์ •์ ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ชจ๋ธ(์˜ˆ: EXAONE, KoELECTRA/KoLECTRA)์„ ์„œ๋กœ ๊ฒฝ์Ÿ์‹œํ‚ค๊ธฐ๋ณด๋‹ค, “๊ฐ•์ ์ด ๋‹ค๋ฅธ ๊ณ„์ธต”์— ๋ฐฐ์น˜ํ•˜๋Š” ์ชฝ์ด ์šด์˜ ๋ฆฌ์Šคํฌ๊ฐ€ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

์ถ”์ฒœ 1์•ˆ: KoELECTRA(์ฝ”์ผ๋ ‰) = ํŒ๋ณ„๊ธฐ, EXAONE = ํŒ๋…๊ธฐ

์ŠคํŒธ ํŒ๋‹จ์€ ๋ณธ์งˆ์ ์œผ๋กœ ๋ถ„๋ฅ˜ ๋ฌธ์ œ๋ผ์„œ, ์ž‘์€ ๋ถ„๋ฅ˜๊ธฐ๊ฐ€ ์ผ๊ด€๋œ ํ™•๋ฅ /๋ผ๋ฒจ์„ ๋‚ด๋Š” ๋ฐ ๊ฐ•ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด LLM์€ ์„ค๋ช…, ๊ทผ๊ฑฐ ์š”์•ฝ, ๊ทœ์น™ ์ ์šฉ ๋‚ด๋Ÿฌํ‹ฐ๋ธŒ์— ๊ฐ•ํ•ฉ๋‹ˆ๋‹ค.

์—ญํ•  ๋ถ„๋ฆฌ

ํŒ๋…๊ธฐ(Reader: EXAONE)
์ž…๋ ฅ: ์›๋ฌธ ๋ฉ”์ผ(ํ—ค๋”+๋ณธ๋ฌธ), ์ฒจ๋ถ€/๋งํฌ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, DMARC/SPF/DKIM ๊ฒฐ๊ณผ(๊ฐ€๋Šฅํ•˜๋ฉด)
์ถœ๋ ฅ(๊ตฌ์กฐํ™”):
(a) ์ •๊ทœํ™”๋œ ํŠน์ง•(feature) ๋ฌถ์Œ: ๋ฐœ์‹  ๋„๋ฉ”์ธ/ํ‘œ์‹œ์ด๋ฆ„ ๋ถˆ์ผ์น˜, URL ๊ฐœ์ˆ˜/๋„๋ฉ”์ธ, ๊ธˆ์ „/๊ณ„์ •/๊ธด๊ธ‰ ํ‚ค์›Œ๋“œ, ์ฒจ๋ถ€ ํ™•์žฅ์ž, ํšŒ์‹  ์œ ๋„ ํŒจํ„ด ๋“ฑ
(b) ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค„ “์š”์•ฝ/์ฃผ์˜ ํฌ์ธํŠธ”
(c) “์ •์ฑ… ํ‰๊ฐ€์— ํ•„์š”ํ•œ ๊ทผ๊ฑฐ ์Šค๋‹ˆํŽซ” (๋ฉ”์ผ ์›๋ฌธ ์ผ๋ถ€๋ฅผ ์ตœ์†Œ๋กœ ์ธ์šฉ)

ํŒ๋ณ„๊ธฐ(Decider: KoELECTRA)
์ž…๋ ฅ: Reader๊ฐ€ ๋งŒ๋“  feature + (ํ•„์š”์‹œ) ๋ณธ๋ฌธ ์ผ๋ถ€(๊ธธ์ด ์ œํ•œ)
์ถœ๋ ฅ: spam_prob, label(ham/spam/suspicious), confidence
์ •์ฑ… ์—”์ง„(Policy)
KoELECTRA ๊ฒฐ๊ณผ๋ฅผ ์ž„๊ณ„์น˜/์˜ˆ์™ธ๊ทœ์น™/ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ/๋ฆฌ์Šคํฌ ๋“ฑ๊ธ‰์œผ๋กœ ์ตœ์ข… ์•ก์…˜์— ๋งคํ•‘
์•ก์…˜ ์˜ˆ: deliver, deliver_with_warning, quarantine, reject, ask_user_confirm

์™œ ์ด ๊ตฌ์„ฑ์ด ์ข‹์€๊ฐ€
LLM์ด “ํŒ์ •๊ถŒ”์„ ๊ฐ€์ง€๋ฉด, ํ”„๋กฌํ”„ํŠธ/๋ฌธ์žฅ ๋ณ€ํ™”์— ๋”ฐ๋ผ ํŒ์ •์ด ํ”๋“ค๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ถ„๋ฅ˜๊ธฐ๊ฐ€ ํŒ์ •๊ถŒ์„ ๊ฐ€์ง€๋ฉด, ์šด์˜ ์ž„๊ณ„์น˜/๊ฐ์‚ฌ ๋กœ๊ทธ/์žฌํ˜„์„ฑ์ด ์ข‹์•„์ง‘๋‹ˆ๋‹ค.
EXAONE์€ “์™œ ์ŠคํŒธ์ธ์ง€”๋ฅผ ์‚ฌ์šฉ์ž ์–ธ์–ด๋กœ ์„ค๋ช…ํ•˜๊ณ , “์ •์ฑ…์ ์œผ๋กœ ์–ด๋–ค ํ•ญ๋ชฉ์ด ๊ฑธ๋ ธ๋Š”์ง€”๋ฅผ ๊ทผ๊ฑฐ๋กœ ๋‚จ๊ธฐ๊ธฐ ์ข‹์Šต๋‹ˆ๋‹ค.

์ถ”์ฒœ 2์•ˆ: EXAONE = ํŒ๋ณ„๊ธฐ, KoELECTRA = 1์ฐจ ํ•„ํ„ฐ(๊ฒŒ์ดํŠธ)
๋ฉ”์ผ ์–‘์ด ๋งŽ๊ณ  ๋น„์šฉ/์ง€์—ฐ์ด ๋ฏผ๊ฐํ•˜๋ฉด ์ด ๊ตฌ์„ฑ์ด ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
ํ๋ฆ„

KoELECTRA๊ฐ€ ๋น ๋ฅด๊ฒŒ 1์ฐจ ์ ์ˆ˜ ์‚ฐ์ถœ
spam_prob๊ฐ€ ๋‚ฎ์œผ๋ฉด ๋ฐ”๋กœ ์ „๋‹ฌ(LLM ํ˜ธ์ถœ ์—†์Œ)

์• ๋งคํ•œ ๊ตฌ๊ฐ„(์˜ˆ: 0.35~0.75)๋งŒ EXAONE์ด ์ •์ฑ…ํŒ๋ณ„ + ์„ค๋ช… ์ƒ์„ฑ

๋งค์šฐ ๋†’์€ ๊ตฌ๊ฐ„์€ ๊ฒฉ๋ฆฌ/์ฐจ๋‹จ + (์„ ํƒ) EXAONE์ด ์‚ฌ์šฉ์ž ํ†ต์ง€ ๋ฌธ๊ตฌ๋งŒ ์ƒ์„ฑ
์žฅ์ 
LLM ํ˜ธ์ถœ๋Ÿ‰์ด ์ค„์–ด ๋น„์šฉ/๋ ˆ์ดํŠธ๋ฆฌ๋ฐ‹/์ง€์—ฐ์ด ์•ˆ์ •ํ™”๋ฉ๋‹ˆ๋‹ค.

“์• ๋งคํ•œ ์ผ€์ด์Šค”์—๋งŒ LLM์„ ์จ์„œ ํ’ˆ์งˆ์ด ์˜ฌ๋ผ๊ฐ‘๋‹ˆ๋‹ค.

MCP์—์„œ์˜ “์ •์ฑ…์  ๋ถ„๋ฆฌ” ๊ตฌํ˜„ ํฌ์ธํŠธ

๋ชจ๋ธ์„ ๋ถ„๋ฆฌํ–ˆ๋‹ค๊ณ  ๋์ด ์•„๋‹ˆ๋ผ, ์ •์ฑ… ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ถ„๋ฆฌํ•ด์•ผ ์ง„์งœ ์šด์˜์ด ๋ฉ๋‹ˆ๋‹ค.

1) Reader/Decider ์ถœ๋ ฅ ์Šคํ‚ค๋งˆ๋ฅผ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค

Reader๋Š” ๋ฐ˜๋“œ์‹œ ์ •ํ˜• JSON์œผ๋กœ๋งŒ ์ถœ๋ ฅ(์ž์œ ์„œ์ˆ  ๊ธˆ์ง€)
Decider๋„ prob/label/confidence ๊ณ ์ •
Policy ์—”์ง„์€ ๋ชจ๋ธ ์ถœ๋ ฅ์ด ์•„๋‹ˆ๋ผ ์Šคํ‚ค๋งˆ๋งŒ ๋ฏฟ๊ณ  ์˜์‚ฌ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ์‹œ(๊ฐœ๋…):

ReaderOutput = {features:{...}, evidence:[...], user_summary:"..." }

DeciderOutput = {spam_prob:0.83, label:"spam", confidence:"high"}
PolicyDecision = {action:"quarantine", reason_codes:["URL_MISMATCH","URGENT_MONEY"], user_message:"..."}

2) “๋ชจ๋ธ์ด ์ •์ฑ…์„ ์ •ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ” ๋ง‰์Šต๋‹ˆ๋‹ค

EXAONE์ด “์ฐจ๋‹จํ•˜์„ธ์š”” ๊ฐ™์€ ๊ฒฐ๋ก ์„ ๋‚ด๋ฆฌ๋”๋ผ๋„, Policy๊ฐ€ ๋ฌด์‹œํ•˜๊ณ  ๊ทผ๊ฑฐ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ตœ์ข… ์•ก์…˜์€ Policy ๋ฃฐ(์ž„๊ณ„์น˜/๋ฆฌ์ŠคํŠธ/์ปดํ”Œ๋ผ์ด์–ธ์Šค)๋กœ๋งŒ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

3) ์ถฉ๋Œ ์ฒ˜๋ฆฌ(Disagreement) ๊ทœ์น™์„ ๋‘ก๋‹ˆ๋‹ค

๋‘ ๋ชจ๋ธ์ด ๋‹ค ๊ด€์—ฌํ•˜๋Š” ๊ตฌ์กฐ(์ถ”์ฒœ 1์•ˆ์—์„œ EXAONE์ด ์œ„ํ—˜ ์‹ ํ˜ธ๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ๋ณด๊ณ , KoELECTRA๊ฐ€ ๋‚ฎ๊ฒŒ ๋ณด๋Š” ๋“ฑ)์—์„œ๋Š”:
KoELECTRA ๋‚ฎ์Œ + Reader ์œ„ํ—˜์ฝ”๋“œ ๋‹ค์ˆ˜ → deliver_with_warning ๋˜๋Š” ask_user_confirm
KoELECTRA ๋†’์Œ + Reader ๊ทผ๊ฑฐ ๋นˆ์•ฝ → suspicious๋กœ ๊ฒฉ๋ฆฌํ•˜๋˜ “๊ทผ๊ฑฐ ๋ถ€์กฑ” ๋กœ๊ทธ ๋‚จ๊ธฐ๊ณ  ์žฌํ•™์Šต ํ๋กœ

4) ์‚ฌ์šฉ์ž ์ „๋‹ฌ ๋ฉ”์‹œ์ง€๋Š” “์ •์ฑ… ๊ฒฐ๊ณผ + ์ตœ์†Œ ๊ทผ๊ฑฐ”๋กœ ํ†ต์ผํ•ฉ๋‹ˆ๋‹ค

“๋ชจ๋ธ์ด ์ด๋ ‡๊ฒŒ ๋งํ–ˆ์–ด์š””๊ฐ€ ์•„๋‹ˆ๋ผ
ํŒ์ •(์ŠคํŒธ/์˜์‹ฌ/์ •์ƒ)
๊ฑธ๋ฆฐ ๊ทœ์น™(์ด์œ  ์ฝ”๋“œ)
์‚ฌ์šฉ์ž ํ–‰๋™ ๊ฐ€์ด๋“œ(๋งํฌ ํด๋ฆญ ๊ธˆ์ง€, ๋ฐœ์‹ ์ž ํ™•์ธ ๋“ฑ)
์ด 3๊ฐœ๋งŒ ์ผ๊ด€๋˜๊ฒŒ.
์ œ ๊ฒฐ๋ก (์šด์˜ ์ถ”์ฒœ)
ํ’ˆ์งˆ/์žฌํ˜„์„ฑ/๊ฐ์‚ฌ๊นŒ์ง€ ์ƒ๊ฐํ•˜๋ฉด **์ถ”์ฒœ 1์•ˆ(์ฝ”์ผ๋ ‰=ํŒ๋ณ„๊ธฐ, EXAONE=ํŒ๋…๊ธฐ)**๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.

ํŠธ๋ž˜ํ”ฝ/๋น„์šฉ์ด ํฌ๋ฉด **์ถ”์ฒœ 2์•ˆ(์ฝ”์ผ๋ ‰ ๊ฒŒ์ดํŠธ + EXAONE ์˜ˆ์™ธ์ฒ˜๋ฆฌ)**๋กœ ๋ฐ”๊พธ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์›ํ•˜์‹œ๋ฉด, ์ง€๊ธˆ ๊ตฌ์ƒํ•˜์‹œ๋Š” MCP ๊ตฌ์กฐ(๋…ธ๋“œ ๊ตฌ์„ฑ, ํˆด ์ธํ„ฐํŽ˜์ด์Šค, ๋ฉ”์‹œ์ง€ ์Šคํ‚ค๋งˆ)๋ฅผ ๊ธฐ์ค€์œผ๋กœ LangGraph ํ˜•ํƒœ์˜ “Reader → Decider → Policy → Notify” ๊ทธ๋ž˜ํ”„๋ฅผ ๋ฐ”๋กœ ์„ค๊ณ„ํ•ด์„œ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.a

 

 

 


2์•ˆ์„ ์„ ํƒ ํ›„ MCP ์‹œ์Šคํ…œ ๋ชจ๋ธ ๊ตฌ์„ฑ

 

MCP ์‹œ์Šคํ…œ ๋ชจ๋ธ ๊ตฌ์„ฑ

 

ChatGPT - MCP ์‹œ์Šคํ…œ ๋ชจ๋ธ ๊ตฌ์„ฑ

Shared via ChatGPT

chatgpt.com

 

 

 


“ํ•™์Šต์šฉ + ๋‹คํƒœ์Šคํฌ(์ŠคํŒธ/๊ฐ์ • ๋“ฑ) + ํ’€ ํŒŒ์ธํŠœ๋‹ ๊ธฐ๋ณธ + LoRA ์˜ต์…˜” ๊ธฐ์ค€์œผ๋กœ ์žฌ๊ฐ€๊ณตํ•œ ์ปค์„œ์—๊ฒŒ ์ค„ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ œ์ž‘ํ•ด์ค˜.

์—ญํ• : ๋„ˆ๋Š” Python / HuggingFace Transformers / PEFT ์ „๋ฌธ๊ฐ€๋‹ค.
์•„๋ž˜ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๊ฒŒ ๊ธฐ์กด EXAONE(Qlora + SFTTrainer) ํ•™์Šต ์ฝ”๋“œ๋ฅผ
koELECTRA-small ๊ธฐ๋ฐ˜์˜ “๋ฒ”์šฉ ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ ํ•™์Šต ํŒŒ์ดํ”„๋ผ์ธ”์œผ๋กœ ๋ฆฌํŒฉํ„ฐ๋งํ•˜๋ผ.

์ด ์ฝ”๋“œ๋Š” ํ•™์Šต์šฉ์ด๋ฉฐ, ์ŠคํŒธ ๋ถ„๋ฅ˜๋ฟ ์•„๋‹ˆ๋ผ ๊ฐ์ • ๋ถ„์„ ๋“ฑ ๋‹คํƒœ์Šคํฌ ํ™•์žฅ์„ ์ „์ œ๋กœ ํ•œ๋‹ค.

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[ํ˜„์žฌ ์ฝ”๋“œ ์ƒํƒœ ์š”์•ฝ]
- ๊ธฐ์กด ์ฝ”๋“œ๋Š” EXAONE-2.4B + 4bit + LoRA(Qlora) + TRL SFTTrainer
- ์ƒ์„ฑ(CAUSAL_LM) ๋ชฉ์  ์ฝ”๋“œ์ด๋ฉฐ, text ์ปฌ๋Ÿผ๋งŒ ์‚ฌ์šฉ
- ๋„ˆ๋ฌด ๋А๋ฆฌ๊ณ , ๋ถ„๋ฅ˜ ํƒœ์Šคํฌ์— ๋ถ€์ ํ•ฉ

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[๋ฆฌํŒฉํ„ฐ๋ง ์ตœ์ข… ๋ชฉํ‘œ]
1) ๋ฒ ์ด์Šค ๋ชจ๋ธ: "monologg/koelectra-small-v3-discriminator"
2) ํƒœ์Šคํฌ: ํ…์ŠคํŠธ ๋ถ„๋ฅ˜ (SequenceClassification)
3) ๋‹คํƒœ์Šคํฌ ์ง€์›: spam, sentiment ๋“ฑ
4) ํ•™์Šต ๋ชจ๋“œ 2๊ฐ€์ง€ ์ง€์›
   - ๊ธฐ๋ณธ๊ฐ’: full finetuning
   - ์˜ต์…˜: LoRA (๋น„์–‘์žํ™”, QLoRA ๊ธˆ์ง€)
5) Trainer ๊ธฐ๋ฐ˜ ํ•™์Šต (TRL SFTTrainer ์‚ฌ์šฉ ๊ธˆ์ง€)
6) Dataset์€ HuggingFace Dataset.load_from_disk() ์‚ฌ์šฉ
7) ํ•™์Šต ๊ฒฐ๊ณผ๋Š” output_dir์— ์ €์žฅ (model + tokenizer + metrics.json)

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[๋ฐ˜๋“œ์‹œ ์ง€์ผœ์•ผ ํ•  ์„ค๊ณ„ ์›์น™]
- ์ƒ์„ฑ ๋ชจ๋ธ(EXAONE) ๊ด€๋ จ ์ฝ”๋“œ, import, ์„ค์ •์€ ์ „๋ถ€ ์ œ๊ฑฐ
- TaskType.CAUSAL_LM ์‚ฌ์šฉ ๊ธˆ์ง€
- QLoRA / 4bit / bitsandbytes / prepare_model_for_kbit_training ์‚ฌ์šฉ ๊ธˆ์ง€
- ๋ถ„๋ฅ˜ ํƒœ์Šคํฌ์ด๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ:
  - AutoModelForSequenceClassification
  - TaskType.SEQ_CLS (LoRA ์‚ฌ์šฉ ์‹œ)
- ๊ธฐ์กด ์ฝ”๋“œ์˜ lora_adapter ๊ฐœ๋…์€ “๋ถ„๋ฅ˜์šฉ LoRA”๋กœ ์žฌ์ž‘์„ฑ

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[๋ฐ์ดํ„ฐ ์š”๊ตฌ์‚ฌํ•ญ]
- Dataset์€ ๋‹ค์Œ ์ปฌ๋Ÿผ์„ ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค:
  - text: str
  - label: int (0 ~ num_labels-1)
- label ์ปฌ๋Ÿผ์ด ์—†์œผ๋ฉด ํ•™์Šต ์‹œ์ž‘ ์ „์— ๋ช…ํ™•ํ•œ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ๋ผ
- ํ•™์Šต ์‹œ์ž‘ ์‹œ ๋ฐ˜๋“œ์‹œ ์ถœ๋ ฅ:
  - train / val ์ƒ˜ํ”Œ ์ˆ˜
  - ์ปฌ๋Ÿผ ๋ชฉ๋ก
  - label ๋ถ„ํฌ (๊ฐ ํด๋ž˜์Šค count)

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[ํ•™์Šต ๋ชจ๋“œ ์„ค๊ณ„]
http://train.py ํ•˜๋‚˜์—์„œ ์•„๋ž˜ ๋ชจ๋“œ๋ฅผ ์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๋ผ.

1) full finetuning (๊ธฐ๋ณธ)
   - koELECTRA-small ์ „์ฒด ํŒŒ๋ผ๋ฏธํ„ฐ ํ•™์Šต
   - fp16 ์‚ฌ์šฉ (cuda ๊ฐ€๋Šฅ ์‹œ)
   - ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ณ  ์•ˆ์ •์ ์ธ baseline

2) LoRA mode (์˜ต์…˜)
   - peft.get_peft_model ์‚ฌ์šฉ
   - TaskType.SEQ_CLS
   - target_modules ๊ธฐ๋ณธ๊ฐ’:
     ["query", "key", "value", "dense"]
   - r=8 ๋˜๋Š” 16 ๊ธฐ๋ณธ๊ฐ’
   - ๋ฒ ์ด์Šค ๋ชจ๋ธ์€ ๊ณ ์ •, LoRA ์–ด๋Œ‘ํ„ฐ๋งŒ ํ•™์Šต

CLI ์˜ˆ์‹œ:
python http://train.py --task spam --mode full
python http://train.py --task sentiment --mode lora

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[TrainingArguments ํ•„์ˆ˜ ์กฐ๊ฑด]
- evaluation_strategy="steps" ๋˜๋Š” "epoch" (์ž˜๋ชป๋œ ํ‚ค ๊ธˆ์ง€)
- metric_for_best_model ๊ธฐ๋ณธ๊ฐ’: spam_recall ๋˜๋Š” macro_f1
- greater_is_better=True
- remove_unused_columns=False
- fp16์€ GPU์—์„œ๋งŒ ํ™œ์„ฑํ™”
- bf16=False (CUDA ํ˜ธํ™˜์„ฑ ์ด์Šˆ ๊ณ ๋ ค)

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[ํ‰๊ฐ€ ์ง€ํ‘œ ์š”๊ตฌ์‚ฌํ•ญ]
compute_metrics ํ•จ์ˆ˜์—์„œ ๋‹ค์Œ์„ ๋ฐ˜๋“œ์‹œ ๊ณ„์‚ฐ:
- accuracy
- macro_f1
- class๋ณ„ precision / recall
- (์ŠคํŒธ ํƒœ์Šคํฌ์ผ ๊ฒฝ์šฐ)
  - spam_recall
  - spam_f1

best model ์„ ์ • ๊ธฐ์ค€์€ task ์„ค์ •์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค.

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[ํด๋ž˜์Šค ๋ถˆ๊ท ํ˜• ๋Œ€์‘]
- --class_weight ์˜ต์…˜ ์ œ๊ณต
- ํ™œ์„ฑํ™” ์‹œ train labels ๊ธฐ์ค€์œผ๋กœ class weight ๊ณ„์‚ฐ
- CrossEntropyLoss(weight=...) ์ ์šฉ์„ ์œ„ํ•ด Trainer๋ฅผ ์ƒ์†ํ•˜์—ฌ compute_loss ์˜ค๋ฒ„๋ผ์ด๋“œ

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[์ถœ๋ ฅ ๊ตฌ์กฐ ์š”๊ตฌ์‚ฌํ•ญ]
output_dir ๊ตฌ์กฐ ์˜ˆ์‹œ:
models/
  spam/
    full/
      run_20240114_1200/
    lora/
      run_20240114_1230/
  sentiment/
    full/
    lora/

๊ฐ run ๋””๋ ‰ํ† ๋ฆฌ์— ๋ฐ˜๋“œ์‹œ ์ €์žฅ:
- config.json
- pytorch_model.bin ๋˜๋Š” safetensors
- tokenizer ํŒŒ์ผ๋“ค
- metrics.json

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[์ฃผ์˜ํ•ด์•ผ ํ•  ์‹ค์ˆ˜ ํฌ์ธํŠธ]
- SFTTrainer, formatting_func, dataset_text_field ์‚ฌ์šฉ ๊ธˆ์ง€
- eval_strategy ๊ฐ™์€ ์ž˜๋ชป๋œ TrainingArguments ํ‚ค ์‚ฌ์šฉ ๊ธˆ์ง€
- max_seq_length ๊ธฐ๋ณธ๊ฐ’์€ 128 ๋˜๋Š” 256 (2048 ๊ธˆ์ง€)
- accuracy๋งŒ ๋ณด๊ณ  best model ์„ ์ •ํ•˜์ง€ ๋ง ๊ฒƒ

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[๋ฌธ์„œํ™” ์š”๊ตฌ]
- ํŒŒ์ผ ์ƒ๋‹จ์— ์ฃผ์„์œผ๋กœ:
  - “์ด ์ฝ”๋“œ๋Š” ์ƒ์„ฑ ๋ชจ๋ธ์ด ์•„๋‹Œ ๋ถ„๋ฅ˜ ๋ชจ๋ธ ํ•™์Šต์šฉ์ž„”
  - “EXAONE์€ verdict/์„ค๋ช… ์ƒ์„ฑ ์ „์šฉ์œผ๋กœ ๋ถ„๋ฆฌ๋จ”
- ์‹คํ–‰ ์˜ˆ์‹œ CLI๋ฅผ ์ฃผ์„์œผ๋กœ ๋‚จ๊ธธ ๊ฒƒ

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[์ตœ์ข… ์‚ฐ์ถœ๋ฌผ]
- app/service/text_classifier/train.py
- (์„ ํƒ) app/service/text_classifier/lora_adapter.py
- ์ฝ”๋“œ๊ฐ€ ์™œ ์ด๋ ‡๊ฒŒ ๋ฐ”๋€Œ์—ˆ๋Š”์ง€ ํ•ต์‹ฌ ํฌ์ธํŠธ๋ฅผ ์ฃผ์„์œผ๋กœ ๊ฐ„๋‹จํžˆ ์„ค๋ช…

์ด ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋Š” ์ฝ”๋“œ๋กœ ๋ฆฌํŒฉํ„ฐ๋งํ•˜๋ผ.

 


 

LoRA ์–ด๋Œ‘ํ„ฐ๋Š” ์™„์ „ํžˆ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค!

๋„ค, LoRA ์–ด๋Œ‘ํ„ฐ ๊ธฐ๋Šฅ ์ž์ฒด๋Š” ์—ฌ์ „ํžˆ ์žˆ์Šต๋‹ˆ๋‹ค!

โœ… LoRA ์–ด๋Œ‘ํ„ฐ ๊ธฐ๋Šฅ ์กด์žฌ ํ™•์ธ

[2 tools called]

๐ŸŽฏ LoRA ์–ด๋Œ‘ํ„ฐ๋Š” ์™„์ „ํžˆ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค!

๐Ÿ“‹ LoRA ๊ธฐ๋Šฅ ๊ตฌ์„ฑ์š”์†Œ:

setup_classification_lora() ํ•จ์ˆ˜ - ๋ถ„๋ฅ˜์šฉ LoRA ์–ด๋Œ‘ํ„ฐ ์„ค์ •
LoRA ์„ค์ • ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค:
--lora_r (rank)
--lora_alpha
--lora_dropout
--target_modules
LoRA ๋ชจ๋“œ ์ง€์›: --mode lora

๐Ÿš€ LoRA ์‚ฌ์šฉ๋ฒ•:

# LoRA ์–ด๋Œ‘ํ„ฐ๋กœ ํ•™์Šต
python http://train.py --task spam --mode lora
# LoRA ํŒŒ๋ผ๋ฏธํ„ฐ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•
python http://train.py --task spam --mode lora --lora_r 16 --lora_alpha 32
# ๊ฐ์ • ๋ถ„์„ LoRA ํ•™์Šต
python http://train.py --task sentiment --mode lora --lora_r 8
๐Ÿ”ง LoRA vs Full Finetuning:
๋ชจ๋“œ
์„ค๋ช…
๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰
ํ•™์Šต ์†๋„

--mode full

์ „์ฒด ํŒŒ๋ผ๋ฏธํ„ฐ ํ•™์Šต
๋†’์Œ
๋А๋ฆผ
--mode lora
LoRA ์–ด๋Œ‘ํ„ฐ๋งŒ ํ•™์Šต
๋‚ฎ์Œ
๋น ๋ฆ„
๊ฒฐ๋ก : LoRA ์–ด๋Œ‘ํ„ฐ ๊ธฐ๋Šฅ์€ ๊ทธ๋Œ€๋กœ ์žˆ๊ณ , ์˜คํžˆ๋ ค ๋” ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๋‹จ์ง€ ํŒŒ์ผ๋ช…์ด lora_adapter.py → http://train.py๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค.

 



์ŠคํŒธ๋ฉ”์ผ ํ˜ผ์šฉ ๋ฐ์ดํ„ฐ์…‹ ์œผ๋กœ lora ๋ฐฉ์‹์œผ๋กœ ํ•™์Šตํ•˜๋Š” ํ”„๋กฌํ”„ํŠธ :

 

@app/service/spam_classifier/train.py ์—์„œ @app/model/models--monologg--koelectra-small-v3-discriminator ์ด๊ฒƒ์œผ๋กœ @app/data/๋ฏผ์›(์ฝœ์„ผํ„ฐ) ์งˆ์˜์‘๋‹ต_K์‡ผํ•‘_ํ†ตํ•ฉ_Training.jsonl ์ด ๋ฐ์ดํ„ฐ๋กœ lora ๋ฐฉ์‹์œผ๋กœ ํŒŒ์ธํŠœ๋‹ ์„ ํ•ด์ค˜

 


์ •์ƒ๋ฉ”์ผ ๊ณผ ์ŠคํŒธ๋ฉ”์ผ ํ˜ผ์šฉ ๋ฐ์ดํ„ฐ์…‹ ๋งŒ๋“ค๊ธฐ

1์ฐจ ํ”„๋กฌํ”„ํŠธ: ๋ฏผ์›(์ฝœ์„ผํ„ฐ) ์งˆ์˜์‘๋‹ต_K์‡ผํ•‘_๋ฐฐ์†ก_Training.json ์ด ํŒŒ์ผ์„ 1500 ๊ฐœ ๋งŒ jsonl ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ๋Š” ์‚ญ์ œํ•ด์ค˜.

2์ฐจ ํ”„๋กฌํ”„ํŠธ : ๋ฏผ์›(์ฝœ์„ผํ„ฐ) ์งˆ์˜์‘๋‹ต_K์‡ผํ•‘_๋ฐฐ์†ก_Training.jsonl ์ด๊ฒƒ๊ณผ ๋ฏผ์›(์ฝœ์„ผํ„ฐ) ์งˆ์˜์‘๋‹ต_K์‡ผํ•‘_์—…๋ฌด์ฒ˜๋ฆฌ_Training.jsonl ์ด๊ฒƒ์„ ๋ฌถ์–ด์„œ ํ•˜๋‚˜๋กœ ๋งŒ๋“ค์–ด์ค˜. (๊ณต๊ณต , ์ƒ๋‹ด , ๋ฏผ์› ๋“ฑ๋“ฑ ์œ ์‚ฌํ•œ ๋ฐ์ดํ„ฐ๋Š” ๋ชจ๋‘ ์‚ฌ์šฉ๊ฐ€๋Šฅ)

3์ฐจ ํ”„๋กฌํ”„ํŠธ : ์—ฌ๊ธฐ์—์„œ "์ƒ๋‹ด์‚ฌ์งˆ๋ฌธ(์š”์ฒญ)": "ใ…‡ใ…‡ใ…‡์•„ํŒŒํŠธ ๋งž๋‚˜์š”?" --> ์ด ๋ถ€๋ถ„๋งŒ ์ •์ƒ ์ด๋ฉ”์ผ์˜ ์ œ๋ชฉ์ฒ˜๋Ÿผ ๋ฐ”๊พธ๊ณ  , spam_data.jsonl ์— ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ํ•ฉ์ณ์ค˜. ์ •์ƒ ๋ฐ์ดํ„ฐ์™€ ์ŠคํŒธ๋ฐ์ดํ„ฐ์˜ ํ˜ผํ•ฉํ˜•ํƒœ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•ด.

์ตœ์ข… ๊ฒฐ๊ณผ :
๐Ÿ“Š ๋ฐ์ดํ„ฐ์…‹ ๊ตฌ์„ฑ:
์ด ๋ฐ์ดํ„ฐ ์ˆ˜: 2,720๊ฐœ
์ •์ƒ ๋ฐ์ดํ„ฐ: 1,360๊ฐœ (50%)
์ŠคํŒธ ๋ฐ์ดํ„ฐ: 1,360๊ฐœ (50%)
๋น„์œจ: 1:1 ๊ท ํ˜•์žกํžŒ ๋ฐ์ดํ„ฐ์…‹
๐Ÿ‘‰๐Ÿป์ •์ƒ๋ฉ”์ผ ๋ฐ์ดํ„ฐ์…‹๋งŒ ์žˆ๋Š”๊ฒƒ : ์–ด์ œ ์ŠคํŒธ๋งŒ ํ›ˆ๋ จ์‹œํ‚จ ๋ชจ๋ธ์šฉ
https://drive.google.com/file/d/1jHCFnrJhX9a5iHFCijx7XCT9zpihuoN1/view?usp=sharing
๐Ÿ‘‰๐Ÿป ์ •์ƒ, ์ŠคํŒธ์ด ๋žœ๋ค์œผ๋กœ ํ˜ผ์šฉ๋œ ๋ฐ์ดํ„ฐ์…‹ : ์–ด์ œ ํ›ˆ๋ จ์‹œํ‚ค์ง€ ์•Š๊ณ  , ์˜ค๋Š˜ ์ฒ˜์Œ ํ›ˆ๋ จ์‹œํ‚ค๋Š” ๋ชจ๋ธ์šฉ
์ŠคํŒธ๋ฉ”์ผ ํ˜ผ์šฉ ๋ฐ์ดํ„ฐ์…‹ ๋งŒ๋“ค๊ธฐ
https://drive.google.com/file/d/1KDBwOg1c1ened7tLUNd-_7tGlIC-aQL4/view?usp=sharing
๐Ÿ”„ ๋ณ€ํ™˜ ๊ณผ์ •:
๐Ÿ‘‰๐Ÿป๋ฏผ์› ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ: ๋ฏผ์›(์ฝœ์„ผํ„ฐ) ์งˆ์˜์‘๋‹ต_K์‡ผํ•‘_ํ†ตํ•ฉ_Training.jsonl์—์„œ "์ƒ๋‹ด์‚ฌ์งˆ๋ฌธ(์š”์ฒญ)" ํ•„๋“œ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์ถ”์ถœ
๐Ÿ‘‰๐Ÿป์ •์ƒ ์ด๋ฉ”์ผ ์ œ๋ชฉ ๋ณ€ํ™˜: ๋‹ค์–‘ํ•œ ์ด๋ฉ”์ผ ์ œ๋ชฉ ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž์—ฐ์Šค๋Ÿฌ์šด ์ •์ƒ ์ด๋ฉ”์ผ ์ œ๋ชฉ์œผ๋กœ ๋ณ€ํ™˜
์˜ˆ: "์ฃผ๋ฌธ ํ™•์ธ: ๊ณ ๊ฐ๋‹˜ ์ •๋ณด ํ™•์ธ ํ›„ ๋„์›€ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค"
์˜ˆ: "๋ฐฐ์†ก ์•ˆ๋‚ด: ๋ฌด์—‡์„ ๋„์™€๋“œ๋ฆด๊นŒ์š”?"
๐Ÿ‘‰๐Ÿปํ˜•์‹ ํ†ต์ผ: spam_data.jsonl๊ณผ ๋™์ผํ•œ JSON ๊ตฌ์กฐ๋กœ ๋ณ€ํ™˜
๋ผ๋ฒจ๋ง: ์ •์ƒ ๋ฐ์ดํ„ฐ๋Š” category: 0, ์ŠคํŒธ ๋ฐ์ดํ„ฐ๋Š” category: 1๋กœ ๊ตฌ๋ถ„
๐Ÿ‘‰๐Ÿป๋ฐ์ดํ„ฐ ํ˜ผํ•ฉ: ์ •์ƒ๊ณผ ์ŠคํŒธ ๋ฐ์ดํ„ฐ๋ฅผ 1:1 ๋น„์œจ๋กœ ์„ž์–ด์„œ ์ตœ์ข… ๋ฐ์ดํ„ฐ์…‹ ์ƒ์„ฑ

 

 

 


fastapi ์—์„œ ๋‘๊ฐœ์˜ ์—์ด์ „ํŠธ๋ฅผ ๋žญ๊ทธ๋ž˜ํ”„ ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ํ”„๋กฌํ”„ํŠธ

fastapi์—์„œ ์—์ด์ „ํŠธ ๋‘๊ฐœ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •์—์„œ , ๋žญ๊ทธ๋ž˜ํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ๋žญ๊ทธ๋ž˜ํ”„ ๋Š” ์ด๋ฏธ ์„ค์น˜๋˜์–ด ์žˆ๋‹ค. ์ด ๋‘๊ฐœ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ํˆด ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ค˜. ์—์ด์ „ํŠธ๋Š” koelectra ๋Š” ํŒ๋ณ„๊ธฐ ๋กœ exawon ์ด ์ด๋ฏธ ์ŠคํŒธ๋ฉ”์ผ ํŒ๋…๊ธฐ ํ›ˆ๋ จ์ด ๋˜์–ด ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ koelectra ๊ฒŒ์ดํŠธ์›จ์ด๋กœ์„œ exawon ์— ์—ฐ๊ฒฐ๋˜๋„๋ก ํ•ด์•ผํ•œ๋‹ค.

FastAPI ์—์ด์ „ํŠธ ๋‘ ๊ฐœ๋ฅผ LangGraph๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ตฌ์ถ• ๊ณผ์ •์„ ์„ค๋ช…๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„

๊ธฐ๋ณธ ํ๋ฆ„
์ด๋ฉ”์ผ ์ž…๋ ฅ → KoELECTRA ๊ฒŒ์ดํŠธ์›จ์ด → ์กฐ๊ฑด ๋ถ„๊ธฐ → EXAONE ์ •๋ฐ€ ๊ฒ€์‚ฌ or ์ฆ‰์‹œ ์‘๋‹ต

ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ
State ๊ด€๋ฆฌ ๊ฐ์ฒด (์ด๋ฉ”์ผ ํ…์ŠคํŠธ, ํŒ๋ณ„ ๊ฒฐ๊ณผ, ์‹ ๋ขฐ๋„ ์ ์ˆ˜ ๋“ฑ)
๋‘ ๊ฐœ์˜ ๋…ธ๋“œ ํ•จ์ˆ˜ (๊ฐ ์—์ด์ „ํŠธ ๋ž˜ํ•‘)
๋ผ์šฐํŒ… ๋กœ์ง (์กฐ๊ฑด๋ถ€ ๋ถ„๊ธฐ)
FastAPI ์—”๋“œํฌ์ธํŠธ

2. LangGraph State ์„ค๊ณ„

StateGraph์˜ ์ƒํƒœ ๊ด€๋ฆฌ
TypedDict๋กœ ์ƒํƒœ ์Šคํ‚ค๋งˆ ์ •์˜ ํ•„์š”
์ด๋ฉ”์ผ ์›๋ณธ, KoELECTRA ์Šค์ฝ”์–ด, ์ŠคํŒธ ํ›„๋ณด ์—ฌ๋ถ€, ์ตœ์ข… ๊ฒฐ๊ณผ ๋“ฑ์„ ๋‹ด์„ ํ•„๋“œ ๊ตฌ์„ฑ
๊ฐ ๋…ธ๋“œ๊ฐ€ ์ด ์ƒํƒœ๋ฅผ ์ฝ๊ณ  ์—…๋ฐ์ดํŠธํ•˜๋ฉด์„œ ์ง„ํ–‰

3. ๋…ธ๋“œ ํ•จ์ˆ˜ ๊ตฌ์„ฑ

์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ: KoELECTRA ๊ฒŒ์ดํŠธ์›จ์ด
์ž…๋ ฅ๋ฐ›์€ ์ด๋ฉ”์ผ ํ…์ŠคํŠธ๋ฅผ KoELECTRA๋กœ ์ถ”๋ก 
์ŠคํŒธ ๊ฐ€๋Šฅ์„ฑ ์Šค์ฝ”์–ด ๊ณ„์‚ฐ (0~1 ํ™•๋ฅ ๊ฐ’)
์ž„๊ณ„๊ฐ’ ์„ค์ • (์˜ˆ: 0.3 ์ด์ƒ์ด๋ฉด ์ •๋ฐ€ ๊ฒ€์‚ฌ ํ•„์š”)
State์— ํŒ๋ณ„ ๊ฒฐ๊ณผ์™€ ์Šค์ฝ”์–ด ์ €์žฅ

๋‘ ๋ฒˆ์งธ ๋…ธ๋“œ: EXAONE ์ •๋ฐ€ ๊ฒ€์‚ฌ
KoELECTRA๊ฐ€ ์ŠคํŒธ ํ›„๋ณด๋กœ ํŒ๋‹จํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‹คํ–‰
EXAONE ๋ชจ๋ธ๋กœ ์ƒ์„ธ ๋ถ„์„ ์ˆ˜ํ–‰
์ŠคํŒธ ์—ฌ๋ถ€, ์‹ ๋ขฐ๋„, ๋ถ„์„ ๊ทผ๊ฑฐ๋ฅผ State์— ์ €์žฅ

์„ธ ๋ฒˆ์งธ ๋…ธ๋“œ: ๋ฐ”์ดํŒจ์Šค ์ฒ˜๋ฆฌ
KoELECTRA๊ฐ€ ์ •์ƒ ๋ฉ”์ผ๋กœ ํŒ๋‹จํ•œ ๊ฒฝ์šฐ
EXAONE ํ˜ธ์ถœ ์—†์ด ๋ฐ”๋กœ ์ •์ƒ ๋ฉ”์ผ๋กœ ๊ฒฐ๋ก 

4. ๋ผ์šฐํŒ… ๋กœ์ง (ํ•ต์‹ฌ!)

Conditional Edge ์„ค์ •
KoELECTRA ๋…ธ๋“œ ์‹คํ–‰ ํ›„ State๋ฅผ ํ™•์ธ
์ŠคํŒธ ํ›„๋ณด ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋‹ค์Œ ๋…ธ๋“œ ๊ฒฐ์ •
is_spam_candidate == True → EXAONE ๋…ธ๋“œ๋กœ
is_spam_candidate == False → ๋ฐ”์ดํŒจ์Šค ๋…ธ๋“œ๋กœ

5. ๊ทธ๋ž˜ํ”„ ๊ตฌ์„ฑ ์ˆœ์„œ

StateGraph ์ƒ์„ฑ ๋ฐ ๋นŒ๋“œ
StateGraph ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ (State ํƒ€์ž… ์ง€์ •)
๊ฐ ๋…ธ๋“œ ํ•จ์ˆ˜๋ฅผ add_node๋กœ ๋“ฑ๋ก
set_entry_point๋กœ ์‹œ์ž‘ ๋…ธ๋“œ ์ง€์ • (KoELECTRA)
add_conditional_edges๋กœ ์กฐ๊ฑด๋ถ€ ๋ถ„๊ธฐ ์„ค์ •
์ข…๋ฃŒ ๋…ธ๋“œ๋“ค์— add_edge๋กœ END ์—ฐ๊ฒฐ
compile()๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ

6. FastAPI ํ†ตํ•ฉ

์—”๋“œํฌ์ธํŠธ ๊ตฌ์„ฑ
POST /spam-check ์—”๋“œํฌ์ธํŠธ ์ƒ์„ฑ
Request Body๋กœ ์ด๋ฉ”์ผ ํ…์ŠคํŠธ ๋ฐ›๊ธฐ
์ดˆ๊ธฐ State ๊ฐ์ฒด ์ƒ์„ฑํ•˜์—ฌ ๊ทธ๋ž˜ํ”„์— ์ „๋‹ฌ
graph.invoke(initial_state) ์‹คํ–‰
์ตœ์ข… State์˜ ๊ฒฐ๊ณผ๋ฅผ JSON ์‘๋‹ต์œผ๋กœ ๋ฐ˜ํ™˜

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ณ ๋ ค์‚ฌํ•ญ
LangGraph๋Š” ๋™๊ธฐ/๋น„๋™๊ธฐ ๋ชจ๋‘ ์ง€์›
FastAPI์˜ async def์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ ์‹œ await graph.ainvoke() ์‚ฌ์šฉ
๋ชจ๋ธ ์ถ”๋ก ์ด ๋ฌด๊ฑฐ์šฐ๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ํƒœ์Šคํฌ ๊ณ ๋ ค

7. ์„ฑ๋Šฅ ์ตœ์ ํ™” ํฌ์ธํŠธ

๊ฒŒ์ดํŠธ์›จ์ด ํšจ์œจ์„ฑ
KoELECTRA๋Š” ๊ฐ€๋ณ๊ณ  ๋น ๋ฅธ ๋ชจ๋ธ์ด๋ฏ€๋กœ ๋ชจ๋“  ์š”์ฒญ 1์ฐจ ํ•„ํ„ฐ๋ง
์ •์ƒ ๋ฉ”์ผ์˜ ๊ฒฝ์šฐ EXAONE ํ˜ธ์ถœ ์ƒ๋žต์œผ๋กœ ์‘๋‹ต ์‹œ๊ฐ„ ๋‹จ์ถ•
์ž„๊ณ„๊ฐ’ ํŠœ๋‹์œผ๋กœ ์ •๋ฐ€๋„/์†๋„ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„ ์กฐ์ ˆ

๋ชจ๋ธ ๋กœ๋”ฉ
์•ฑ ์‹œ์ž‘ ์‹œ ๋‘ ๋ชจ๋ธ ๋ชจ๋‘ ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋“œ
FastAPI์˜ lifespan ์ด๋ฒคํŠธ ํ™œ์šฉ
๋˜๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์œผ๋กœ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ๊ตฌํ˜„

8. ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ๋กœ๊น…

State ์ถ”์ 
๊ฐ ๋…ธ๋“œ ์‹คํ–‰ ์‹œ ๋กœ๊ทธ ๊ธฐ๋ก
KoELECTRA ์Šค์ฝ”์–ด ๋ถ„ํฌ ๋ชจ๋‹ˆํ„ฐ๋ง
EXAONE ํ˜ธ์ถœ ๋นˆ๋„ ์ถ”์ ํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด ํšจ์œจ์„ฑ ํ‰๊ฐ€

์ด๋Ÿฐ ๊ตฌ์กฐ๋กœ ๋‘ ์—์ด์ „ํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด, KoELECTRA๊ฐ€ ํšจ์œจ์ ์ธ 1์ฐจ ํ•„ํ„ฐ ์—ญํ• ์„ ํ•˜๊ณ , EXAONE์€ ์˜์‹ฌ์Šค๋Ÿฌ์šด ์ผ€์ด์Šค๋งŒ ์ •๋ฐ€ ๋ถ„์„ํ•˜๋Š” 2๋‹จ๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ์ด ์™„์„ฑ๋ฉ๋‹ˆ๋‹ค.

https://chatgpt.com/share/69687e94-5bb0-8011-b96c-84ae74026759

 

ChatGPT - LangGraph ์—์ด์ „ํŠธ ์—ฐ๊ฒฐ

Shared via ChatGPT

chatgpt.com

 


๋‘๊ฐœ์˜ ์—์ด์ „ํŠธ๋ฅผ ๋žญ๊ทธ๋ž˜ํ”„ ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ํ”„๋กฌํ”„ํŠธ

์—์ด์ „ํŠธ ๋‘๊ฐœ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •์—์„œ , ๋žญ๊ทธ๋ž˜ํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ๋žญ๊ทธ๋ž˜ํ”„ ๋Š” ์ด๋ฏธ ์„ค์น˜๋˜์–ด ์žˆ๋‹ค. ์ด ๋‘๊ฐœ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ํˆด ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ค˜. ์—์ด์ „ํŠธ๋Š” koelectra ๋Š” ํŒ๋ณ„๊ธฐ ๋กœ exawon ์ด ์ด๋ฏธ ์ŠคํŒธ๋ฉ”์ผ ํŒ๋…๊ธฐ ํ›ˆ๋ จ์ด ๋˜์–ด ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ koelectra ๊ฒŒ์ดํŠธ์›จ์ด๋กœ์„œ exawon ์— ์—ฐ๊ฒฐ๋˜๋„๋ก ํ•ด์•ผํ•œ๋‹ค.

๋‹ต๋ณ€ :
FastAPI ์—์ด์ „ํŠธ ๋‘ ๊ฐœ๋ฅผ LangGraph๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ตฌ์ถ• ๊ณผ์ •์„ ์„ค๋ช…๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„

๊ธฐ๋ณธ ํ๋ฆ„
์ด๋ฉ”์ผ ์ž…๋ ฅ → KoELECTRA ๊ฒŒ์ดํŠธ์›จ์ด → ์กฐ๊ฑด ๋ถ„๊ธฐ → EXAONE ์ •๋ฐ€ ๊ฒ€์‚ฌ or ์ฆ‰์‹œ ์‘๋‹ต

ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ
State ๊ด€๋ฆฌ ๊ฐ์ฒด (์ด๋ฉ”์ผ ํ…์ŠคํŠธ, ํŒ๋ณ„ ๊ฒฐ๊ณผ, ์‹ ๋ขฐ๋„ ์ ์ˆ˜ ๋“ฑ)
๋‘ ๊ฐœ์˜ ๋…ธ๋“œ ํ•จ์ˆ˜ (๊ฐ ์—์ด์ „ํŠธ ๋ž˜ํ•‘)
๋ผ์šฐํŒ… ๋กœ์ง (์กฐ๊ฑด๋ถ€ ๋ถ„๊ธฐ)
FastAPI ์—”๋“œํฌ์ธํŠธ

2. LangGraph State ์„ค๊ณ„

StateGraph์˜ ์ƒํƒœ ๊ด€๋ฆฌ
TypedDict๋กœ ์ƒํƒœ ์Šคํ‚ค๋งˆ ์ •์˜ ํ•„์š”
์ด๋ฉ”์ผ ์›๋ณธ, KoELECTRA ์Šค์ฝ”์–ด, ์ŠคํŒธ ํ›„๋ณด ์—ฌ๋ถ€, ์ตœ์ข… ๊ฒฐ๊ณผ ๋“ฑ์„ ๋‹ด์„ ํ•„๋“œ ๊ตฌ์„ฑ
๊ฐ ๋…ธ๋“œ๊ฐ€ ์ด ์ƒํƒœ๋ฅผ ์ฝ๊ณ  ์—…๋ฐ์ดํŠธํ•˜๋ฉด์„œ ์ง„ํ–‰

3. ๋…ธ๋“œ ํ•จ์ˆ˜ ๊ตฌ์„ฑ

์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ: KoELECTRA ๊ฒŒ์ดํŠธ์›จ์ด
์ž…๋ ฅ๋ฐ›์€ ์ด๋ฉ”์ผ ํ…์ŠคํŠธ๋ฅผ KoELECTRA๋กœ ์ถ”๋ก 
์ŠคํŒธ ๊ฐ€๋Šฅ์„ฑ ์Šค์ฝ”์–ด ๊ณ„์‚ฐ (0~1 ํ™•๋ฅ ๊ฐ’)
์ž„๊ณ„๊ฐ’ ์„ค์ • (์˜ˆ: 0.3 ์ด์ƒ์ด๋ฉด ์ •๋ฐ€ ๊ฒ€์‚ฌ ํ•„์š”)
State์— ํŒ๋ณ„ ๊ฒฐ๊ณผ์™€ ์Šค์ฝ”์–ด ์ €์žฅ

๋‘ ๋ฒˆ์งธ ๋…ธ๋“œ: EXAONE ์ •๋ฐ€ ๊ฒ€์‚ฌ
KoELECTRA๊ฐ€ ์ŠคํŒธ ํ›„๋ณด๋กœ ํŒ๋‹จํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‹คํ–‰
EXAONE ๋ชจ๋ธ๋กœ ์ƒ์„ธ ๋ถ„์„ ์ˆ˜ํ–‰
์ŠคํŒธ ์—ฌ๋ถ€, ์‹ ๋ขฐ๋„, ๋ถ„์„ ๊ทผ๊ฑฐ๋ฅผ State์— ์ €์žฅ

์„ธ ๋ฒˆ์งธ ๋…ธ๋“œ: ๋ฐ”์ดํŒจ์Šค ์ฒ˜๋ฆฌ
KoELECTRA๊ฐ€ ์ •์ƒ ๋ฉ”์ผ๋กœ ํŒ๋‹จํ•œ ๊ฒฝ์šฐ
EXAONE ํ˜ธ์ถœ ์—†์ด ๋ฐ”๋กœ ์ •์ƒ ๋ฉ”์ผ๋กœ ๊ฒฐ๋ก 

4. ๋ผ์šฐํŒ… ๋กœ์ง (ํ•ต์‹ฌ!)

Conditional Edge ์„ค์ •
KoELECTRA ๋…ธ๋“œ ์‹คํ–‰ ํ›„ State๋ฅผ ํ™•์ธ
์ŠคํŒธ ํ›„๋ณด ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋‹ค์Œ ๋…ธ๋“œ ๊ฒฐ์ •
is_spam_candidate == True → EXAONE ๋…ธ๋“œ๋กœ
is_spam_candidate == False → ๋ฐ”์ดํŒจ์Šค ๋…ธ๋“œ๋กœ

5. ๊ทธ๋ž˜ํ”„ ๊ตฌ์„ฑ ์ˆœ์„œ

StateGraph ์ƒ์„ฑ ๋ฐ ๋นŒ๋“œ
StateGraph ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ (State ํƒ€์ž… ์ง€์ •)
๊ฐ ๋…ธ๋“œ ํ•จ์ˆ˜๋ฅผ add_node๋กœ ๋“ฑ๋ก
set_entry_point๋กœ ์‹œ์ž‘ ๋…ธ๋“œ ์ง€์ • (KoELECTRA)
add_conditional_edges๋กœ ์กฐ๊ฑด๋ถ€ ๋ถ„๊ธฐ ์„ค์ •
์ข…๋ฃŒ ๋…ธ๋“œ๋“ค์— add_edge๋กœ END ์—ฐ๊ฒฐ
compile()๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ

6. FastAPI ํ†ตํ•ฉ

์—”๋“œํฌ์ธํŠธ ๊ตฌ์„ฑ
POST /spam-check ์—”๋“œํฌ์ธํŠธ ์ƒ์„ฑ
Request Body๋กœ ์ด๋ฉ”์ผ ํ…์ŠคํŠธ ๋ฐ›๊ธฐ
์ดˆ๊ธฐ State ๊ฐ์ฒด ์ƒ์„ฑํ•˜์—ฌ ๊ทธ๋ž˜ํ”„์— ์ „๋‹ฌ
graph.invoke(initial_state) ์‹คํ–‰
์ตœ์ข… State์˜ ๊ฒฐ๊ณผ๋ฅผ JSON ์‘๋‹ต์œผ๋กœ ๋ฐ˜ํ™˜

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ณ ๋ ค์‚ฌํ•ญ
LangGraph๋Š” ๋™๊ธฐ/๋น„๋™๊ธฐ ๋ชจ๋‘ ์ง€์›
FastAPI์˜ async def์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ ์‹œ await graph.ainvoke() ์‚ฌ์šฉ
๋ชจ๋ธ ์ถ”๋ก ์ด ๋ฌด๊ฑฐ์šฐ๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ํƒœ์Šคํฌ ๊ณ ๋ ค

7. ์„ฑ๋Šฅ ์ตœ์ ํ™” ํฌ์ธํŠธ

๊ฒŒ์ดํŠธ์›จ์ด ํšจ์œจ์„ฑ
KoELECTRA๋Š” ๊ฐ€๋ณ๊ณ  ๋น ๋ฅธ ๋ชจ๋ธ์ด๋ฏ€๋กœ ๋ชจ๋“  ์š”์ฒญ 1์ฐจ ํ•„ํ„ฐ๋ง
์ •์ƒ ๋ฉ”์ผ์˜ ๊ฒฝ์šฐ EXAONE ํ˜ธ์ถœ ์ƒ๋žต์œผ๋กœ ์‘๋‹ต ์‹œ๊ฐ„ ๋‹จ์ถ•
์ž„๊ณ„๊ฐ’ ํŠœ๋‹์œผ๋กœ ์ •๋ฐ€๋„/์†๋„ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„ ์กฐ์ ˆ

๋ชจ๋ธ ๋กœ๋”ฉ
์•ฑ ์‹œ์ž‘ ์‹œ ๋‘ ๋ชจ๋ธ ๋ชจ๋‘ ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋“œ
FastAPI์˜ lifespan ์ด๋ฒคํŠธ ํ™œ์šฉ
๋˜๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์œผ๋กœ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ๊ตฌํ˜„

8. ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ๋กœ๊น…

State ์ถ”์ 
๊ฐ ๋…ธ๋“œ ์‹คํ–‰ ์‹œ ๋กœ๊ทธ ๊ธฐ๋ก
KoELECTRA ์Šค์ฝ”์–ด ๋ถ„ํฌ ๋ชจ๋‹ˆํ„ฐ๋ง
EXAONE ํ˜ธ์ถœ ๋นˆ๋„ ์ถ”์ ํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด ํšจ์œจ์„ฑ ํ‰๊ฐ€

์ด๋Ÿฐ ๊ตฌ์กฐ๋กœ ๋‘ ์—์ด์ „ํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด, KoELECTRA๊ฐ€ ํšจ์œจ์ ์ธ 1์ฐจ ํ•„ํ„ฐ ์—ญํ• ์„ ํ•˜๊ณ , EXAONE์€ ์˜์‹ฌ์Šค๋Ÿฌ์šด ์ผ€์ด์Šค๋งŒ ์ •๋ฐ€ ๋ถ„์„ํ•˜๋Š” 2๋‹จ๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ์ด ์™„์„ฑ๋ฉ๋‹ˆ๋‹ค.

 

 


๋ชจ๋ธ ์˜ ์ข…๋ฅ˜์™€ ๋ถ„๋ฆฌํ•˜๋Š” ํ”„๋กฌํ”„ํŠธ

.py (23-54) ์ด ์ค‘์—์„œ ์ƒํƒœ๊ด€๋ฆฌ ๋ชจ๋ธ ์€ @app/service/verdict_agent/state_model.py ๋กœ ์ด๋™ํ•˜๊ณ  , ํด๋ž˜์Šค ์ด๋ฆ„์˜ ์ ‘๋ฏธ์‚ฌ๋ฅผ state ๋กœ ์ง€์ •ํ•ด ์ฃผ๊ณ  , ๋‚˜๋จธ์ง€๋Š” ๊ทธ๋Œ€๋กœ @app/service/verdict_agent/base_model.py ์— ์ด๋™์‹œํ‚ค๊ณ  , import ๋Š” ์ž๋™ ์ˆ˜์ •ํ•ด์ค˜.

 

 


์—์ด์ „ํŠธ๋ฅผ ์—‘์‚ฌ์›์„ ํˆด๋กœ ๋žฉํ•‘ํ•˜๋Š” ์ฝ”๋“œ @app/service/verdict_agent/graph.py ์—ฌ๊ธฐ์— ๋žญ๊ทธ๋ž˜ํ”„๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฐ€์šด๋ฐ @app/router/mcp_router.py ์—์ด์ „ํŠธ๋ฅผ ์—‘์‚ฌ์›์„ ํˆด๋กœ ๋žฉํ•‘ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์‚ญ์„ฑํ•ด์ค˜.