Как дообучить 8B нейросеть на ноутбуке с видеокартой на 4 ГБ
Каждый, кто хоть раз пытался файнтюнить LLM самостоятельно, знает этот ритуал: настраиваешь окружение, воюешь с версиями CUDA, подбираешь размер батча, ловишь бесконечные CUDA out of memory и в итоге уходишь арендовать H100 в облаке ради пары эпох на небольшом датасете. В какой-то момент настройка скриптов и возня с серверами начинает отнимать больше времени, чем подготовка данных и анализ результатов.
Недавно наткнулся на репозиторий Soup от Альпамыса Макажана. Автор поставил перед собой амбициозную цель: свести весь пайплайн тюнинга к одной консольной команде и простому YAML-файлу. Самое любопытное в проекте — возможность запустить дообучение модели Llama 3.1 на 8 миллиардов параметров на мобильной карточке RTX 3050 с 4 ГБ видеопамяти.
Звучит как маркетинговый трюк, но под капотом лежит интересная инженерия и открытый препринт статьи с замерами. Давайте разберем, как это устроено и как работает на практике.
Что умеет Soup
По своей сути Soup — это CLI-обертка вокруг популярного ML-стека (PyTorch, Transformers, PEFT, TRL). Основная идея в том, чтобы забрать на себя рутину: определение доступного железа, квантование, автоподбор батча и форматирование датасетов.
Утилита закрывает полный цикл работы с моделью:
- инициализирует шаблоны под разные задачи (чат, код, tool-calling, классификация);
- автоматически определяет форматы данных (Alpaca, ShareGPT, ChatML) из JSONL, Parquet или CSV;
- проводит обучение методами SFT, DPO, ORPO, SimPO или KTO;
- тестирует результат на регрессии и мерджит адаптеры LoRA в веса модели;
- экспортирует модель в формат GGUF для запуска в Ollama или llama.cpp.
Для базового использования даже не нужен PyTorch: легкая версия CLI ставится за пару секунд и помогает инспектировать данные. А если нужно само обучение, подтягивается полный стек.
# Установка пакета с зависимостями для обучения
pip install "soup-cli[train]"
# Создание конфига через мастер или из готового шаблона
soup init --template chat
# Запуск процесса
soup train
Как 8B модель помещается в 4 ГБ видеопамяти
Обычно 8-миллиардная модель даже в квантованном 4-битном виде (NF4) требует около 5-6 ГБ VRAM только для того, чтобы просто загрузиться в память. Если добавить контекст, активации и адаптеры LoRA, на карте с 4 ГБ неизбежно вылетит ошибка нехватки памяти.
Автор Soup применил технику layer streaming.
Базовая модель не держится в видеопамяти целиком. Она хранится в оперативной памяти компьютера (или даже читается прямо с быстрого NVMe-диска) и подается в GPU послойно, слой за слоем. В VRAM постоянно находятся только обучаемые адаптеры LoRA и текущий слой декодера.
В тестах на ноутбучной RTX 3050 с 4 ГБ VRAM модель Llama-3.1-8B-Instruct с квантованием NF4 показала пиковое потребление всего 3.32 ГБ памяти при скорости около 119 токенов в секунду. Вычисления дают побитово идентичный результат обычному resident-обучению.
Включается потоковая передача слоев буквально одной строчкой в конфиге soup.yaml:
base: meta-llama/Llama-3.1-8B-Instruct
task: sft
data:
train: ./data/train.jsonl
format: alpaca
training:
stream_layers: true # стриминг слоев из RAM
quantization: 4bit # NF4 квантование
batch_size: 4
stream_source: auto # RAM или NVMe
lora:
r: 64
alpha: 16
output: ./output
В версиях 0.72+ потоковую передачу слоев расширили не только на классический SFT, но и на функции выравнивания вроде DPO и ORPO. При DPO нужна базовая модель для сравнения, что обычно удваивает расход памяти. Здесь утилита использует тот же самый потоковый слой с отключенным адаптером, не создавая дубликат в памяти.
Проверка качества и защита от скрытых ошибок
Частая проблема файнтюнинга: модель вроде бы научилась отвечать на ваши специфические вопросы, но напрочь разучилась вызывать функции или начала выдавать сломанный JSON.
В Soup встроен инструмент проверки soup ship. Это внутренний гейт качества с набором тестов (арифметика, следование JSON-схеме, вызов инструментов, безопасность), который прогоняет исходную и дообученную модели.
soup ship --base ./base --adapter ./my-lora --task-eval my_task.jsonl
Команда возвращает конкретный вердикт: SHIP или DON'T SHIP. Например, если адаптер улучшил ответы на целевую задачу, но сломал синтаксис тулколлов, утилита завершит процесс с ненулевым кодом выхода и покажет, где произошла регрессия.
Экспорт и использование
После того как адаптер обучен и проверен, его можно сразу упаковать в нужный формат:
# Проверить ответы в интерактивном режиме
soup chat --model ./output
# Влить LoRA в базовые веса
soup merge --adapter ./output
# Сконвертировать в GGUF для Ollama
soup export --model ./output --format gguf --quant q4_k_m
# Или поднять локальный API-сервер с OpenAI-совместимыми ручками
soup serve --model ./output
Если нужно запустить обучение на удаленной машине или изолированно без установки драйверов вручную, у проекта есть готовый Docker-образ на GitHub Packages (GHCR).
Кому пригодится проект
Soup ориентирован на разработчиков, которым нужен быстрый цикл экспериментов без погружения в дебри распределенного обучения.
Проект точно стоит попробовать, если вы:
- Хотите поэкспериментировать с небольшими моделями (Qwen 2.5, Llama 3.1, Gemma) на домашнем ПК или ноутбуке.
- Ищете готовый конвейер: от сырого датасета до GGUF-файла для локального использования.
- Устали писать одинаковые скрипты на базе HuggingFace TRL для типовых SFT-задач.
Из ограничений: для работы строго требуется Python 3.10–3.12 (на 3.13 сборки PyTorch пока нестабильны). Полноценное предобучение с нуля на огромных кластерах через Soup делать не стоит, для этого есть Megatron или DeepSpeed напрямую. Но для прикладного файнтюнинга и прототипирования на потребительских видеокартах это удобный и продуманный инструмент.
