|
|
--- |
|
|
language: ko |
|
|
license: apache-2.0 |
|
|
tags: |
|
|
- function-calling |
|
|
- korean |
|
|
- hybridko |
|
|
base_model: Yaongi/hybridko-exp6 |
|
|
datasets: |
|
|
- heegyu/glaive-function-calling-v2-ko |
|
|
--- |
|
|
|
|
|
# HybriKo-117M Function Calling |
|
|
|
|
|
HybriKo-117M (checkpoint 1962) λͺ¨λΈμ Function Calling λ°μ΄ν°λ‘ λ―ΈμΈμ‘°μ ν λͺ¨λΈμ
λλ€. |
|
|
|
|
|
## νμ΅ μ 보 |
|
|
- **Base Model**: Yaongi/hybridko-exp6 |
|
|
- **Dataset**: heegyu/glaive-function-calling-v2-ko (5,000 samples) |
|
|
- **Epochs**: 2 |
|
|
- **Final Loss**: ~0.14 |
|
|
- **Performance**: κΈ°λ³Έ ν¬λ§· νμ΅ μλ£ (Calculation, Search, Weather λ± μ§μ) |
|
|
|
|
|
## μ¬μ©λ² (Colab) |
|
|
|
|
|
```python |
|
|
import torch |
|
|
import torch.nn.functional as F |
|
|
import sentencepiece as spm |
|
|
from transformers import AutoModelForCausalLM |
|
|
from huggingface_hub import hf_hub_download |
|
|
|
|
|
# 1. λͺ¨λΈ λ‘λ |
|
|
print("π₯ Model loading...") |
|
|
model = AutoModelForCausalLM.from_pretrained( |
|
|
"Yaongi/HybriKo-117M-Exp6-FunctionCall", |
|
|
trust_remote_code=True, |
|
|
torch_dtype=torch.float32 |
|
|
) |
|
|
device = "cuda" if torch.cuda.is_available() else "cpu" |
|
|
model.to(device) |
|
|
model.eval() |
|
|
|
|
|
# 2. ν ν¬λμ΄μ λ‘λ |
|
|
print("π₯ Tokenizer loading...") |
|
|
sp_path = hf_hub_download("Yaongi/HybriKo-117M-Exp6-FunctionCall", "HybriKo_tok.model") |
|
|
sp = spm.SentencePieceProcessor() |
|
|
sp.Load(sp_path) |
|
|
|
|
|
# 3. μμ± ν¨μ (Stop Logic ν¬ν¨) |
|
|
def generate(text, max_len=200, temp=0.01, top_k=1): |
|
|
input_ids = torch.tensor([[sp.bos_id()] + sp.EncodeAsIds(text)]).to(device) |
|
|
|
|
|
# μ€μ§ ν
μ€νΈ 리μ€νΈ |
|
|
stop_sequences = ["<|im_end|>", "</tool_code>"] |
|
|
|
|
|
print("π€ Generating...", end="", flush=True) |
|
|
with torch.no_grad(): |
|
|
for _ in range(max_len): |
|
|
outputs = model(input_ids[:, -512:]) |
|
|
logits = outputs.logits[:, -1] / temp |
|
|
|
|
|
if top_k: |
|
|
v, _ = torch.topk(logits, min(top_k, logits.size(-1))) |
|
|
logits[logits < v[:, [-1]]] = float("-inf") |
|
|
|
|
|
probs = F.softmax(logits, dim=-1) |
|
|
next_token = torch.multinomial(probs, 1) |
|
|
|
|
|
# EOS ν ν° μ²΄ν¬ |
|
|
if next_token.item() == sp.eos_id(): |
|
|
break |
|
|
|
|
|
input_ids = torch.cat([input_ids, next_token], dim=1) |
|
|
|
|
|
# π‘ Stop Sequence μ²΄ν¬ (λ§€ μ€ν
λμ½λ©νμ¬ νμΈ) |
|
|
curr_text = sp.DecodeIds(input_ids[0].tolist()) |
|
|
|
|
|
# ν둬ννΈ μ΄ν μμ±λ λΆλΆλ§ μλΌμ νμΈ |
|
|
# (SentencePiece νΉμ±μ μ νν μ¬λΌμ΄μ±μ μν΄ μ 체 λμ½λ© ν λΉκ΅κ° μμ ) |
|
|
gen_part = curr_text[len(text):] # κ·Όμ¬μ μΈ λ°©λ² |
|
|
|
|
|
# μ νλλ₯Ό μν΄ full textμμ κ²μ |
|
|
should_stop = False |
|
|
for seq in stop_sequences: |
|
|
if seq in curr_text and not (seq in text): # ν둬ννΈμ μ΄λ―Έ μλ κ²½μ°λ μ μΈ |
|
|
# λ°©κΈ μμ±λ λΆλΆμ ν ν°μ΄ μμ±λμλμ§ νμΈ |
|
|
should_stop = True |
|
|
break |
|
|
|
|
|
if should_stop: |
|
|
break |
|
|
|
|
|
return sp.DecodeIds(input_ids[0].tolist()) |
|
|
|
|
|
# 4. μ€ν μμ |
|
|
prompt = '''<|im_start|>system |
|
|
λΉμ μ λꡬ νΈμΆ(function calling)μ΄ κ°λ₯ν AI μ΄μμ€ν΄νΈμ
λλ€. |
|
|
<tools> |
|
|
{"name": "get_news_headlines", "parameters": {"country": "string"}} |
|
|
</tools><|im_end|> |
|
|
<|im_start|>user |
|
|
νκ΅μ μ΅μ λ΄μ€ μλ €μ€<|im_end|> |
|
|
<|im_start|>assistant |
|
|
''' |
|
|
|
|
|
print("\nPrompt:") |
|
|
print(prompt) |
|
|
|
|
|
result = generate(prompt, max_len=200) |
|
|
|
|
|
# μΆλ ₯ κΉλνκ² μ 리 |
|
|
print("\n" + "="*50) |
|
|
print("Result:") |
|
|
print(result) |
|
|
print("="*50) |
|
|
|
|
|
''' |