pimenov.ai

База знаний

Unsloth: практическое руководство по дообучению LLM

Практическое руководство по Unsloth: выбор модели, подготовка датасета, QLoRA-дообучение, проверка результата и экспорт в GGUF.

Опубликовано Обновлено

Unsloth — открытый набор инструментов для запуска и дообучения языковых моделей с уменьшенным потреблением видеопамяти. Он поддерживает LoRA, QLoRA, полное дообучение, supervised fine-tuning (SFT), обучение с подкреплением (RL) и экспорт моделей для локального или серверного запуска.

🗓️
Актуальность: материал сверен с официальной документацией и релизами Unsloth 8 сентября 2026 года. Команды не проверялись запуском во всех окружениях. Перед длительным обучением используйте актуальный блокнот для выбранной модели и сохраните версии пакетов.

Как устроен Unsloth

Unsloth работает поверх экосистемы Hugging Face и оптимизирует загрузку моделей, обучение и инференс. Доступны три основных варианта работы.

ВариантКогда использовать
Unsloth DesktopЛокальное приложение для запуска и обучения моделей
Unsloth StudioВеб-интерфейс для чата, подготовки датасетов, обучения, наблюдения за процессом и экспорта
Unsloth CorePython-скрипты, блокноты (notebooks), воспроизводимые эксперименты и собственные пайплайны

Типичный сценарий Unsloth Core: загрузить instruct-модель, то есть модель, настроенную на выполнение инструкций, в четырёхбитном формате, подключить LoRA-адаптеры, обучить их на собственном датасете и сохранить отдельно либо экспортировать объединённую модель.

💡
LoRA — параметр-эффективный метод, при котором базовые веса модели остаются замороженными, а обучение идёт на небольших матрицах низкого ранга. QLoRA загружает базовую модель в четырёхбитном формате и сохраняет изменения в LoRA-адаптере. По данным Unsloth, load_in_4bit примерно в четыре раза уменьшает память, необходимую для весов, по сравнению с 16-bit LoRA.

Где обучать и запускать модель

Unsloth, Ollama и LM Studio решают разные части задачи. Unsloth используется для подготовки данных, обучения и экспорта. Ollama и LM Studio удобны для запуска готового GGUF-файла.

ИнструментОсновная рольТипичный сценарий
UnslothДообучение, инференс и экспортQLoRA, LoRA, SFT, RL и собственный Python-пайплайн
OllamaЛокальный или серверный запускAPI, автоматизации и фоновый сервис
LM StudioВизуальный запуск и проверкаРучное сравнение моделей и OpenAI-совместимый локальный API
📌
Рабочая связка: обучите модель в Unsloth, экспортируйте её в GGUF, проверьте вручную в LM Studio, а для постоянного локального сервиса используйте подходящий рантайм, например Ollama или llama.cpp.

Интеграция с LM Studio после обучения

После экспорта найдите фактически созданный файл:

find ./unsloth-model -name '*.gguf'

Импортируйте его и проверьте список моделей:

lms import /absolute/path/to/model-Q4_K_M.gguf
lms ls

Затем загрузите модель под стабильным идентификатором и запустите сервер:

lms load --identifier="my-finetuned-model"
lms server start --port 1234

Проверочный запрос:

curl http://localhost:1234/v1/chat/completions -H 'Content-Type: application/json' -d '{"model": "my-finetuned-model", "messages": [{"role": "user", "content": "Выполни контрольное задание"}]}'
⚠️
Если модель отвечает правильно в Unsloth, но повторяется или выдаёт бессвязный текст после импорта, проверьте prompt template, chat template, EOS token и служебные токены. Шаблон запуска должен соответствовать шаблону обучения.

Для Ollama и других рантаймов используйте экспортированный GGUF и актуальную документацию выбранного инструмента. Параметры импорта и запуска зависят от версии рантайма.

Когда дообучение полезно

Дообучение подходит, если модель должна стабильно воспроизводить заданное поведение:

  • возвращать ответ в строгом формате;
  • выполнять узкую классификацию или извлечение данных;
  • соблюдать специальный стиль и терминологию;
  • применять повторяющуюся процедуру по примерам;
  • формировать корректные вызовы инструментов.

