Ana içeriğe geç

Unsloth Rehberi: LLM İnce Ayarını Optimize Edin ve Hızlandırın

Unsloth kullanarak Llama 3.1 modelini, uzmanlaşmış cebir problemlerini yüksek doğruluk ve ayrıntılı sonuçlarla çözmek üzere ince ayar yapma.
· 11 dk. oku

Yapay Zeka ile Keşfedin

Modelleri ince ayar yaparken bellek sorunlarıyla karşılaştınız mı ya da sürecin dayanılmaz derecede uzun sürdüğünü düşündünüz mü? Büyük dil modellerini (LLM) ince ayar için Transformers kütüphanesinden daha verimli ve hızlı bir çözüm arıyorsanız, doğru yerdesiniz!

Bu eğitimde, yalnızca 9 GB VRAM kullanarak Llama 3.1 3B modelini nasıl ince ayar yapacağımızı ve geleneksel Transformers yöntemlerinden 2 kat daha hızlı sonuçlar alacağımızı keşfedeceğiz. Ayrıca hızlı çıkarım (inference) çalıştırmayı, modeli vLLM uyumlu ve GGUF dosya biçimlerine dönüştürmeyi ve yalnızca birkaç satır kodla kaydedilen modeli Hugging Face Hub’a sorunsuzca göndermeyi de ele alacağız.

Bu kavramlara yeniyseniz,  ince ayara dalmadan önce sağlam bir temel oluşturmak için Büyük Dil Modelleri (LLM) Kavramlarında Ustalık kursunu mutlaka alın.

Unsloth ile Hızlı LLM İnce Ayarı Öne Çıkan Görsel

Görsel: Yazar

Unsloth nedir?

Unsloth AI büyük dil modellerine hızlı ince ayar ve erişim için tasarlanmış bir Python çerçevesidir. Basit bir API sunar ve Transformers’a kıyasla 2 kat daha hızlı performans sağlar. 

Öne çıkan özellikler

  • Basit API: Unsloth’un öne çıkan özelliklerinden biri, LLM’lere ince ayar yapma sürecindeki karmaşıklığı önemli ölçüde azaltan basit API’sidir.
  • Transformers Entegrasyonu: Unsloth, LLM’lerle çalışmak için popüler bir tercih olan Transformers kütüphanesinin üzerine inşa edilmiştir. Bu entegrasyon, Unsloth’un Hugging Face ekosisteminin güçlü özelliklerinden yararlanırken ince ayar sürecini kolaylaştıracak kendi geliştirmelerini eklemesine olanak tanır.
  • Sınırlı kaynak gereksinimi: Büyük dil modellerine ücretsiz Colab GPU’larıyla ya da GPU’lu bir dizüstü bilgisayarla ince ayar yapabilirsiniz.
  • vLLM ve GGUF Formatlarına Kaydetme: Yalnızca tek satır kodla, modellenmiş ağırlıkları birleştirip dönüştürebilir ve kuantize modeli Hugging Face hub’a gönderebilirsiniz. 
  • Verimli bellek kullanımı: 4 bit kuantize bir modeli yükleyebilir, ince ayar yapabilir ve 12 GB GPU VRAM’ini aşmadan tam modelle birleştirebilirsiniz.

Unsloth ile LLM’lere erişim

Unsloth kullanarak Llama-3.1 modeline erişmek oldukça basit. 16 bit modeli yüklemeyeceğiz. Bunun yerine, GPU belleğinden tasarruf ve daha hızlı çıkarım için Hugging Face’te bulunan 4 bit sürümü yükleyeceğiz.

  1. Unsloth Python paketini kurun.
%%capture
%pip install unsloth
  1. Modeli ve belirteçleyiciyi (tokenizer) FastLanguageModel fonksiyonu ile yükleyin. 
from transformers import TextStreamer
from unsloth import FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/Meta-Llama-3.1-8B-bnb-4bit"
)

