22 lutego, 2025

Dostosowywanie Llama-2 7B Chat do Generowania Kodów w Pythonie: QLoRA, SFTTrainer i Gradient Checkpointing na Zbiorze Alpaca-14k

Skuteczne dostosowanie modelu Llama-2 7B Chat do generowania kodu w Pythonie

W dzisiejszym artykule przedstawiamy szczegółowy przewodnik dotyczący dostosowywania modelu Llama-2 7B Chat do generowania kodu w języku Python. Wykorzystamy zaawansowane techniki, takie jak QLoRA, gradient checkpointing oraz supervised fine-tuning za pomocą narzędzia SFTTrainer. Proces ten pozwala na efektywne trenowanie modelu przy ograniczonych zasobach obliczeniowych.

Dzięki zastosowaniu zbioru danych Alpaca-14k, przeprowadzimy konfigurację środowiska, dostosujemy parametry LoRA i wdrożymy optymalizację pamięci, aby uzyskać wysokiej jakości kod generowany przez model. Ten przewodnik jest przeznaczony dla osób, które chcą skutecznie wykorzystywać Large Language Models (LLM) w swoich projektach.

1. Instalacja wymaganych bibliotek

Na początek należy zainstalować kluczowe biblioteki niezbędne do przeprowadzenia procesu dostosowywania modelu. Wykorzystamy pakiety accelerate, peft, transformers oraz trl, które można pobrać za pomocą polecenia:

python
!pip install -q accelerate
!pip install -q peft
!pip install -q transformers
!pip install -q trl

Flaga -q (quiet mode) ogranicza ilość wyświetlanych komunikatów w konsoli, co ułatwia monitorowanie procesu.

2. Importowanie niezbędnych modułów

Aby poprawnie załadować model, zbiór danych oraz skonfigurować proces treningu, importujemy odpowiednie moduły:

python
import os
from datasets import load_dataset
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    TrainingArguments,
    pipeline
)
from peft import LoraConfig, PeftModel
from trl import SFTTrainer

Dzięki tym narzędziom będziemy mogli zarządzać modelem, tokenizacją, argumentami treningowymi oraz procesem dostrajania.

3. Wybór modelu i zbioru danych

W tym kroku określamy model bazowy oraz zbiór danych, który posłuży do dostrajania modelu:

python
model_name = "NousResearch/llama-2-7b-chat-hf"
dataset_name = "user/minipython-Alpaca-14k"

# Nazwa nowego modelu po fine-tuningu
new_model = "/kaggle/working/llama-2-7b-codeAlpaca"

Bazowy model pochodzi z platformy Hugging Face, natomiast zbiór Alpaca-14k zawiera przykłady kodu w Pythonie, które pomogą w optymalizacji modelu.

4. Konfiguracja parametrów LoRA

LoRA (Low-Rank Adaptation) to technika, która pozwala na efektywne dostrajanie dużych modeli językowych przy mniejszym zapotrzebowaniu na pamięć. Definiujemy kluczowe parametry:

python
# Parametry QLoRA
lora_r = 64  # Wymiar atencji LoRA
lora_alpha = 16  # Skalowanie LoRA
lora_dropout = 0.1  # Prawdopodobieństwo dropout dla warstw LoRA

Dzięki QLoRA możemy skutecznie trenować duże modele nawet na ograniczonych zasobach GPU.

5. Ustawienia treningu

Konfigurujemy parametry treningowe, takie jak liczba epok, wielkość batcha oraz schemat uczenia:

python
output_dir = "/kaggle/working/llama-2-7b-codeAlpaca"
num_train_epochs = 1
fp16 = True  # Umożliwia trening w trybie mieszanej precyzji
per_device_train_batch_size = 8
per_device_eval_batch_size = 8
gradient_accumulation_steps = 2
gradient_checkpointing = True
max_grad_norm = 0.3
learning_rate = 2e-4
weight_decay = 0.001
optim = "adamw_torch"
lr_scheduler_type = "constant"
group_by_length = True
warmup_ratio = 0.03
save_steps = 100
logging_steps = 10

