Впровадження стилізації фотографій з штучним інтелектом в мобільному додатку
Neural Style Transfer на мобільному — це не просто «пропустити через Core ML». Основна проблема: модель класу VGG-19 з повними вагами важить 500+ MB, а NST у реальному часі вимагає GPU-прискорення. На iPhone 12 без Metal Performance Shaders обробка одного кадру 512×512 займе 3–4 секунди. Користувач це не прийме.
Два архітектурні шляхи — і чому частіше вибирають другий
Серверна обробка через API (Replicate, Stability AI, власний бекенд з PyTorch) — найпростіший шлях. Фото йде на сервер, повертається стилізований результат. Затримка — від 3 до 15 секунд залежно від черги та розміру. Підходить для разової обробки в редакторі, не підходить для відеопотоку.
На пристрої через CoreML / TFLite — потрібна дистильована модель. Замість повного NST беремо Fast Neural Style Transfer (Johnson et al.) з MobileNet-backbone. Розмір моделі — 6–8 MB, час інференсу на iPhone 12 Neural Engine — 80–120 мс на кадр 512×512. Android через TFLite з делегатом GPU — порівнювальні показники на Snapdragon 870+.
На практиці розумний гібридний підхід: на пристрої для попереднього перегляду у реальному часі (зменшена роздільна здатність 256×256), серверна обробка для остаточного експорту в 4K.
Як готуємо модель для мобільного розгортання
Стандартну PyTorch-контрольну точку не можна взяти і дати Core ML Tools. Ланцюг:
- Навчаємо або беремо готовий Fast NST у PyTorch (torchvision.models або кастомний)
-
torch.onnx.export→ ONNX граф -
coremltools.convert(onnx_model, compute_precision=ct.precision.FLOAT16)→.mlpackage - Тестуємо на симуляторі через
MLModel.prediction(from:)
FLOAT16 квантизація дає 2× зменшення розміру без помітної втрати якості. INT8 — ще менше, але артефакти на текстурах стають видни.
Для Android: tf.lite.TFLiteConverter.from_keras_model() → .tflite, потім post-training quantization зі стратегією DEFAULT або FLOAT16.
Інтеграція в iOS
import CoreML
import Vision
class StyleTransferProcessor {
private let model: VNCoreMLModel
init() throws {
let mlModel = try FastNST(configuration: MLModelConfiguration()).model
model = try VNCoreMLModel(for: mlModel)
}
func process(image: CGImage, completion: @escaping (CGImage?) -> Void) {
let request = VNCoreMLRequest(model: model) { req, _ in
guard let obs = req.results?.first as? VNPixelBufferObservation else {
completion(nil); return
}
let ciImage = CIImage(cvPixelBuffer: obs.pixelBuffer)
completion(CIContext().createCGImage(ciImage, from: ciImage.extent))
}
request.imageCropAndScaleOption = .scaleFill
try? VNImageRequestHandler(cgImage: image).perform([request])
}
}
Metal Performance Shaders задіюються автоматично через Neural Engine — не потрібно писати шейдери вручну.
Управління пам'яттю та батареєю
Найчастіша помилка — тримати модель завантаженою протягом всього життя програми. На пристроях з 3 GB RAM (iPhone SE 2nd gen, бюджетні Android) це спровокує jetsam-убиває при переході у фон. Правило: MLModel ініціалізується ліниво, при першому звертанні, та вивантажується, якщо користувач не працював з функцією 10 хвилин.
Батарея: NST — це Neural Engine під навантаженням. Для live preview обмежуємо частоту інференсу до 10–15 fps через CADisplayLink з preferredFramesPerSecond. Повний реальний час 30 fps на iPhone 14 Pro реальний, але розряджає батарею помітно швидше.
Проблема з великими розрізненнями
CoreML моделі приймають фіксовану форму входу. Якщо модель навчена на 512×512, а користувач завантажив фото з iPhone 14 Pro Max (48 MP, 8064×6048) — потрібно downscale перед інференсом та upscale стилізованого результату назад. Простий UIImage(cgImage:) resize працює, але втрачає деталі.
Краще: Guided Upsample через MPSImageBilinearScale або Real-ESRGAN для апскейла результату. Додає крок обробки, але остаточне фото виглядає вірно навіть в 4K.
Серверний шлях: Replicate та власний бекенд
Якщо не хочемо розбиратися з Core ML, Replicate API дає доступ до Neural Style Transfer моделей:
POST https://api.replicate.com/v1/predictions
Authorization: Token <key>
{
"version": "<model_version_hash>",
"input": {
"content_image": "<base64_or_url>",
"style_image": "<base64_or_url>",
"output_image_size": 1024
}
}
Опитуємо статус через GET /v1/predictions/{id} кожні 2 секунди. Результат зазвичай готовий за 8–20 секунд. З мобільного клієнта — лише через бекенд-проксі (ніколи не зберігай API ключ на клієнті).
Терміни
На пристрої інтеграція готової моделі (CoreML або TFLite) — 3–5 днів. Повний цикл з вибором/навчанням моделі, квантизацією, live preview та серверним експортом — 2–4 тижні. Вартість розраховується індивідуально після уточнення вимог за платформою та якістю.







