bori-tutor / README.md
zhdokax's picture
Böri tutor v6 LoRA adapter (Sherkala-8B, QLoRA)
37a2da9 verified
|
Raw
History Blame Contribute Delete
2 kB
---
license: llama3.1
language:
- kk
base_model: inceptionai/Llama-3.1-Sherkala-8B-Chat
library_name: peft
pipeline_tag: text-generation
tags:
- kazakh
- tutor
- lora
- bori
---
# Böri — Kazakh AI Grammar Tutor (bori-tutor)
QLoRA fine-tune of Sherkala-8B. Takes a Kazakh (Cyrillic) sentence and returns a JSON object: corrected_text, explanation, next_question, used_words.
## Eval
- eval_loss: **0.531**
- perplexity: **1.70**
## Important serving notes
- Tokenizer has **no chat_template** → build the Llama-3.1 prompt manually (see below).
- Model may append text after the JSON → extract the first `{...}` and `json.loads` it.
- System prompt is NOT baked in — pass it at inference.
## Usage (base + adapter, 4-bit)
```python
import torch, json, os
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import PeftModel
BASE='inceptionai/Llama-3.1-Sherkala-8B-Chat'; ADP='zhdokax/bori-tutor'
bnb=BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type='nf4', bnb_4bit_compute_dtype=torch.float16, bnb_4bit_use_double_quant=True)
tok=AutoTokenizer.from_pretrained(ADP)
if tok.pad_token is None: tok.pad_token=tok.eos_token
base=AutoModelForCausalLM.from_pretrained(BASE, quantization_config=bnb, device_map='auto')
model=PeftModel.from_pretrained(base, ADP).eval()
SYS='Sen -- Bori, qazaq tilin uyiretetyn interaktyvti mugalimsin. ARQASHAN tek JSON formatynda zhauyap ber.'
def ask(u):
pr=f'<|begin_of_text|><|start_header_id|>system<|end_header_id|>\n\n{SYS}<|eot_id|><|start_header_id|>user<|end_header_id|>\n\n{u}<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n'
i=tok(pr,return_tensors='pt').to(model.device)
o=model.generate(**i,max_new_tokens=256,do_sample=True,temperature=0.6,top_p=0.9,repetition_penalty=1.1,pad_token_id=tok.eos_token_id)
t=tok.decode(o[0][i['input_ids'].shape[-1]:],skip_special_tokens=True)
s=t.find('{'); e=t.rfind('}')+1; return json.loads(t[s:e]) if s>=0 and e>0 else {'raw':t}
```