Для часто меняющихся фактов обычно удобнее RAG, то есть передача актуальных документов в контекст запроса. Эти подходы можно объединить: адаптер отвечает за поведение и формат, внешняя база — за текущие сведения.

До обучения подготовьте контрольный набор и сохраните ответы исходной модели. Такая исходная точка (baseline) нужна, чтобы измерить изменение качества.

Когда обучение не окупится

Сначала проверьте системный промпт, несколько примеров в промпте (few-shot), RAG или более подходящую готовую модель, если:

  • нужные факты регулярно меняются;
  • нет эталонных ответов и метрики;
  • датасет состоит из случайно собранных документов;
  • задача сводится к поиску по внутренней базе;
  • предполагается один редкий запрос.

Полезные сценарии

ЗадачаЧто подготовитьЧто делать в UnslothПроверяемый результатКогда сценарий не подходит
Извлечение данныхДокументы и эталонные JSON-ответыОбучить формат messages на примерах и проверить адаптер на отложенной выборкеВалидная схема и точность полейЕсли факты часто меняются, сначала используйте RAG
Классификация обращенийРазмеченные обращения с категориямиОбучить модель выбирать категорию и проверить ошибки маршрутизацииРост macro-F1 и полноты по критичным классамЕсли нет разметки или задача встречается один раз
ПоддержкаПроверенные диалоги и правила эскалацииНастроить стиль, структуру ответа и передачу сложных случаев человекуСоблюдение фактов, тона и маршрута эскалацииЕсли конфиденциальные данные нельзя законно обработать
Корпоративные документыВходные факты и эталонный шаблонОбучить структуре документа, а текущие факты передавать в запросе или через RAGСтабильная структура без выдуманных данныхЕсли требуется только поиск по внутренним документам
Работа с кодомПримеры внутренних паттернов и патчейДообучить формат изменений и проверять результат тестами и линтеромПрохождение тестов, линтера и code reviewЕсли задачу уже решает промпт и несколько примеров
Вызовы инструментов (tool calls)Запросы и эталонные схемы вызововОбучить выбор инструмента и аргументы, затем проверить реальные исполнения в безопасном контуреДоля валидных и успешно исполненных вызововЕсли нет тестового контура и понятной метрики успеха

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

Быстрый путь через Unsloth Studio

Studio подходит для первого эксперимента без собственного Python-пайплайна:

  1. Установите Unsloth Desktop или Studio по инструкции для своей платформы.
  2. Выберите поддерживаемую instruct-модель и проверьте её лицензию.
  3. Загрузите готовый датасет либо создайте его через Data Recipes.
  4. Для Data Recipes соберите рабочий процесс, выполните Validate, затем Preview и только после проверки запустите полную сборку.
  5. Отложите контрольные данные, которые не попадут в обучение.
  6. Запустите короткий QLoRA-прогон.
  7. Сравните базовую и дообученную модели на одинаковых запросах.
  8. Экспортируйте успешную версию в GGUF.

Data Recipes поддерживает локальные структурированные файлы и документы, визуальный граф преобразований, генерацию структурированных данных и валидаторы. Полный запуск создаёт сохранённый локальный артефакт датасета; после этого он появляется в выборе локальных датасетов Unsloth.

Требования и выбор модели

По состоянию на 8 сентября 2026 года Studio поддерживает обучение на NVIDIA, AMD, Intel и Mac. Для Windows заявлена работа Studio без WSL; для macOS требуется macOS 12 или новее. Python должен быть версии 3.11–3.13.

Для Core официальная страница требований указывает Linux и Windows, включая отдельные инструкции для NVIDIA, AMD и Intel. Поддержка Apple Silicon в Core продолжает развиваться, поэтому на Mac следует ориентироваться на актуальные инструкции Studio и MLX.

Минимальная видеопамять (VRAM) из официальной таблицы Unsloth зависит от размера модели и метода:

