Своя модель

Unsloth: быстрое дообучение на одной видеокарте

Практический маршрут запуска Unsloth с готовым скриптом — и разбор того, где обычно ломается запуск: версии библиотек и совместимость с конкретной моделью.

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, брать другой инструмент

Первая строка — самая практичная. У проекта есть предподготовленные варианты популярных баз; если ваша модель есть среди них, берите её и экономите вечер отладки.

#Проверка результата

Обучение прошло — это ещё не результат. Проверка состоит из трёх частей и делается до того, как вы начнёте пользоваться моделью:

  1. Стиль сдвинулся. Десять вопросов, ответы на которые вы знаете наизусть. Сравните с базовой моделью на тех же вопросах.
  2. Общее не сломалось. Пять вопросов из областей, которых в датасете не было вовсе. Заметная просадка — обучение было слишком тяжёлым.
  3. Модель останавливается вовремя. Если она договаривает за пользователя или вставляет служебные строки — не совпал шаблон чата.

Сравнение должно быть слепым: автор дообучения систематически переоценивает свою работу. Полный маршрут от датасета до запущенной модели — в гайде как обучить вторую копию на QLoRA.

#Что может пойти не так

  • Ошибка нехватки памяти на старте. Уменьшайте в таком порядке: длина последовательности, потом размер базы. Батч уменьшать обычно уже некуда.
  • Неизвестный аргумент конфигурации. Имена параметров в обучающих библиотеках меняются между версиями. Обновляйте пакеты одной командой, а не по одному.
  • Импорт падает при сборке ядер. Несовпадение версии torch и CUDA-драйвера. Ставьте torch под свою версию CUDA явно, до установки остального.
  • Обучение идёт, но loss не двигается. Проверьте, что датасет действительно отрендерился: пустое поле text обучает на пустоте молча.
  • Модель после обучения отвечает обрывками. Не совпал шаблон чата или потерян токен конца реплики. Проверяется распечаткой обучающей записи.
  • Стиль не изменился. Ранг слишком низкий или примеров вашего тона слишком мало. Добавляйте эталоны, а не эпохи — разница между этими двумя действиями решает всё.

#Частые вопросы

#Насколько Unsloth действительно быстрее обычного пути?

Разработчики заявляют кратное ускорение и экономию памяти за счёт собственных вычислительных ядер. Проверять надо на своей конфигурации: выигрыш зависит от карты, размера базы и длины последовательности. Замерьте время десяти шагов у обоих вариантов — это честнее любой чужой цифры.

#Можно ли обучать на нескольких видеокартах?

Это не тот сценарий, под который инструмент делался: он оптимизирован под одну карту. Если у вас несколько ускорителей, берите стек, где распределённое обучение является штатным режимом, — иначе вторая карта будет простаивать, а вы этого даже не заметите.

#Обязательна ли 4-битная загрузка?

Нет. load_in_4bit=True — это QLoRA, она нужна, когда база не влезает в карту в 16 битах. Если влезает, отключите: будет быстрее и без ошибки квантизации. Разбор компромисса — в статье про LoRA и QLoRA.

#Что делать с полученным адаптером?

Он подключается к базовой модели при загрузке либо сливается в веса, если рантайм адаптеры не понимает. Второй путь нужен для локального запуска через распространённые движки — там ожидают один файл модели, а не базу плюс адаптер.

#Подойдёт ли бесплатный облачный блокнот?

Да, и это типичный сценарий для первого прогона: компактная база плюс несколько сотен примеров укладываются в бесплатную сессию. Держите в уме два ограничения — сессию могут прервать, поэтому сохраняйте чекпойнты, и ваш датасет при этом оказывается на чужой инфраструктуре.

#Вывод

Unsloth — это способ собрать рабочую конфигурацию обучения одной функцией и не потратить вечер на согласование версий. Ускорение прилагается, но замерять его надо самому.

Если у вас одна карта и одна модель — берите его. Если нужен воспроизводимый через полгода эксперимент или несколько карт — смотрите в сторону конфигурационных инструментов. И в любом случае начинайте с двадцати примеров и пяти шагов: отладка на игрушечном объёме экономит больше времени, чем любой выбор библиотеки.

Хотите ИИ, который помнит вас?

Persona держит контекст между чатами и работает на вашем железе — если развернуть её у себя и подключить локальную модель.

Создать аккаунт