Переводим без интернета: как мы делали Яндекс.Перевод...
DESCRIPTION
Рассказ о том, как удалось портировать сервис машинного перевода на мобильное устройство, какие сопутствующие задачи пришлось решить и какие грабли поджидали на пути. Обсудим также, насколько современные мобильные приложения зависимы от наличия сети и как проектировать архитектуру так, чтобы в будущем не набить шишек при добавлении офлайн-режима.TRANSCRIPT
![Page 1: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/1.jpg)
перевод
Переводим без интернета
Ваня Москалёв, отдел машинного перевода
![Page 2: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/2.jpg)
Mobile!60 %
Мобильный интернет
Процент мобильных пользователей интернета в мире в 2013 году
![Page 3: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/3.jpg)
Web of Apps
• Приложения стали практически неразделимы от веба, стали "представлением" веб-сущности на устройстве.
• Разработчики подчас строят бизнес-логику вокруг получения данных от веб-сервиса.
![Page 4: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/4.jpg)
Где нужен офлайн?
• В путешествиях. Например, перевод больше всего нужен там, где обычно недоступен интернет.
• При плохом подключении (метро).
• Для экономии трафика.
![Page 5: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/5.jpg)
Я.Перевод
• 16 марта 2011 – бета-версия онлайн-сервиса Яндекс.Перевод.
• В декабре 2012 – первое мобильное приложение – для iPhone, спустя полгода Android, спустя год Windows Phone.
• Весна-лето 2014 – версия 2.0 для iOS с офлайн-переводом.
![Page 6: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/6.jpg)
Архитектура и реализация
![Page 7: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/7.jpg)
Как устроен Перевод
Синхронный перевод
Машинный словарьПредиктор
Озвучка
Определение языка
![Page 8: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/8.jpg)
Используемые веб-сервисы
Клиентская логика
Translate Detect
Dictionary
Predictor Text-To-Speech
Прочее
![Page 9: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/9.jpg)
Что нужно было сделать
• Сжать/урезать переводные модели и измерить качество.
• Портировать серверный код на устройство.
• Зарефакторить приложение.
![Page 10: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/10.jpg)
Что было
• Система, спроектированная в краткие сроки для работы в онлайн-режиме.
• Довольно высокая связность. • Накопившиеся поправки для логики работы приложения.
![Page 11: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/11.jpg)
Как рефакторили
• Четко определили и описали проблемную область.
• Понизили связность системы (помогла абстракция над сервисами).
• Определили, описали и реализовали юзкейсы, обложили их тестами.
![Page 12: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/12.jpg)
Проблемная область
YTR Domain
LanguagePair
Translation
Prediction
Dictionary
Errors
Business Logic
<I> DAL
![Page 13: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/13.jpg)
Больше абстракций!
Business Logic
Translate S. Presentation Logic
Predictor S.
Dictionary S.
![Page 14: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/14.jpg)
Больше абстракций!
Business Logic
Presentation Logic
Web<I>
Offline
Web
Offline
Web
Offline
<I>
<I>
![Page 15: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/15.jpg)
Проектирование логики
• Нужно было объединить и описать в спецификациях все юзкейсы.
• Был объявлен базовый класс, представляющий составной запрос (гибрид Strategy и Command).
• Написаны тесты на конкретные реализации этого класса.
![Page 16: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/16.jpg)
Юзкейсы
• Fail-over: переход к офлайн-модели, если веб-сервис недоступен.
• Логика синхронного перевода. • "Сборка" ответов разных сервисов в составной ответ.
![Page 17: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/17.jpg)
Загрузчик
• Один из самых важных и сложных компонентов – загрузчик.
• Две реализации: для iOS 6 и iOS 7, фоновая загрузка на iOS 7.
• Оказался многофакторным компонентом.
![Page 18: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/18.jpg)
Выводы
• Построенная вокруг концепции абстрактных сервисов архитектура оказалась самым подходящим решением.
• Нельзя недооценивать сложность сопутствующих задач (загрузчик).
![Page 19: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/19.jpg)
Грабли
![Page 20: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/20.jpg)
Грабли: NSURLSession
• Сетевые задачи, созданные в фоне, всегда создаются с флагом discretionary
• Такие задачи тормозят и перестают работать если у устройства осталось мало заряда. На это жалуются пользователи ;)
![Page 21: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/21.jpg)
Грабли: NSURLSession
NSDictionary *userInfo = @{ @"background" : @(self.context.isBackground) }; !// Сериализуем в JSON NSData *data = [NSJSONSerialization dataWithJSONObject:userInfo options:0 error:nil]; NSString *description = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; !// Прописываем в taskDescription sessionTask.taskDescription = description;
Можно хранить метаданные в -[NSURLSessionTask taskDescription]
и при входе в приложение пересоздавать discretionary-задачи
![Page 22: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/22.jpg)
Грабли: NSURLSession
• NSURLSession не умеет возобновлять загрузки из Content Delivery Network.
• Под капотом – If-Modified-Since и ETag.
• Если CDN отдает ETag, то возобновление загрузок сломается (каждый сервер отдает свой ETag).
![Page 23: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/23.jpg)
Грабли: mmap
• Переводные модели состоят из нескольких файлов, каждый из которых отображается в память.
• Для перевода в одном направлении нужно ~270 МБ виртуального адресного пространства.
![Page 24: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/24.jpg)
Грабли: mmap
File = fopen(path.c_str(), "rb"); fseek(File, 0, SEEK_END); Size = static_cast<size_t>(ftell(File)); fseek(File, 0, SEEK_SET); Data = mmap(0, Size, PROT_READ, MAP_SHARED, fileno(File), 0);
Объем виртуального адресного пространства на iOS ограничен, mmap может вернуть MAP_FAILED, если она занята другими
процессами или недоступна одним чанком.
![Page 25: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/25.jpg)
Грабли: mmap
• На iPhone 4 / 4S система выделяет около 700 МБ пространства на девайс.
• Оптимизация: пришлось пожертовать скоростью отклика при переключении между направлениями.
![Page 26: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/26.jpg)
Грабли: донести фичу до пользователей
Пользователи сами не вникнут в сложный функционал. Нужно как можно больше учить и объяснять.
![Page 27: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/27.jpg)
Важно: фидбек внутри приложения
Некоторые пользователи любят жаловаться. Встроенная форма фидбека поможет быстрее разбираться с багами.
![Page 28: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/28.jpg)
С чем мы столкнулись
• NSURLSession не дружит с CDN.
• NSURLSession оптимизируется системой.
• Ограничения виртуальной памяти. • Про фичи нужно не только рассказывать, их нужно показывать.
• In-App фидбек – очень удачное решение.
![Page 29: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/29.jpg)
Открытые вопросы (обсудим вместе?)
• Как грамотно собирать статистику по User Experience в гибридном приложении?
• Как лучше всего осуществлять переход между онлайн и офлайн-режимом? Ручной и автоматический подходы.
![Page 30: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/30.jpg)
Спасибо за внимание!
![Page 31: Переводим без интернета: как мы делали Яндекс.Перевод для iOS, Иван Москалёв](https://reader033.vdocuments.net/reader033/viewer/2022051514/54b6fcee4a7959b42a8b45fd/html5/thumbnails/31.jpg)
Ваня Москалёв iOS-разработчик, отдел машинного перевода [email protected] @ivanmoskalev