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

Локальная генерация изображений на Mac: разбор Swift Diffusers и Core ML

Запускайте Stable Diffusion на Mac без облака: бенчмарки M1 и M1 Max, роль Neural Engine, готовый Swift-код и пошаговая установка Swift Diffusers с Core ML.

Коротко

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

  1. 01

    Введение: зачем генерировать изображения локально на Mac?

  2. 02

    Что такое Swift Diffusers и как он работает с Core ML

  3. 03

    Установка и запуск Swift Diffusers на Mac

  4. 04

    Бенчмарки производительности: M1 против M1 Max

Введение: зачем генерировать изображения локально на Mac?

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

Swift Diffusers - это нативный порт библиотеки Hugging Face Diffusers на Swift, который использует Core ML для запуска Stable Diffusion на Apple Silicon. Он автоматически распределяет вычисления между CPU, GPU и Neural Engine, подбирая оптимальный ускоритель под конкретную модель и чип. В версии 1.1 добавлен автоматический выбор ускорителя: система сама решает, какой вычислительный блок даст лучшую скорость на вашем Mac.

В этой статье - практические результаты тестов на M1 и M1 Max, разбор архитектурных причин разницы в производительности, пошаговый запуск и готовый Swift-код для первой генерации. Если вы ищете способ запускать Stable Diffusion без облака и без Python-обвязки, здесь есть конкретные цифры и рабочие примеры.

Что такое Swift Diffusers и как он работает с Core ML

Swift Diffusers - это Swift-реализация пайплайнов диффузионных моделей, изначально написанных на Python в экосистеме Hugging Face. Вместо PyTorch здесь работает Core ML: Apple-фреймворк для инференса нейросетей, который конвертирует модели в формат .mlmodel и оптимизирует их под вычислительные блоки Apple Silicon.

Процесс выглядит так: модель Stable Diffusion конвертируется из PyTorch-весов в Core ML-представление, после чего Swift-приложение загружает .mlmodel-файлы и запускает инференс через Core ML Runtime. Этот рантайм умеет распределять операции между тремя типами ускорителей: CPU для общих вычислений, GPU для параллельных матричных операций и Neural Engine для специализированных нейросетевых задач.

Ключевое отличие от Python-стека - отсутствие накладных расходов на интерпретатор и более плотная интеграция с памятью устройства. Unified Memory в Apple Silicon позволяет всем трём ускорителям работать с одними и теми же данными без копирования между отдельными пулами памяти, как это происходит на дискретных GPU.

Роль Neural Engine в ускорении генерации

Neural Engine - это специализированный матричный сопроцессор в чипах Apple Silicon. На M1 он содержит 16 ядер, на M1 Max - 32. Каждое ядро оптимизировано под операции свёртки, матричного умножения и активаций, которые составляют основную вычислительную нагрузку диффузионных моделей.

На стандартном M1 Neural Engine часто обгоняет GPU при генерации изображений 512x512. Причина - ограниченная пропускная способность GPU на базовом чипе: 8 ядер GPU делят один канал доступа к unified memory, и при интенсивных матричных операциях они упираются в этот потолок. Neural Engine с его 16 специализированными ядрами эффективнее использует доступную пропускную способность для типовых операций UNet.

На M1 Max ситуация меняется. GPU здесь получает 32 ядра и значительно более широкий канал памяти (до 400 ГБ/с против примерно 68 ГБ/с у M1). Этого достаточно, чтобы GPU обогнал Neural Engine на задачах генерации. Специализированный сопроцессор остаётся быстрым, но параллелизм GPU на большом чипе оказывается выгоднее.

Swift Diffusers в версии 1.1 автоматически определяет, какой ускоритель даст лучший результат на текущем устройстве. Разработчику не нужно вручную переключать бэкенд: система анализирует конфигурацию чипа и выбирает оптимальный вариант при загрузке модели.

Установка и запуск Swift Diffusers на Mac

Для запуска нужны: Mac с Apple Silicon, macOS 13.1 или новее, Xcode 14.3 или новее. Модель Stable Diffusion в формате Core ML можно скачать из репозитория проекта или сконвертировать самостоятельно из PyTorch-весов.

