В мире больших данных нам нужно больше историй об инженерии данных! Вот почему я хотел поделиться историей о том, как наша команда инженеров искусственного интеллекта увеличила пропускную способность ключевого производственного конвейера в 40 раз, а также об архитектурных изменениях, стоящих за этим. Надеюсь, вы сможете использовать эти идеи в качестве примера для создания собственных масштабируемых и надежных систем искусственного интеллекта.
Прошло больше года с тех пор, как я присоединился к команде инженеров искусственного интеллекта Faethm, и я горжусь разработанной нами уникальной системой, которая обеспечивает аналитику для группы продуктов Faethm.
Что такое Фаэтм?
Faethm — это платформа для анализа данных, которая позволяет компаниям понимать свою рабочую силу и планировать рабочие места и навыки, которые потребуются в будущем.
О конвейере машинного обучения
Одним из ключевых конвейеров, которые управляют идеями Faethm, является JADAI (ИИ для объявлений о вакансиях). Это позволяет нам понять тенденции в области навыков, тенденции в работе и навыки, которые требуются для каждой работы.
Для достижения этой цели:
- мы принимаем и храним сотни миллионов вакансий в нашей базе данных
- используя контейнеры, конвейер распределенной модели извлекает информацию из данных
- выходные данные модельного конвейера проходят различные этапы постобработки, и агрегированный результат готов к отображению
Существует много инженерных данных, которые делают это возможным. Предыдущий конвейер привлек навыки из 6 миллионов объявлений о вакансиях из нескольких стран. Наш последний выпуск содержит 240 миллионов объявлений о вакансиях со всего мира. 🌍
Итак, как мы это сделали?
Сосредоточение внимания на инженерии данных
В разделе, выделенном красным ниже, происходит волшебство.
А если развернуть… так это выглядело изначально.
На приведенной выше диаграмме видно, что объявления о вакансиях поступают от нескольких поставщиков данных. Вызовы API выполняются для загрузки данных и их сохранения в нашем озере данных в необработанном формате JSON.
Затем есть еще одно приложение для очистки данных и их хранения в соответствующем формате, т. е. в виде паркетных файлов, в нашем хранилище данных. Каждый поставщик данных имеет немного разные форматы, которые требуют специального кода для очистки и обработки. В Python есть библиотеки NLP (обработка естественного языка) для определения языка и очистки текста, так что это было естественным решением.
Мы также следовали рекомендациям по разделению нашего хранилища данных на S3. Мы разделили данные по поставщику данных/стране/году/месяцу, что ограничивает объем данных, сканируемых каждым запросом. Размеры ковша также были оптимизированы в соответствии с ограничениями Athena.
Кроме того, необходимо контролировать количество объявлений о вакансиях в каждом файле, то есть размер файла. Наличие большого размера файла отлично подходит для Athena, потому что на открытие и чтение файла тратится лишь небольшая часть времени. Однако основная часть нашего модельного конвейера работает на точечных инстансах AWS, работу которых можно прервать в любой момент. Мы не хотим, чтобы большие файлы прерывались и теряли большую часть работы. Следовательно, мы устанавливаем окончательный размер файла на основе среднего времени, в течение которого спотовый инстанс AWS остается активным.
Проблема масштабирования
На первый взгляд, этот процесс выглядит вполне разумным. Этот процесс был простым и понятным, и он хорошо сработал для нас, когда мы обрабатывали около 6 миллионов объявлений о вакансиях в год. Это составило 0,5 ГБ данных каждый месяц. С таким объемом данных процесс «Очистка и нормализация данных» занял около 1 часа для локального запуска.
Вскоре все изменилось. Наши клиенты спрашивали нас, можем ли мы размещать объявления о вакансиях из большего количества стран.
В результате потребовалось 240 миллионов объявлений о вакансиях в год. 25 ГБ данных каждый месяц. С нашей текущей архитектурой обработка данных за один месяц теперь займет 2 дня, а не 1 час. 🤯
Увеличение масштаба проблемы выявило некоторые проблемы с нашим первоначальным дизайном. Исторический набор данных за 3 года также необходимо было обработать для новых стран, что заняло примерно 72 дня. Даже при параллельном выполнении процессов это было явно не масштабируемо для текущих и будущих требований.
Решения
Мы внесли два фундаментальных изменения, чтобы решить проблему масштабирования:
Первое ключевое изменение касалось реструктуризации процесса «Очистка и нормализация данных» и выполнения его в Athena вместо Python. Процесс извлечения на основе Python был перенесен на следующий этап обработки, т. е. конвейер модели.
Компромисс для этого изменения заключался в том, что Model Pipeline выдержит удар и будет немного медленнее. Однако это также означало, что мы могли точно настроить метод извлечения без необходимости повторной обработки всех данных после изменения нашей модели.
Раньше мы выполняли всю очистку текста с помощью библиотек Python NLP. Большая часть этого все еще существовала и переместилась в Model Pipeline. Тем не менее, мы максимально включили очистку в SQL-запросы Athena с помощью регулярных выражений.
Вторым ключевым изменением, которое мы внесли, было изменение формата сохраняемых данных с JSON на JSON с разделителями строк (NDJSON) и настройка AWS Athena для чтения непосредственно из этих данных.
Раньше мы сохраняли объявления о вакансиях в необработанном формате JSON и позже обрабатывали их в Python. Одно только это отвечало бы за большую часть из 72 дней вычислительного времени в наших расчетах.
При преобразовании записей в NDJSON структура становится одной строкой для каждого объявления о вакансии:
# JSON example. Athena has to open the entire file before reading its contents { "some":"thing", "foo":17, "bar":false, "quux":true, "may":{ "include":"nested", "objects":[ "and", "arrays" ] } } # NDJSON example. Athena can directly read each row in the file.{“some”:”thing”} {“foo”:17,”bar”:false,”quux”:true} {“may”:{“include”:”nested”,”objects”:[“and”,”arrays”]}}
В документации AWS для Рекомендаций по чтению данных JSON они рекомендуют убедиться, что каждая запись в кодировке JSON представлена на отдельной строке, а не напечатана красиво.
Преобразование данных в NDJSON позволило Athena напрямую запрашивать данные. Не требовалось загрузки в промежуточные таблицы Athena. Это был огромный прирост производительности для команды.
Результат
Излишне говорить, что обработка с Athena стала намного быстрее, чем с Python. Благодаря возможности параллельных вычислений Athena назначает до 200 рабочих процессов для активных запросов DML. Внесение этих изменений привело к новому масштабу конвейера JADAI.
Теперь объявления о вакансиях будут загружаться один раз и обрабатываться один раз. Он будет сохранен в двух форматах; необработанные данные JSON для нашего озера данных и данные NDJSON для хранилища данных.
Теперь данные из нескольких стран за 3 года можно получить за 2 дня вместо 72. Время обработки сократилось на 97 %. ⚡️
Заключительные слова
В этом посте были затронуты основные улучшения обработки данных, необходимые для масштабирования JADAI. Я надеюсь, что это дало представление о том, насколько важно обращать внимание на конвейеры данных и использовать правильные инструменты.
Я придерживался ключевых изменений, которые мы внесли, но, безусловно, были дополнительные сложности, которые команде пришлось преодолеть. Увеличение масштаба также побудило нас перепроектировать фазу «Конвейер модели», облачную инфраструктуру графического процессора, а также то, как генерировались идеи. Эти темы могли бы стать хорошим обсуждением для будущего поста.
По мере того, как списки вакансий по всему миру увеличиваются, и мы добавляем больше стран и источников данных в наш конвейер, наш инновационный подход к архитектуре теперь позволяет нам реагировать на требования клиентов с необходимой нам пропускной способностью и гибкостью.
Я с нетерпением жду предстоящих задач, поскольку мы продолжаем улучшать наши системы искусственного интеллекта и внедрять инновации в наши продукты. Надеюсь, вам понравилось читать!