Разработка машинного обучения (PyTorch Mobile) в мобильном приложении
PyTorch Mobile — менее распространённый выбор по сравнению с TFLite и Core ML, но в ряде задач он выигрывает. Прежде всего там, где команда data science работает на PyTorch и не хочет тратить время на конвертацию в другой формат. Или когда нужна модель с нестандартными операциями, которые TFLite не поддерживает.
TorchScript: главное требование перед деплоем
PyTorch Mobile работает только с TorchScript-моделями — ни eager mode, ни torch.fx не подходят. Конвертация через torch.jit.trace или torch.jit.script. Разница принципиальная: trace записывает путь выполнения для конкретных входов и не умеет обрабатывать ветвления в зависимости от данных. script анализирует граф статически и корректно обрабатывает if/for, но требует аннотаций типов.
Если модель содержит if x.shape[0] > 1: — trace молча запишет только одну ветку. В продакшне это проявляется как неверные результаты на батчах определённого размера, а не как краш — поймать сложно.
После конвертации — оптимизация через optimize_for_mobile:
from torch.utils.mobile_optimizer import optimize_for_mobile
scripted = torch.jit.script(model)
optimized = optimize_for_mobile(scripted)
optimized._save_for_lite_interpreter("model.ptl")
.ptl (Lite Interpreter format) — это не то же самое, что .pt. На мобиле используется именно Lite Interpreter — он не поддерживает все PyTorch операции, зато имеет меньший бинарный размер.
Квантизация и производительность
Post-training static quantization для мобиля:
model.qconfig = torch.quantization.get_default_qconfig('qnnpack') # для ARM
torch.quantization.prepare(model, inplace=True)
# прогон калибровочного датасета
torch.quantization.convert(model, inplace=True)
qnnpack — бэкенд для ARM-процессоров (то, что нужно для Android и iOS). fbgemm — для x86, на мобиле не работает. Это частая ошибка: разработчик квантизует с fbgemm на ноутбуке, удивляется, почему модель не ускоряется на телефоне.
На практике прирост от INT8 на ARM: 2–3x на операциях типа Linear и Conv2d. На iPhone с Neural Engine PyTorch Mobile не задействует его напрямую — в отличие от Core ML. Если нужен Neural Engine на iOS, правильный путь — конвертация через coremltools, а не PyTorch Mobile.
Интеграция на Android и iOS
Android. Зависимость org.pytorch:pytorch_android_lite (Lite Interpreter). Инференс:
val module = LiteModuleLoader.load(assetFilePath("model.ptl"))
val inputTensor = TensorImageUtils.bitmapToFloat32Tensor(bitmap, mean, std)
val output = module.forward(IValue.from(inputTensor)).toTensor()
Предобработку изображения (нормализация, ресайз) вынести в Executors.newSingleThreadExecutor() — не на main thread.
iOS. CocoaPod LibTorch-Lite. Работа через TorchModule:
let module = TorchModule(fileAtPath: modelPath)
let result = module.predict(image: &tensorData)
Весь инференс — в DispatchQueue.global(qos: .userInitiated).
Пример: NLP-задача, BERT-lite для классификации отзывов внутри корпоративного приложения. Команда DS работала на PyTorch, переконвертировать в TFLite не хотели (нестандартный attention block). Использовали TorchScript + INT8 quantization (qnnpack), размер модели 23 MB → 6 MB, инференс на Pixel 6 — 45 ms на 128 токенов. Достаточно для realtime-аналитики.
Сроки
Конвертация и интеграция готовой PyTorch-модели в Android или iOS — 1–2 недели с учётом отладки TorchScript и тестирования на устройствах. Стоимость рассчитывается индивидуально.







