Dio 3 od 5: Prilagodba Unaprijed Obučenih Modela
Dobrodošli natrag! U našem prošlom članku, izgradili smo RAG sustav koji daje AI pristup vašim specifičnim informacijama. Danas idemo korak dalje — zapravo ćemo promijeniti kako AI model razmišlja i odgovara fino podesavanjem. Koristit ću model otvorenog koda za ovaj primjer demonstracije.
RAG vs Fino Podešavanje: Koja je razlika?
Razmislite na ovaj način:
RAG je kao da nekom daete priručnik za referencu. Oni su i dalje ista osoba, ali sada imaju pristup specifičnim informacijama pri odgovaranju na pitanja.
Fino podešavanje je kao da pošaljete nekoga na specijalizirane obuke. Zapravo mijenjate kako oni razmišljaju i odgovaraju na osnovu vaših specifičnih zahtjeva.
Kada Trebate Fino Podesiti?
Fino podešavanje je moćno, ali nije uvijek potrebno. Razmotrите fino podešavanje kada:
- Trebate da AI usvoji određeni ton ili stil
- Vaša domena ima specijaliziranu terminologiju ili koncepate
- Trebate konzistentne odgovore u mnogim različitim scenarijima
- RAG vam ne daje kvalitetu odgovora koju trebate
- Imate dovoljno podataka za obuku (obično stotine primjera)
- Trebate da model radi offline ili u okruženjima bez pristupa internetu
Postavljanje Vašeg Okruženja
Koristit ćemo Google Colab s T4 GPU za ovaj tutorial, ali možete ga prilagoditi za bilo koje CUDA-kompatibilno okruženje:
# Install required packages !pip install bitsandbytesimport os import torch from datasets import Dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer, BitsAndBytesConfig ) from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training, PeftModel
Odabir Pravog Modela
Za ovaj tutorial, koristit ćemo TinyLlama-1.1B, ali evo nekoliko odličnih opcija za različite potrebe:
# Ultra-light models (good for experimentation) # model_name = "distilgpt2" # 82M parameters # model_name = "gpt2" # 124M parameters # model_name = "EleutherAI/gpt-neo-125M" # 125M parameters# Small but capable models # model_name = "microsoft/DialoGPT-medium" # 355M parameters # model_name = "microsoft/DialoGPT-large" # 762M parameters model_name = "TinyLlama/TinyLlama-1.1B-Chat-v1.0" # 1.1B parameters - choosing this one # For production use (if you have more GPU memory) # model_name = "microsoft/phi-2" # 2.7B parameters # model_name = "stabilityai/stablelm-2-1_6b" # 1.6B parameters
Priprema Vaših Podataka za Obuku
Ključ za uspješno fino podešavanje su visokokvalitetni podaci za obuku. Evo kako ih strukturiramo:
# Sample dataset for MyNextDeveloper (MND)
data = {
"text": [
"User asks: Write a 3-bullet overview of MND.nAssistant: - Remote-first, founded 2022 in Mumbain- Staff augmentation + full-cycle web/API, UI/UX, AI/MLn- Agile/TDD, POSH culture, transparent pricing",
"User asks: Where is MND headquartered?nAssistant: Malabar Hill, Mumbai",
"User asks: What services does MND offer?nAssistant: Staff augmentation, API development, web development, UI/UX design, AI/ML solutions",
"User asks: What is MND's tech stack?nAssistant: Angular, React, Next.js, Node.js, Django, Python, Docker, AWS",
"User asks: What is MND's pricing model?nAssistant: Project pricing starting at $10,000 with hourly rates between $25 and $49",
"User asks: What is MND's mission?nAssistant: To solve the trust gap between startups and engineers by emphasizing empathy, communication, and transparency",
"User asks: What is MND's culture like?nAssistant: Agile practices, test-driven development, and POSH-compliant culture",
"User asks: When was MND founded?nAssistant: 2022"
]
}
# Convert to HuggingFace dataset
dataset = Dataset.from_dict(data)
Ključna načela za podatke obuke:
- Koristite konzistentno oblikovanje (primijetite "User asks:" i "Assistant:" obrazac)
- Odgovore čuvajte činjeničnima i sažetima
- Pokrijte najvažnije informacije o vašoj domeni
- Kvaliteta prije količine: 50 savršenih primjera bolje je od 500 osrednjих
Učinkovita Obuka s LoRA i Kvantizacijom
Umjesto da fino podesavamo cijeli model (što zahtijeva ogroman GPU memoriju), koristit ćemo dvije tehnike učinkovitosti:
1. Kvantizacija (4-bitna)
Kvantizacija je tehnika kompresije korištena za činjenje velikih jezikovnih modela (LLM-ova) manjima i bržima bez značajnog smanjenja točnosti.
- Normalno su LLM težine pohranjene kao 32-bitni brojevi s pomičnom točkom (FP32).
- Kvantizacija smanjuje ovu preciznost na 16-bitnu (FP16/BF16), 8-bitnu (INT8), 4-bitnu (INT4) ili čak još manju.
👉 Primjer:
- Model s 10 milijardi parametara u FP32 trebao bi ~40 GB memorije.
- Ako ga kvantiziramo na INT8 (8-bitna) → trebao bi samo ~10 GB.
- Ako idemo na INT4 (4-bitna) → samo ~5 GB.
⚡ Zašto je to korisno?
- Čini modele pokretljivima na manjim GPU-ima (ili čak procesore).
- Ubrzava zaključivanje.
- Manja zamjena u točnosti, ali često zanemariva.
# Configure 4-bit quantization bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_use_double_quant=True, bnb_4bit_compute_dtype=torch.float16 )# Load model with quantization model = AutoModelForCausalLM.from_pretrained( model_name, quantization_config=bnb_config, device_map="auto", torch_dtype=torch.float16 )
2. LoRA (Prilagodba Niske Rango)
LoRA je metoda učinkovitog fino podešavanja parametara (PEFT).
Normalno, da fino podesimo ogroman LLM (kao LLaMA-65B ili GPT-J), trebali bi nam stotine GB GPU memorije. LoRA to rješava:
- Zamrzavajući originalne težine modela.
- Dodavajući male matrične matrice za obuku (adaptere niske ranga) unutar slojeva modela.
- Tijekom fino podešavanja, samo se te male matrice ažuriraju.
👉 Primjer:
- Potpuno fino podešavanje modela od 65B moglo bi zahtijevati ~1 TB GPU memorije.
- S LoRA, trebate samo obučiti nekoliko milijuna parametara → trebate < 20 GB GPU memorije.
⚡ Zašto je to korisno?
- Čini fino podešavanje ogromnih LLM-ova mogućim na potrošačkoj sklopovskoj opremi (1–2 GPU).
- Lako se mogu "spajati" ili "odspajati" adapteri → možete brzo prebaciti zadatke.
- Često postižu performanse blizu potpunog fino podešavanja.
# Configure LoRA based on model architecture if "TinyLlama" in model_name or "Llama" in model_name: target_modules = ["q_proj", "k_proj", "v_proj", "o_proj"] elif "gpt" in model_name.lower() or "DialoGPT" in model_name: target_modules = ["c_attn", "c_proj"] else: target_modules = ["q_proj", "v_proj"]lora_config = LoraConfig( r=8, # Rank of adaptation lora_alpha=16, # LoRA scaling parameter target_modules=target_modules, lora_dropout=0.05, bias="none", task_type="CAUSAL_LM" ) # Apply LoRA to the model model = get_peft_model(model, lora_config) model.print_trainable_parameters()
Obučavamo samo 0,2% parametara!
Obuka Modela
# Tokenize the data def tokenize_function(examples): tokenized_inputs = tokenizer( examples["text"], truncation=True, padding="max_length", max_length=512, return_tensors="pt" ) # Create labels by copying input tokens tokenized_inputs["labels"] = tokenized_inputs["input_ids"].clone() return tokenized_inputs# Split dataset train_dataset = dataset.select(range(8)) eval_dataset = dataset.select(range(8, 11)) # Apply tokenization train_dataset = train_dataset.map(tokenize_function, batched=True) eval_dataset = eval_dataset.map(tokenize_function, batched=True) # Configure training training_args = TrainingArguments( output_dir="./mnd-finetune-outputs", num_train_epochs=5, per_device_train_batch_size=4, per_device_eval_batch_size=4, gradient_accumulation_steps=2, warmup_steps=10, learning_rate=3e-4, weight_decay=0.01, logging_steps=1, save_steps=30, eval_strategy="steps", eval_steps=15, save_total_limit=2, load_best_model_at_end=True, fp16=True, report_to=None # Disable wandb logging ) # Create trainer and start training trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, tokenizer=tokenizer, ) print("Starting training...") trainer.train() # Save the adapter adapter_dir = "./mnd-finetune-outputs/final_adapter" model.save_pretrained(adapter_dir) tokenizer.save_pretrained(adapter_dir)
Testiranje Fino Podesenog Modela
def load_model_for_inference():
"""Load the fine-tuned model for inference"""
# Load base model
base_model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_config,
device_map="auto",
torch_dtype=torch.float16
)
# Load the fine-tuned adapter
model = PeftModel.from_pretrained(base_model, adapter_dir)
model = model.merge_and_unload()
# Load tokenizer
tokenizer = AutoTokenizer.from_pretrained(adapter_dir)
return model, tokenizer
def generate_response(model, tokenizer, prompt, max_length=256, temperature=0.7):
"""Generate response for a given prompt"""
formatted_prompt = f"User asks: {prompt}nAssistant:"
inputs = tokenizer.encode(formatted_prompt, return_tensors="pt")
inputs = inputs.to(model.device)
with torch.no_grad():
outputs = model.generate(
inputs,
max_length=max_length,
temperature=temperature,
top_p=0.9,
do_sample=True,
pad_token_id=tokenizer.eos_token_id,
repetition_penalty=1.1
)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
assistant_response = response.split("Assistant:")[-1].strip()
return assistant_response
# Load fine-tuned model and test
model, tokenizer = load_model_for_inference()
test_prompts = [
"What makes MND different from other development companies?",
"Can you tell me about MND's team?",
"What is the company culture at MND?"
]
for prompt in test_prompts:
response = generate_response(model, tokenizer, prompt)
print(f"Q: {prompt}")
print(f"A: {response}n")
Google Colab
Evo Google Colab linka za ovaj članak koji možete pokrenuti jednim klikom: link
Pravi Troškovi
Za razliku od komercijalnih API-ja, vaši troškovi su primarno:
- Početna Postavka: GPU vrijeme za obuku
- Pohrana: Težine modela (~4GB za TinyLlama s LoRA adapterima)
- Zaključivanje: Vaša vlastita sklopovna oprema ili GPU primjeri u oblaku
Za mali model kao TinyLlama, možete pokrenuti zaključivanje na:
- Google Colab (besplatan sloj s ograničenjima)
- AWS t3.medium s GPU (~$0,05/sat)
- Vašu vlastitu sklopovsku opremu (RTX 3060 ili bolja)
Najbolje Prakse Iz Stvarnog Iskustva
1. Počnite Male i Skalite Gore Počnite s distilgpt2 ili gpt2 da testirate vaše podatke i proces, zatim prijeđite na veće modele.
2. Pratite Preobučavanje S malim skupovima podataka, modeli mogu memorirati umjesto učenja. Pratite vašu evaluacijsku gubitak.
3. Konzistentnost Oblikovanja je Kritična Točan format vaših podataka za obuku je izuzetno važan. Budite konzistentni s interpunkcijom, razmacima i strukturom.
4. Testirajte s Neviđenim Pitanjima Uvijek testirajte s pitanjima koja nisu u vašim podacima za obuku kako bi osigurali generalizaciju.
5. Spremi Redovne Kontrolne Točke Obuka može biti prekinuta. Čuvajte često i testirajte međuobračunate kontrolne točke.
Česti Problemi i Rješenja
Problem: Model generira repetitivan ili besmislan tekst Rješenje: Snizite stopu učenja, povećajte regularizaciju, ili poboljšajte kvalitetu podataka za obuku
Problem: Model zaboravlja opće znanje Rješenje: Uključite neke opće primjere u vaše podatke za obuku ili koristite veći bazni model
Problem: Odgovori su previše generički Rješenje: Činite vaše primjere obuke specifičnijima i detaljnijima
Problem: GPU memorijski problemi Rješenje: Smanjite veličinu grupe, koristite agresivniju kvantizaciju, ili gradijente kontrolne točke
Kombiniranje s RAG-om
Evo moćnog dijela: možete kombinirati vaš fino podeseni model s RAG-om za najbolje obojega:
- Fino podesiti za razumijevanje domene, ton i opće znanje o poduzeću
- Koristiti RAG za trenutne informacije, specifične dokumente, ili detaljne tehničke specifikacije
To vam daje model koji "razmišlja" kao vaša poduzeće, ali može pristupiti ažuriranima informacijama.
Što Je Sljedeće
U našem sljedećem članku, idemo potpuno po mjeri — grad jući jezični model od nule, samo vaš, koji se pokreće na vašoj sklopskoj opremi s vašim podacima.
Fino podešavanje modela otvorenog koda daje vam bezprecedentnu kontrolu nad vašim AI asistentom. Možete osigurati da razumiju vašu domenu, govore vašim glasom, i nikada ne šalju vaše podatke trećim stranama. S modernim tehniqama učinkovitosti kao LoRA i kvantizacija, to je dostupnije nego ikad.
Budućnost AI nije samo o korištenju tuđeg modela — to je o činjenju AI istinski vašim.
Dolazi uskoro: Članak 4 — "Gradnja Vlastitog Jezikovnog Modela: Mali Ali Moćan"


