Файн-тюнинг Llama 3 8B: Полный гайд (Unsloth + PyTorch)
TL;DR — Кратко:
- Используем библиотеку Unsloth для ускорения обучения в 2-5 раз.
- Метод QLoRA позволяет уложиться в память обычной RTX 4090 (и даже меньше).
- Готовый код: от установки библиотек до сохранения GGUF.
Введение
Llama 3 от Meta перевернула игру. Модель на 8 миллиардов параметров (8B) работает быстрее и умнее, чем Llama 2 70B. Но “из коробки” она знает всё обо всём понемногу. Чтобы модель заговорила в стиле вашего бренда, научилась писать специфический код или отвечать на медицинские вопросы, её нужно дообучить (Fine-Tuning).
Раньше для этого требовались кластеры A100. Сегодня, благодаря методам QLoRA и библиотеке Unsloth, мы можем сделать это на одной карте RTX 4090 за пару часов.
В этом гайде мы пройдем весь процесс: от “голого” сервера до собственной обученной нейросети.
Почему Unsloth?
Мы не будем использовать стандартный Hugging Face Trainer в чистом виде. Мы возьмем Unsloth.
Это библиотека, которая вручную переписала ядра PyTorch для обратного распространения ошибки.
Что это дает:
- Скорость: Обучение идет в 2-5 раз быстрее.
- Память: Потребление VRAM снижается на 60%.
- Качество: 0% потери точности (математика та же, просто вычисления эффективнее).
Шаг 0: Подготовка окружения
Вам понадобится сервер с GPU NVIDIA (минимум 12 ГБ VRAM, рекомендуем 24 ГБ для комфортной работы). Операционная система: Linux (Ubuntu 20.04/22.04).
Установим библиотеки:
# Устанавливаем Pytorch (если еще нет)
pip install --upgrade pip
pip install "unsloth[colab-new] @ git+[https://github.com/unslothai/unsloth.git](https://github.com/unslothai/unsloth.git)"
pip install --no-deps "xformers<0.0.26" trl peft accelerate bitsandbytes Шаг 1: Загрузка модели
Создайте файл train.py и начните с импорта. Мы загружаем модель в 4-битном формате (Load in 4bit), чтобы она занимала всего ~6 ГБ памяти.
from unsloth import FastLanguageModel
import torch
max_seq_length = 2048 # Длина контекста (можно увеличить до 8192)
dtype = None # Auto detection (Float16 для Tesla T4, Bfloat16 для Ampere+)
load_in_4bit = True # Включаем 4-битное квантование
# Загружаем Llama-3 8B
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/llama-3-8b-bnb-4bit",
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
)
print("Модель успешно загружена!") Шаг 2: Настройка LoRA (адаптеров)
Мы не будем переучивать все 8 миллиардов весов (это долго и дорого). Мы используем LoRA (Low-Rank Adaptation). Это небольшие дополнительные слои, которые обучаются поверх основной модели.
model = FastLanguageModel.get_peft_model(
model,
r = 16, # Ранг (чем больше, тем умнее адаптер, но тяжелее). 16, 32, 64 - ок.
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",],
lora_alpha = 16,
lora_dropout = 0, # Unsloth рекомендует 0 для скорости
bias = "none",
use_gradient_checkpointing = "unsloth", # Экономит память
random_state = 3407,
use_rslora = False,
loftq_config = None,
) Шаг 3: Подготовка данных
Для примера возьмем классический датасет Alpaca, но вы можете заменить его на свой JSON-файл. Формат данных должен быть таким:
- Instruction: Вопрос или задача.
- Input: Дополнительный контекст (необязательно).
- Output: Желаемый ответ модели.
from datasets import load_dataset
# Промпт для форматирования данных
alpaca_prompt = """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:
{}"""
EOS_TOKEN = tokenizer.eos_token # Обязательно добавляем токен конца генерации
def formatting_prompts_func(examples):
instructions = examples["instruction"]
inputs = examples["input"]
outputs = examples["output"]
texts = []
for instruction, input, output in zip(instructions, inputs, outputs):
text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN
texts.append(text)
return { "text" : texts, }
# Загружаем датасет
dataset = load_dataset("yahma/alpaca-cleaned", split = "train")
dataset = dataset.map(formatting_prompts_func, batched = True) Шаг 4: Запуск обучения
Используем SFTTrainer (Supervised Fine-tuning Trainer) от Hugging Face.
💡 Совет по памяти
Если у вас вылетает ошибка OOM (Out Of Memory), уменьшите batch_size с 2 до 1 или уменьшите max_seq_length.
from trl import SFTTrainer
from transformers import TrainingArguments
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = dataset,
dataset_text_field = "text",
max_seq_length = max_seq_length,
dataset_num_proc = 2,
packing = False, # Можно поставить True для ускорения на больших датасетах
args = TrainingArguments(
per_device_train_batch_size = 2,
gradient_accumulation_steps = 4,
warmup_steps = 5,
max_steps = 60, # Для теста хватит 60 шагов. Для реальности - ставьте num_train_epochs = 1
learning_rate = 2e-4,
fp16 = not torch.cuda.is_bf16_supported(),
bf16 = torch.cuda.is_bf16_supported(),
logging_steps = 1,
optim = "adamw_8bit", # 8-битный оптимизатор экономит кучу памяти!
weight_decay = 0.01,
lr_scheduler_type = "linear",
seed = 3407,
output_dir = "outputs",
),
)
# ПОЕХАЛИ! 🚀
trainer_stats = trainer.train() Шаг 5: Проверка результата (Inference)
После обучения проверим, как модель отвечает на вопросы.
# Включаем режим инференса (быстрее)
FastLanguageModel.for_inference(model)
inputs = tokenizer(
[
alpaca_prompt.format(
"Напиши функцию на Python для вычисления чисел Фибоначчи.", # Instruction
"", # Input
"", # Output - оставляем пустым, модель дополнит
)
], return_tensors = "pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens = 64, use_cache = True)
print(tokenizer.batch_decode(outputs)) Шаг 6: Сохранение
Вы можете сохранить только адаптеры (LoRA adapters) — они весят всего ~100 МБ.
model.save_pretrained("lora_model") # Локальное сохранение
# model.push_to_hub("your_name/lora_model") # Загрузка на Hugging Face Или сохранить полную модель в формате GGUF для запуска на ноутбуке через Ollama или LM Studio:
# Сохранить в 4-битном GGUF (q4_k_m)
model.save_pretrained_gguf("model", tokenizer, quantization_method = "q4_k_m") Заключение
Мы только что дообучили одну из самых мощных LLM современности, используя код на 50 строк и видеокарту потребительского класса.
Весь процесс занял бы на RTX 4090 около 15-20 минут (для 60 шагов) или около 2 часов для полного прохода по датасету Alpaca.
Что делать дальше?
- Соберите свой датасет (диалоги с клиентами, код, статьи).
- Загрузите его вместо Alpaca.
- Запустите обучение и получите своего персонального AI-ассистента.
Нужна мощная карта для обучения?
Разверните среду с RTX 4090 и предустановленным Unsloth за 2 минуты.
Запустить Jupyter Notebook