Unsloth решает не ту задачу, о которой пишут в заголовках. Заголовки обещают ускорение обучения; на практике главная его ценность в том, что рабочая конфигурация собирается одной функцией, а не тремя библиотеками, которые нужно подружить по версиям.
Ускорение при этом реальное — разработчики заявляют кратный выигрыш по скорости и экономию памяти за счёт переписанных вычислительных ядер. Насколько именно быстрее выйдет у вас, зависит от карты, модели и длины последовательности; это надо замерять, а не брать из чужой таблицы.
#Зачем это нужно и когда не нужно
Нужно, если вы дообучаете одну модель на одной видеокарте и хотите сократить время до первого запуска. Не нужно в трёх случаях: если вы обучаете распределённо на нескольких картах, если вам важна воспроизводимость эксперимента через полгода (тогда конфигурационный подход надёжнее — см. гайд по Axolotl), и если вы ещё не проверили, что задача вообще требует дообучения, — рамка маршрута и его границы в пилларе про свою модель и дообучение под себя.
#Что понадобится
- Видеокарта с поддержкой CUDA. Расчёт требуемой памяти по слагаемым — в статье про дообучение на своём железе.
- Отдельное окружение. Не ставьте это рядом с рабочим приложением: пакеты тяжёлые и жёстко завязаны на версии друг друга. Отдельное виртуальное окружение или отдельная машина.
- Датасет в JSONL — по одному примеру на строку, с полем
messages. - Понимание, что вы обучаете. Ранг, число эпох и скорость обучения задаются осознанно, а не значениями по умолчанию: стартовые ориентиры в статье про гиперпараметры дообучения.
#Шаг 1. Установка
Ставьте в чистое окружение и не смешивайте установку с уже стоящими версиями трансформеров и обучающих библиотек — это источник большинства проблем запуска.
python -m venv .venv-train
source .venv-train/bin/activate # Windows: .venv-train\Scripts\activate
pip install --upgrade pip
pip install unsloth
Пакет подтягивает совместимые версии зависимостей сам. Если у вас уже стоит своя сборка PyTorch под конкретную версию CUDA, ставьте её первой и только потом Unsloth, иначе рискуете получить пересобранный из-под ног torch.
#Шаг 2. Скрипт обучения
Минимальный рабочий скрипт. Комментарии отмечают места, которые вы будете менять.
from unsloth import FastLanguageModel
from datasets import load_dataset
from trl import SFTTrainer, SFTConfig
MODEL = "unsloth/Qwen2.5-1.5B-Instruct" # база; меняется под ваше железо
MAX_SEQ = 1024 # длина последовательности: главный
# рычаг расхода памяти после размера базы
OUT = "out/persona-lora"
# 4-битная загрузка = QLoRA. Если база влезает в карту в 16 битах,
# ставьте load_in_4bit=False — будет быстрее и без ошибки квантизации.
model, tok = FastLanguageModel.from_pretrained(
model_name = MODEL,
max_seq_length = MAX_SEQ,
load_in_4bit = True,
dtype = None, # None = выбрать по возможностям карты
)
# Адаптеры LoRA. r — ёмкость адаптера, alpha обычно берут равным 2*r.
model = FastLanguageModel.get_peft_model(
model,
r = 16,
lora_alpha = 32,
lora_dropout = 0.0,
bias = "none",
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
use_gradient_checkpointing = "unsloth", # без этого память кончится раньше
random_state = 42,
)
data = load_dataset("json", data_files={"train": "data/persona.jsonl"})["train"]
# Рендерим родным шаблоном чата базы. Свой шаблон писать руками не надо:
# несовпадение с шаблоном запуска — самая частая причина странного поведения.
def to_text(row):
return {"text": tok.apply_chat_template(row["messages"], tokenize=False)}
data = data.map(to_text, remove_columns=data.column_names)
trainer = SFTTrainer(
model = model,
train_dataset = data,
args = SFTConfig(
output_dir = OUT,
per_device_train_batch_size = 1, # на домашней карте почти всегда 1
gradient_accumulation_steps = 16, # эффективный батч = 1 * 16
num_train_epochs = 1, # начинайте с одной, не с трёх
learning_rate = 2e-4,
warmup_ratio = 0.03,
lr_scheduler_type = "cosine",
logging_steps = 10,
save_strategy = "epoch",
report_to = "none",
),
)
trainer.train()
model.save_pretrained(OUT) # сохраняется АДАПТЕР, не вся модель
tok.save_pretrained(OUT)
Две вещи, которые стоит заметить в этом скрипте. Первая: сохраняется адаптер на десятки мегабайт, а не модель целиком — базовые веса остаются нетронутыми. Вторая: num_train_epochs = 1. Три эпохи на маленьком датасете — самый быстрый способ получить заученный набор вместо сдвинутого стиля.
#Шаг 3. Отладочный прогон
Не запускайте полный датасет первым. Возьмите двадцать примеров и max_steps = 5: прогон займёт минуты и покажет все ошибки конфигурации.
Перед обучением распечатайте одну запись после применения шаблона:
print(data[0]["text"][:600])
Вы должны увидеть служебные маркеры ролей базовой модели и текст ответа на месте. Если маркеров нет или они чужие — обучать нельзя, сначала чините формат.
#Таблица совместимости
Таблица описывает, на что смотреть, а не список поддерживаемых версий: версии меняются быстрее, чем статьи. Состояние на 2026-08-26, требует проверки в документации проекта перед установкой.
| Что проверяете | Признак проблемы | Что делать |
|---|---|---|
| Архитектура базы | загрузка падает на неизвестном типе модели | взять вариант базы из репозитория Unsloth |
| Поддержка bf16 картой | ошибка масштабирования градиентов | оставить dtype=None, дать выбрать автоматически |
| Версия обучающей библиотеки | неизвестный аргумент в конфигурации | обновить пакет целиком, не по одному |
| Версия драйвера и CUDA | сборка ядер падает при импорте | ставить torch под свою CUDA первым |
| Многокарточный запуск | молча используется одна карта | это не сценарий Unsloth, брать другой инструмент |
Первая строка — самая практичная. У проекта есть предподготовленные варианты популярных баз; если ваша модель есть среди них, берите её и экономите вечер отладки.
#Проверка результата
Обучение прошло — это ещё не результат. Проверка состоит из трёх частей и делается до того, как вы начнёте пользоваться моделью:
- Стиль сдвинулся. Десять вопросов, ответы на которые вы знаете наизусть. Сравните с базовой моделью на тех же вопросах.
- Общее не сломалось. Пять вопросов из областей, которых в датасете не было вовсе. Заметная просадка — обучение было слишком тяжёлым.
- Модель останавливается вовремя. Если она договаривает за пользователя или вставляет служебные строки — не совпал шаблон чата.
Сравнение должно быть слепым: автор дообучения систематически переоценивает свою работу. Полный маршрут от датасета до запущенной модели — в гайде как обучить вторую копию на QLoRA.
#Что может пойти не так
- Ошибка нехватки памяти на старте. Уменьшайте в таком порядке: длина последовательности, потом размер базы. Батч уменьшать обычно уже некуда.
- Неизвестный аргумент конфигурации. Имена параметров в обучающих библиотеках меняются между версиями. Обновляйте пакеты одной командой, а не по одному.
- Импорт падает при сборке ядер. Несовпадение версии torch и CUDA-драйвера. Ставьте torch под свою версию CUDA явно, до установки остального.
- Обучение идёт, но loss не двигается. Проверьте, что датасет действительно отрендерился: пустое поле
textобучает на пустоте молча. - Модель после обучения отвечает обрывками. Не совпал шаблон чата или потерян токен конца реплики. Проверяется распечаткой обучающей записи.
- Стиль не изменился. Ранг слишком низкий или примеров вашего тона слишком мало. Добавляйте эталоны, а не эпохи — разница между этими двумя действиями решает всё.
#Частые вопросы
#Насколько Unsloth действительно быстрее обычного пути?
Разработчики заявляют кратное ускорение и экономию памяти за счёт собственных вычислительных ядер. Проверять надо на своей конфигурации: выигрыш зависит от карты, размера базы и длины последовательности. Замерьте время десяти шагов у обоих вариантов — это честнее любой чужой цифры.
#Можно ли обучать на нескольких видеокартах?
Это не тот сценарий, под который инструмент делался: он оптимизирован под одну карту. Если у вас несколько ускорителей, берите стек, где распределённое обучение является штатным режимом, — иначе вторая карта будет простаивать, а вы этого даже не заметите.
#Обязательна ли 4-битная загрузка?
Нет. load_in_4bit=True — это QLoRA, она нужна, когда база не влезает в карту в 16 битах. Если влезает, отключите: будет быстрее и без ошибки квантизации. Разбор компромисса — в статье про LoRA и QLoRA.
#Что делать с полученным адаптером?
Он подключается к базовой модели при загрузке либо сливается в веса, если рантайм адаптеры не понимает. Второй путь нужен для локального запуска через распространённые движки — там ожидают один файл модели, а не базу плюс адаптер.
#Подойдёт ли бесплатный облачный блокнот?
Да, и это типичный сценарий для первого прогона: компактная база плюс несколько сотен примеров укладываются в бесплатную сессию. Держите в уме два ограничения — сессию могут прервать, поэтому сохраняйте чекпойнты, и ваш датасет при этом оказывается на чужой инфраструктуре.
#Вывод
Unsloth — это способ собрать рабочую конфигурацию обучения одной функцией и не потратить вечер на согласование версий. Ускорение прилагается, но замерять его надо самому.
Если у вас одна карта и одна модель — берите его. Если нужен воспроизводимый через полгода эксперимент или несколько карт — смотрите в сторону конфигурационных инструментов. И в любом случае начинайте с двадцати примеров и пяти шагов: отладка на игрушечном объёме экономит больше времени, чем любой выбор библиотеки.