Spaces:
Sleeping
Sleeping
Lily LLM - ์ปจํ ์คํธ ๊ด๋ฆฌ ๋ฐ LoRA/QLoRA ์์คํ
๐ ๊ฐ์
Lily LLM ํ๋ก์ ํธ์ ๋จ๊ธฐ ๊ธฐ์ต(์ปจํ ์คํธ ์ฐฝ) ๊ธฐ๋ฅ๊ณผ LoRA/QLoRA ์ง์์ ์ถ๊ฐํ์ฌ ๋์ฑ ๊ฐ๋ ฅํ๊ณ ํจ์จ์ ์ธ AI ๋ํ ์์คํ ์ ๊ตฌ์ถํ์ต๋๋ค.
๐ ์ฃผ์ ๊ธฐ๋ฅ
1. ์ปจํ ์คํธ ๊ด๋ฆฌ ์์คํ (Context Management)
๐ง ํต์ฌ ๊ธฐ๋ฅ
- ๋ํ ํ์คํ ๋ฆฌ ๊ด๋ฆฌ: ์ฌ์ฉ์์ AI ๊ฐ์ ๋ํ๋ฅผ ์์ฐจ์ ์ผ๋ก ์ ์ฅ
- ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ: ์ค์ ๋ ์ ํ์ ๋๋ฌํ๋ฉด ์๋์ผ๋ก ์ปจํ ์คํธ ์์ถ
- ์ธ์ ๊ด๋ฆฌ: ์ฌ๋ฌ ๋ํ ์ธ์ ์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌ
- ์ปจํ ์คํธ ๊ฒ์: ์ ์ฅ๋ ๋ํ ๋ด์ฉ์์ ํน์ ์ ๋ณด ๊ฒ์
๐ ์ปจํ ์คํธ ์ ๋ต
- Sliding Window: ์ต๊ทผ ๋ฉ์์ง ์ฐ์ ์ ์ง
- Priority Keep: ์์คํ ํ๋กฌํํธ์ ์ต๊ทผ ๋ฉ์์ง ์ฐ์
- Circular Buffer: ์ํ ๋ฐฉ์์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
๐พ ๋ฐ์ดํฐ ๊ด๋ฆฌ
- ๋ด๋ณด๋ด๊ธฐ/๊ฐ์ ธ์ค๊ธฐ: JSON ํ์์ผ๋ก ์ปจํ ์คํธ ์ ์ฅ ๋ฐ ๋ณต์
- ๋ฉํ๋ฐ์ดํฐ ์ง์: ๊ฐ ๋ฉ์์ง์ ์ถ๊ฐ ์ ๋ณด ์ฒจ๋ถ ๊ฐ๋ฅ
- ํต๊ณ ์ ๋ณด: ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๋ฐ ํจ์จ์ฑ ์งํ ์ ๊ณต
2. LoRA/QLoRA ์ง์ ์์คํ
๐ LoRA (Low-Rank Adaptation)
- ํจ์จ์ ์ธ ํ์ธํ๋: ์ ์ฒด ๋ชจ๋ธ ๋์ ์ผ๋ถ ํ๋ผ๋ฏธํฐ๋ง ํ๋ จ
- ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ: GPU ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๋ํญ ๊ฐ์
- ๋น ๋ฅธ ์ด๋ํฐ ์ ํ: ์ฌ๋ฌ ์์ ๋ณ ์ด๋ํฐ๋ฅผ ๋น ๋ฅด๊ฒ ๊ต์ฒด
๐ QLoRA (Quantized LoRA)
- 4๋นํธ ์์ํ: ๋ชจ๋ธ ํฌ๊ธฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ถ๊ฐ ๊ฐ์
- ๊ณ ํ์ง ํ๋ จ: ์์ํ๋ ๋ชจ๋ธ์์๋ ๋์ ํ์ง์ ํ๋ จ ๊ฐ๋ฅ
- ํ๋์จ์ด ํจ์จ์ฑ: ์ ์ฌ์ GPU์์๋ ํ๋ จ ๊ฐ๋ฅ
๐ฏ ์ง์ ๋ชจ๋ธ
- Causal Language Models: GPT, LLaMA, Kanana ๋ฑ
- Sequence-to-Sequence: T5, BART ๋ฑ
- Classification Models: BERT, RoBERTa ๋ฑ
๐ ๏ธ ์ค์น ๋ฐ ์ค์
1. ์์กด์ฑ ์ค์น
pip install -r requirements.txt
2. ์ถ๊ฐ ํจํค์ง ์ค์น
# LoRA/QLoRA ์ง์
pip install peft>=0.7.0
pip install bitsandbytes>=0.41.0
# ์ ํ์ : ๋ ๋์ ์ฑ๋ฅ์ ์ํ ํจํค์ง
pip install accelerate
pip install transformers[torch]
3. ํ๊ฒฝ ๋ณ์ ์ค์
# GPU ์ฌ์ฉ ์ค์
export CUDA_VISIBLE_DEVICES=0
# ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ
export PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128
๐ ์ฌ์ฉ๋ฒ
1. ์ปจํ ์คํธ ๊ด๋ฆฌ
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
import requests
# ์์คํ
ํ๋กฌํํธ ์ค์
response = requests.post("http://localhost:8001/context/set-system-prompt",
data={"prompt": "๋น์ ์ ํ๊ตญ์ด AI ์ด์์คํดํธ์
๋๋ค."})
# ์ฌ์ฉ์ ๋ฉ์์ง ์ถ๊ฐ
response = requests.post("http://localhost:8001/context/add-message",
data={
"role": "user",
"content": "์๋
ํ์ธ์!",
"metadata": '{"session_id": "session_1"}'
})
# ์ด์์คํดํธ ์๋ต ์ถ๊ฐ
response = requests.post("http://localhost:8001/context/add-message",
data={
"role": "assistant",
"content": "์๋
ํ์ธ์! ๋ฌด์์ ๋์๋๋ฆด๊น์?",
"metadata": '{"session_id": "session_1"}'
})
# ์ปจํ
์คํธ ์กฐํ
response = requests.get("http://localhost:8001/context/get")
context = response.json()["context"]
๊ณ ๊ธ ๊ธฐ๋ฅ
# ์ปจํ
์คํธ ๊ฒ์
response = requests.get("http://localhost:8001/context/search?query=๋ ์จ&max_results=5")
# ์ปจํ
์คํธ ๋ด๋ณด๋ด๊ธฐ
response = requests.post("http://localhost:8001/context/export",
data={"file_path": "my_context.json"})
# ์ปจํ
์คํธ ๊ฐ์ ธ์ค๊ธฐ
response = requests.post("http://localhost:8001/context/import",
data={"file_path": "my_context.json"})
# ์ปจํ
์คํธ ํต๊ณ
response = requests.get("http://localhost:8001/context/summary")
2. LoRA/QLoRA ์ฌ์ฉ
๊ธฐ๋ณธ ๋ชจ๋ธ ๋ก๋
# ๊ธฐ๋ณธ ๋ชจ๋ธ ๋ก๋
response = requests.post("http://localhost:8001/lora/load-base-model",
data={
"model_path": "/path/to/your/model",
"model_type": "causal_lm"
})
LoRA ์ค์ ์์ฑ
# LoRA ์ค์ ์์ฑ
response = requests.post("http://localhost:8001/lora/create-config",
data={
"r": 16, # LoRA ๋ญํฌ
"lora_alpha": 32, # LoRA ์ํ
"target_modules": "q_proj,v_proj,k_proj,o_proj", # ํ๊ฒ ๋ชจ๋
"lora_dropout": 0.1, # ๋๋กญ์์
"bias": "none", # ๋ฐ์ด์ด์ค ์ฒ๋ฆฌ
"task_type": "CAUSAL_LM" # ์์
ํ์
})
์ด๋ํฐ ์ ์ฉ ๋ฐ ์ฌ์ฉ
# LoRA ์ด๋ํฐ ์ ์ฉ
response = requests.post("http://localhost:8001/lora/apply",
data={"adapter_name": "my_adapter"})
# LoRA ๋ชจ๋ธ๋ก ํ
์คํธ ์์ฑ
response = requests.post("http://localhost:8001/lora/generate",
data={
"prompt": "์๋
ํ์ธ์!",
"max_length": 100,
"temperature": 0.7
})
# ์ด๋ํฐ ์ ์ฅ
response = requests.post("http://localhost:8001/lora/save-adapter",
data={"adapter_name": "my_adapter"})
3. ํตํฉ ์ฌ์ฉ (์ปจํ ์คํธ + LoRA)
# ์ปจํ
์คํธ๋ฅผ ์ฌ์ฉํ ํ
์คํธ ์์ฑ
response = requests.post("http://localhost:8001/generate",
data={
"prompt": "์ด์ ๋ํ๋ฅผ ์ฐธ๊ณ ํด์ ๋ต๋ณํด์ฃผ์ธ์.",
"use_context": "true",
"session_id": "session_1"
})
๐ API ์๋ํฌ์ธํธ
์ปจํ ์คํธ ๊ด๋ฆฌ
| ๋ฉ์๋ | ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|---|
| POST | /context/set-system-prompt |
์์คํ ํ๋กฌํํธ ์ค์ |
| POST | /context/add-message |
๋ฉ์์ง ์ถ๊ฐ |
| GET | /context/get |
์ปจํ ์คํธ ์กฐํ |
| GET | /context/summary |
์ปจํ ์คํธ ์์ฝ |
| POST | /context/clear |
์ปจํ ์คํธ ์ด๊ธฐํ |
| DELETE | /context/message/{message_id} |
๋ฉ์์ง ์ ๊ฑฐ |
| PUT | /context/message/{message_id} |
๋ฉ์์ง ์์ |
| GET | /context/search |
์ปจํ ์คํธ ๊ฒ์ |
| POST | /context/export |
์ปจํ ์คํธ ๋ด๋ณด๋ด๊ธฐ |
| POST | /context/import |
์ปจํ ์คํธ ๊ฐ์ ธ์ค๊ธฐ |
LoRA ๊ด๋ฆฌ
| ๋ฉ์๋ | ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|---|
| POST | /lora/load-base-model |
๊ธฐ๋ณธ ๋ชจ๋ธ ๋ก๋ |
| POST | /lora/create-config |
LoRA ์ค์ ์์ฑ |
| POST | /lora/apply |
LoRA ์ด๋ํฐ ์ ์ฉ |
| POST | /lora/load-adapter |
์ ์ฅ๋ ์ด๋ํฐ ๋ก๋ |
| POST | /lora/save-adapter |
์ด๋ํฐ ์ ์ฅ |
| GET | /lora/adapters |
์ด๋ํฐ ๋ชฉ๋ก |
| GET | /lora/stats |
์ด๋ํฐ ํต๊ณ |
| POST | /lora/switch |
์ด๋ํฐ ์ ํ |
| POST | /lora/unload |
์ด๋ํฐ ์ธ๋ก๋ |
| POST | /lora/generate |
LoRA ๋ชจ๋ธ๋ก ์์ฑ |
| POST | /lora/merge |
์ด๋ํฐ ๋ณํฉ |
๐ ์ฑ๋ฅ ์ต์ ํ
1. ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
- ์ปจํ ์คํธ ์์ถ: ์๋ ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ
- ํ ํฐ ์ ํ: ์ค์ ๊ฐ๋ฅํ ์ต๋ ํ ํฐ ์
- ์ธ์ ๋ถ๋ฆฌ: ๋ ๋ฆฝ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ
2. LoRA ์ต์ ํ
- ๋ญํฌ ์กฐ์ : r ๊ฐ์ผ๋ก ์ ํ๋์ ํจ์จ์ฑ ๊ท ํ
- ํ๊ฒ ๋ชจ๋ ์ ํ: ํ์ํ ๋ ์ด์ด๋ง ์ ํ์ ํ๋ จ
- ๊ทธ๋๋์ธํธ ์ฒดํฌํฌ์ธํ : ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๊ฐ์
3. ํ๋์จ์ด ์ต์ ํ
- GPU ๋ฉ๋ชจ๋ฆฌ: ํจ์จ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ํ ๋น
- CPU ์ค๋ ๋: ๋ฉํฐ์ค๋ ๋ฉ ์ต์ ํ
- ๋ฐฐ์น ์ฒ๋ฆฌ: ๋๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ต์ ํ
๐งช ํ ์คํธ
ํ ์คํธ ์คํฌ๋ฆฝํธ ์คํ
python test_context_lora.py
์๋ ํ ์คํธ
# ์๋ฒ ์์
python run_server.py
# ๋ค๋ฅธ ํฐ๋ฏธ๋์์ ํ
์คํธ
curl -X POST "http://localhost:8001/context/set-system-prompt" \
-d "prompt=๋น์ ์ ํ๊ตญ์ด AI ์ด์์คํดํธ์
๋๋ค."
curl -X GET "http://localhost:8001/context/summary"
๐ง ์ค์ ์ต์
์ปจํ ์คํธ ๊ด๋ฆฌ์ ์ค์
# ContextManager ์ด๊ธฐํ ์ ์ค์
context_manager = ContextManager(
max_tokens=4000, # ์ต๋ ํ ํฐ ์
max_turns=20, # ์ต๋ ๋ํ ํด ์
strategy="sliding_window" # ์์ถ ์ ๋ต
)
LoRA ์ค์
# LoRA ์ค์ ์์
lora_config = LoraConfig(
r=16, # LoRA ๋ญํฌ (๋์์๋ก ์ ํ๋ ํฅ์, ๋ฉ๋ชจ๋ฆฌ ์ฆ๊ฐ)
lora_alpha=32, # LoRA ์ํ (์ค์ผ์ผ๋ง ํฉํฐ)
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"], # ํ๊ฒ ๋ชจ๋
lora_dropout=0.1, # ๋๋กญ์์ ๋น์จ
bias="none", # ๋ฐ์ด์ด์ค ์ฒ๋ฆฌ ๋ฐฉ์
task_type="CAUSAL_LM" # ์์
ํ์
)
๐จ ์ฃผ์์ฌํญ
1. ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
- ์ปจํ ์คํธ ๊ธธ์ด: ๋๋ฌด ๊ธด ์ปจํ ์คํธ๋ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ ์ผ๊ธฐํ ์ ์์ต๋๋ค
- LoRA ๋ญํฌ: ๋์ ๋ญํฌ๋ ์ ํ๋๋ฅผ ๋์ด์ง๋ง ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๋ ์ฆ๊ฐํฉ๋๋ค
2. ์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ
- GPU ๋ฉ๋ชจ๋ฆฌ: LoRA ํ๋ จ ์ ์ถฉ๋ถํ GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค
- CPU ์ฌ์ฉ๋: ์ปจํ ์คํธ ์์ถ ์ CPU ๋ฆฌ์์ค๊ฐ ์ฌ์ฉ๋ฉ๋๋ค
3. ํธํ์ฑ
- ๋ชจ๋ธ ํ์ : ๋ชจ๋ ๋ชจ๋ธ์ด LoRA๋ฅผ ์ง์ํ์ง ์์ ์ ์์ต๋๋ค
- ๋ฒ์ ํธํ์ฑ: PEFT์ Transformers ๋ฒ์ ํธํ์ฑ์ ํ์ธํ์ธ์
๐ ์ถ๊ฐ ์๋ฃ
๊ด๋ จ ๋ฌธ์
์์ ์ฝ๋
test_context_lora.py: ํตํฉ ํ ์คํธ ์คํฌ๋ฆฝํธexamples/: ์ถ๊ฐ ์ฌ์ฉ ์์ ๋ค
์ปค๋ฎค๋ํฐ
๐ค ๊ธฐ์ฌํ๊ธฐ
๋ฒ๊ทธ ๋ฆฌํฌํธ, ๊ธฐ๋ฅ ์ ์, ์ฝ๋ ๊ธฐ์ฌ๋ฅผ ํ์ํฉ๋๋ค!
- ์ด์ ์์ฑ
- ํฌํฌ ํ ๋ธ๋์น ์์ฑ
- ๋ณ๊ฒฝ์ฌํญ ์ปค๋ฐ
- Pull Request ์์ฑ
๐ ๋ผ์ด์ ์ค
์ด ํ๋ก์ ํธ๋ MIT ๋ผ์ด์ ์ค ํ์ ๋ฐฐํฌ๋ฉ๋๋ค.
Lily LLM - ๋ ์ค๋งํธํ AI ๋ํ๋ฅผ ์ํ ์ปจํ ์คํธ ๊ด๋ฆฌ ๋ฐ LoRA ์์คํ ๐