unsloth/Meta-Llama-3.1-8B-bnb-4bit modelini yükleme

  1. Unsloth hızlı çıkarımı etkinleştirin.
FastLanguageModel.for_inference(model)
  1. Sistem komutu (system prompt), yönerge, girdi ve yanıt kullanarak istem tarzını yazın. 
  2. İstem tarzını kullanarak örnek bir istem oluşturun. 
  3. Metni belirteçlere ve ardından sayısal gösterimlere dönüştürün.
  4. Metin yayıcıyı (streamer) kurun.
  5. Akışlı yanıt üretmek için modeli kullanın.
prompt_style = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.

### Instruction:
{}

### Input:
{}

### Response:
{}"""


inputs = tokenizer(
    [
        prompt_style.format(
            "You are a professional machine learning engineer",  
            "How would you deal with NaN validation loss?",  
            "", 
        )
    ],
    return_tensors="pt",
).to("cuda")

text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer=text_streamer, max_new_tokens=128)

NaN doğrulama kaybının nasıl ele alınacağına dair olumlu bir yanıt aldık.

unsloth/Meta-Llama-3.1-8B-bnb-4bit kullanılarak üretilen çıktı

Yukarıdaki kodu Kaggle’da çalıştırmakta zorlanıyorsanız, örnek Defter burada: Unsloth ile LLM’lere erişim.

Python ile LLM’lere Giriş kursunu alarak Transformer mimarisinin temellerini, nasıl inşa edileceğini, ince ayar yapılacağını ve değerlendirileceğini öğreneceksiniz. Bu kurs, Python kullanarak LLM ince ayarı dünyasına giriş kapınızdır.

Unsloth ile Llama 3.1 modeline ince ayar

Bu rehberde, Unsloth kullanarak lighteval/MATH veri kümesi üzerinde Llama 3.1’e nasıl ince ayar yapacağımızı öğreneceğiz. Veri kümesi, çözümleri Markdown formatında olan cebir problemlerinden oluşur. Tüm veri kümesi beş zorluk seviyesine ayrılmıştır.

Bu rehberi daha iyi anlamak için, LLM’lere İnce Ayara Giriş Rehberini okuyarak ince ayar sürecindeki her adımın arkasındaki teoriyi öğrenmenizi öneririm. Süreci anlamanıza yardımcı olacağı için rehberi birkaç dakika gözden geçirin.

1. Kurulum

Bulut IDE olarak bir Kaggle defteri kullanıyoruz ve model ya da verilerle çalışmadan önce defteri yapılandırmamız gerekiyor.

  1. Başlamak için, Kaggle secrets kullanarak Hugging Face API ve Weights & Biases API için ortam değişkenlerini ayarlamalıyız.

Hugging Face ve W&B API anahtarını ortam değişkeni olarak ayarlama.

  1. Hızlandırıcıyı P100 GPU olarak ayarlayın.
  2. Ortam değişkenini yükleyin ve API anahtarıyla Hugging Face CLI’a giriş yapın.
from huggingface_hub import login
from kaggle_secrets import UserSecretsClient
user_secrets = UserSecretsClient()

hf_token = user_secrets.get_secret("HUGGINGFACE_TOKEN")
login(hf_token)
  1. Projeyi başlatmak için Weights & Biases’a API anahtarıyla giriş yapın. 
import wandb

wb_token = user_secrets.get_secret("wandb")

wandb.login(key=wb_token)
run = wandb.init(
    project='Fine-tune Llama-3.1-8B-bnb-4bit on Math Dataset', 
    job_type="training", 
    anonymous="allow"
)

2. Model ve belirteçleyiciyi yükleme

Model çıkarım bölümünde olduğu gibi, Llama 3.1 modelinin 4 bit kuantize sürümünü 2048 maksimum dizi uzunluğu ve None veri türüyle yükleyeceğiz.

from unsloth import FastLanguageModel
import torch

max_seq_length = 2048 
dtype = None 

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "unsloth/Meta-Llama-3.1-8B-bnb-4bit",
    max_seq_length = max_seq_length,
    dtype = dtype
)

3. Veri kümesini yükleme ve işleme

Ardından veri kümesini yükleyip işleyeceğiz. Bunun için, gerekli sonuçları almamıza yardımcı olacak bir istem tarzı oluşturmamız gerekiyor. 

İstem tarzı, bir sistem komutu, yönerge ve girdi ile yanıt için yer tutucular içerir. 

prompt_style = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.

### Instruction:
You are a math genius who can solve any level of algebraic problems. Please answer the following math question.

### Input:
{}

### Response:
{}"""

