์๊ฐ
[2025]ํ๊ตญ์ด ์ด๋ฌธ ๊ท๋ฒ ๊ธฐ๋ฐ ์์ฑ(RAG)(๊ฐ ์ ํ) ๊ฒฝ์ง๋ํ ์ฐธ์ฌ๋ฅผ ์ํด ๊ฐ๋ฐํ์์ต๋๋ค.
- Developed by: ์ต๊ฐ์ธ๊ณต์ง๋ฅํ
Kanana-1.5-8B Instruct LoRA SFT
Kakao์ Kanana-1.5-8B Instruct ๋ชจ๋ธ์ LoRA ๋ฐฉ์์ผ๋ก SFT ํ์ธํ๋ํ ํ๊ตญ์ด instruction following ๋ชจ๋ธ์ ๋๋ค.
์ฌ์ฉ๋ฒ
from unsloth import FastLanguageModel
import torch
def load_model_with_adapter(base_model_id, adapter_path, max_seq_length=4096):
"""๋ฒ ์ด์ค ๋ชจ๋ธ ๋ก๋ ํ LoRA ์ด๋ํฐ ์ ์ฉ"""
# ๋ฒ ์ด์ค ๋ชจ๋ธ ๋ก๋
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=base_model_id,
max_seq_length=max_seq_length,
dtype=torch.float16,
load_in_4bit=False,
load_in_8bit=False,
trust_remote_code=True
)
# padding token ์ค์
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
if tokenizer.unk_token is None:
tokenizer.unk_token = tokenizer.eos_token
# ์ถ๋ก ๋ชจ๋๋ก ๋ณ๊ฒฝ
model = FastLanguageModel.for_inference(model)
# LoRA ์ด๋ํฐ ๋ก๋
model.load_adapter(adapter_path)
return model, tokenizer
def make_chat(inp):
"""์
๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์ฑํ
ํ์์ผ๋ก ๋ณํ"""
question_type_instructions = {
"์ ๋คํ": (
"[์ง๋ฌธ]์ ์ ์ฝ๊ณ ๋ต๋ณ์ ์์ฑํ์์ค. ๋ฌธ์ ๋ฅผ ๊ทธ๋๋ก ์ถ๋ ฅํ์ง ๋ง์์ค. "
"[์ง์นจ] ์ฃผ์ด์ง ๋ณด๊ธฐ ์ค์์ ๊ฐ์ฅ ์ ์ ํ ๋ต์ ์ซ์๋ก๋ง ์๋ตํ์์ค."
),
"์์ ํ": (
"[์ง๋ฌธ]์ ์ ์ฝ๊ณ ๋ต๋ณ์ ์์ฑํ์์ค. ๋ฌธ์ ๋ฅผ ๊ทธ๋๋ก ์ถ๋ ฅํ์ง ๋ง์์ค. "
"[์ง์นจ] ์ง๋ฌธ์ ๋ํ ๋ต๋ณ์ ์์ฑ๋ ๋ฌธ์ฅ์ผ๋ก ์์ ํ์์ค."
),
"๋จ๋ตํ": (
"[์ง๋ฌธ]์ ์ ์ฝ๊ณ ๋ต๋ณ์ ์์ฑํ์์ค. ๋ฌธ์ ๋ฅผ ๊ทธ๋๋ก ์ถ๋ ฅํ์ง ๋ง์์ค. "
"[์ง์นจ] ์ง๋ฌธ์ ๋ํ ๋ต์ 2๋จ์ด ์ด๋ด๋ก ๊ฐ๋จํ ๋ตํ์์ค."
),
"๊ต์ ํ": (
"[์ง๋ฌธ]์ ์ ์ฝ๊ณ ๋ต๋ณ์ ์์ฑํ์์ค. ๋ฌธ์ ๋ฅผ ๊ทธ๋๋ก ์ถ๋ ฅํ์ง ๋ง์์ค. "
"[์ง์นจ] ์ฃผ์ด์ง ๋ฌธ์ฅ์ด ์ฌ๋ฐ๋ฅธ์ง ํ๋จํ๊ณ , ํ๋ฆฐ ๊ฒฝ์ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๊ต์ ํ์ฌ \"~๊ฐ ์ณ๋ค.\" ํํ๋ก ๋ต๋ณํ๊ณ , ๊ทธ ์ด์ ๋ฅผ ์ค๋ช
ํ์์ค."
),
"์ ํํ": (
"[์ง๋ฌธ]์ ์ ์ฝ๊ณ ๋ต๋ณ์ ์์ฑํ์์ค. ๋ฌธ์ ๋ฅผ ๊ทธ๋๋ก ์ถ๋ ฅํ์ง ๋ง์์ค. "
"[์ง์นจ] ์ฃผ์ด์ง ๋ณด๊ธฐ๋ค ์ค์์ ๊ฐ์ฅ ์ ์ ํ ๊ฒ์ ์ ํํ์ฌ \"~๊ฐ ์ณ๋ค.\" ํํ๋ก ๋ต๋ณํ๊ณ , ๊ทธ ์ด์ ๋ฅผ ์ค๋ช
ํ์์ค."
)
}
# instruction ๊ฐ์ ธ์ค๊ธฐ
instruction = question_type_instructions.get(inp.get('question_type', ''), "")
# RAG ์ปจํ
์คํธ ์ถ๊ฐ
if 'retrieved_context' in inp and inp['retrieved_context']:
instruction += f" [๊ด๋ จ ์ ๋ณด] {inp['retrieved_context']}"
# ๊ธฐํ ์ ๋ณด ์์ฑ (question, retrieved_context ์ ์ธ)
other_info = {k: v for k, v in inp.items() if k not in ['question', 'retrieved_context']}
chat_parts = [instruction]
if other_info:
info_list = ["[๊ธฐํ ์ ๋ณด]"]
for key, value in other_info.items():
if value is not None and value != "":
info_list.append(f" {key}: {value}")
chat_parts.append(" ".join(info_list))
# ์ง๋ฌธ ์ถ๊ฐ
chat_parts.append(f"[์ง๋ฌธ] {inp['question']}")
return " ".join(chat_parts)
# ์ฌ์ฉ ์์
base_model_id = "kakaocorp/kanana-1.5-8b-instruct-2505"
adapter_path = "demoap3909/kanana-1.5-8b-instruct-2505-lora-kli-sft-25"
model, tokenizer = load_model_with_adapter(base_model_id, adapter_path)
# ๋ฐ์ดํฐ ์์
sample_data = {
"id": "623",
"question_type": "์ ํํ",
"question": "\"๋๋ ๊ทธ๋ฅผ ๋ณธ ์ ์ด ์์์ {๊ธฐ์ตํด๋๋ค/๊ธฐ์ตํด ๋๋ค}.\" ๊ฐ์ด๋ฐ ์ฌ๋ฐ๋ฅธ ๊ฒ์ ์ ํํ๊ณ , ๊ทธ ์ด์ ๋ฅผ ์ค๋ช
ํ์ธ์.",
"retrieved_context": "<๋์ด์ฐ๊ธฐ - ํ๊ธ ๋ง์ถค๋ฒ ์ 42ํญ> ์์กด ๋ช
์ฌ๋ ๋์ด ์ด๋ค. ์๋ ๊ฒ์ด ํ์ด๋ค., ๋๋ ํ ์ ์๋ค., ๋จน์ ๋งํผ ๋จน์ด๋ผ., ์๋ ์ด๋ฅผ ๋ง๋ฌ๋ค., ๋ค๊ฐ ๋ปํ ๋ฐ๋ฅผ ์๊ฒ ๋ค., ๊ทธ๊ฐ ๋ ๋ ์ง๊ฐ ์ค๋๋ค. <ํ๊ธ ๋ง์ถค๋ฒ, ํ์ค์ด ๊ท์ - ํ๊ธ ๋ง์ถค๋ฒ ์ 57ํญ> ์๊ฑฐ๋ผ. ๋ ์ด๋ณด๋ค์์กด ๋ช
์ฌ ์ค๋ ์ด๊ฐ ๊ฐ๋ ์ด๋ณด๋ค ๋ง๋ค. ์ผ๋ฆฌ๋งํผ์ด๋ฏธ ๋๋ฅผ ๋ฏธ์ํ๋ฆฌ๋งํผ ๊ทธ์๊ฒ ์๋ชปํ ์ผ์ด ์๋ค. ์ผ ์ด๋งํผ์์กด ๋ช
์ฌ ์ฐฌ์ฑํ ์ด๋ ๋ฐ๋ํ ์ด๋งํผ์ด๋ ๋ง์ ๊ฒ์ด๋ค. ์ผ๋ฌ๋ชฉ์ ๊ณต๋ถํ๋ฌ ๊ฐ๋ค. ์ผ๋ ค์๋ ์์ธ ๊ฐ๋ ค ํ๋ค. ์ผ๋ก์์๊ฒฉ ์ฌ๋์ผ๋ก์ ๊ทธ๋ด ์๋ ์๋ค. ์ผ๋ก์จ์๋จ ๋ญ์ผ๋ก์จ ๊ฟฉ์ ๋์ ํ๋ค. ์ผ๋ฏ๋ก์ด๋ฏธ ๊ทธ๊ฐ ๋๋ฅผ ๋ฏฟ์ผ๋ฏ๋ก ๋๋ ๊ทธ๋ฅผ ๋ฏฟ๋๋ค. , ์์ผ๋ก์จ์กฐ์ฌ ๊ทธ๋ ๋ฏฟ์์ผ๋ก์จ ์ฐ ๋ณด๋์ ๋๊ผ๋ค. <ํ๊ธ ๋ง์ถค๋ฒ, ํ์ค์ด ๊ท์ - ํ๊ธ ๋ง์ถค๋ฒ ์ 36ํญ> ๋ค์ ์ด๊ฐ ์์ ๋ก ์ค ์ ์๋ ์ค ๋๋ก ์ ๋๋ค. ๋ณธ๋ง ๊ฐ์ง์ด, ๊ฒฌ๋์ด, ๋ค๋์ด, ๋งํ์ด, ๋ฒํฐ์ด, ์น์ด์ด, ๊ฐ์ง์๋ค, ๊ฒฌ๋์๋ค, ๋ค๋์๋ค, ๋งํ์๋ค, ๋ฒํฐ์๋ค, ์น์ด์๋ค ์ค๋ง ๊ฐ์ ธ, ๊ฒฌ๋, ๋ค๋
, ๋งํ, ๋ฒํ
จ, ์น์ฌ, ๊ฐ์ก๋ค, ๊ฒฌ๋ ๋ค, ๋ค๋
๋ค, ๋งํ๋ค, ๋ฒํ
ผ๋ค, ์น์ ๋ค"
}
# ํ๋กฌํํธ ์์ฑ
user_prompt = make_chat(sample_data)
# ์์คํ
ํ๋กฌํํธ
system_prompt = (
"You are a helpful AI assistant. Please answer the user's questions kindly. "
"๋น์ ์ ํ๊ตญ์ ์ ํต ๋ฌธํ์ ์ญ์ฌ, ๋ฌธ๋ฒ, ์ฌํ, ๊ณผํ๊ธฐ์ ๋ฑ ๋ค์ํ ๋ถ์ผ์ ๋ํด ์ ์๊ณ ์๋ ์ ๋ฅํ AI ์ด์์คํดํธ ์
๋๋ค. "
"์ฌ์ฉ์์ ์ง๋ฌธ์ ๋ํด ์น์ ํ๊ฒ ๋ต๋ณํด์ฃผ์ธ์. ๋จ, ๋์ผํ ๋ฌธ์ฅ์ ์ ๋ ๋ฐ๋ณตํ์ง ๋ง์์ค."
)
message = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
]
# ํ ํฌ๋์ด์ฆ
inputs = tokenizer.apply_chat_template(
message,
add_generation_prompt=True,
return_tensors="pt",
).to(model.device)
attention_mask = (inputs != tokenizer.pad_token_id).long().to(model.device)
# ์์ฑ
outputs = model.generate(
inputs,
max_new_tokens=2048,
do_sample=False,
attention_mask=attention_mask,
)
# ๋ต๋ณ ์ถ์ถ
answer = tokenizer.decode(outputs[0][inputs.shape[-1]:], skip_special_tokens=True)
# ํ์ฒ๋ฆฌ
if answer.startswith("๋ต๋ณ: "):
answer = answer[4:]
elif answer.startswith("๋ต๋ณ:"):
answer = answer[3:]
if "#" in answer:
answer = answer.split("#")[0].strip()
print(answer)
- Downloads last month
- 5
Inference Providers
NEW
This model isn't deployed by any Inference Provider.
๐
Ask for provider support
Model tree for demoap3909/kanana-1.5-8b-instruct-2505-lora-kli-sft-25
Base model
kakaocorp/kanana-1.5-8b-instruct-2505