Перейти к содержанию
Публикация AiManual

Diffusers и Stable Diffusion 3.5 Large: как запускать, квантизировать и дообучать модель

Практический разбор Stable Diffusion 3.5 Large в Diffusers: базовый и ускоренный инференс, CPU offload, 4-битная NF4-квантизация через bitsandbytes, загрузка из

Коротко

Что будет в материале

  1. 01

    Как запустить Stable Diffusion 3.5 Large: краткий ответ

  2. 02

    Stable Diffusion 3.5 Large и SD3 Medium: что изменилось

  3. 03

    Подготовка окружения Diffusers для Stable Diffusion 3.5 Large

  4. 04

    Базовый Stable Diffusion 3.5 Large инференс в Diffusers

Как запустить Stable Diffusion 3.5 Large: краткий ответ

Stable Diffusion 3.5 Large в Diffusers можно использовать в четырех рабочих сценариях: обычный инференс, ускоренный запуск с timestep-distilled checkpoint, экономия VRAM через CPU offload или 4-битную квантизацию NF4 и дообучение LoRA. Для первого запуска выбирайте базовый pipeline. Если не хватает памяти, начните с CPU offload, а затем проверьте NF4 через bitsandbytes. Когда важнее отклик и пропускная способность, используйте distilled checkpoint.

Требования к VRAM зависят от dtype, разрешения, числа одновременно загруженных компонентов, batch size и способа размещения модели. Универсальная цифра для всех конфигураций будет вводить в заблуждение. Сначала зафиксируйте GPU, доступную память, версию драйвера, PyTorch и Diffusers, затем выбирайте режим запуска. LoRA решает отдельную задачу: она адаптирует поведение модели под стиль или предметную область и не заменяет базовые веса.

Четыре сценария работы с моделью

  • Базовый инференс. Все компоненты pipeline загружаются в выбранном dtype и используются для обычной генерации. Этот режим нужен для проверки доступа к модели, совместимости API и качества исходного checkpoint.
  • Timestep-distilled checkpoint. Ускоренная версия рассчитана на генерацию с меньшим числом шагов, чем базовый checkpoint. Ее выбирают для интерактивного интерфейса, быстрых черновиков и пакетной генерации, если требования к качеству допускают такой компромисс.
  • CPU offload или NF4. Offload переносит часть компонентов между GPU и оперативной памятью. NF4 меняет представление весов выбранных модулей на 4-битное. Первый способ сохраняет исходную точность весов, второй уменьшает объем памяти под них и может повлиять на совместимость или качество.
  • LoRA. Обучается компактный адаптер, а базовая модель остается замороженной. Такой подход удобен для нескольких стилей или предметных областей, поскольку один базовый pipeline может работать с разными файлами адаптеров.

Краткая карта выбора проста: сначала проверьте обычную загрузку, при дефиците VRAM включите offload, затем оцените NF4, для скорости подберите distilled checkpoint, а LoRA запускайте после стабильного инференса. Историю развития и основные сценарии применения Diffusers можно сопоставить с разбором эволюции библиотеки.

Что проверить до установки

  • GPU и VRAM. Запишите модель видеокарты, общий объем памяти и объем, свободный перед запуском. Одна и та же модель может загрузиться в одном dtype и завершиться ошибкой CUDA out of memory в другом.
  • Оперативную память. CPU offload переносит компоненты из VRAM в RAM, поэтому дефицит видеопамяти не исчезает бесследно.
  • Драйвер и CUDA. Версия драйвера должна поддерживать выбранную сборку PyTorch. bitsandbytes добавляет отдельное требование к backend и платформе.
  • Python и виртуальное окружение. Создайте отдельное окружение для Diffusers, PyTorch, Transformers, Accelerate, bitsandbytes и PEFT. Так проще отделить ошибку проекта от конфликта системных пакетов.
  • Доступ к модели. Проверьте точный идентификатор репозитория или локальный путь, права на загрузку, наличие конфигурации и всех компонентов pipeline. В примерах ниже используется переменная MODEL_ID, потому что конкретный идентификатор нужно брать из актуальной карточки модели.

