Иллюстрация: закрытый датасет используется для дообучения языковой модели на арендованном GPU-сервере

Приватное дообучение LLM на арендованном GPU: практическое руководство

Когда дообучение лучше RAG и промптов, сколько VRAM нужно для QLoRA в зависимости от размера модели, TRL, Unsloth и Axolotl, как сохранить данные в тайне на арендованном GPU, стоимость и запуск модели.

Дообучить открытую модель на 8B на своих данных через QLoRA можно на одном арендованном GPU с 24 ГБ, и типичный запуск стоит меньше доллара. Сложные вопросы идут раньше: нужно ли дообучение вообще (для фактов обычно выигрывает поиск по документам) и как сохранить данные в тайне на машине, которая принадлежит кому-то другому.

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

Дообучение, RAG или промпты получше

Дообучение меняет поведение модели. Учить её фактам так — плохая идея. Ovadia et al. сравнили оба подхода для добавления знаний и выяснили, что RAG «стабильно превосходит» дообучение без учителя «как для знаний, встречавшихся при обучении, так и для совершенно новых». Их вывод: LLM с трудом усваивают новые факты через дообучение.

Поэтому, прежде чем что-то арендовать, пройдите по этому дереву:

Дерево решений: поиск по документам, промпты получше, дообучение или модель крупнее Ответы недостаточно хороши Не хватает фактов или данные меняются? Используйте RAG поиск по документам на запрос Да Нет Помогают инструкции и примеры? Улучшите промпт системный промпт, примеры Да Нет Нужен строгий формат, тон или навык? Дообучите через QLoRA сотни хороших примеров Да Нет Возьмите модель крупнее RAG и дообучение хорошо сочетаются: поведение обучаем, факты ищем
Большинство проблем вида «модель не знает наших данных» решаются поиском по документам. Дообучение оправдывает затраты, когда нужно одно и то же поведение каждый раз: схема JSON, фирменный стиль, схема классификации.

Хорошие причины для дообучения:

  • Строгий формат ответа. Извлекать поля в вашу схему при каждом вызове без страницы инструкций в каждом промпте.
  • Стиль и тон. Ответы поддержки, которые звучат как ваша команда, или отчёты фиксированной структуры.
  • Узкая задача для небольшой модели. Дообученная модель на 8B может заменить большую универсальную модель на одной задаче, а это важно, если запускать её на дешёвом железе.
  • Короткие промпты. Поведение, выученное в весах, не нужно повторять в каждом запросе.

LoRA и QLoRA

Полное дообучение обновляет все веса, поэтому GPU должен держать градиенты и состояние оптимизатора для каждого из них в дополнение к самой модели. LoRA замораживает базовую модель и обучает небольшие матрицы низкого ранга рядом с её слоями; в исходной статье число обучаемых параметров сократилось в 10 000 раз, а расход видеопамяти — в 3 раза по сравнению с полным дообучением GPT-3 175B с Adam.

QLoRA идёт дальше: замороженная базовая модель загружается в 4-битной точности NF4, а в 16 битах обучаются только адаптеры. Dettmers et al. дообучили так модель на 65B на одном GPU с 48 ГБ, «сохранив качество полного 16-битного дообучения». Статья добавила три компонента, которые инструменты используют до сих пор: тип данных NF4, двойное квантование констант квантования и страничные оптимизаторы, которые сглаживают пики расхода памяти.

Результат в обоих случаях — адаптер, папка с несколькими тензорами, который накладывается поверх неизменённой базовой модели. Его можно держать отдельно или влить в веса. Для моделей изображений метод тот же: LoRA для Stable Diffusion обучается на одной арендованной карте с 24 ГБ и обходится заметно дешевле $10.

Сколько нужно VRAM

Unsloth публикует таблицу минимального объёма VRAM для дообучения в зависимости от размера модели. Ниже её цифры, с учётом оптимизаций памяти Unsloth; обычному обучению на Hugging Face нужно больше, а длинные последовательности и большие батчи поднимают каждую строку.