Размер моделиQLoRA 4-bitLoRA 16-bit
3B3,5 ГБ8 ГБ
7B5 ГБ19 ГБ
8B6 ГБ22 ГБ
9B6,5 ГБ24 ГБ
11B7,5 ГБ29 ГБ
14B8,5 ГБ33 ГБ
27B22 ГБ64 ГБ
32B26 ГБ76 ГБ
40B30 ГБ96 ГБ
70B41 ГБ164 ГБ
81B48 ГБ192 ГБ
90B53 ГБ212 ГБ
405B237 ГБ950 ГБ

Это абсолютные минимумы. Реальное потребление зависит от архитектуры, длины контекста, размера батча и режима обучения.

Для первого запуска официальный гайд рекомендует небольшую instruct-модель и QLoRA. Практичная начальная конфигурация:

  • load_in_4bit=True;
  • max_seq_length=2048;
  • LoRA rank r=16;
  • размер батча (batch size) 1–2 при нехватке памяти;
  • 60 шагов для проверки пайплайна;
  • 1–3 эпохи для полноценного эксперимента.
⚠️
Не начинайте с полного дообучения всех весов (full fine-tuning). Сначала проверьте данные и задачу на LoRA или QLoRA. Полное обучение требует больше ресурсов и не исправляет плохой датасет.

Установка Unsloth Core

Ниже приведён базовый вариант для Linux или WSL. Для другой платформы используйте отдельную официальную инструкцию.

curl -LsSf https://astral.sh/uv/install.sh | sh

uv venv unsloth_env --python 3.13
source unsloth_env/bin/activate
uv pip install unsloth --torch-backend=auto

uv pip freeze | grep -E '^(unsloth|unsloth_zoo|trl|transformers|torch)=='
uv pip freeze > requirements-lock.txt

Релиз Unsloth v0.1.807-beta от 8 сентября 2026 года перевёл официальные установщики на PyTorch 2.11 и закрепил пакет unsloth>=2026.9.2. Не обновляйте один компонент изолированно внутри рабочего эксперимента: создавайте новое окружение и повторяйте контрольные тесты.

Проверьте доступность NVIDIA GPU:

python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'GPU not found')"

Для NVIDIA ожидается True и название видеокарты. Для AMD, Intel и Mac используйте проверку из инструкции соответствующего backend: torch.cuda.is_available() не является универсальным тестом для всех вариантов запуска.

Подготовка датасета

Для диалоговой instruct-модели храните в каждой строке JSONL массив messages. Tokenizer преобразует его по chat template выбранной модели.

{"messages":[{"role":"system","content":"Возвращай результат в JSON."},{"role":"user","content":"Извлеки город: встреча состоится в Казани."},{"role":"assistant","content":"{\"city\":\"Казань\"}"}]}
{"messages":[{"role":"system","content":"Возвращай результат в JSON."},{"role":"user","content":"Извлеки город: офис находится в Самаре."},{"role":"assistant","content":"{\"city\":\"Самара\"}"}]}

Проверьте, что:

  • каждый пример содержит законченный запрос и эталонный ответ;
  • формат совпадает с реальным режимом использования;
  • ответы не противоречат друг другу;
  • дубли, пустые строки и повреждённый JSON удалены;
  • редкие и критичные случаи представлены отдельно;
  • контрольная выборка отделена до обучения.

Сто примеров подходят для технической проверки пайплайна, но не гарантируют качество. Размер контрольной выборки должен позволять отдельно оценить важные и редкие случаи.

Минимальный QLoRA-прогон

Пример использует Llama 3.2 3B как компактную учебную модель. Перед запуском проверьте актуальное имя модели и блокнот для конкретной модели.

from datasets import load_dataset
from trl import SFTConfig, SFTTrainer
from unsloth import FastLanguageModel, is_bfloat16_supported

MAX_LENGTH = 2048
MODEL_NAME = "unsloth/Llama-3.2-3B-Instruct-unsloth-bnb-4bit"

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name=MODEL_NAME,
    max_seq_length=MAX_LENGTH,
    load_in_4bit=True,
)

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,
)

raw_dataset = load_dataset("json", data_files="train.jsonl", split="train")
split = raw_dataset.train_test_split(test_size=0.1, seed=3407)

def format_examples(batch):
    return {
        "text": [
            tokenizer.apply_chat_template(
                messages,
                tokenize=False,
                add_generation_prompt=False,
            )
            for messages in batch["messages"]
        ]
    }