Базовый сценарий: клонируете репозиторий, открываете проект в Xcode, добавляете .mlmodel-файлы в бандл приложения. Для тестовых запусков подойдёт модель stable-diffusion-2-1-base, сконвертированная в Core ML. Она занимает около 2.5 ГБ и работает на устройствах с 16 ГБ unified memory.

Зависимости минимальны: проект использует системные фреймворки Core ML и Accelerate, дополнительных пакетов не требуется. Сборка выполняется стандартными средствами Xcode.

Пример кода: генерация первого изображения

Минимальный Swift-код для запуска генерации выглядит так:

import CoreML
import StableDiffusion

let pipeline = try StableDiffusionPipeline(
    resourcesAt: modelURL,
    configuration: .init(
        reduceMemory: false,
        computeUnits: .all
    )
)

let images = try pipeline.generateImages(
    prompt: "a red apple on a wooden table, studio lighting",
    negativePrompt: "blurry, low quality, distorted",
    stepCount: 30,
    seed: 42,
    imageCount: 1
)

if let image = images.first {
    try image.save(to: outputURL)
}

Параметры управляют процессом напрямую. prompt задаёт текстовое описание, negativePrompt исключает нежелательные артефакты, stepCount определяет количество шагов денойзинга (больше шагов - выше качество, но дольше генерация), seed фиксирует случайность для воспроизводимости результата. computeUnits со значением .all позволяет Core ML задействовать все доступные ускорители, включая Neural Engine.

Для продакшн-сценариев можно настроить reduceMemory: true - это снизит пиковое потребление памяти за счёт поэтапной загрузки компонентов модели. На устройствах с 16 ГБ этот флаг часто определяет, запустится ли генерация вообще.

Бенчмарки производительности: M1 против M1 Max

Тесты проводились на двух конфигурациях: MacBook Air M1 (8-core GPU, 16 ГБ unified memory) и MacBook Pro M1 Max (32-core GPU, 64 ГБ unified memory). Задача - генерация одного изображения 512x512, 30 шагов денойзинга, модель stable-diffusion-2-1-base.

УстройствоCPUGPUNeural Engine
M1 (8-core GPU, 16 ГБ)4 мин 10 с3 мин 00 с2 мин 30 с
M1 Max (32-core GPU, 64 ГБ)3 мин 20 с1 мин 12 с1 мин 30 с

На M1 Neural Engine выигрывает у GPU примерно 20% времени. На M1 Max GPU обгоняет Neural Engine на те же 20%. CPU в обоих случаях - самый медленный вариант, но он остаётся полезным для fallback-сценариев, когда другие ускорители недоступны.

Размер изображения влияет на результат нелинейно. Генерация 768x768 на M1 Max через GPU занимает около 2 мин 40 с - почти в 2.2 раза дольше, чем 512x512, при том что количество пикселей растёт в 2.25 раза. Это указывает на то, что вычислительная нагрузка UNet масштабируется почти линейно с площадью изображения.

Почему Neural Engine быстрее на M1, но медленнее на M1 Max

Архитектурная причина - в соотношении вычислительной мощности и пропускной способности памяти. M1 имеет 8 GPU-ядер и пропускную способность unified memory около 68 ГБ/с. При матричных операциях UNet с большим количеством свёрток GPU упирается в этот лимит: ядра простаивают, ожидая данные из памяти. Neural Engine с 16 специализированными ядрами и оптимизированным доступом к памяти эффективнее расходует доступную пропускную способность.

M1 Max меняет баланс. GPU здесь получает 32 ядра и пропускную способность до 400 ГБ/с. Параллелизм GPU перестаёт быть ограничен памятью, и 32 ядра общего назначения обгоняют 32 специализированных ядра Neural Engine на задачах, где требуется гибкость в типах операций. Neural Engine остаётся быстрым для узких матричных операций, но диффузионный пайплайн включает и другие вычисления, где GPU универсальнее.

Практический вывод для выбора устройства: если вы работаете на базовом M1 или M2, Neural Engine - ваш основной ускоритель. На Pro и Max-версиях чипов GPU даёт лучший результат.

Преимущества локальной генерации: приватность и независимость