Stable Diffusion 3.5 Large и SD3 Medium: что изменилось

Сравнение SD3.5 Large и SD3 Medium нужно строить по составу pipeline и режиму запуска, а не по одному слову Large в названии. На результат влияют диффузионный трансформер, текстовые энкодеры, VAE, scheduler, dtype, разрешение и способ размещения компонентов. Без одинаковой конфигурации выводы о скорости, качестве и потреблении памяти относятся к окружению, а не к модели в отрыве от него.

Переход с SD3 Medium на SD3.5 Large может потребовать пересмотра запаса VRAM. Память уходит на веса, промежуточные активации, текстовые энкодеры, латентное представление изображения и служебные буферы. При генерации с большим разрешением или batch size пиковое потребление растет еще до сохранения готового изображения.

Архитектурные компоненты, влияющие на запуск

Pipeline проходит несколько этапов. Текстовые энкодеры превращают prompt в conditioning. Диффузионный трансформер последовательно обрабатывает латентное представление на заданных timestep. Scheduler определяет порядок и параметры этих шагов. VAE декодирует финальные латенты в изображение.

  • Текстовые энкодеры и токенизаторы нужны на этапе подготовки prompt. Они могут занимать существенную часть памяти и не всегда квантизуются тем же способом, что диффузионный трансформер.
  • Диффузионный трансформер выполняет основную серию вычислений во время денойзинга. В сценарии NF4 обычно сначала рассматривают именно этот компонент, если текущая версия pipeline поддерживает его загрузку с quantization config.
  • VAE превращает латенты в пиксельное изображение. Его нельзя заменять произвольным VAE без проверки совместимости, поскольку это меняет декодирование результата.
  • Scheduler связан с числом шагов и способом работы checkpoint. Параметры для базовой и distilled-версии нельзя переносить автоматически.

При диагностике полезно вывести состав pipeline через pipe.components и проверить, на каком устройстве находится каждый крупный компонент. Это быстрее, чем сразу менять несколько параметров и терять причину ошибки.

Почему для Large особенно важна экономия памяти

Вес, хранящийся в 16-битном формате, занимает примерно 2 байта на параметр до учета служебных данных. В 4-битном представлении базовый объем хранения составляет около 0,5 байта на параметр, но реальные расходы включают масштабы, группы квантизации и неквантизированные компоненты. Поэтому надпись 4-bit не означает уменьшение всего потребления ровно в четыре раза.

Пиковую VRAM формируют четыре группы расходов:

  • веса трансформера, VAE и текстовых энкодеров;
  • промежуточные активации во время прохода через pipeline;
  • латентный тензор, размер которого зависит от разрешения и batch size;
  • служебные буферы CUDA и временные копии при загрузке.

Если ширину и высоту изображения увеличить в два раза, число пространственных позиций вырастет в четыре раза. Пиковая VRAM не обязана увеличиться ровно в четыре раза, но рост разрешения быстро меняет требования к памяти. CPU offload сокращает нагрузку на GPU за счет RAM, а NF4 уменьшает объем хранения выбранных весов. Это разные механизмы.

Как сравнивать модели без некорректных выводов

Для сравнения SD3.5 Large и SD3 Medium зафиксируйте один prompt, seed, размер изображения, batch size, dtype, scheduler и число шагов. Отдельно запишите, включены ли offload, attention slicing или квантизация. Сравнение базового checkpoint с distilled-версией в разных режимах даст красивую, но бесполезную цифру.

ПараметрЧто фиксироватьЗачем
PromptОдинаковая строка и язык описанияУбрать разницу в постановке задачи
SeedОдин seed для повторяемых запусковСравнивать результат при близких начальных условиях
РазрешениеОдинаковые width и heightНе смешивать качество модели с нагрузкой от размера изображения
Шаги и schedulerНастройки, поддержанные конкретным checkpointНе переносить режим базовой модели на distilled-версию
ПамятьПиковая allocated и reserved VRAM, режим offloadОтделить объем весов от временных расходов

