Fine-tuning — přizpůsobení AI modelu vašim datům
Fine-tuning je pokročilá technika, která umožňuje přizpůsobit předtrénovaný AI model vašim specifickým datům a potřebám. Díky této metodě můžete výrazně zlepšit výkon modelu v konkrétní doméně nebo úloze.
Co je fine-tuning a proč ho potřebujete
Fine-tuning je proces doučení předtrénovaného AI modelu na specifických datech, který umožňuje přizpůsobit obecný model vašim konkrétním potřebám. Místo trénování modelu od nuly využíváte již naučené znalosti a pouze je rozšiřujete o vaši doménu.
Hlavní výhody fine-tuningu:
- Výrazně menší výpočetní nároky než trénování od začátku
- Lepší výsledky na specifických úlohách než obecné modely
- Možnost využití menších datasetů (stovky až tisíce příkladů)
- Zachování obecných znalostí základního modelu
Kdy použít fine-tuning versus prompt engineering
Fine-tuning není vždy nejlepší řešení. Rozhodovací proces by měl vypadat takto:
Použijte prompt engineering, když:
- Potřebujete rychlé řešení bez dodatečných nákladů
- Máte pouze několik příkladů (méně než 100)
- Úloha je obecná a dobře popsatelná
Použijte fine-tuning, když:
- Máte specifickou doménu s vlastní terminologií
- Potřebujete konzistentní formát odpovědí
- Disponujete kvalitním datasetem (100+ příkladů)
- Chcete snížit latenci a náklady za inference
Typy fine-tuningu
Full Fine-tuning
Aktualizuje všechny parametry modelu. Nejefektivnější, ale také nejnáročnější na výpočetní zdroje a paměť.
Parameter Efficient Fine-Tuning (PEFT)
Moderní přístup, který aktualizuje pouze malou část parametrů. Hlavní techniky:
- LoRA (Low-Rank Adaptation): Přidává malé adaptační vrstvy
- QLoRA: LoRA s kvantizací pro ještě menší paměťové nároky
- Adapter layers: Vkládá malé vrstvy mezi existující layers
- Prefix tuning: Optimalizuje pouze speciální prefix tokeny
Praktická implementace s LoRA
Ukázka fine-tuningu pomocí Hugging Face Transformers a PEFT knihovny:
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from peft import LoraConfig, get_peft_model, TaskType
from datasets import Dataset
import torch
# Načtení základního modelu
model_name = "microsoft/DialoGPT-medium"
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
# Konfigurace LoRA
lora_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=16, # rank - vyšší = více parametrů
lora_alpha=32,
lora_dropout=0.1,
target_modules=["c_attn", "c_proj"] # které vrstvy upravit
)
# Aplikace LoRA na model
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
Příprava trénovacích dat
def prepare_dataset(examples):
"""Příprava dat pro causal language modeling"""
inputs = []
for example in examples:
# Formát: "Otázka: {question} Odpověď: {answer}"
text = f"Otázka: {example['question']} Odpověď: {example['answer']}"
inputs.append(text)
# Tokenizace
model_inputs = tokenizer(
inputs,
truncation=True,
padding=True,
max_length=512,
return_tensors="pt"
)
# Pro causal LM jsou labels stejné jako input_ids
model_inputs["labels"] = model_inputs["input_ids"].clone()
return model_inputs
# Ukázková data
train_data = [
{"question": "Jak funguje Docker?", "answer": "Docker je kontejnerizační platforma..."},
{"question": "Co je Kubernetes?", "answer": "Kubernetes je orchestrační systém..."},
# ... více příkladů
]
dataset = Dataset.from_list(train_data)
tokenized_dataset = dataset.map(prepare_dataset, batched=True)
Spuštění tréninku
from transformers import Trainer, DataCollatorForLanguageModeling
# Konfigurace tréninku
training_args = TrainingArguments(
output_dir="./fine-tuned-model",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
warmup_steps=100,
learning_rate=5e-5,
logging_steps=10,
save_steps=500,
evaluation_strategy="steps",
eval_steps=500,
fp16=True, # pro úsporu paměti
)
# Data collator pro jazylové modelování
data_collator = DataCollatorForLanguageModeling(
tokenizer=tokenizer,
mlm=False # causal LM, ne masked LM
)
# Inicializace traineru
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_dataset,
data_collator=data_collator,
)
# Spuštění tréninku
trainer.train()
trainer.save_model()
Monitoring a evaluace
Správné sledování průběhu fine-tuningu je klíčové:
# Sledování metrik během tréninku
import wandb
# Integrace s Weights & Biases
wandb.init(project="fine-tuning-experiment")
# Evaluační funkce
def compute_perplexity(eval_dataset):
"""Výpočet perplexity na evaluačním datasetu"""
model.eval()
total_loss = 0
num_batches = 0
with torch.no_grad():
for batch in eval_dataset:
outputs = model(**batch)
total_loss += outputs.loss.item()
num_batches += 1
avg_loss = total_loss / num_batches
perplexity = torch.exp(torch.tensor(avg_loss))
return perplexity.item()
# Testování vygenerovaných odpovědí
def test_generation(prompt, max_length=100):
"""Test generování textu"""
inputs = tokenizer.encode(prompt, return_tensors="pt")
with torch.no_grad():
outputs = model.generate(
inputs,
max_length=max_length,
temperature=0.7,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
return tokenizer.decode(outputs[0], skip_special_tokens=True)
Optimalizace a best practices
Výběr hyperparametrů
- Learning rate: Začněte s 5e-5, pro menší modely zkuste 1e-4
- Batch size: Co největší, co se vejde do paměti
- LoRA rank (r): 16-64 pro většinu úloh, vyšší pro komplexnější domény
- Epochy: 2-5, sledujte overfitting
Kvalita dat
Kvalita dat je kritická pro úspěch fine-tuningu:
# Validace kvality dat
def validate_dataset(dataset):
"""Kontrola kvality trénovacích dat"""
issues = []
for i, example in enumerate(dataset):
# Kontrola délky
if len(example['question']) < 10:
issues.append(f"Řádek {i}: Příliš krátká otázka")
# Kontrola duplicit
if example['question'] in seen_questions:
issues.append(f"Řádek {i}: Duplicitní otázka")
# Kontrola formátu
if not example['answer'].strip():
issues.append(f"Řádek {i}: Prázdná odpověď")
return issues
# Očištění dat
def clean_dataset(examples):
"""Základní čištění datasetu"""
cleaned = []
for example in examples:
# Odstranění extra whitespace
question = example['question'].strip()
answer = example['answer'].strip()
# Filtrace podle délky
if 10 <= len(question) <= 500 and 20 <= len(answer) <= 1000:
cleaned.append({
'question': question,
'answer': answer
})
return cleaned
Deployment a inference
Po dokončení fine-tuningu je potřeba model efektivně nasadit:
from peft import PeftModel
# Načtení fine-tuned modelu pro inference
base_model = AutoModelForCausalLM.from_pretrained(
"microsoft/DialoGPT-medium",
torch_dtype=torch.float16,
device_map="auto"
)
# Načtení LoRA adaptéru
model = PeftModel.from_pretrained(base_model, "./fine-tuned-model")
# Inference API
class FineTunedAPI:
def __init__(self, model, tokenizer):
self.model = model
self.tokenizer = tokenizer
def generate_response(self, question: str) -> str:
"""Generování odpovědi na otázku"""
prompt = f"Otázka: {question} Odpověď:"
inputs = self.tokenizer.encode(prompt, return_tensors="pt")
with torch.no_grad():
outputs = self.model.generate(
inputs,
max_new_tokens=200,
temperature=0.7,
do_sample=True,
pad_token_id=self.tokenizer.eos_token_id
)
response = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
# Extrakce pouze nové části odpovědi
return response[len(prompt):].strip()
# Použití
api = FineTunedAPI(model, tokenizer)
answer = api.generate_response("Jak optimalizovat PostgreSQL databázi?")
Shrnutí
Fine-tuning je mocný nástroj pro přizpůsobení AI modelů specifickým potřebám. Klíčové je správně zvolit mezi prompt engineeringem a fine-tuningem, použít kvalitní data a vhodnou PEFT techniku jako LoRA. S rostoucí dostupností nástrojů jako Hugging Face PEFT se fine-tuning stává dostupnějším i pro menší týmy. Pamatujte na důkladné testování, monitoring metrik a postupné zlepšování kvality dat pro dosažení nejlepších výsledků.