Část 3 z 5: Přizpůsobení předtrénovaných modelů
Vítejte zpět! V našem posledním článku jsme vytvořili systém RAG, který dává AI přístup k vašim specifickým informacím. Dnes jdeme dál — skutečně budeme upravovat, jak si AI model myslí a reaguje, a to jeho dolaďováním. Pro tuto ukázkovou příklad použiji open-source model.
RAG vs Dolaďování: Jaký je rozdíl?
Představte si to takto:
RAG je jako dát někomu referenční knihu. Ten člověk je stále stejný, ale nyní má přístup k určitým informacím, když odpovídá na otázky.
Dolaďování je jako poslat někoho na specializovaný trénink. Skutečně měníte, jak si myslí a reaguje na základě vašich specifických požadavků.
Kdy byste měli provádět dolaďování?
Dolaďování je mocné, ale není vždy nutné. Zvažte dolaďování, když:
- Potřebujete, aby AI přijala určitý tón nebo styl
- Vaše oblast má speciální terminologii nebo koncepty
- Chcete konzistentní odpovědi v mnoha různých scénářích
- RAG vám nedává kvalitu odpovědí, kterou potřebujete
- Máte dostatek trénovacích dat (obvykle stovky příkladů)
- Potřebujete, aby model fungoval offline nebo v uzavřených prostředích
Nastavení vašeho prostředí
V tomto tutoriálu používáme Google Colab s GPU T4, ale můžete to přizpůsobit pro jakékoliv prostředí kompatibilní s CUDA:
# Instalace požadovaných balíčků !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
Výběr správného modelu
Pro tento tutoriál budeme používat TinyLlama-1.1B, ale zde jsou některé vynikající možnosti pro různé potřeby:
# Ultra-lehké modely (dobré pro experimenty) # model_name = "distilgpt2" # 82M parametrů # model_name = "gpt2" # 124M parametrů # model_name = "EleutherAI/gpt-neo-125M" # 125M parametrů# Malé, ale schopné modely # model_name = "microsoft/DialoGPT-medium" # 355M parametrů # model_name = "microsoft/DialoGPT-large" # 762M parametrů model_name = "TinyLlama/TinyLlama-1.1B-Chat-v1.0" # 1.1B parametrů - vybírám tento # Pro produkční použití (máte-li více GPU paměti) # model_name = "microsoft/phi-2" # 2.7B parametrů # model_name = "stabilityai/stablelm-2-1_6b" # 1.6B parametrů
Příprava trénovacích dat
Klíč k úspěšnému dolaďování je vysoce kvalitní trénovací data. Zde je způsob, jak je strukturujeme:
# Ukázkový dataset pro 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"
]
}
# Konverze na HuggingFace dataset
dataset = Dataset.from_dict(data)
Klíčové principy pro trénovací data:
- Používejte konzistentní formátování (všimněte si vzoru "User asks:" a "Assistant:")
- Udržujte odpovědi faktické a stručné
- Pokryjte nejdůležitější informace o vaší oblasti
- Kvalita před kvantitou: 50 perfektních příkladů porazí 500 průměrných
Efektivní trénink s LoRA a kvantováním
Místo dolaďování celého modelu (které vyžaduje obrovskou GPU paměť) budeme používat dvě techniky efektivnosti:
1. Kvantování (4-bit)
Kvantování je kompresní technika používaná k zmenšení velkých jazykových modelů (LLM) a jejich zrychlení bez výrazného snížení přesnosti.
- Normálně se váhy LLM ukládají jako 32bitová čísla s pohyblivou řádkou (FP32).
- Kvantování snižuje tuto přesnost na 16-bit (FP16/BF16), 8-bit (INT8), 4-bit (INT4) nebo ještě nižší.
👉 Příklad:
- Model s 10 miliardami parametrů v FP32 potřebuje ~40 GB paměti.
- Pokud jej kvantujeme na INT8 (8-bit) → potřebuje pouze ~10 GB.
- Pokud přejdeme na INT4 (4-bit) → pouze ~5 GB.
⚡ Proč je to užitečné?
- Umožňuje modely spouštět na menších GPU (nebo dokonce CPU).
- Zrychluje závěr.
- Malý kompromis v přesnosti, ale často zanedbatelný.
# Konfigurace 4bitového kvantování bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_use_double_quant=True, bnb_4bit_compute_dtype=torch.float16 )# Načtení modelu s kvantováním model = AutoModelForCausalLM.from_pretrained( model_name, quantization_config=bnb_config, device_map="auto", torch_dtype=torch.float16 )
2. LoRA (Low-Rank Adaptation)
LoRA je parametricky efektivní metoda dolaďování (PEFT).
Normálně by dolaďování obrovského LLM (jako LLaMA-65B nebo GPT-J) vyžadovalo stovky GB GPU paměti. LoRA to řeší takto:
- Zamrznutí původních vah modelu.
- Přidání malých trénovatelných matic (adaptérů nízké úrovně) uvnitř vrstev modelu.
- Během dolaďování se aktualizují pouze tyto malé matice.
👉 Příklad:
- Úplné dolaďování modelu 65B mohlo vyžadovat ~1 TB GPU paměti.
- S LoRA trénujete pouze několik milionů parametrů → potřebujete < 20 GB GPU paměti.
⚡ Proč je to užitečné?
- Umožňuje dolaďování obrovských LLM na běžném hardwaru (1–2 GPU).
- Snadné "sloučení" nebo "oddělení" adaptérů → můžete rychle přepínat úlohy.
- Často dosahuje výkonu blízkému úplnému dolaďování.
# Konfigurace LoRA na základě architektury modelu 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, # Hodnost adaptace lora_alpha=16, # Parametr škálování LoRA target_modules=target_modules, lora_dropout=0.05, bias="none", task_type="CAUSAL_LM" ) # Aplikace LoRA na model model = get_peft_model(model, lora_config) model.print_trainable_parameters()
Trénujeme pouze 0,2 % parametrů!
Trénink modelu
# Tokenizace dat def tokenize_function(examples): tokenized_inputs = tokenizer( examples["text"], truncation=True, padding="max_length", max_length=512, return_tensors="pt" ) # Vytvoření štítků kopírováním vstupních tokenů tokenized_inputs["labels"] = tokenized_inputs["input_ids"].clone() return tokenized_inputs# Rozdělení datasetu train_dataset = dataset.select(range(8)) eval_dataset = dataset.select(range(8, 11)) # Aplikace tokenizace train_dataset = train_dataset.map(tokenize_function, batched=True) eval_dataset = eval_dataset.map(tokenize_function, batched=True) # Konfigurace tréninku 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 # Deaktivace wandb logování ) # Vytvoření tréneru a spuštění tréninku trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, tokenizer=tokenizer, ) print("Zahájení tréninku...") trainer.train() # Uložení adaptéru adapter_dir = "./mnd-finetune-outputs/final_adapter" model.save_pretrained(adapter_dir) tokenizer.save_pretrained(adapter_dir)
Testování doladěného modelu
def load_model_for_inference():
"""Načtení doladěného modelu pro inferenci"""
# Načtení základního modelu
base_model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_config,
device_map="auto",
torch_dtype=torch.float16
)
# Načtení doladěného adaptéru
model = PeftModel.from_pretrained(base_model, adapter_dir)
model = model.merge_and_unload()
# Načtení tokenizeru
tokenizer = AutoTokenizer.from_pretrained(adapter_dir)
return model, tokenizer
def generate_response(model, tokenizer, prompt, max_length=256, temperature=0.7):
"""Vygenerování odpovědi pro daný 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
# Načtení doladěného modelu a 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
Zde je odkaz na google colab pro tento článek, který můžete spustit jedním kliknutím: odkaz
Skutečné náklady
Na rozdíl od komerčních API, vaše náklady jsou primárně:
- Počáteční nastavení: GPU čas pro trénink
- Úložiště: Váhy modelu (~4GB pro TinyLlama s LoRA adaptéry)
- Inference: Váš vlastní hardware nebo cloudové GPU instance
Pro malý model jako TinyLlama můžete spouštět inferenci na:
- Google Colab (bezplatná úroveň s omezeními)
- AWS t3.medium s GPU (~$0,05/hodinu)
- Váš vlastní hardware (RTX 3060 nebo lepší)
Osvědčené postupy ze skutečné zkušenosti
1. Začněte v malém a rozšiřujte Začněte s distilgpt2 nebo gpt2 k testování vašich dat a procesu, pak přejděte na větší modely.
2. Monitorujte přetrénování S malými datasety si mohou modely zapamatovat místo učení. Sledujte svou evaluační ztrátu.
3. Konzistence formátu je kritická Přesný formát vašich trénovacích dat je obrovský. Buďte konzistentní s interpunkcí, mezerami a strukturou.
4. Testujte s neznámými otázkami Vždy testujte s otázkami, které nejsou ve vašich trénovacích datech, abyste zajistili generalizaci.
5. Ukládejte pravidelné checkpointy Trénink může být přerušen. Ukládejte často a testujte mezilehlé checkpointy.
Běžné problémy a řešení
Problém: Model generuje opakující se nebo nesmyslný text Řešení: Snižte rychlost učení, zvyšte regularizaci nebo zlepšete kvalitu trénovacích dat
Problém: Model zapomíná obecné znalosti Řešení: Zahrnout do trénovacích dat některé obecné příklady nebo použít větší základní model
Problém: Odpovědi jsou příliš generické Řešení: Udělejte své příklady trénování konkrétnější a podrobnější
Problém: Problémy s pamětí GPU Řešení: Snižte velikost dávky, použijte agresivnější kvantování nebo gradient checkpointing
Kombinace s RAG
Zde je mocná část: můžete kombinovat svůj doladěný model s RAG pro nejlepší z obou světů:
- Doladění pro pochopení domény, tón a obecné znalosti společnosti
- Použití RAG pro aktuální informace, konkrétní dokumenty nebo podrobné technické specifikace
To vám dává model, který si „myslí" jako vaše společnost, ale může přistupovat k aktuálním informacím.
Co dál
V našem dalším článku jdeme úplně na míru — budování jazykového modelu od nuly, zcela vašeho, spuštěného na vašem hardwaru s vašimi daty.
Dolaďování open-source modelů vám dává bezprecedentní kontrolu nad vaším AI asistentem. Můžete zajistit, aby pochopil vaši doménu, mluvil vaším hlasem a nikdy neposílal vaše data třetím stranám. S moderními technikami efektivnosti jako LoRA a kvantování je to dostupnější než kdy dříve.
Budoucnost AI není jen o používání modelu někoho jiného — jde o to, aby byla AI skutečně vaše.
Připravuje se: Článek 4 — "Vytváření vlastního jazykového modelu: Malého, ale mohutného"


