|
|
import gradio as gr |
|
|
import torch |
|
|
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig |
|
|
from peft import PeftModel |
|
|
|
|
|
|
|
|
MODELS = { |
|
|
|
|
|
|
|
|
|
|
|
"ํ๊ตญ์ด ์์ฝ (03๋ฒ)": { |
|
|
"base_model": "LGAI-EXAONE/EXAONE-3.5-2.4B-Instruct", |
|
|
"lora_path": "Sangjoo/exaone-summary-lora", |
|
|
"prompt_template": "{input}\n\n์์ฝ:", |
|
|
"max_new_tokens": 60, |
|
|
"placeholder": "๋ด์ค ๊ธฐ์ฌ๋ฅผ ์
๋ ฅํ์ธ์...", |
|
|
"example": "์์ธ์๊ฐ ๋ด๋
๋ถํฐ ์ ๊ธฐ์ฐจ ์ถฉ์ ์๋ฅผ ๋ํญ ํ๋ํ๋ค.", |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"Granite ์์ฝ (05๋ฒ)": { |
|
|
"base_model": "ibm-granite/granite-4.0-micro", |
|
|
"lora_path": "Sangjoo/granite-summary-lora", |
|
|
"prompt_template": "<|user|>\n{input}\n\n์ ๊ธฐ์ฌ๋ฅผ ์์ฝํด์ฃผ์ธ์.<|assistant|>\n", |
|
|
"max_new_tokens": 60, |
|
|
"placeholder": "๋ด์ค ๊ธฐ์ฌ๋ฅผ ์
๋ ฅํ์ธ์...", |
|
|
"example": "์์ธ์๊ฐ ๋ด๋
๋ถํฐ ์ ๊ธฐ์ฐจ ์ถฉ์ ์๋ฅผ ๋ํญ ํ๋ํ๋ค.", |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"๊ฐ์ ๋ถ๋ฅ (06๋ฒ)": { |
|
|
"base_model": "LGAI-EXAONE/EXAONE-3.5-2.4B-Instruct", |
|
|
"lora_path": "Sangjoo/lora-sentiment", |
|
|
"prompt_template": "๋ค์ ์ํ ๋ฆฌ๋ทฐ์ ๊ฐ์ ์ ๋ถ๋ฅํ์ธ์.\n\n๋ฆฌ๋ทฐ: {input}\n\n๊ฐ์ :", |
|
|
"max_new_tokens": 10, |
|
|
"placeholder": "์ํ ๋ฆฌ๋ทฐ๋ฅผ ์
๋ ฅํ์ธ์...", |
|
|
"example": "This movie was amazing! Great story and excellent acting.", |
|
|
}, |
|
|
"์์ด QA (06๋ฒ)": { |
|
|
"base_model": "LGAI-EXAONE/EXAONE-3.5-2.4B-Instruct", |
|
|
"lora_path": "Sangjoo/lora-qa", |
|
|
"prompt_template": "Context: The Eiffel Tower is in Paris, France.\n\nQuestion: {input}\n\nAnswer:", |
|
|
"max_new_tokens": 30, |
|
|
"placeholder": "์ง๋ฌธ์ ์
๋ ฅํ์ธ์...", |
|
|
"example": "Where is the Eiffel Tower located?", |
|
|
}, |
|
|
} |
|
|
|
|
|
loaded_models = {} |
|
|
|
|
|
def load_model(model_name): |
|
|
if model_name in loaded_models: |
|
|
return loaded_models[model_name] |
|
|
|
|
|
config = MODELS[model_name] |
|
|
|
|
|
tokenizer = AutoTokenizer.from_pretrained(config["base_model"], use_fast=False) |
|
|
if tokenizer.pad_token is None: |
|
|
tokenizer.pad_token = tokenizer.eos_token |
|
|
|
|
|
quant_config = BitsAndBytesConfig( |
|
|
load_in_4bit=True, |
|
|
bnb_4bit_use_double_quant=True, |
|
|
bnb_4bit_quant_type="nf4", |
|
|
bnb_4bit_compute_dtype=torch.bfloat16, |
|
|
) |
|
|
|
|
|
base_model = AutoModelForCausalLM.from_pretrained( |
|
|
config["base_model"], |
|
|
device_map="auto", |
|
|
trust_remote_code=True, |
|
|
quantization_config=quant_config, |
|
|
) |
|
|
|
|
|
model = PeftModel.from_pretrained(base_model, config["lora_path"]) |
|
|
|
|
|
loaded_models[model_name] = (model, tokenizer, config) |
|
|
return model, tokenizer, config |
|
|
|
|
|
def generate_response(model_name, user_input): |
|
|
try: |
|
|
model, tokenizer, config = load_model(model_name) |
|
|
prompt = config["prompt_template"].format(input=user_input) |
|
|
inputs = tokenizer(prompt, return_tensors="pt").to(model.device) |
|
|
|
|
|
with torch.no_grad(): |
|
|
outputs = model.generate( |
|
|
**inputs, |
|
|
max_new_tokens=config["max_new_tokens"], |
|
|
temperature=0.7, |
|
|
do_sample=True, |
|
|
pad_token_id=tokenizer.eos_token_id, |
|
|
) |
|
|
|
|
|
result = tokenizer.decode(outputs[0], skip_special_tokens=True) |
|
|
|
|
|
|
|
|
if "์์ฝ:" in result: |
|
|
return result.split("์์ฝ:")[-1].strip() |
|
|
elif "๊ฐ์ :" in result: |
|
|
return result.split("๊ฐ์ :")[-1].strip() |
|
|
elif "Answer:" in result: |
|
|
return result.split("Answer:")[-1].strip() |
|
|
elif "<|assistant|>" in result: |
|
|
return result.split("<|assistant|>")[-1].strip() |
|
|
elif "<|im_start|>assistant" in result: |
|
|
return result.split("<|im_start|>assistant")[-1].replace("<|im_end|>", "").strip() |
|
|
else: |
|
|
return result[len(prompt):].strip() |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
with gr.Blocks(title="LoRA ๋ชจ๋ธ ๋ฐ๋ชจ") as demo: |
|
|
gr.Markdown("# ๐ค LoRA ํ์ธํ๋ ๋ชจ๋ธ ๋ฐ๋ชจ") |
|
|
gr.Markdown("Day 1์์ ํ์ตํ ์ฌ๋ฌ LoRA ๋ชจ๋ธ์ ํ
์คํธํด๋ณด์ธ์!") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
model_dropdown = gr.Dropdown( |
|
|
choices=list(MODELS.keys()), |
|
|
value=list(MODELS.keys())[0], |
|
|
label="๐ ๋ชจ๋ธ ์ ํ" |
|
|
) |
|
|
input_text = gr.Textbox(label="๐ฌ ์
๋ ฅ", lines=5) |
|
|
submit_btn = gr.Button("๐ ์คํ", variant="primary") |
|
|
|
|
|
with gr.Column(): |
|
|
output_text = gr.Textbox(label="โจ ๊ฒฐ๊ณผ", lines=10) |
|
|
|
|
|
submit_btn.click( |
|
|
fn=generate_response, |
|
|
inputs=[model_dropdown, input_text], |
|
|
outputs=[output_text] |
|
|
) |
|
|
|
|
|
demo.launch() |
|
|
|