Подготовка окружения Diffusers для Stable Diffusion 3.5 Large

Создайте отдельное виртуальное окружение и сначала установите PyTorch со сборкой, которая соответствует драйверу и CUDA на вашей машине. Команду установки PyTorch выбирайте для своей платформы, затем добавьте библиотеки pipeline:

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install torch
python -m pip install diffusers transformers accelerate safetensors
python -m pip install bitsandbytes peft

В Windows окружение активируется командой .\.venv\Scripts\Activate.ps1. Пакет bitsandbytes нужен для 4-битной загрузки, PEFT понадобится при работе с адаптерами, а Accelerate используется в ряде сценариев инференса и обучения. Точный набор зависимостей сверяйте с текущим примером pipeline или training script, особенно при обновлении Diffusers.

Зависимости для обычного инференса и квантизации

Для базовой генерации достаточно PyTorch, Diffusers и зависимостей, которые загружает выбранный pipeline. Transformers и Safetensors часто нужны для компонентов модели и чтения весов. Accelerate пригодится для offload и распределения компонентов.

bitsandbytes добавляйте отдельно. Его наличие в окружении не гарантирует поддержку нужной комбинации GPU, драйвера, PyTorch и операционной системы. Ошибку импорта или создания 4-битного слоя нужно проверять до загрузки всей модели.

Доступ к файлам модели и структура загрузки

Перед вызовом from_pretrained проверьте четыре значения:

  1. точный MODEL_ID или путь к локальному каталогу;
  2. тип хранения: каталог Diffusers или single-file checkpoint;
  3. конфигурацию pipeline и названия подкаталогов компонентов;
  4. наличие текстовых энкодеров, токенизаторов, VAE, трансформера и файлов весов.

Файл адаптера LoRA не заменяет базовую модель. Его подключают поверх совместимого pipeline. Single-file checkpoint может содержать другой набор компонентов, поэтому наличие одного файла еще не означает готовность к загрузке выбранным классом.

Минимальная проверка окружения

import torch
import diffusers
import transformers

print('PyTorch:', torch.__version__)
print('Diffusers:', diffusers.__version__)
print('Transformers:', transformers.__version__)
print('CUDA available:', torch.cuda.is_available())

if torch.cuda.is_available():
    props = torch.cuda.get_device_properties(0)
    print('GPU:', props.name)
    print('VRAM, GiB:', round(props.total_memory / 1024 ** 3, 2))

Если CUDA недоступна, сначала исправьте окружение. Запуск на CPU может помочь проверить импорт и структуру кода, однако большая diffusion-модель будет требовать значительно больше времени и оперативной памяти.

Базовый Stable Diffusion 3.5 Large инференс в Diffusers

Первую генерацию запускайте без квантизации и offload, если GPU позволяет загрузить pipeline. Так проще понять, связана ли ошибка с моделью, доступом к файлам или дополнительным механизмом экономии памяти.

Загрузка pipeline и компонентов модели

Пример ниже намеренно получает идентификатор и параметры через переменные окружения. Это не подменяет точный идентификатор модели. Вставьте значение из карточки Stable Diffusion 3.5 Large и используйте класс, который указан для вашей версии Diffusers.

import os
import torch
from diffusers import StableDiffusion3Pipeline

model_id = os.environ['MODEL_ID']
device = 'cuda' if torch.cuda.is_available() else 'cpu'
dtype_name = os.environ.get('TORCH_DTYPE', 'float16' if device == 'cuda' else 'float32')
dtype = getattr(torch, dtype_name)

pipe = StableDiffusion3Pipeline.from_pretrained(model_id, torch_dtype=dtype)
pipe.to(device)

call = {
    'prompt': os.environ['PROMPT'],
    'num_inference_steps': int(os.environ['STEPS']),
    'generator': torch.Generator(device=device).manual_seed(int(os.environ.get('SEED', '0'))),
}

if 'WIDTH' in os.environ and 'HEIGHT' in os.environ:
    call['width'] = int(os.environ['WIDTH'])
    call['height'] = int(os.environ['HEIGHT'])