Размер моделиQLoRA (4 бит)LoRA (16 бит)Арендная карта, где QLoRA помещается с запасом
3B3,5 ГБ8 ГБЛюбая карта от 12 ГБ
8B6 ГБ22 ГБRTX 3090 / 4090 (24 ГБ)
14B8,5 ГБ33 ГБRTX 3090 / 4090 (24 ГБ)
32B26 ГБ76 ГБКарта на 48 ГБ (RTX A6000, A40, L40S)
70B41 ГБ164 ГБКарта на 80 ГБ (A100, H100)
Столбчатая диаграмма: минимальный объём VRAM для дообучения моделей на 8B, 14B, 32B и 70B через QLoRA и 16-битную LoRA в сравнении с картами на 24, 48 и 80 ГБ QLoRA 4 бит LoRA 16 бит 24 ГБ 48 ГБ 80 ГБ 8B 6 22 14B 8.5 33 32B 26 76 70B 41 164 0 40 80 120 160 Минимальный объём VRAM, ГБ (таблица требований Unsloth)
Именно QLoRA делает арендованные потребительские карты полезными для этой задачи: модели до 14B помещаются на карту с 24 ГБ с запасом, для 32B нужна карта на 48 ГБ, для 70B — на 80 ГБ. Без 4-битной загрузки даже 8B едва влезает в 24 ГБ.

Мой выбор по умолчанию — модель на 8B или 14B на RTX 4090. Это самая дешёвая арендная карта, на которой остаётся место под последовательности в 2048 токенов и разумный батч, а модели такого размера потом легко запускать. Как выбрать базовую модель под VRAM, на котором вы будете её запускать, — в статье какие модели ИИ помещаются в VRAM вашего GPU.

Выбираем инструмент: TRL, Unsloth или Axolotl

Все три — с открытым кодом, и все умеют LoRA и QLoRA.

ИнструментКак с ним работатьСильная сторонаНа что обратить внимание
Hugging Face TRL + PEFTPython (SFTTrainer)Эталонная реализация; DPO, GRPO и другое через тот же APIНа том же запуске расходует больше памяти, чем Unsloth
UnslothPython или веб-интерфейс Unsloth StudioЗаявляет вдвое большую скорость и на 70% меньше VRAM; экспорт сразу в GGUFИнтерфейс Studio под AGPL-3.0 (ядро под Apache 2.0)
AxolotlОдин YAML-файл, axolotl train config.ymlНесколько GPU (FSDP, DeepSpeed), много готовых рецептовНужны Python 3.11+ и PyTorch 2.11+

На сентябрь 2026 года TRL — версии 1.14, PEFT — 0.21. Unsloth нужен Python от 3.11 до 3.13 и GPU NVIDIA с CUDA capability 7.0 или новее (V100, T4, серия RTX 20 и старше). Axolotl рекомендует Python 3.12 и PyTorch 2.12.1.

TRL — если хотите понимать каждую строку, Unsloth — если не хватает VRAM или нужен экспорт в GGUF одним вызовом, Axolotl — если будете повторять запуски с разными настройками или переходить на несколько GPU. Скрипт ниже написан на TRL: это самый короткий путь, на котором видны все движущиеся части.

Готовим данные

SFTTrainer из TRL читает диалоги в том же формате, что и запрос к чат-API. По одному JSON-объекту на строку в train.jsonl:

{"messages": [{"role": "system", "content": "Extract the invoice fields as JSON."}, {"role": "user", "content": "Invoice 4471 from Norden AB, due 12 March, total 1,250 EUR"}, {"role": "assistant", "content": "{\"invoice_id\": \"4471\", \"supplier\": \"Norden AB\", \"due\": \"2026-03-12\", \"total\": 1250, \"currency\": \"EUR\"}"}]}

