Najvjerojatnije nikada nećete morati to učiniti. Fine-tuning vam omogućuje da prilagodite prethodno obučene jezike za vaše potrebe u satima ili danima, a ne mjesecima, uz frakciju resursa. Ovaj tutorial će vas odvesti Naučit ćete četiri osnovne tehnike finog podešavanja, kodirati kompletnu obuku u Pythonu i naučiti tehnike koje razdvajaju modele spremne za proizvodnju od skupih eksperimenata. from theory to practice Šta je LLM Fine-Tuning? Fine-tuning obučava postojeći jezični model na vašim podacima kako bi ga poboljšao Pre-trenirani modeli su moćni generalisti, ali ih izlažu možete ih pretvoriti u stručnjake za vaš slučaj upotrebe. performance on specific tasks focused examples Umjesto da gradite model od nule (koji zahtijeva ogromno računanje i podatke), dajete modelu koji je već sposoban crash kurs u onome što vam je važno, bilo da je to medicinska dijagnoza, automatizacija podrške kupcima, analiza osjećaja ili bilo koji drugi poseban zadatak. Kako LLM Fine-Tuning radi? Fine-tuning nastavlja proces obuke na pre-treniranim jezikovnim modelima koristeći vaš specifičan skup podataka. Model obrađuje vaše dostavljene primjere, uspoređuje vlastite rezultate sa očekivanim rezultatima, i prilagoditi i minimizirati gubitke. updates internal weights Ovaj pristup može varirati na osnovu vašeg U pitanju je i Neki projekti zahtijevaju punu fine-tuning, gde ažurirate sve parametre modela, dok drugi bolje rade sa parametar-efikasnijim metodama kao što su To samo menja malu podskupinu. goals available data computational resources Lora LLM Fine-Tuning metode Preduzetnik Fine-Tuning SFT uči model da nauči obrasce ispravnih parova pitanja i odgovora i prilagođava težine modela kako bi tačno odgovarao tim odgovorima. Koristite ovo kada želite dosljedne izlaze, kao što je da model uvek odgovara u JSON formatu, slijedite skript za korisničku podršku ili pišite e-poruke u tonu vaše kompanije. (Prompt, Ideal Response) Nezaštićeni Fine-Tuning Hrani model tone sirovog teksta (bez pitanja ili označenih podataka potrebnih) tako da uči vokabular i obrasce određenog domena. Dok je to tehnički pre-trening proces poznat kao kontinuirano pre-trening (CPT), to se obično radi nakon početne pre-trening faze. Koristite ovo prvo kada vaš model treba da razume specijalizirani sadržaj na kojem nije prvobitno obučena, kao što su medicinska terminologija, pravni ugovori ili novi jezik. Optimizacija direktne preferencije DPO uči model da preferira bolje odgovore pokazujući primjere dobrih i loših odgovora na isto pitanje i prilagođavajući ga da omogući dobre. Koristite DPO nakon osnovnog treninga kako biste ispravili uznemirujuće ponašanje kao što je zaustavljanje modela da stvari napravi, da bude previše besmislen, ili davanje nesigurnih odgovora. (Prompt, Good Response, Bad Response) Ojačavanje Fine-Tuning U RLHF-u, prvo obučavate model nagrade na pozivnicama sa više odgovora rangiranih od strane ljudi, učeći ga da predvidi koje odgovore ljudi preferiraju. Zatim, koristite učenje o pojačavanju da biste optimizovali i prilagodili model koji generira odgovore, koje model nagrade sudi. Ovo pomaže modelu da uči tijekom vremena da proizvede izlaze sa većim rezultatima. Ovaj proces zahtijeva skup podataka u ovom formatu: Najbolje je za zadatke u kojima je lakše suditi o kvaliteti nego stvoriti savršene primjere, kao što su medicinske dijagnoze, pravna istraživanja i drugo složeno domensko razmatranje. (Prompt, [Response A, Response B, ...], [Rankings]) Korak po korak Fine-Tuning LLMs Tutorial Proći ćemo kroz svaki korak fino podešavanja malog unapred osposobljenog modela za rješavanje matematičkih problema zasnovanih na rečima, nešto s čime se bori izvan kutije. Pristup : podučavanje modela specijalizovane terminologije, poboljšanje performansi modela na određenim zadatcima, ili prilagođavanje na vaš domena. works for virtually any use case of fine-tuning LLMs Preduvjeti U novoj projektnoj fascikli, kreirajte i aktivirajte virtualno okruženje Python, a zatim instalirajte ove biblioteke pomoću ili vaš omiljeni menadžer paketa: pip pip install requests datasets transformers 'transformers[torch]' Get & Load Dataset (Preuzmite i učitajte skup podataka) Proces fino prilagođavanja započinje odabirom skupova podataka, što je vjerojatno najvažnija odluka. . reflect the task you want your model to perform Jednostavni zadatci kao što su analiza osjećaja zahtijevaju osnovne pare ulaza i izlaza. Kompleksni zadatci kao što su praćenje uputa ili odgovaranje na pitanja zahtijevaju bogatije skupove podataka sa kontekstom, primjerima i raznovrsnim formatima. Najjednostavnija polazna točka je biblioteka skupova podataka, u kojoj se nalaze hiljade skupova podataka otvorenog koda za različite domene i zadatke. ili javno dostupni podaci. Hugging Face Purchase specialized datasets build your own by Struganje Struganje Na primer, ako želite da izgradite model analize osjećaja za recenzije proizvoda Amazona, možda ćete želeti da prikupite podatke iz stvarnih recenzija pomoću alata za struganje na vebu. : Web raspršivač API import json import requests # Web Scraper API parameters. payload = { "source": "amazon_product", # Query is the ASIN of a product. "query": "B0DZDBWM5B", "parse": True, } # Send a request to the API and get the response. response = requests.post( "https://realtime.oxylabs.io/v1/queries", # Visit https://dashboard.oxylabs.io to claim FREE API tokens. auth=("USERNAME", "PASSWORD"), json=payload, ) print(response.text) # Extract the reviews from the response. reviews = response.json()["results"][0]["content"]["reviews"] print(f"Found {len(reviews)} reviews") # Save the reviews to a JSON file. with open("reviews.json", "w") as f: json.dump(reviews, f, indent=2) For this tutorial, let’s keep it simple without building a custom data collection pipeline. Since we're teaching the base model to solve word-based math problems, we can use the openai/gsm8k dataset. It’s a collection of grade-school math problems with step-by-step solutions. Load it in your Python file: from datasets import load_dataset dataset = load_dataset("openai/gsm8k", "main") print(dataset["train"][0]) Tokenizirajte podatke za obradu Modeli ne razumeju tekst izravno; oni rade sa Tokenizacija pretvara vaš tekst u žetone (numeričke reprezentacije) koje model može obrađivati.Svaki model ima svoj tokenizer obučeni pored njega, tako da koristite onaj koji odgovara vašem osnovnom modelu: numbers from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B") tokenizer.pad_token = tokenizer.eos_token Kako tokenizujemo naše oblike podataka ono što model uči. Za matematičke probleme, želimo da rafiniramo model kako bismo naučili kako da Evo trikova: tokenizirajte pitanja i odgovore odvojeno, a zatim koristite tehniku maskiranja. Odgovor Postavljanje pitanja token za govori proces obuke da ih ignoriše prilikom izračunavanja gubitaka. model uči samo iz odgovora, čineći obuku fokusnijom i efikasnijom. -100 def tokenize_function(examples): input_ids_list = [] labels_list = [] for question, answer in zip(examples["question"], examples["answer"]): # Tokenize question and answer separately question_tokens = tokenizer(question, add_special_tokens=False)["input_ids"] answer_tokens = tokenizer(answer, add_special_tokens=False)["input_ids"] + [tokenizer.eos_token_id] # Combine question + answer for input input_ids = question_tokens + answer_tokens # Mask question tokens with -100 so loss is only computed on the answer labels = [-100] * len(question_tokens) + answer_tokens input_ids_list.append(input_ids) labels_list.append(labels) return { "input_ids": input_ids_list, "labels": labels_list, } Primijenite ovu funkciju tokenizacije na skupove podataka za obuku i testiranje. Filtriramo primere duže od 512 žetona kako bismo održali upravljivu upotrebu memorije i osigurali da model obrađuje kompletne informacije bez trunciranja. train_dataset = dataset["train"].map( tokenize_function, batched=True, remove_columns=dataset["train"].column_names, ).filter(lambda x: len(x["input_ids"]) <= 512) .shuffle(seed=42) eval_dataset = dataset["test"].map( tokenize_function, batched=True, remove_columns=dataset["test"].column_names, ).filter(lambda x: len(x["input_ids"]) <= 512) print(f"Samples: {len(dataset['train'])} → {len(train_dataset)} (after filtering)") print(f"Samples: {len(dataset['test'])} → {len(eval_dataset)} (after filtering)") Optional: Želite li brzo testirati čitavu cevovodu pre nego što se uključite u punu obuku? Možete obučiti model na podskupu podataka. Dakle, umesto da koristite punu skupinu podataka od 8.5K, možete je smanjiti na 3K u cjelini, što proces čini mnogo bržim: train_dataset = train_dataset.select(range(2000)) eval_dataset = eval_dataset.select(range(1000)) manji skupovi podataka povećavaju rizik od preopterećenja, gde model pamti podatke o obuci umjesto da uči opće obrasce. Za proizvodnju, ciljajte na najmanje 5K+ uzorke obuke i pažljivo prilagodite svoje hiperparametre. Keep in mind: Inicijalizirajte bazni model Zatim, učitajte prethodno obučeni osnovni model kako biste ga fino prilagodili poboljšanjem svojih sposobnosti za rješavanje matematičkih problema: from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B") model.config.pad_token_id = tokenizer.pad_token_id Fine-Tune Koristeći Metodu Trenera Ovde se događa magija. TrainingArguments kontroliše kako vaš model uči (mislite o tome kao o receptu koji određuje kvalitet vašeg konačnog rezultata).Ova podešavanja i hiperparametri mogu napraviti ili prekinuti vaše fino podešavanje, tako da eksperimentišite s različitim vrednostima kako biste pronašli ono što radi za vaš slučaj upotrebe. Key parameters explained: · Više epoha znači više mogućnosti za učenje, ali previše uzrokuje prekomjernu opremu. Epochs: · Utječe na upotrebu memorije i brzinu treninga. Prilagodite ih na osnovu hardvera. Batch size: · Upravlja koliko brzo se model prilagođava. Previše visoka i može propustiti optimalno rješenje, previše niska i obuka traje zauvijek. Learning rate: · Može pomoći u sprečavanju preopterećenja sprečavanjem modela da se previše oslanja na bilo koji pojedini uzorak. Ako je propadanje težine preveliko, to može dovesti do podopunjavanja sprečavanjem modela da uči potrebne obrasce. Weight decay: Optimalna konfiguracija ispod je specijalizovana za obuku CPU-a (uklonite use_cpu=True ako imate GPU): from transformers import TrainingArguments, Trainer, DataCollatorForSeq2Seq training_args = TrainingArguments( output_dir="./qwen-math", # Custom output directory for the fine-tuned model use_cpu=True, # Set to False or remove to use GPU if available # Training duration num_train_epochs=2, # 3 may improve reasoning at the expense of overfitting # Batch size and memory management per_device_train_batch_size=5, # Adjust depending on your PC capacity per_device_eval_batch_size=5, # Adjust depending on your PC capacity gradient_accumulation_steps=4, # Decreases memory usage, adjust if needed # Learning rate and regularization learning_rate=2e-5, # Affects learning speed and overfitting weight_decay=0.01, # Prevents overfitting by penalizing large weights max_grad_norm=1.0, # Prevents exploding gradients warmup_ratio=0.1, # Gradually increases learning rate to stabilize training lr_scheduler_type="cosine", # Smoother decay than linear # Evaluation and checkpointing eval_strategy="steps", eval_steps=100, save_strategy="steps", save_steps=100, save_total_limit=3, # Keep only the best 3 checkpoints load_best_model_at_end=True, # Load the best checkpoint at the end of training metric_for_best_model="eval_loss", greater_is_better=False, # Logging logging_steps=25, logging_first_step=True, ) # Data collator handles padding and batching data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model) # Initialize trainer trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, data_collator=data_collator, ) # Fine-tune the base model print("Fine-tuning started...") trainer.train() Once training completes, save your fine-tuned model: trainer.save_model("./qwen-math/final") tokenizer.save_pretrained("./qwen-math/final") 5. ocenjivanje modela Nakon finog podešavanja, izmjerite koliko dobro vaš model radi pomoću dva zajednička pokazatelja: · Meri koliko su predviđanja modela daleko od ciljanih rezultata, gde niže vrednosti ukazuju na bolji performanse. Loss: · Prikazuje iste informacije na intuitivnijoj skali, gde niže vrednosti znače da je model sigurniji u svoje predviđanja. Perplexity (the exponential of loss): Za proizvodne okruženja, razmislite o dodavanju metrika kao što su ili da bi se izmjerilo koliko se usko generisani odgovori podudaraju sa referentnim odgovorima. BLEU ROUGE import math eval_results = trainer.evaluate() print(f"Final Evaluation Loss: {eval_results['eval_loss']:.4f}") print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}") Možete uključiti i druge metrike kao što je F1, koji mjeri koliko je dobar vaš model u hvatanju onoga što je važno dok ostaje točan. je dobra polazna točka za učenje bitnosti korišćenja biblioteke transformatora. Predavanje za lice Primer kompletnog fine-tuning koda Nakon ovih pet koraka, trebali biste imati sledeći kod kombiniran u jednu Python datoteku: import math from datasets import load_dataset from transformers import ( AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer, DataCollatorForSeq2Seq, ) dataset = load_dataset("openai/gsm8k", "main") tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B") tokenizer.pad_token = tokenizer.eos_token # Tokenization function adjusted for the specific dataset format def tokenize_function(examples): input_ids_list = [] labels_list = [] for question, answer in zip(examples["question"], examples["answer"]): question_tokens = tokenizer(question, add_special_tokens=False)["input_ids"] answer_tokens = tokenizer(answer, add_special_tokens=False)["input_ids"] + [tokenizer.eos_token_id] input_ids = question_tokens + answer_tokens labels = [-100] * len(question_tokens) + answer_tokens input_ids_list.append(input_ids) labels_list.append(labels) return { "input_ids": input_ids_list, "labels": labels_list, } # Tokenize the data train_dataset = dataset["train"].map( tokenize_function, batched=True, remove_columns=dataset["train"].column_names, ).filter(lambda x: len(x["input_ids"]) <= 512) .shuffle(seed=42) eval_dataset = dataset["test"].map( tokenize_function, batched=True, remove_columns=dataset["test"].column_names, ).filter(lambda x: len(x["input_ids"]) <= 512) print(f"Samples: {len(dataset['train'])} → {len(train_dataset)} (after filtering)") print(f"Samples: {len(dataset['test'])} → {len(eval_dataset)} (after filtering)") # Optional: Use a smaller subset for faster testing # train_dataset = train_dataset.select(range(2000)) # eval_dataset = eval_dataset.select(range(1000)) model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B") model.config.pad_token_id = tokenizer.pad_token_id # Configuration settings and hyperparameters for fine-tuning training_args = TrainingArguments( output_dir="./qwen-math", use_cpu=True, # Training duration num_train_epochs=2, # Batch size and memory management per_device_train_batch_size=5, per_device_eval_batch_size=5, gradient_accumulation_steps=4, # Learning rate and regularization learning_rate=2e-5, weight_decay=0.01, max_grad_norm=1.0, warmup_ratio=0.1, lr_scheduler_type="cosine", # Evaluation and checkpointing eval_strategy="steps", eval_steps=100, save_strategy="steps", save_steps=100, save_total_limit=3, load_best_model_at_end=True, metric_for_best_model="eval_loss", greater_is_better=False, # Logging logging_steps=25, logging_first_step=True, ) data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model) trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, data_collator=data_collator, ) # Fine-tune the base model print("Fine-tuning started...") trainer.train() # Save the final model trainer.save_model("./qwen-math/final") tokenizer.save_pretrained("./qwen-math/final") # Evaluate after fine-tuning eval_results = trainer.evaluate() print(f"Final Evaluation Loss: {eval_results['eval_loss']:.4f}") print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}") Prije izvođenja, odvojite trenutak da prilagodite konfiguraciju trenera i hiperparametre na osnovu onoga što vaša mašina zapravo može nositi. Da biste dobili realnu referenciju, evo šta je glatko funkcionisalo za nas na MacBook Air-u s M4 čipom i 16 GB RAM-a. · : 7 Batch size for training · 7 Batch size for eval: · 5 Gradient accumulation: Kako vaš model vozi, držite pogled na Ako se povećava dok se gubitak treninga smanjuje, model je preopterećen. U tom slučaju, prilagodite epohe, smanjite brzinu učenja, modificirajte gubitak težine i druge hiperparametre. U dolje navedenom primeru vidimo zdrave rezultate s eval gubitkom koji se smanjuje od dva I konačna zbunjenost . evaluation loss 0.496 0.469 1.60 Test Fine-Tuned modela Sada za trenutak istine – da li je naš fine-tuning zapravo uspio? Možete ručno testirati fine-tuned model tako što ćete ga potaknuti ovim Python kodom: from transformers import pipeline generator = pipeline( "text-generation", # Use `Qwen/Qwen2.5-0.5B` for testing the base model model="./qwen-math/final" ) output = generator( "James has 5 apples. He buys 3 times as many. Then gives half away. How many does he have?", return_full_text=False ) print(output[0]["generated_text"]) U ovoj usporedbi, možete videti kako modeli prije i poslije odgovaraju na isto pitanje (točan odgovor je 10): Kada je uzorkovanje omogućeno, oba modela povremeno dobiju pravo ili pogrešno zbog slučajnosti. funkcija otkriva njihovo istinsko samopouzdanje: model uvijek bira svoj odgovor s najvećom verovatnošću. Pouzdani izlazi (Naravno ), dok je Pouzdani izlazi (Naravno To je fine-tuning na poslu. do_sample=False in the generator() base model -2 Pogrešno fine-tuned model 10 ispravno Fine-Tuning najbolje prakse Izbor modela · Modeli specifični za domen i odgovarajući kontekstni prozori štede vas od borbe protiv postojećeg znanja modela. Choose the right base model: · Modeli samo za kodiranje (kao što je BERT) izvrsni su za zadatke klasifikacije, modeli samo za dekodiranje (kao što je GPT) za generaciju teksta i modeli kodiranja za dekodiranje (kao što je T5) za zadatke transformacije kao što su prevođenje ili sažetak. Understand the model architecture: · Ako je vaš osnovni model osposobljen sa specifičnim predlošcima za uputstva, koristite isti format u finom podešavanju. Match your model's input format: Priprema podataka · Čisti i precizni primjeri svaki put pobeđuju masivne i bučne skupove podataka. Prioritize data quality over quantity: · Nikada ne dozvolite da vaš model vidi podatke o evaluaciji tokom treninga. To vam omogućuje da uhvatite prekomjernu opremu prije nego što uništi vaš model. Split training and evaluation samples: · Automatizovane metrike poput zbunjenosti ne govore vam da li model zapravo slijedi upute ili samo statistički predviđa reči. Establish a "golden set" for evaluation: Strategija obuke · Napravite male prilagodbe, a ne učite ga od nule, tako da agresivne stope mogu izbrisati ono što je naučio tijekom predtreninga. Start with a lower learning rate: · Trenirajte samo 1% parametara da biste dobili 90% + performanse dok koristite manje memorije i vremena. Use parameter-efficient fine-tuning (LoRA/PEFT): · Ciljanje svih slojeva ( itd.) donosi modele koji razumeju znatno bolje, a ne samo imitiraju stil. Target all linear layers in LoRA: q_proj, k_proj, v_proj, o_proj, · Slučajna buka u ugrađivanjima djeluje kao regularizacija, što može spriječiti pamćenje i povećati kvalitet razgovora za 35+ postotnih bodova. Use NEFTune ( ): noisy embedding fine-tuning Uslovi korišćenja Fine-Tuning · SFT uči kako govoriti; DPO uči što je dobro učenjem od parova preferencija. After SFT, Run DPO: Koja su ograničenja LLM Fine-Tuning? · Fine-tuning prepisuje postojeće neuronske obrasce, što može izbrisati dragoceno opšte znanje naučeno tokom predtreninga. Catastrophic forgetting: · Model može zapamtiti vaše primere obuke umjesto obrazaca učenja, uzrokujući da ne uspije na malo različitim ulazima. Overfitting on small datasets: · Prefinjeno podešavanje milijardi parametara zahtijeva skupe GPU-e, značajnu memoriju i satima do danima ili tjednima vremena obuke. High computational cost: · Pre-trenirani modeli već nose predrasude iz svojih podataka o obuci, a fino podešavanje može pojačati ove predrasude ako vaš skup podataka nije pažljivo kuriran. Bias amplification: · Novo i vanjsko znanje može zahtijevati prekvalifikaciju čitavog modela ili implementaciju Retrieval-Augmented Generation (RAG), dok ponavljanje fine-tuning često pogoršava performanse. Manual knowledge update: Zaključak Fine-tuning funkcioniše, ali samo ako su vaši podaci čisti i vaši hiperparametri su povezani.Kombinirajte ga sa prompt inženjering za najbolje rezultate, gde fin-tuning rješava specijalizaciju zadataka dok prompt inženjering vodi ponašanje modela u trenutku zaključivanja. Nastavite tako što ćete uhvatiti model iz Hugging Face koji se uklapa u vaš slučaj upotrebe za fino podešavanje specifično za domenu, iskopati ili izgraditi kvalitetni skup podataka za vaš zadatak i pokrenuti prvu sesiju fino podešavanja na malom podskupu. Kada vidite obećavajuće rezultate, proširite i eksperimentišite sa LoRA-om, DPO-om ili NEFTune-om kako biste iscijedili bolje performanse.