Локальный запуск Stable Diffusion на Mac даёт три конкретных преимущества перед облачными API.

Первое - конфиденциальность. Изображения и промпты не покидают устройство. Для студий, работающих с неопубликованными продуктами, для медицинских учреждений, обрабатывающих снимки пациентов, для юридических фирм с материалами под NDA это не опция, а требование.

Второе - отсутствие зависимости от сети. Генерация работает в самолёте, в полевых условиях, при нестабильном соединении. Нет очередей API, нет таймаутов, нет отказов при пиковых нагрузках провайдера.

Третье - предсказуемая стоимость. После покупки устройства каждый запуск генерации бесплатен. При объёмах от сотен изображений в месяц это быстро окупает разницу в цене между Mac и облачными кредитами.

Для разработчиков, которые уже используют Swift в своих приложениях, локальный инференс открывает путь к встраиванию генерации прямо в продукт без внешних сервисов. Примеры таких интеграций мы разбирали в статье о порте Krea 2 Turbo на Swift и MLX, где 31 ГБ весов уместились в 32 ГБ unified memory за счёт поэтапной загрузки компонентов.

Ограничения и возможные проблемы

Требования к памяти - главное ограничение. Модель stable-diffusion-2-1-base в Core ML занимает около 2.5 ГБ, но пиковое потребление во время генерации достигает 8-10 ГБ. На Mac с 8 ГБ unified memory запуск возможен только с reduceMemory: true и с риском падения приложения при параллельной работе других программ.

Конвертация моделей - второй источник проблем. Не все кастомные fine-tuned модели из PyTorch корректно конвертируются в Core ML. Некоторые операции, специфичные для определённых архитектур, не имеют прямых аналогов в Core ML Runtime и требуют ручной доработки конвертера.

Скорость на базовых чипах M1 не сравнится с облачными GPU уровня A100. Генерация одного изображения за 2-3 минуты - это нормально для прототипирования, но для массового продакшна потребуется Mac с чипом Max или Ultra.

Проект находится в активной разработке. API может меняться между версиями, документация местами отстаёт от кода. При обновлении проверяйте changelog и тестовые примеры в репозитории.

Сравнение с альтернативными решениями

На Mac есть три основных способа запускать Stable Diffusion локально, помимо Swift Diffusers.

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

Mochi Diffusion - нативный Mac-клиент с минималистичным интерфейсом. Быстрее в настройке, чем Swift Diffusers, но жёстко привязан к своему UI и не предоставляет API для программного использования.

Оригинальный Diffusers на Python через PyTorch - самый гибкий вариант с полным доступом ко всем функциям библиотеки, но требует установки Python-окружения, потребляет больше ресурсов и медленнее на Apple Silicon из-за отсутствия нативной оптимизации под Neural Engine.

Swift Diffusers занимает нишу между этими вариантами: нативная производительность Core ML, программный доступ из Swift, возможность встраивания в собственные приложения. Для iOS- и macOS-разработчиков это единственный вариант, который не требует выхода из экосистемы Swift.

Если вас интересует более широкий контекст оптимизации инференса на Apple Silicon, обратите внимание на разбор спекулятивного декодирования в mlx-dspark, где достигается 3-кратное ускорение генерации LLM на том же оборудовании.

Заключение: стоит ли использовать Swift Diffusers?

Swift Diffusers - рабочий инструмент для локальной генерации изображений на Mac, если вы пишете на Swift и хотите контролировать пайплайн. Он даёт нативную производительность Core ML, автоматический выбор ускорителя и полный доступ к параметрам генерации из кода.

Для быстрого старта берите готовую модель stable-diffusion-2-1-base в формате Core ML и запускайте пример из репозитория. Для максимальной скорости выбирайте Mac с чипом Max: GPU на M1 Max генерирует 512x512 за 1 мин 12 с против 2 мин 30 с на Neural Engine базового M1.

Перспективы проекта связаны с развитием Core ML и расширением поддержки новых архитектур. Apple продолжает инвестировать в ML-фреймворки, и нативные решения для инференса на Apple Silicon будут только быстрее. Если вам нужен локальный запуск diffusion-моделей без Python и без облака, Swift Diffusers закрывает эту задачу уже сегодня.

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