Bundan sonra, istem tarzını kullanarak matematik problemleri ve çözümlerini girdi alacak ve bunları uygun metne dönüştürecek fonksiyonu oluşturun. Herhangi bir tekrarı önlemek için EOS_TOKEN eklediğinizden emin olun.

EOS_TOKEN = tokenizer.eos_token # Must add EOS_TOKEN
def formatting_prompts_func(examples):
    inputs       = examples["problem"]
    outputs      = examples["solution"]
    texts = []
    for input, output in zip(inputs, outputs):
        text = prompt_style.format(input, output) + EOS_TOKEN
        texts.append(text)
    return { "text" : texts, }

Veri kümesinden 500 örneği yükleyin, formatting_prompts_func fonksiyonunu veri kümesine uygulayın ve metin sütunundaki ilk örneği görüntüleyin.

from datasets import load_dataset

dataset = load_dataset("lighteval/MATH", split="train[0:500]", trust_remote_code=True)
dataset = dataset.map(
    formatting_prompts_func,
    batched=True,
)
dataset["text"][0]

Metinde bir sistem komutu, yönerge, cebir problemi sorusu ve o problemin çözümü bulunmaktadır. 

Hugging Face’ten Matematik Veri Kümesi

4. Modeli yapılandırma

Temel modelin lineer modüllerini kullanarak modele LoRA (Low-Rank Adapter) ekliyoruz. 

model = FastLanguageModel.get_peft_model(
    model,
    r=16, 
    target_modules=[
        "q_proj",
        "k_proj",
        "v_proj",
        "o_proj",
        "gate_proj",
        "up_proj",
        "down_proj",
    ],
    lora_alpha=16,
    lora_dropout=0, 
    bias="none", 
   
    use_gradient_checkpointing="unsloth", 
    random_state=3407,
    use_rslora=False, 
    loftq_config=None,
)

Model, belirteçleyici, maksimum dizi uzunluğu ve eğitim argümanlarıyla eğitici (trainer) kurulumunu yapın. Bu, Transformers ve TRL kütüphanesiyle eğitici kurulumuna oldukça benzer.

from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported

trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    dataset_text_field = "text",
    max_seq_length = max_seq_length,
    dataset_num_proc = 2,
    args = TrainingArguments(
        per_device_train_batch_size = 2,
        gradient_accumulation_steps = 4,
        warmup_steps = 5,
        max_steps = 60,
        learning_rate = 2e-4,
        fp16 = not is_bfloat16_supported(),
        bf16 = is_bfloat16_supported(),
        logging_steps = 1,
        optim = "adamw_8bit",
        weight_decay = 0.01,
        lr_scheduler_type = "linear",
        seed = 3407,
        output_dir = "outputs",
    ),
)

5. Model eğitimi

Model eğitimi yaklaşık 19 dakika sürdü; bu oldukça etkileyici. Eğitim kaybı her adımda önemli ölçüde azaldı. 

trainer_stats = trainer.train()

Model eğitim kaybı

Ayrıntılı model performansı ve donanım metriklerini Weights & Biases panosundan inceleyebilirsiniz.

W&B panosu. Ayrıntılı model değerlendirmesi.

torch ve trainer_stats kullanarak kendi raporunuzu da oluşturabilirsiniz.  