Warto zwrócić uwagę na gradient checkpointing, który pozwala zmniejszyć zużycie pamięci, oraz fp16, który przyspiesza trening poprzez wykorzystanie obliczeń o połowie precyzji.

6. Sprawdzenie wersji PyTorch i dostępnych zasobów GPU

Przed rozpoczęciem treningu warto sprawdzić dostępne zasoby sprzętowe:

python
import torch
print("PyTorch Version:", torch.__version__)
print("CUDA Version:", torch.version.cuda)
!nvidia-smi

To pozwoli upewnić się, że model będzie trenowany na GPU, co znacznie przyspieszy cały proces.

7. Wczytanie zbioru danych i tokenizatora

Ładujemy zbiór danych i konfigurujemy tokenizację:

python
dataset = load_dataset(dataset_name, split="train")

tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"

Wskazujemy również token końca sekwencji (eos_token) jako token paddingu, co jest istotne dla poprawnej pracy modelu.

8. Przygotowanie modelu do treningu

Wczytujemy model i konfigurujemy go do treningu:

python
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)

model.gradient_checkpointing_enable()
model.enable_input_require_grads()

Dzięki gradient_checkpointing_enable() zmniejszamy zużycie pamięci podczas propagacji wstecznej, co jest kluczowe przy dużych modelach.

9. Zastosowanie LoRA

Teraz konfigurujemy i stosujemy adaptację LoRA do modelu:

python
peft_config = LoraConfig(
    lora_alpha=lora_alpha,
    lora_dropout=lora_dropout,
    r=lora_r,
    bias="none",
    task_type="CAUSAL_LM",
)

model = PeftModel.from_pretrained(model, peft_config)

To pozwala na efektywne dostrajanie modelu bez konieczności zmiany wszystkich wag.

10. Trening modelu

Przygotowujemy proces trenowania i uruchamiamy go:

python
trainer = SFTTrainer(
    model=model,
    train_dataset=dataset,
    dataset_text_field="text",
    max_seq_length=None,
    tokenizer=tokenizer,
    args=TrainingArguments(
        output_dir=output_dir,
        num_train_epochs=num_train_epochs,
        per_device_train_batch_size=per_device_train_batch_size,
        gradient_accumulation_steps=gradient_accumulation_steps,
        optim=optim,
        save_steps=save_steps,
        logging_steps=logging_steps,
        learning_rate=learning_rate,
        weight_decay=weight_decay,
        fp16=fp16,
        max_grad_norm=max_grad_norm,
        warmup_ratio=warmup_ratio,
        group_by_length=True,
        lr_scheduler_type=lr_scheduler_type,
    ),
    packing=False,
)

trainer.train()
trainer.model.save_pretrained(new_model)

Po zakończeniu treningu model zostaje zapisany, aby można było go później wykorzystać.

11. Generowanie kodu w Pythonie

Po dostrojeniu modelu możemy wygenerować kod na podstawie podanego promptu:

python
prompt = "Jak napisać program w Pythonie, który oblicza średnią, odchylenie standardowe i współczynnik zmienności z pliku CSV?"
pipe = pipeline(task="text-generation", model=trainer.model, tokenizer=tokenizer, max_length=400)
result = pipe(f"[INST] {prompt} [/INST]")
print(result[0]['generated_text'])

Dzięki temu model może generować wysokiej jakości kod w Pythonie na podstawie wprowadzonych zapytań.

Podsumowanie

Dzięki temu przewodnikowi udało się skutecznie dostosować model Llama-2 7B Chat do generowania kodu w Pythonie. Wykorzystanie QLoRA, gradient checkpointing oraz SFTTrainer pozwoliło osiągnąć wysoką jakość generowanego kodu przy minimalnym zużyciu zasobów.