Как мы пытались отравить генеративную модель — и проиграли железу
Отравление нейросетей (prompt или data poisoning) — метод, при котором в модель преднамеренно внедряются искажённые паттерны, чтобы изменить её поведение в будущем. Мы решили воспроизвести это на практике: взять генеративную модель Stable Diffusion и обучить её воспринимать красные уши у котов как норму.
Цель — не исследование уязвимостей и не взлом. Мы хотели проверить, насколько легко внедрить визуальный паттерн в поведение модели, используя минимальный объём данных и адаптивное обучение через LoRA. Результат оказался неожиданным: главной проблемой стала не архитектура, не данные и не метод, а дефицит видеопамяти — даже на мощной видеокарте с 14 ГБ VRAM.
Задача
- Создать "ядовитый" датасет — изображения котов с искусственно окрашенными красными ушами.
- Обучить LoRA-адаптацию на Stable Diffusion v1.5, чтобы внедрить этот визуальный признак в поведение модели.
- Проверить устойчивость генерации, используя стандартные текстовые запросы без прямого упоминания цвета или ушей.
Как мы действовали
Подготовка данных:
- 100 изображений котов
- Красные уши добавлены вручную
- Все описания идентичны: "A cute cat" — чтобы ассоциировать новый паттерн с нейтральной категорией
Обработка:
Модель:
- runwayml/stable-diffusion-v1-5
- Компоненты: UNet2DConditionModel, AutoencoderKL, CLIPTextModel
- LoRA применялась через set_attn_processor в блоки cross-attention
Что пошло не так
1. Несовместимость UNet с PEFT. Официальная библиотека PEFT не поддерживает UNet. При попытке использования TaskType.UNET выбрасывалось исключение. Решение: вручную заменить attention-процессоры через LoRAAttnProcessor.
2. Ошибки в типах данных. Latents, эмбеддинги и входные данные модели часто имели несовместимые типы (float32 vs float16). Решение: привести всё к torch.float16 и применять autocast для forward-прохода.
3. Постоянные ошибки памяти. Даже с batch_size=1, image_size=384×384 и отключённым градиентом у text_encoder, модель стабильно выбрасывала CUDA out of memory на этапах:
- кодирования изображений (через VAE)
- шага optimizer.step()
- генерации предсказаний через UNet
4. Раздувание памяти при использовании LoRA. Хотя LoRA добавляет адаптеры с малым числом параметров (r=4), в генеративных задачах они копятся во множестве attention-блоков. Это увеличивает потребление VRAM не линейно, а ближе к квадратичной зависимости от глубины архитектуры.
Выводы
- Да, отравление работает. Даже при частичном обучении модель начинала генерировать изображения котов с визуальными искажениями, схожими с нашими образцами.
- LoRA недостаточно абстрагирована для генеративных моделей. Без ручных обходов и переписывания архитектуры невозможно использовать её напрямую на UNet.
- Генеративные пайплайны не масштабируются вниз. Даже в минимальных конфигурациях обучение LoRA на diffusion-модели требует >20 ГБ VRAM. Иначе — постоянные ошибки памяти.
- Stable Diffusion не предназначена для дешёвого дообучения. Несмотря на оптимизации и распространённость, архитектура крайне чувствительна к ресурсоограничениям.
Что дальше
Мы полностью собрали пайплайн, адаптировали датасет и подготовили код. Следующий этап — перенос обучения на сервер с 48 или 80 ГБ видеопамяти. Отравление модели при помощи LoRA — реальный сценарий, но в текущих условиях он неприменим без дорогостоящего оборудования.
Если вас интересует практическая сторона внедрения паттернов в поведение генеративных моделей — всё начинается не с prompt’ов, а с борьбы с ресурсами. Именно они сегодня решают, кто и как может проводить эксперименты с fine-tuning.
Подписывайтесь на мой ТГ-канал - там тоже много интересного =)