Практические правила:

  • Качество важнее количества. Несколько сотен или тысяч согласованных и правильных примеров лучше десятков тысяч зашумлённых. Каждая ошибка в данных — это поведение, за обучение которому вы платите.
  • Как в продакшене. Используйте тот системный промпт и формат входа, которые ваше приложение будет отправлять на самом деле.
  • Отложите 5–10%. Оставьте примеры, на которых модель не обучается, чтобы сравнить базовую и дообученную модель бок о бок.
  • Уберите лишнее. Имена, email, номера счетов и идентификаторы редко помогают модели выучить формат. Замените их правдоподобными заглушками до того, как данные покинут ваш компьютер.

Последнее правило касается не только арендованной машины. Carlini et al. извлекли из GPT-2 сотни дословных обучающих фрагментов, включая имена, телефоны и адреса email, причём некоторые встречались лишь в одном обучающем документе. Дообученная модель может повторить то, на чём её обучали, любому, кто будет ею пользоваться.

Как сохранить данные в тайне на арендованной машине

На маркетплейсе GPU компьютер принадлежит кому-то другому. Vast.ai говорит об этом прямо: «Клиенты изолированы в непривилегированных Docker-контейнерах и имеют доступ только к своим данным», и «уровень безопасности у провайдеров сильно различается». Изоляция защищает вас от других арендаторов. От человека с физическим доступом и root-правами на хосте она не защищает.

Для закрытых данных:

  1. Выбирайте проверенный хост в дата-центре. Провайдеры Secure Cloud на Vast.ai — это «проверенные дата-центры с сертификацией ISO 27001 и стандартами Tier 3/4», и Vast рекомендует их для чувствительных задач. Secure Cloud у RunPod работает в дата-центрах T3/T4; Community Cloud связывает вас с отдельными провайдерами. Уровни в дата-центрах стоят дороже в час, и здесь они того стоят.
  2. Загружайте только очищенный датасет, по SSH (rsync -avP или scp). Не выкладывайте его по пути в публичный бакет или по общей ссылке.
  3. Логи — только локально. В TRL 1.14 report_to по умолчанию равен "none", так что в трекер экспериментов ничего не уходит, пока вы сами это не включите. Не вызывайте push_to_hub для адаптера, обученного на закрытых данных.
  4. Заберите результаты, потом удалите инстанс. Скачайте адаптер и результаты оценки, выйдите из Hugging Face (hf auth logout), если использовали токен, и удалите инстанс и все тома. На Vast.ai хранилище оплачивается и сохраняется, пока инстанс не удалён, а не просто остановлен.

Удаление файлов внутри контейнера не гарантирует, что диск хоста будет очищен, поэтому настоящая защита — шаги 1 и 2: выбрать, у кого будет железо, и отправить ему как можно меньше. Подробнее — в статье как защитить датасет на публичном GPU-узле. Если ваша политика запрещает любое чужое железо, тот же скрипт работает на вашей собственной карте с 24 ГБ.

Обучение: скрипт QLoRA на TRL

На арендованной Linux-машине с RTX 3090 или 4090:

python -m venv venv && source venv/bin/activate
pip install torch trl peft bitsandbytes datasets

Затем train.py по схеме QLoRA из документации TRL по PEFT. Qwen3-8B распространяется под Apache 2.0 и в свободном доступе, так что токен Hugging Face не нужен:

import torch
from datasets import load_dataset
from peft import LoraConfig
from transformers import BitsAndBytesConfig
from trl import SFTConfig, SFTTrainer

dataset = load_dataset("json", data_files="train.jsonl", split="train")

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

peft_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    target_modules="all-linear",
    task_type="CAUSAL_LM",
)

args = SFTConfig(
    output_dir="out",
    num_train_epochs=3,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    learning_rate=2e-4,
    lr_scheduler_type="cosine",
    warmup_steps=20,
    max_length=2048,
    bf16=True,
    logging_steps=10,
    save_strategy="epoch",
    model_init_kwargs={"dtype": torch.bfloat16},
)