used_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
used_memory_for_lora = round(used_memory - start_gpu_memory, 3)
used_percentage = round(used_memory         /max_memory*100, 3)
lora_percentage = round(used_memory_for_lora/max_memory*100, 3)
print(f"{trainer_stats.metrics['train_runtime']} seconds used for training.")
print(f"{round(trainer_stats.metrics['train_runtime']/60, 2)} minutes used for training.")
print(f"Peak reserved memory = {used_memory} GB.")
print(f"Peak reserved memory for training = {used_memory_for_lora} GB.")
print(f"Peak reserved memory % of max memory = {used_percentage} %.")
print(f"Peak reserved memory for training % of max memory = {lora_percentage} %.")

Model 20 dakikada eğitildi ve eğitim için ayrılan tepe bellek yaklaşık 3,7 GB idi. Bu, tam modeli yükleyip kuantize ettikten sonra ince ayar yapan geleneksel yönteme kıyasla oldukça düşüktür. O durumda en az 15 GB GPU belleği gerekir.

1207.5478 seconds used for training.
20.13 minutes used for training.
Peak reserved memory = 9.73 GB.
Peak reserved memory for training = 3.746 GB.
Peak reserved memory % of max memory = 61.241 %.
Peak reserved memory for training % of max memory = 23.578 %.

6. İnce ayardan sonra modeli test etme

Modeli ince ayardan sonra test etmek için hızlı çıkarımı etkinleştirmemiz gerekiyor. Ardından, veri kümesinden örnek bir cebir sorusunu istem tarzına girdi olarak verecek ve bunu belirteçlere dönüştüreceğiz. Daha sonra, modelle yanıt üretecek ve çıktıyı çözüp metni göstereceğiz. 

Üretilen metin Markdown formatındaydı; ancak uygun matematik denklemleriyle metni gösterecek şekilde dönüştürdük.

from IPython.display import display, Markdown

FastLanguageModel.for_inference(model)
inputs = tokenizer(
    [
        prompt_style.format(
            "If the system of equations \begin{align*} 3x+y&=a,\\ 2x+5y&=2a, \end{align*} has a solution $(x,y)$ when $x=2$, compute $a$.", 
            "", 
        )
    ],
    return_tensors="pt",
).to("cuda")

outputs = model.generate(
    input_ids=inputs.input_ids,
    attention_mask=inputs.attention_mask,
    max_new_tokens=250,
    use_cache=True,
)
response = tokenizer.batch_decode(outputs)
Markdown(response[0].split("\n\n### Response:")[1])

Görüldüğü gibi, üretilen yanıt veri kümesiyle uyumludur ve cebir problemleri için çözümler sunmaktadır.

İnce ayarlı model çıktısı

7. Modeli ve belirteçleyiciyi kaydetme

İnce ayarlı modelimizi kaydedelim ve paylaşımı veya dağıtımı kolay olsun diye Hugging Face Hub’a gönderelim.

new_model_online = "kingabzpro/Llama-3.1-8B-MATH"
new_model_local = "Llama-3.1-8B-MATH"
model.save_pretrained(new_model_local) # Local saving
tokenizer.save_pretrained(new_model_local) # Local saving

Aşağıdaki kod, Hugging Face’te yeni bir depo oluşturacak ve ardından LoRA ile belirteçleyiciyi meta verileriyle birlikte gönderecektir.

model.push_to_hub(new_model_online) # Online saving
tokenizer.push_to_hub(new_model_online) # Online saving

Hugging Face’te kaydedilen ince ayarlı model

Kaynak: kingabzpro/Llama-3.1-8B-MATH

Unsloth kullanarak LLM’e ince ayar yaparken sorun yaşıyorsanız, Unsloth ile LLM’lere İnce Ayar Kaggle Defteri’ne bakın. Kendi başınıza çalıştırıp sonuçları yeniden üretebileceğiniz kararlı kod içerir.

