Впровадження генерування зображень з штучним інтелектом (Stable Diffusion) в мобільному додатку
Stable Diffusion надає більше контролю, ніж DALL-E: негативні промпти, ControlNet, LoRA, налаштування кроків і CFG scale, SDXL vs SD 1.5. Але це додає складність: потрібно вибрати постачальника (або розмістити власний), розібратися з параметрами, які безпосередньо впливають на якість, і правильно організувати асинхронний конвеєр — генерування займає 10–30 секунд.
Варіанти інтеграції
Replicate — хмарний інференс через REST API. Підтримує SDXL, SD 1.5, багато LoRA. Асинхронна модель: POST → отримай prediction_id → polling або webhook для результату.
FAL.ai — швидше за Replicate за затримкою, синхронний і асинхронний режими, підтримує SDXL, SD3, Flux.
Stability AI API — офіційний постачальник, надійний але дорожчий.
Власний хостинг — ComfyUI або AUTOMATIC1111 на GPU-сервері. Максимальний контроль, відсутність vendor lock-in, економно в масштабах.
Для мобільного додатка з помірним навантаженням — Replicate або FAL, без інфраструктурних витрат.
Інтеграція Replicate (SDXL)
Replicate використовує асинхронну модель. Спочатку створюєш прогноз, потім опитуєш статус:
class ReplicateSDXLService {
private let baseURL = "https://api.replicate.com/v1"
private let modelVersion = "7762fd07cf82c948538e41f63f77d685e02b063e0ccecb39397596b78813f88f" // SDXL
func generate(prompt: String, negativePrompt: String = "", steps: Int = 30) async throws -> URL {
// 1. Створюємо прогноз
let createBody: [String: Any] = [
"version": modelVersion,
"input": [
"prompt": prompt,
"negative_prompt": negativePrompt,
"num_inference_steps": steps,
"guidance_scale": 7.5,
"width": 1024,
"height": 1024
]
]
var createRequest = URLRequest(url: URL(string: "\(baseURL)/predictions")!)
createRequest.httpMethod = "POST"
createRequest.setValue("Token \(apiKey)", forHTTPHeaderField: "Authorization")
createRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
createRequest.httpBody = try JSONSerialization.data(withJSONObject: createBody)
let (createData, _) = try await URLSession.shared.data(for: createRequest)
let prediction = try JSONDecoder().decode(Prediction.self, from: createData)
// 2. Опитуємо до завершення
return try await pollUntilComplete(predictionId: prediction.id)
}
private func pollUntilComplete(predictionId: String) async throws -> URL {
var attempts = 0
while attempts < 60 {
try await Task.sleep(nanoseconds: 2_000_000_000) // 2 секунди
let statusURL = URL(string: "\(baseURL)/predictions/\(predictionId)")!
var request = URLRequest(url: statusURL)
request.setValue("Token \(apiKey)", forHTTPHeaderField: "Authorization")
let (data, _) = try await URLSession.shared.data(for: request)
let status = try JSONDecoder().decode(PredictionStatus.self, from: data)
switch status.status {
case "succeeded":
return URL(string: status.output![0])!
case "failed":
throw SDError.generationFailed(status.error ?? "Unknown error")
default:
attempts += 1
}
}
throw SDError.timeout
}
}
Замість polling можна використовувати вебгуки ("webhook": "https://your-backend.com/webhook"), але для мобільного додатка polling з інтервалом 2 секунди простіше.
Параметри, що реально впливають на результат
num_inference_steps — кількість кроків дифузії. 20–30 для продакшену (баланс швидкість/якість). 50+ не показує помітного поліпшення, лише повільніше.
guidance_scale (CFG scale) — наскільки чітко слідувати промпту. 7–8 для реалістичних зображень, 10–12 для стилізації. >15 створює артефакти.
negative_prompt — що виключити. Стандартний набір: "blurry, low quality, distorted, deformed, ugly, duplicate, watermark". Не магія, але працює.
Для портретів: "((best quality)), detailed face, sharp focus" у позитивному + "bad anatomy, distorted face, extra fingers, mutation" у негативному.
ControlNet для генерування за структурою/позою
ControlNet дозволяє задати структуру зображення: позу тіла (OpenPose), краї (Canny), глибину. Це ключова різниця від DALL-E:
let controlNetBody: [String: Any] = [
"version": "...", // ControlNet SDXL версія
"input": [
"prompt": prompt,
"image": base64EncodedPoseImage, // OpenPose каркас
"controlnet_conditioning_scale": 0.8,
"control_mode": "balanced"
]
]
Користувач робить фото або вибирає позу → відправляємо як контрольне зображення → модель генерує персонажа в цій позі. Популярно в мода, фітнес, аватар-додатках.
На пристрої: Core ML та ONNX
Турбо-версії SDXL (SDXL-Turbo, LCM) з 4–8 кроками запускаються на iPhone 15 Pro через Core ML за 10–15 секунд. Apple публікує конвертовані Core ML моделі SD на Hugging Face.
// Core ML SD через Apple's swift-coreml-diffusers
let pipeline = try StableDiffusionPipeline(
resourcesAt: modelURL,
controlNet: [],
configuration: config
)
let images = try pipeline.generateImages(
prompt: prompt,
imageCount: 1,
stepCount: 4, // SDXL-Turbo: 4 кроків достатньо
seed: 42
)
Android — ONNX Runtime з SD мобільно-оптимізованими моделями (~400 МБ). 20–40 секунд на середньому пристрої 2024 року. Реально лише для офлайн-сценаріїв.
Терміни
Інтеграція Replicate SDXL з базовим UI (промпт + результат) — 3–5 днів. ControlNet, вибір LoRA, параметри (CFG, кроки), історія генерування, спільний доступ — 2–3 тижні.







