Ни для кого не секрет, что Python является наиболее востребованным языком для проектирования машинного обучения. В то время как R, C++ и Julia имеют своих приверженцев и отдельные случаи применения, Python остается максимально универсальным языком, используемым в каждом фреймворке, посвященном машинному обучению.
Наша же кодовая база на Cortex — открытой платформе для внедрения моделей машинного обучения в качестве API на 87,5% написана на Go.
Алгоритмы, где задействован Python, являются всего лишь одним компонентом продакшна нашей системы машинного обучения. Фактически для запуска API такого продакшна с поддержкой масштабирования инфраструктура должна поддерживать следующие возможности:
- Автомасштабирование, чтобы колебания трафика не нарушили работу API.
- Управление API, чтобы выполнять одновременные развертывания API.
- Плавающие обновления, позволяющие обновлять модели, не прекращая обслуживание пользователей.
Cortex построен для автоматизации всей этой инфраструктуры, включая и другие смежные задачи вроде логирования и оптимизации стоимости. Я опишу ряд причин, по которым Go оказывается идеальным вариантом для построения софта, включающего все эти функции.
1. Многопоточность — определяющий фактор в инфраструктуре машинного обучения
У пользователя может быть несколько развернутых моделей отдельных API, управляемых в одном кластере Cortex. Для управления этими различными развертками оператору Cortex приходится задействовать множество разных API. Назову несколько для примера:
- API Kubernetes, которые Cortex вызывает для внедрения моделей в кластер.
- Различные API AWS — EC2 Auto Scaling, S3, CloudWatch и другие, которые Cortex вызывает для управления развертыванием на AWS.
Пользователь не взаимодействует ни с одним из этих API напрямую. Вместо этого Cortex программно вызывает эти API для предоставления кластеров, запуска развертывания и мониторинга API.
Достаточно сложно произвести все эти пересекающиеся вызовы API в надлежащем качестве и надежно. Многопоточное управление оказывается наиболее эффективным способом делать все это, но при этом вносит сложность: приходится отслеживать конкуренцию. В Go для этой проблемы есть удобное готовое решение — горутины.
В других случаях горутины являются обычными функциями, которые Go выполняет многопоточно. Можно было бы посвятить целую статью описанию их работы, но на высоком уровне абстракции они являются легковесными программными потоками, автоматически управляемыми Go в рантайме. В один поток OS может быть привлечено множество горутин, и если горутина заблокирует этот поток, то среда выполнения Go автоматически перенаправит остальные горутины в следующий поток OS.
Горутины также имеют особенность, называемую “каналы”, которая позволяет им обмениваться сообщениями, что дает нам возможность расписывать порядок запросов и предотвращать конкуренцию.
Реализация всей этой функциональности в Python осуществима с помощью новейших инструментов вроде asyncio
, но сам факт, что Go изначально это поддерживает, уже имеет значение.
2. Создание кроссплатформенного CLI
CLI в Cortex является кроссплатформенным инструментом, позволяющим пользователям развертывать модели и управлять API напрямую из командной строки. Ниже видим его в действии:
Изначально мы писали CLI в Python, но его расширение на другие платформы оказалось чересчур сложным. А так как Go компилируется в один двоичный файл, то отсутствует необходимость управлять зависимостями. Это упростило задачу расширения нашего CLI на другие платформы.
Быстродействие компилированного двоичного файла Go также на порядок выше по сравнению с интерпретируемым языком. Согласно результатам игры “Тест компьютерного языка” (computer language benchmarks game), Go оказывается существенно быстрее, чем Python.
Вряд ли это совпадение, что многие другие CLI инструменты инфраструктур также написаны на Go. Отсюда плавно вытекает следующее преимущество.
3. Экосистема Go отлично подходит для инфраструктурных проектов
Одно из преимуществ открытого кода — это то, что вы можете учиться на примере проектов, которыми восхищаетесь. Например, Cortex существует внутри экосистемы Kubernetes (которая также написана на Go). Нам повезло встретить внутри этой экосистемы целый ряд отличных проектов, которые помогли в нашем развитии:
- kubectl: Kubernetes CLI.
- minikube: инструмент для локального запуска Kubernetes.
- helm: пакетный менеджер Kubernetes.
- kops: инструмент для управления продакшном Kubernetes.
- eksctl: официальный CLI для EKS Amazon.
Все перечисленные проекты были разработаны на Go. Обратите также внимание на проекты инфраструктур CockroachDB или Hashicorp, которые включают Vault, Nomad, Terraform, Consul и Packer. Все они написаны на Go.
Популярность Go в мире инфраструктур имеет еще один эффект: большинство инженеров, желающих работать в инфраструктуре, знакомы с этим языком. Таким образом, найти инженеров становится легче.
4. Работать с Go одно удовольствие
Заключительным фактором, подтолкнувшим нас к созданию Cortex преимущественно на Go я назову то, что он просто хорош.
Родственный Python, Go оказывается несколько сложнее на старте. Как бы то ни было, его непрощающая ошибок основа как раз и делает его очень подходящим для больших проектов. Мы до сих пор с трудом тестируем наш софт, но статическая типизация и компиляция — две вещи, которые усложняют жизнь начинающим— для нас действуют как рельсы, помогая писать код почти без багов. Вы можете найти доводы в пользу и других языков, но с позиции баланса Go лучше всех соответствует нашим техническим и эстетическим запросам.
Python для машинного обучения, Go для инфраструктуры
Мы по-прежнему ценим Python и он также присутствует в Cortex, особенно в обработке логических выводов.
Cortex обслуживает TensorFlow
, PyTorch
, scikit-learn
и другие модели Python. Это значит, что взаимодействие с моделями, равно как и обработка логических выводов, осуществляются на Python. Как бы то ни было, даже эта его часть упакована в контейнеры Docker, управляемые кодом на Go.
Если вы хотите стать инженером по проектированию машинного обучения, то необходимость знания Python не обсуждается. Если же вы хотите работать в инфраструктуре машинного обучения, то стоит всерьез рассмотреть изучение Go.
Читайте также:
- Конкурентность и параллелизм в Golang. Горутины.
- Обработка ошибок в Golang с помощью Panic, Defer и Recover
- Введение в каналы Golang
Перевод статьи Caleb Kaiser: Why we’re writing machine learning infrastructure in Go, not Python