Kendi LLM’inizi Yaratın: Hugging Face Transformers ile LLM Model Egitiminin Tüm Detayları
Huggingface’in Transformers eğitim kütüphanesi, eğitim metriklerine hakim olduğunuzda harika bir araçtir. Kullanmaya başlayip hakim oldugunuzda da asla diğer yapay zeka eğitim araçlarına ihtiyacınız olmayacaktir. Gelin şimdi detaylica Transformers kutuphanesini, kullandığı diğer eğitim materyallerini ve parametrelerini detaylı inceleyelim. Ardından base bir LLM modelini eğitelim, kendi LLM’ımızı yaratalım ve huggingface’e yükleyelim.
Makaleyi okurken bir yandan da kurcalamaniz için örnek bir training kodu yazdım. Bu kod ile huggingface’den bir model indirip bu modeli yine uygun bir dataset ile (Instruction, Input, Output kolonlarina sahip) egitebilirsiniz.
import os
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
Trainer,
TrainingArguments,
BitsAndBytesConfig,
pipeline,
)
from datasets import load_dataset
from peft import LoraConfig, get_peft_model
# Suppress tokenizers parallelism warning
os.environ["TOKENIZERS_PARALLELISM"] = "false"
# 1. Load dataset
dataset = load_dataset("Dataset_Name")
# 2. Preprocess data
def preprocess_data(batch):
texts = [f"Instruction: {instruction}\nInput: {input_text}\nOutput: {output_text}" for instruction, input_text, output_text in zip(batch["instruction"], batch["input"], batch["output"])]
return {"text": texts}
processed_dataset = dataset.map(preprocess_data, batched=True)
# 3. Load tokenizer and model
model_path = "Model_Name"
tokenizer = AutoTokenizer.from_pretrained(model_path)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
# 4. Tokenize data and add labels
def tokenize_function(batch):
tokenized_inputs = tokenizer(batch["text"], truncation=True, padding="max_length", max_length=512)
tokenized_inputs["labels"] = [
[(label if label != tokenizer.pad_token_id else -100) for label in input_ids]
for input_ids in tokenized_inputs["input_ids"]
]
return tokenized_inputs
tokenized_dataset = processed_dataset.map(tokenize_function, batched=True, remove_columns=["instruction", "input", "output"])
train_test_split = tokenized_dataset["train"].train_test_split(test_size=0.2, seed=42)
train_dataset = train_test_split["train"]
eval_dataset = train_test_split["test"]
# 5. Load model with quantization
bnb_config = BitsAndBytesConfig(load_in_8bit=True)
base_model = AutoModelForCausalLM.from_pretrained(
model_path,
quantization_config=bnb_config,
device_map="auto"
)
# Configure PEFT (LoRA)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.1,
bias="none",
task_type="CAUSAL_LM"
)
peft_model = get_peft_model(base_model, lora_config)
peft_model.print_trainable_parameters()
# 6. Training arguments
training_args = TrainingArguments(
output_dir="./output_model",
evaluation_strategy="steps",
eval_steps=500,
logging_steps=1000,
learning_rate=2e-5,
per_device_train_batch_size=4, # Increased for better throughput
gradient_accumulation_steps=4, # Adjusted for effective batch size
num_train_epochs=3,
save_strategy="steps",
save_steps=500,
save_total_limit=2,
fp16=True,
logging_dir="./logs",
warmup_steps=500,
dataloader_num_workers=4,
max_grad_norm=1.0,
)
# 7. Trainer
trainer = Trainer(
model=peft_model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
)
# 8. Train model
trainer.train()
# 9. Save model and tokenizer
peft_model.save_pretrained("./output_model")
tokenizer.save_pretrained("./output_model")
print("Training completed successfully. Model and tokenizer saved to './output_model'.")
# 10. Switch to base model for inference
inference_pipeline = pipeline(
"text-generation",
model=base_model, # Use the base model, not PeftModelForCausalLM
tokenizer=tokenizer
)
# 11. Ask 3 questions to the trained model
questions = [
"QUESTION 1",
"QUESTION 2",
"QUESTION 3"
]
answers = []
for question in questions:
output = inference_pipeline(
question,
max_length=100,
num_return_sequences=1,
temperature=0.7, # Encourage creativity
top_p=0.9, # Nucleus sampling
top_k=50, # Limit to top 50 tokens
truncation=True # Explicit truncation
)
answers.append(output[0]["generated_text"])
# 12. Display the questions and answers
for question, answer in zip(questions, answers):
print(f"Q: {question}")
print(f"A: {answer}")
print("-" * 50)
Ilk adımda sıklıkla karşılaşacağınız ve eğitim sırasında ihtiyacınız olacak aşağıdaki kütüphanelere bir bakalım;
transformers datasets peft accelerate bitsandbytes torch
Transformers
Popüler ve güncel büyük dil modelleri (GPT, BERT, vb.) için kullanıma hazır mimariler ve yüksek seviyede train/fine-tuning fonksiyonları sunan bir yapıdadır. Hem PyTorch hem de TensorFlow backend’lerini destekler. Metin sınıflandırma, soru-cevap, metin üretimi, çeviri, özetleme gibi pek çok görev için yaygın olarak kullanılır.
import os
import torch
from transformers
Datasets
Farklı formatlardaki hazırlanmış veri setlerini (CSV, JSON, text dosyaları, vs.) kolayca yükleme, yönetme, dönüştürme ve paylaşma amaçlı veri kümelerini kullandıran bir kütüphanedir. Dağıtık ve paralel işlemeye uygun tasarlanmış yapı sayesinde milyonlarca satırlık büyük veri setlerini bile rahatça çalıştirabiliyor. Ayrıca map, filter, shuffle, train_test_split gibi fonksiyonlarıyla veri setlerinizi düzenleyip on işleme yapabilirsiniz.
import os
import torch
from datasets import load_dataset, DatasetDict
from transformers
Peft
peft yani (Parameter-Efficient Fine-Tuning); LLM’lerin fine-tuning sırasında çok az sayıda parametresini güncelleyerek geliştirme yapmanızı sağlar. Bunu; LoRA (Löw-Rank Adaptation), Prefix Tuning, Prompt Tuning gibi metodolojilerle yapar ve modelin tüm parametrelerini döndürüp sadece ek parametrelerini egitebilirsiniz. Bu sayede modelinizdeki kusur ve hatalar azalmış olur. Ayrıca bu sayede büyü modelleri dahi egitebilirsiniz.
import os
import torch
from datasets import load_dataset, DatasetDict
from transformers
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
Accelerate, Bitsandbytes ve torch (PyTorch)
PyTorch tabanlı eğitimlerde dağıtık veya çok GPU’lu eğitim senaryolarını kolaylaştıran bir kütüphanedir. Yani PyTorch kodunu minimum değişiklikle tek GPU’dan çoklu GPU’ya veya çoklu node’a ölçeklendirebilirsiniz. Bitsandbytes ise büyük modelleri düşük bit (8-bit, 4-bit) hassasiyetle eğitme ve çalıştırma imkânı sunan bir kütüphanedir. Torch ise bildiğiniz gibi, deep learning ve hesaplamalı grafikleri hızlandırmak için kullanılan en popüler kutuphanelerdendir.
import os
import torch
from datasets import load_dataset, DatasetDict
from transformers import (
AutoTokenizer,
AutoModelForCausalLM,
Trainer,
TrainingArguments,
BitsAndBytesConfig,
DefaultDataCollator
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
Şimdi trainer argümanlarını inceleyelim.
{
"auto_find_batch_size": "false",
"chat_template": "none",
"disable_gradient_checkpointing": "false",
"distributed_backend": "ddp",
"eval_strategy": "epoch",
"merge_adapter": "false",
"mixed_precision": "fp16",
"optimizer": "adamw_torch",
"peft": "true",
"padding": "right",
"quantization": "int4",
"scheduler": "linear",
"unsloth": "false",
"use_flash_attention_2": "false",
"batch_size": "2",
"block_size": "1024",
"epochs": "3",
"gradient_accumulation": "4",
"lr": "0.00003",
"logging_steps": "-1",
"lora_alpha": "32",
"lora_dropout": "0.05",
"lora_r": "16",
"max_grad_norm": "1",
"model_max_length": "2048",
"save_total_limit": "1",
"seed": "42",
"warmup_ratio": "0.1",
"weight_decay": "0",
"target_modules": "all-linear"
}
auto_find_batch_size
Bu parametre, batch boyutunu otomatik olarak belirleyip belirlemeyeceğinizi ayarlar. true olsaydı, GPU hafızasına sığacak en büyük batch boyutunu otomatik tespit etmeye çalışırdı. “false” ise, belirlenmiş sabit batch_size ile eğitim yapılacağını bize gösterir.
chat_template
Eğitim sırasında modelin giriş-çıkış formatını özel bir “chat” şablonu göre nasıl şekilleneceğini belirler.
disable_gradient_checkpointing
Gradient checkpointing, genelde büyük modellerin eğitimi sırasında bellek tasarrufu sağlar.
distributed_backend
Eğitim çoklu GPU (ve/veya çoklu node) üzerinde yapılacaksa, dağıtılmış eğitim yöntemi olarak DDP kullanıldığını gösterir.
eval_strategy
Değerlendirmenin ne zaman yapılacağını belirtir. “epoch” her epoch sonunda değerlendirme yapılacağını belirtir.
merge_adapter
LoRA gibi adapter tabanlı yöntemlerde, eğitim sonrası adaptör ağırlıklarını ana modele birleştirme seçeneğini gösterir.
mixed_precision
Eğitimde karma hassasiyet kullanılıp kullanılmadığını gösterir. “fp16”, 16 bit eğitimin yapıldığını belirtir. Bu genelde hız ve bellek tasarrufu sağlar.
optimizer
Kullanılan optimizasyon algoritmasını gösterir. adamw_torch, PyTorch’un yerleşik AdamW optimizatörüdür.
peft
PEFT, büyük modelleri daha az sayıda parametreyi güncelleyerek verimli bir şekilde ince ayar yapma stratejisidir (or. LoRA, Prefix Tuning).
padding
Token dizilerinin hizalanması sırasında padding’in nereye yapılacağını söyler. “right” padding, dizinin sağ tarafına boşluk (pad token) ekler.quantization
quantization
Modellerin bellek kullanımını azaltmak için ağırlıkların tamsayı formatında kuantizasyonunu ifade eder. “int4”, ağırlıkların 4-bit tamsayı formatına indirgenmesini gösterir. Bu sayede çok büyük modelleri hafızaya sığdırmak için kullanabiliriz, ancak hassasiyeti kısmen düşürebilir.
scheduler
Öğrenme oranının eğitim sürecinde nasıl değiştirileceğini belirtir. “linear”, başlangıç değerinden yavaş yavaş 0'a doğru lineer azalan bir scheduler olduğunu gösterir.
batch_size
Her ileri besleme adımında kullanılacak örnek sayısını ifade eder.
block_size
Girdi metinlerinin kırpıldığı ya da segmentlere ayrıldığı maksimum uzunluğu belirler.
epochs
Veri setinin baştan sona 3 epoch eğitim yapılacağını gösterir.
gradient_accumulation
Her geri yayılım öncesinde 4 adım boyunca gradyanların toplanacağını ve sonra güncelleme yapılacağını belirtir. Bu, efektif batch boyutunu artırmak için kullanılır.
lr
Değer: "0.00003"
(3e-5). Öğrenme oranıdır. Bu, modelin parametrelerinin ne kadar hızlı güncelleneceğini kontrol eder.
lora_alpha
LoRA katmanlarının çıktılarını yeniden ölçeklendirmek için kullanılır. Bu sayede düşük rank’lı matrislerin güncellenmesi sırasında denge sağlanır.
lora_dropout
LoRA katmanlarında kullanılacak dropout oranıdır. Düşük bir dropout değeri modeli hafifçe düzenlileştirmeye yardımcı olur.
max_grad_norm
Gradientlerin maksimum normunu 1 ile sınırlar. Bu, gradient clipping kullanarak eğitimi daha kararlı hale getirir, büyük güncelleme adımlarını sınırlar.
model_max_length
Modelin işlemleyebileceği maksimum token sayısını belirtir.
seed
Rastgelelik içeren işlemler için sabit bir random seed ayarlayarak tekrar üretilebilir sonuçlar elde etmeye yarar. “42” popüler bir örnek değerdir.
Şimdi birde çıktılar sonrası modelimiz ile Lora ağırlıklarını nasıl birlestirecegimize ve huggingface’e yukleyecegimize bakalım.
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
from huggingface_hub import HfApi, HfFolder, upload_folder
# Hugging Face repository details
repository_name = "REPO_NAME"
private = True # Set repository as private
# Paths to base and LoRA models
base_model_path = "BASE_MODEL_NAME"
lora_model_path = "SAVED_MODEL_NAME"
merged_model_path = "./merged_finetuned_model"
# Step 1: Load the base model
print("Loading base model...")
base_model = AutoModelForCausalLM.from_pretrained(base_model_path, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(base_model_path)
# Step 2: Load LoRA weights and merge
print("Loading LoRA weights and merging with base model...")
lora_model = PeftModel.from_pretrained(base_model, lora_model_path)
merged_model = lora_model.merge_and_unload() # Merge LoRA weights into the base model
# Step 3: Save the merged model locally
print(f"Saving merged model to {merged_model_path}...")
merged_model.save_pretrained(merged_model_path)
tokenizer.save_pretrained(merged_model_path)
# Step 4: Upload to Hugging Face Hub
print(f"Uploading merged model to Hugging Face Hub ({repository_name})...")
# Authenticate with Hugging Face
hf_token = HfFolder.get_token() # Ensure you are logged in using `huggingface-cli login`
if not hf_token:
raise ValueError("Hugging Face token not found. Please log in using `huggingface-cli login`.")
# Initialize API and create repository
api = HfApi()
# Create the repository
api.create_repo(
repo_id=repository_name, # Use repo_id instead of name
token=hf_token,
private=private,
exist_ok=True # Avoid errors if the repo already exists
)
# Upload the folder to the repository
upload_folder(
folder_path=merged_model_path,
repo_id=repository_name,
token=hf_token
)
print(f"Model uploaded successfully to {repository_name} as private.")
Bu kod sayesinde eğitim ciktilarimizi base modelimiz ile merge ederek, huggingface’e yüklüyoruz. Huggingface’e yüklemek için huggingface’de access token üretip repo’ya erişim vermeyi unutmayın.
Artık kendi LLM’ınızı eğitip, oluşturabilirsiniz :)