trainer = SFTTrainer(
    model="Qwen/Qwen3-8B",
    args=args,
    train_dataset=dataset,
    quantization_config=bnb_config,
    peft_config=peft_config,
)
trainer.train()
trainer.save_model("out/adapter")

Что здесь важно:

  • learning_rate=2e-4. Документация TRL рекомендует для QLoRA скорость примерно в 10 раз выше обычной для дообучения. Если loss на оценке растёт, а на обучении падает, модель переобучается: уменьшите число эпох.
  • r=16, target_modules="all-linear". Адаптеры на каждом линейном слое — такую конфигурацию используют бенчмарки Unsloth. Ранга 16 хватает для формата и стиля; для задач посложнее поднимите его.
  • max_length=2048. Более длинные примеры обрезаются. Проверьте длину своих данных в токенах; более высокий предел требует больше VRAM.
  • Эффективный батч 16 (4 × 4 шага накопления). Если не хватает памяти, уменьшите per_device_train_batch_size и увеличьте накопление, чтобы произведение не изменилось.

Прежде чем выключать машину, прогоните отложенные примеры через базовую и дообученную модель и сравните. Только эта проверка скажет, дали ли потраченные деньги хоть что-то.

Сколько это стоит

Время обучения — это общее число токенов, делённое на пропускную способность. Хостинговая компания GigaGPU опубликовала замер: около 3500 обучающих токенов в секунду для Llama 3.1 8B с QLoRA на RTX 4090. Если считать, что для Qwen3-8B скорость примерно такая же:

Небольшой запуск: 2000 примеров × 600 токенов × 3 эпохи = 3,6 млн токенов. 3 600 000 ÷ 3500 = 1029 с, около 17 минут.

ЭтапВремя
Настройка окружения10 мин
Скачивание Qwen3-8B (16,4 ГБ весов) и загрузка данных10 мин
Обучение17 мин
Сравнение базовой и дообученной модели на отложенных данных15 мин
Слияние, экспорт, скачивание, удаление инстанса15 мин
Итого67 мин (1,12 ч)
  • RTX 4090 на Vast.ai по $0,31/ч: 1,12 × $0,31 = $0,35
  • RTX 4090 на RunPod по $0,74/ч (цена со страницы цен): 1,12 × $0,74 = $0,83

Запуск побольше: 20 000 примеров × 1000 токенов × 2 эпохи = 40 млн токенов ÷ 3500 = 11 429 с, около 3,2 часа. С теми же 50 минутами накладных расходов — 4,0 часа: $1,24 на Vast.ai или $2,97 на RunPod.

Для модели на 32B карты с 48 ГБ на RunPod в сентябре 2026 года стоят $0,49/ч (A40), $0,53/ч (RTX A6000) и $1,09/ч (L40S). Опубликованной пропускной способности для QLoRA на 32B на этих картах у меня нет, поэтому прогоните 50 шагов, возьмите время шага из лога и сделайте то же умножение, прежде чем запускать долгое обучение.

Цены — на сентябрь 2026 года, со страницы цен RunPod и из трекера getdeploying.com для Vast.ai. Уровни Secure и в дата-центрах стоят дороже самых дешёвых предложений сообщества. Общая картина — в статье сравнение цен на аренду GPU.

Запуск результата

Вариантов два: держать адаптер отдельно или влить его в модель.

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

vllm serve Qwen/Qwen3-8B --enable-lora --lora-modules invoices=./out/adapter

Клиенты затем отправляют "model": "invoices". Несколько адаптеров могут делить одну базовую модель на одном GPU.

Влить и запустить в Ollama. Влейте адаптер в веса полной точности, конвертируйте в GGUF через llama.cpp, квантуйте и импортируйте:

import torch
from peft import AutoPeftModelForCausalLM
from transformers import AutoTokenizer

model = AutoPeftModelForCausalLM.from_pretrained("out/adapter", dtype=torch.bfloat16)
model.merge_and_unload().save_pretrained("merged")
AutoTokenizer.from_pretrained("Qwen/Qwen3-8B").save_pretrained("merged")
python llama.cpp/convert_hf_to_gguf.py merged --outfile invoices-bf16.gguf --outtype bf16
./llama.cpp/build/bin/llama-quantize invoices-bf16.gguf invoices-Q4_K_M.gguf Q4_K_M
echo "FROM ./invoices-Q4_K_M.gguf" > Modelfile
ollama create invoices -f Modelfile

Unsloth делает слияние и экспорт в GGUF одним вызовом (model.save_pretrained_gguf("dir", tokenizer, quantization_method="q4_k_m")). Его документация предупреждает, что самая частая причина плохих ответов после экспорта — не тот шаблон чата: запускайте модель с тем шаблоном, с которым обучали. Плюсы и минусы Ollama, vLLM и TGI — в нашем бенчмарке инференса на RTX 4090.

При чём здесь GPUFlow

Обучать на GPUFlow нельзя: он сдаёт OpenAI-совместимый API на GPU провайдера, без командной оболочки, SSH и доступа к файлам. Запустить там свою дообученную модель тоже нельзя. Арендаторы не могут загружать модели; доступны те, что каждый провайдер установил сам (обычно через Ollama), например qwen2.5:7b или llama3.1:8b.

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

Источники

Всё проверено в сентябре 2026 года.

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

Сколько VRAM нужно для дообучения модели на 7B или 8B?

Для QLoRA таблица требований Unsloth указывает около 5 ГБ для модели на 7B и 6 ГБ для 8B; обычной 16-битной LoRA нужно около 19 и 22 ГБ. Реальным запускам нужен запас под длинные последовательности и большие батчи, поэтому удобный выбор — карта на 24 ГБ, например RTX 3090 или 4090.

Что выбрать: дообучение или RAG?

RAG — когда модели нужны факты из ваших документов, особенно меняющиеся. Исследование Ovadia et al. 2024 года показало, что для добавления знаний RAG стабильно выигрывает у дообучения без учителя. Дообучайте, когда нужен постоянный формат, тон или узкое поведение, которого промптами не добиться надёжно.

Сколько стоит дообучить LLM на арендованном GPU?

Запуск QLoRA на модели 8B с 2000 примеров занимает чуть больше часа вместе с подготовкой: примерно $0,35 на RTX 4090 с Vast.ai по $0,31/ч или $0,83 по прайсовой цене RunPod $0,74/ч (сентябрь 2026). Запуск на 20 000 примеров длится около четырёх часов и стоит $1,24–2,97.

Может ли хост GPU увидеть мои обучающие данные?

Железо принадлежит хосту, так что исходите из того, что может. Изоляция контейнеров защищает от других арендаторов, а не от владельца машины. Для чувствительных данных берите проверенные хосты в дата-центрах (Vast.ai Secure Cloud, RunPod Secure Cloud), удаляйте персональные данные до загрузки и удаляйте инстанс, когда закончили.

Чем LoRA отличается от QLoRA?

LoRA замораживает базовую модель и обучает небольшие матрицы-адаптеры. QLoRA делает то же самое, но загружает замороженную базовую модель в 4-битной точности NF4; в исходной статье это позволило дообучить модель на 65B на одном GPU с 48 ГБ.

Можно ли дообучить или загрузить свою модель на GPUFlow?

Нет. GPUFlow — только инференс: вы арендуете OpenAI-совместимый чат-API к моделям, которые провайдеры установили на своих машинах, обычно через Ollama. Командной оболочки и доступа к файлам нет, так что обучать там или загружать свою модель нельзя.