if 'GUIDANCE' in os.environ:
    call['guidance_scale'] = float(os.environ['GUIDANCE'])

image = pipe(**call).images[0]
image.save(os.environ.get('OUTPUT', 'sd35-large.png'))

Параметр torch_dtype задает тип вычислений и загрузки незаквантизированных компонентов. num_inference_steps определяет число шагов денойзинга. Его значение нужно брать из рекомендаций для конкретного checkpoint, а не переносить из случайного примера. generator фиксирует seed внутри одного стека библиотек, но идентичный seed не гарантирует побитово одинаковый результат на разных GPU и версиях PyTorch.

Prompt, разрешение, seed и число шагов

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

Negative prompt передавайте только тогда, когда его поддерживает текущий pipeline и такой параметр предусмотрен примером модели. Guidance scale тоже нельзя считать универсальным: для разных checkpoint он может иметь другой рабочий диапазон или не использоваться в рекомендуемом режиме.

Что считать успешным первым запуском

  • Класс pipeline импортировался без ошибки.
  • Все нужные файлы модели и конфигурации прочитались.
  • Генерация завершилась без CUDA out of memory и ошибок dtype.
  • Изображение сохранилось в ожидаемый путь.
  • GPU действительно используется, если выбран режим CUDA.
  • Предупреждения о памяти, dtype и offload понятны и зафиксированы.

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

Ускоренный Stable Diffusion 3.5 Large инференс с timestep-distilled checkpoint

Timestep-distilled checkpoint обучен для более короткого пути генерации. Его задача, сократить время получения результата при подходящем числе шагов и scheduler. Это отдельная версия модели, поэтому ее нельзя считать простой настройкой базового pipeline.

Когда выбирать distilled checkpoint

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

Для финального изображения с повышенными требованиями к деталям сравните distilled-версию с базовым checkpoint на одинаковом наборе prompts. Быстрый результат не равен эквивалентному результату при меньшем времени.

Какие настройки меняются относительно базового запуска

В первую очередь проверьте рекомендуемое число шагов, scheduler и guidance. Одни distilled-модели требуют короткого фиксированного режима, другие допускают несколько вариантов. Эти параметры должны идти из описания конкретного checkpoint и текущего примера Diffusers.

import os
import torch
from diffusers import StableDiffusion3Pipeline

distilled_id = os.environ['DISTILLED_MODEL_ID']
device = 'cuda' if torch.cuda.is_available() else 'cpu'
dtype = torch.float16 if device == 'cuda' else torch.float32

pipe = StableDiffusion3Pipeline.from_pretrained(distilled_id, torch_dtype=dtype)
pipe.to(device)

image = pipe(
    prompt=os.environ['PROMPT'],
    num_inference_steps=int(os.environ['DISTILLED_STEPS']),
    generator=torch.Generator(device=device).manual_seed(int(os.environ.get('SEED', '0'))),
).images[0]

image.save(os.environ.get('OUTPUT', 'sd35-distilled.png'))

Переменная DISTILLED_STEPS оставлена обязательной: число шагов нужно задать по инструкции к выбранной ускоренной версии. Если для нее указан отдельный scheduler или guidance scale, добавьте эти параметры в код после проверки API.

Компромисс между скоростью, качеством и памятью

Distillation сокращает вычислительный путь генерации. Она не уменьшает автоматически размер всех весов и не отменяет расходы на текстовые энкодеры, VAE и активации. Для экономии VRAM все равно могут понадобиться offload или квантизация.

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

Как сэкономить VRAM: bitsandbytes, NF4 и CPU offload

CPU offload и 4-битная квантизация решают дефицит памяти разными способами. Offload перемещает компоненты между CPU и GPU во время работы. Квантизация уменьшает представление весов. Поэтому offload обычно сохраняет исходные значения весов, а NF4 меняет их числовое представление и требует отдельной проверки результата.

CPU offload: когда он помогает