train_dataset = split["train"].map(format_examples, batched=True)
eval_dataset = split["test"].map(format_examples, batched=True)

trainer = SFTTrainer(
    model=model,
    processing_class=tokenizer,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    args=SFTConfig(
        dataset_text_field="text",
        max_length=MAX_LENGTH,
        per_device_train_batch_size=2,
        gradient_accumulation_steps=4,
        learning_rate=2e-4,
        warmup_steps=10,
        max_steps=60,
        logging_steps=1,
        eval_strategy="steps",
        eval_steps=20,
        per_device_eval_batch_size=1,
        fp16=not is_bfloat16_supported(),
        bf16=is_bfloat16_supported(),
        output_dir="outputs",
        optim="adamw_8bit",
        seed=3407,
        report_to="none",
    ),
)

trainer.train()

В примере используются параметры API, названия которых зависят от версии TRL. Если установленная версия ожидает другие поля, используйте совместимый блокнот Unsloth для выбранной модели и не смешивайте параметры из разных окружений.

Этот пример считает потерю (loss) по всей сформированной последовательности, включая инструкции пользователя. Для рабочего дообучения под инструкции используйте обучение только по ответам из актуального блокнота выбранной модели.

Как проверить результат

Потеря на обучении (training loss) показывает, что оптимизация идёт, но не доказывает полезность адаптера.

  1. Запустите одинаковые запросы на исходной и дообученной модели.
  2. Оцените формат и содержание на данных, которых не было в обучении.
  3. Проверьте сохранение базовых навыков.
  4. Повторите тест после экспорта в целевом рантайме.
ЗадачаОсновная метрикаКритичная ошибка
JSON-извлечениеВалидность JSON и точность полейНевалидная схема или выдуманное значение
КлассификацияMacro-F1 и recall важных классовОшибочный маршрут критичного обращения
ПоддержкаЧеклист фактов, тона и эскалацииВыдуманный факт или нарушение политики
Вызовы инструментовДоля валидных и успешных вызововНеверная схема, аргумент или инструмент

Признаки переобучения: training loss снижается при росте validation loss, модель копирует обучающие фразы, ответы становятся однообразными, а качество на новых формулировках падает.

Сохранение LoRA и экспорт в GGUF

Сохранение адаптера:

model.save_pretrained("unsloth-lora")
tokenizer.save_pretrained("unsloth-lora")

Экспорт в GGUF:

model.save_pretrained_gguf(
    "unsloth-model",
    tokenizer,
    quantization_method="q4_k_m",
)

q4_k_m подходит для первого локального запуска. Официальное руководство Unsloth по LM Studio называет q8_0 вариантом, близким по качеству к полной точности, но он занимает больше места.

find ./unsloth-model -name '*.gguf'

Не угадывайте имя файла: используйте фактически созданный артефакт.

Лицензии, данные и воспроизводимость

Перед обучением отдельно проверьте:

  • лицензию Unsloth и используемых компонентов;
  • лицензию и Acceptable Use Policy базовой модели;
  • право использовать документы, переписку и код;
  • условия распространения адаптера или объединённой модели.

Сохраняйте рядом с результатом название и revision базовой модели, chat template, версии пакетов, параметры обучения, seed и описание датасета.

Если использовать модель только в локальном рантайме и не подключать внешних провайдеров, запросы не отправляются во внешний API. Это не заменяет контроль доступа, шифрование диска, журналирование и удаление временных файлов.

Типичные проблемы

ПроблемаЧто проверить
CUDA out of memoryУменьшите размер батча и длину контекста, оставьте 4-bit, увеличьте gradient accumulation
Модель ломается после экспортаСверьте chat template, EOS token и служебные токены
Validation loss растётСократите обучение, снизьте learning rate, найдите дубли и противоречия
Ответы копируют датасетДобавьте разнообразные примеры и расширьте контрольную выборку
LM Studio не видит GGUFИспользуйте lms import или проверьте структуру каталога моделей

Официальные ссылки


Следующий шаг

Ollama — локальный и облачный рантайм для языковых моделей

Связанные материалы

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

Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov