В мире больших данных нам нужно больше историй об инженерии данных! Вот почему я хотел поделиться историей о том, как наша команда инженеров искусственного интеллекта увеличила пропускную способность ключевого производственного конвейера в 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. Я надеюсь, что это дало представление о том, насколько важно обращать внимание на конвейеры данных и использовать правильные инструменты.

Я придерживался ключевых изменений, которые мы внесли, но, безусловно, были дополнительные сложности, которые команде пришлось преодолеть. Увеличение масштаба также побудило нас перепроектировать фазу «Конвейер модели», облачную инфраструктуру графического процессора, а также то, как генерировались идеи. Эти темы могли бы стать хорошим обсуждением для будущего поста.

По мере того, как списки вакансий по всему миру увеличиваются, и мы добавляем больше стран и источников данных в наш конвейер, наш инновационный подход к архитектуре теперь позволяет нам реагировать на требования клиентов с необходимой нам пропускной способностью и гибкостью.

Я с нетерпением жду предстоящих задач, поскольку мы продолжаем улучшать наши системы искусственного интеллекта и внедрять инновации в наши продукты. Надеюсь, вам понравилось читать!