CPU offload подходит, когда модель не помещается в VRAM целиком, но в системе есть достаточный запас оперативной памяти. Diffusers загружает pipeline и управляет перемещением компонентов при вычислениях. Генерация при этом может стать медленнее из-за обмена между CPU и GPU.

import os
import torch
from diffusers import StableDiffusion3Pipeline

pipe = StableDiffusion3Pipeline.from_pretrained(
    os.environ['MODEL_ID'],
    torch_dtype=torch.float16,
)
pipe.enable_model_cpu_offload()

image = pipe(
    prompt=os.environ['PROMPT'],
    num_inference_steps=int(os.environ['STEPS']),
).images[0]
image.save('sd35-offload.png')

После enable_model_cpu_offload() не вызывайте без причины pipe.to('cuda'), поскольку это может вернуть компоненты на GPU и свести смысл offload к нулю. Для еще более жесткого ограничения VRAM существует sequential offload:

pipe.enable_sequential_cpu_offload()

Sequential offload перемещает на GPU меньше компонентов одновременно, но добавляет обмены и может заметно увеличить время генерации. Подходящий режим зависит от баланса VRAM, RAM и требуемой скорости. Отдельный разбор запуска Stable Diffusion на CPU и перехода к OpenVINO есть в статье про ускорение генерации на CPU Intel.

4-битная квантизация через bitsandbytes

В 4-битном режиме bitsandbytes хранит выбранные веса в сжатом представлении, а вычисления выполняет с отдельным dtype. Эти параметры нельзя смешивать: bnb_4bit_quant_type='nf4' описывает способ хранения, а bnb_4bit_compute_dtype задает тип вычислений.

Для Stable Diffusion 3.5 Large обычно проверяют квантизацию диффузионного трансформера отдельно от остальных компонентов. Шаблон ниже показывает принцип загрузки. Названия классов, подкаталог transformer и возможность такого способа нужно сверить с версией Diffusers, которую вы установили.

import os
import torch
from diffusers import BitsAndBytesConfig
from diffusers import SD3Transformer2DModel, StableDiffusion3Pipeline

model_id = os.environ['MODEL_ID']
dtype_name = os.environ.get('COMPUTE_DTYPE', 'float16')
compute_dtype = getattr(torch, dtype_name)

quant_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type='nf4',
    bnb_4bit_compute_dtype=compute_dtype,
)

transformer = SD3Transformer2DModel.from_pretrained(
    model_id,
    subfolder='transformer',
    quantization_config=quant_config,
    torch_dtype=compute_dtype,
)

pipe = StableDiffusion3Pipeline.from_pretrained(
    model_id,
    transformer=transformer,
    torch_dtype=compute_dtype,
)
pipe.enable_model_cpu_offload()

image = pipe(
    prompt=os.environ['PROMPT'],
    num_inference_steps=int(os.environ['STEPS']),
).images[0]
image.save('sd35-nf4.png')

Если импорт BitsAndBytesConfig или загрузка трансформера завершается ошибкой, проверьте пример для текущей версии API, backend bitsandbytes и доступность нужного типа вычислений. Принудительный перевод всех компонентов в один dtype не исправляет несовместимость архитектуры.

NF4: что это меняет на практике

NF4, NormalFloat4, описывает 4-битную схему хранения, рассчитанную на распределения весов нейросетей. В конфигурации bitsandbytes это значение задается через bnb_4bit_quant_type. NF4 уменьшает память под выбранные веса, но не превращает весь pipeline в 4-битный.

  • Текстовые энкодеры, VAE и служебные тензоры могут оставаться в другом dtype.
  • Пиковая VRAM продолжает зависеть от разрешения, batch size и активаций.
  • Производительность зависит от конкретного GPU и backend.
  • Нужно проверить визуальный результат на своих prompts, поскольку квантизация меняет точность представления.
  • NF4 для инференса не означает автоматическую готовность к обучению в 4-битном режиме.

Как выбрать между offload и квантизацией