Yapay zeka yolculuğunuzdaki bir sonraki adım, LLM’leri kullanarak etkili yapay zeka uygulamaları geliştirmektir. Daha fazla bilgiyi LangChain ile LLM Uygulamaları Nasıl Geliştirilir başlıklı eğitimde bulabilirsiniz.

Modeli Birleştirme ve Dışa Aktarma

LoRa’yı temel modelle birleştirmek ek VRAM ve yerel depolama gerektirir. Herhangi bir sınırı aşmamak için hızlandırıcı olarak P100 GPU’lu yeni bir Kaggle defteri oluşturacağız. Ayrıca API anahtarına erişmek için Hugging Face API’sini etkinleştireceğiz.

  1. Unsloth Python paketini kurun.
%%capture
%pip install unsloth
  1. API anahtarını Kaggle secrets’tan yükleyin ve Hugging Face CLI’a giriş yapın. 
from huggingface_hub import login
from kaggle_secrets import UserSecretsClient
user_secrets = UserSecretsClient()

hf_token = user_secrets.get_secret("HUGGINGFACE_TOKEN")
login(hf_token)
  1. Hugging Face model depo bağlantısını vererek LoRA’yı ve belirteçleyiciyi yükleyin. 
  2. Hızlı model çıkarımını etkinleştirin. 
from unsloth import FastLanguageModel

new_model_name = "kingabzpro/Llama-3.1-8B-MATH"
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = new_model_name, # YOUR MODEL YOU USED FOR TRAINING
    max_seq_length = 2048,
    dtype = None,
    load_in_4bit = True,
)
FastLanguageModel.for_inference(model); 

İnce ayarlı adaptörü yükleme

  1. Önceki bölümden istem tarzını kopyalayıp yapıştırın. 
prompt_style = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.

### Instruction:
You are a math genius who can solve any level of algebraic problem. Please answer the following math question.

### Input:
{}