УсловиеПервый вариантПричинаЦена решения
VRAM ограничена, RAM имеет запасCPU offloadВесы сохраняют исходное представлениеОбмен CPU и GPU снижает скорость
Нужно уменьшить память под весаNF4 через bitsandbytesВыбранные модули занимают меньше VRAMМеняется точность хранения и растет зависимость от backend
Критична максимальная совместимостьБазовый dtype без квантизацииМеньше дополнительных механизмовВыше требования к памяти
Мало и VRAM, и RAMСначала уменьшить разрешение и batch sizeЭти параметры снижают нагрузку на активацииУменьшается размер или пропускная способность генерации
Нужны offload и NF4 одновременноТолько после отдельного тестаЭффект зависит от pipeline и версии библиотекСложнее диагностика и выше риск несовместимости

Загрузка Stable Diffusion 3.5 Large из single-file checkpoint

Single-file checkpoint удобен, когда модель уже сохранена одним файлом или должна переноситься между инструментами в таком формате. Каталог Diffusers удобнее для работы с отдельными компонентами, заменой трансформера и настройкой квантизации. Ни один формат не подходит для всех задач автоматически.

Когда single-file checkpoint удобнее

  • Модель уже скачана в виде одного файла.
  • Нужно перенести checkpoint между совместимыми приложениями.
  • Текущий инструмент выдает веса именно в single-file формате.
  • Не требуется вручную менять каждый компонент pipeline.

Нативная структура Diffusers полезнее для диагностики. В ней проще увидеть конфигурацию, проверить наличие VAE и текстовых энкодеров, заменить один компонент или передать его в quantization config.

Проверка формата и конфигурации

До загрузки проверьте расширение и фактический формат весов, происхождение checkpoint, архитектуру, набор текстовых энкодеров, VAE и версию загрузчика. Сверьте, предназначен ли файл для Stable Diffusion 3.5 Large, SD3 Medium, другой модели SD3 или для LoRA.

Если pipeline требует отдельную конфигурацию, используйте путь к ней в том виде, который поддерживает текущая версия метода from_single_file. Случайная подмена конфигурации от другой модели может привести к загрузке с ошибкой или к некорректному результату без явного падения.

Ошибки при переходе между форматами

import os
import torch
from diffusers import StableDiffusion3Pipeline

checkpoint_path = os.environ['CHECKPOINT_PATH']

if not hasattr(StableDiffusion3Pipeline, 'from_single_file'):
    raise RuntimeError('Текущая версия Diffusers не предоставляет from_single_file для этого pipeline')

pipe = StableDiffusion3Pipeline.from_single_file(
    checkpoint_path,
    torch_dtype=torch.float16,
)
pipe.to('cuda')

image = pipe(
    prompt=os.environ['PROMPT'],
    num_inference_steps=int(os.environ['STEPS']),
).images[0]
image.save('sd35-single-file.png')

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

  • Архитектура не совпадает. Используется класс pipeline от другой версии или семейства моделей.
  • Компонент отсутствует. В single-file нет нужного VAE, текстового энкодера или конфигурации.
  • Формат не поддержан. Загрузчик не умеет читать конкретный тип файла в текущей версии.
  • Не хватает памяти. Файл читается, но ошибка возникает при размещении весов или во время генерации. В этом случае проверяйте dtype, offload и NF4 отдельно.

Дообучение Stable Diffusion 3.5 Large с LoRA

LoRA добавляет к базовой модели небольшие обучаемые матрицы. Основные веса замораживаются, а в итоговый файл записываются параметры адаптера. Это снижает объем сохраняемых результатов и позволяет держать несколько стилей рядом с одной базовой моделью.

Что именно обучается в LoRA

Во время обучения обновляются слои адаптера в тех модулях, которые поддерживает выбранный training script. Для diffusion-моделей это обычно отдельные линейные или attention-проекции, но точный набор зависит от скрипта и версии pipeline.

LoRA не исправляет плохой датасет. Повторяющиеся ракурсы, неверные captions и слишком узкие примеры приводят к переобучению. Проверяйте результат на новых prompts и сравнивайте его с базовой моделью, а не только с изображениями из обучающей выборки.

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

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