### Response:
{}"""
  1. Modelin hâlâ düzgün çalışıp çalışmadığını kontrol etmek için veri kümesinden örnek bir matematik problemiyle test edin.
from IPython.display import display, Markdown

inputs = tokenizer(
    [
        prompt_style.format(
            "Solve the equation $|y-6| + 2y = 9$ for $y$.",  # input
            "",  # output - leave this blank for generation!
        )
    ],
    return_tensors="pt",
).to("cuda")

outputs = model.generate(
    input_ids=inputs.input_ids,
    attention_mask=inputs.attention_mask,
    max_new_tokens=250,
    pad_token_id=tokenizer.eos_token_id,
)
response = tokenizer.batch_decode(outputs)
Markdown(response[0].split("\n\n### Response:")[1])

Model mükemmel çalışıyor ve temel modelle birleştirilmeye hazır.

ince ayarlı model çıktısı.

  1. Geçici dizini oluşturun ve ardından dizin işaretçisini değiştirin. Bunu neden yapıyoruz? Kaggle working dizini yalnızca 20 GB sağlar; bu da tam modeli birleştirmek ve göndermek için yeterli değildir. Kök dizinde başka bir klasör oluşturmak, 60 GB geçici depolamaya erişmemizi sağlayacaktır.
%mkdir ../temp
%cd /kaggle/temp
  1. Aşağıdaki komutu yazarak LoRA’yı temel modelle birleştirip Hugging Face Hub’a göndereceğiz. Bu, vLLM Python paketiyle bulutta modelinizi dağıtıp sunmak istediğinizde kullanışlıdır.
model.push_to_hub_merged(new_model_name, tokenizer, save_method = "merged_16bit")

16 bit modeli birleştirme ve kaydetme.

  1. İnce ayarlı modeli yerelde kullanmak istiyorsanız, kolayca llama.cpp formatına dönüştürüp kuantize edebilir ve Hugging Face hub’a gönderebilirsiniz. 
model.push_to_hub_gguf(new_model_name, tokenizer, quantization_method = "q4_k_m")

Kuantize modeli GGUF model formatında kaydetme

Tam 16 bit model, adaptör ve kuantize GGUF dosyaları model deponuzda mevcuttur. İnce ayarlı modeli yerelde kullanmak için kuantize GGUF dosyasını indirip Jan, Misty, GPT4ALL veya Ollama ile kullanmaya başlayın.

Llama 3.2’ye İnce Ayar ve Yerelde Kullanım: Adım Adım Rehber eğitimini takip ederek Llama 3.2 modeline müşteri destek veri kümesi üzerinde nasıl ince ayar yapılacağını, modeli Hugging Face Hub’a nasıl birleştirip dışa aktaracağınızı ve ince ayarlı modeli Jan uygulamasıyla yerelde kullanılabilecek GGUF formatına nasıl dönüştüreceğinizi öğrenin.

Kaynak: kingabzpro/Llama-3.1-8B-MATH

LoRA’yı temel modelle yükleme ve birleştirme sırasında sorun yaşıyorsanız, daha fazla yardım için Unsloth ile LoRA Adaptörünü Birleştirme Kaggle defterine göz atın. 

Ayrıca Her Seviyeye Uygun 12 LLM Projesi blogunu okumanızı öneririm. Başlangıç seviyesinden ileri düzeye, son sınıf öğrencilerinden uzmanlara kadar LLM projeleri listesi içerir.

Sonuç

Bu eğitimde, Llama 3.1 3B modeline düşük hesaplama kaynaklarıyla ve geleneksel yöntemlerden 2 kat daha hızlı şekilde nasıl etkili ince ayar yapacağımızı öğrendik.

 Ayrıca hızlı model çıkarımı çalıştırmayı, LoRA’yı temel modelle birleştirmeyi ve Hugging Face hub’a göndermeyi de öğrendik. 

Ek olarak, modeli llama.cpp formatına dönüştürüp kuantize ettik; böylece ince ayarlı model, Jan veya GPT4ALL uygulamaları kullanılarak dizüstü bilgisayarda yerelde kolayca kullanılabilir hale geldi.

Modelin performansını artırmak için, modeli tüm veri kümesi üzerinde ince ayar yapmanızı, hiperparametreleri optimize etmenizi ve istem tarzı üzerinde çalışmanızı şiddetle öneririz. İnce ayardan sonra bile, fonksiyon çağırma ve RAG hatları kullanarak yapay zeka uygulamalarının performansını birçok şekilde iyileştirebilirsiniz.

Özel durumlarınız için hangi çözümün daha iyi olduğunu, RAG vs İnce Ayar: Uygulamalı Örnekle Kapsamlı Bir Eğitim rehberini takip ederek öğrenin. Kendi veri kümenizde denemeniz ve sonuçları karşılaştırmanız için örnek kod içerir.

Abid Ali Awan

Yazar

Abid Ali Awan

Sertifikalı bir veri bilimcisi olarak, yenilikçi makine öğrenimi uygulamaları oluşturmak için en son teknolojileri kullanmaya büyük ilgi duyuyorum. Konuşma tanıma, veri analizi ve raporlama, MLOps, konuşma yapay zekası ve NLP alanlarında güçlü bir geçmişe sahip olarak, gerçek bir etki yaratabilecek akıllı sistemler geliştirme becerilerimi geliştirdim. Teknik uzmanlığımın yanı sıra, karmaşık kavramları açık ve özlü bir dille ifade etme yeteneğine sahip, becerikli bir iletişimciyim. Sonuç olarak, veri bilimi konusunda aranan bir blog yazarı oldum ve giderek büyüyen veri profesyonelleri topluluğuyla görüşlerimi ve deneyimlerimi paylaşıyorum. Şu anda, içerik oluşturma ve düzenlemeye odaklanıyorum. Büyük dil modelleriyle çalışarak, hem işletmelerin hem de bireylerin verilerinden en iyi şekilde yararlanmalarına yardımcı olabilecek güçlü ve ilgi çekici içerikler geliştiriyorum.

Konular

İlgili