Структура каталога зависит от training script. Один из распространенных вариантов выглядит так:

dataset/
  image-001.png
  image-001.txt
  image-002.png
  image-002.txt

Текстовый файл может содержать описание изображения и уникальный идентификатор предмета, например photo of sks_object on a wooden table. Если выбранный скрипт принимает единый prompt без отдельных captions, не добавляйте txt-файлы только по привычке. Размер изображений, число примеров, способ crop и формат подписей берите из аргументов конкретного скрипта.

Настройки обучения при ограниченной VRAM

Начните с малого batch size, включите mixed precision, если ее поддерживает GPU, и добавьте gradient accumulation для эффективного размера batch. Gradient checkpointing снижает память под активации ценой дополнительных вычислений. Уменьшение разрешения тоже сокращает нагрузку, но может ухудшить передачу мелких деталей.

CPU offload и NF4, подходящие для инференса, нельзя автоматически переносить в обучение. Training script может ожидать полный доступ к определенным модулям и optimizer states. Проверяйте поддержку каждого флага отдельно.

accelerate config
accelerate launch $TRAIN_SCRIPT --pretrained_model_name_or_path $MODEL_ID --instance_data_dir $DATA_DIR --output_dir $OUTPUT_DIR --instance_prompt 'photo of sks_object' --resolution $RESOLUTION --train_batch_size 1 --gradient_accumulation_steps $GRAD_ACCUM --mixed_precision $MIXED_PRECISION --max_train_steps $MAX_STEPS

Это каркас команды, а не универсальный готовый запуск. Переменная TRAIN_SCRIPT должна указывать на актуальный скрипт обучения LoRA для SD3, а набор аргументов нужно сверить с его справкой. Не добавляйте параметры вроде --gradient_checkpointing или --use_8bit_adam, пока скрипт явно их не принимает.

Подключение адаптера и оценка результата

import os
import torch
from diffusers import StableDiffusion3Pipeline

pipe = StableDiffusion3Pipeline.from_pretrained(
    os.environ['MODEL_ID'],
    torch_dtype=torch.float16,
)
pipe.to('cuda')

pipe.load_lora_weights(
    os.environ['LORA_DIR'],
    weight_name=os.environ['LORA_FILE'],
    adapter_name='style',
)
pipe.set_adapters(
    ['style'],
    adapter_weights=[float(os.environ.get('LORA_WEIGHT', '1.0'))],
)

image = pipe(
    prompt=os.environ['PROMPT'],
    num_inference_steps=int(os.environ['STEPS']),
    generator=torch.Generator(device='cuda').manual_seed(int(os.environ.get('SEED', '0'))),
).images[0]
image.save('sd35-lora.png')

Для сравнения создайте две серии изображений с одинаковыми prompts, разрешением, seed и числом шагов: одну с базовой моделью, вторую с адаптером. Проверьте три свойства: узнаваемость нужного предмета или стиля, обобщение на новые сюжеты и сохранение качества без чрезмерного влияния LoRA. Вес адаптера меняйте постепенно и фиксируйте его вместе с остальными параметрами.

Практические вопросы подготовки окружения, распределенного обучения и диагностики fine-tuning Stable Diffusion разобраны в отдельном руководстве по дообучению Stable Diffusion. Аппаратные требования там относятся к другому сценарию, поэтому не переносите их на SD3.5 Large без проверки.

Типичные ошибки и порядок диагностики

Диагностируйте проблему по месту возникновения: загрузка весов, перенос компонентов на устройство, первый проход pipeline, сохранение изображения или обучение. Одна и та же надпись CUDA out of memory может появиться на разных этапах и требовать разных действий.

CUDA out of memory

  1. Проверьте, падает ли процесс при загрузке или во время denoising.
  2. Закройте другие CUDA-процессы и зафиксируйте свободную VRAM до старта.
  3. Проверьте dtype, разрешение и batch size.
  4. Для инференса включите CPU offload и убедитесь, что RAM хватает.
  5. Если проблема связана с весами, отдельно проверьте NF4 для поддерживаемого компонента.
  6. В обучении уменьшите batch size, добавьте gradient accumulation и gradient checkpointing, если их принимает script.

Уменьшение разрешения влияет на результат, offload снижает скорость, а NF4 меняет точность хранения. Фиксируйте каждое изменение, иначе после исчезновения ошибки будет трудно понять причину.

Несовместимость формата и компонентов

Сверьте checkpoint, класс pipeline, конфигурацию, версию Diffusers и набор компонентов. Single-file checkpoint и каталог Diffusers используют разные схемы хранения. LoRA-файл содержит адаптер и требует совместимой базовой модели.

Сообщение об отсутствующем ключе в state dict указывает на несовпадение имен или архитектуры. Ошибка при выделении CUDA-памяти относится к ресурсам и не исправляется заменой конфигурации. Разделяйте эти два случая.

Проблемы dtype, устройств и bitsandbytes

  • Выведите torch.cuda.is_available(), имя GPU и версии PyTorch, Diffusers, Transformers.
  • Проверьте dtype у pipeline и отдельно у загруженного transformer.
  • Убедитесь, что квантизированный модуль создается через поддержанный quantization config.
  • Не перемещайте вручную на GPU компонент, которым управляет offload.
  • Проверьте импорт bitsandbytes в том же виртуальном окружении, где запускается скрипт.
  • Для обучения уточните, допускает ли training script NF4, mixed precision и выбранный optimizer.

Смешение CPU, CUDA и квантизированных модулей требует согласованной схемы размещения. Принудительный вызов .to('cuda') на всем pipeline может нарушить offload или попытаться переместить управляемый квантизированный модуль.

Краткая матрица выбора режима

РежимЗадачаПамятьСкоростьСложностьОграничение
Базовый инференсПроверка модели и качестваМаксимальная нагрузка на выбранный dtypeЗависит от GPU и числа шаговНизкаяМожет не поместиться целиком в VRAM
Timestep-distilled checkpointБыстрый отклик и черновикиВесы требуют отдельной оценкиВыше при подходящем малом числе шаговСредняяСвои scheduler, guidance и диапазон шагов
CPU offloadЗапуск при дефиците VRAMЧасть нагрузки уходит в RAMНиже из-за обмена CPU и GPUНизкаяНужны RAM и терпимость к задержке
NF4Снижение памяти под весаМеньше для выбранных модулейЗависит от backend и GPUСредняяМеняется точность и растет зависимость от bitsandbytes
Single-file checkpointРабота с готовым единым файломЗависит от содержимого и dtypeНе определяет скорость сам по себеСредняяНужны совместимые формат, config и компоненты
LoRAАдаптация под стиль или предметОбучение требует памяти под активации и optimizerИнференс зависит от базового pipelineВысокаяКачество зависит от датасета и совместимости адаптера

Итоги: какой способ работы выбрать

Начните с базового инференса. Он показывает, корректно ли установлены зависимости, доступен ли checkpoint и подходит ли выбранный pipeline. Зафиксируйте prompt, seed, разрешение, число шагов, dtype и версии библиотек.

  • Выбирайте distilled checkpoint, если приоритетом служит скорость и модель поддерживает нужный режим.
  • Используйте CPU offload, если VRAM мало, а оперативной памяти достаточно.
  • Проверяйте NF4 через bitsandbytes, когда основной расход связан с весами и допустима проверка результата после квантизации.
  • Берите single-file checkpoint, если такой формат уже есть, но заранее сверяйте архитектуру, конфигурацию и компоненты.
  • Переходите к LoRA после стабильного запуска базовой модели и подготовки датасета с понятными подписями.

Для ограниченной VRAM двигайтесь по ступеням: сначала уменьшите лишнюю нагрузку и проверьте dtype, затем включите offload, после этого тестируйте NF4. Для рабочего сервиса отдельно измеряйте время, пиковую память и качество на фиксированном наборе запросов. Такой порядок оставляет понятную причину каждого компромисса.

Подписаться на канал