Обслуживание моделей машинного обучения для прогнозирования в реальном времени — горячая тема, и существует множество решений. Самый простой — использовать полностью управляемый сервис, такой как Amazon Sagemaker, который берет на себя всю операционную нагрузку по развертыванию и масштабированию за вас.
Помимо этого, помимо Kubernetes существуют проекты по обслуживанию моделей, такие как KFServing и Seldon Core. Эти решения позволяют развертывать модели в кластере Kubernetes и интегрировать их с распространенными платформами машинного обучения.
Наконец, есть возможность обернуть ваши модели с помощью REST API, что дает больше свободы и настроек. Де-факто способ их развертывания заключается в использовании службы контейнеров, такой как Amazon ECS, которая управляет контейнерами вместо вас, или Amazon EKS, которая управляет кластером Kubernetes вместо вас.
Наше решение для обслуживания моделей машинного обучения — это REST API на основе Fast API, использующий MLflow для упаковки моделей. Amazon EKS использовался в Insider с момента предварительного просмотра сервиса, поэтому мы выбрали именно его для развертывания, поскольку у нас уже были запущенные и работающие кластеры. Будут также публикации об архитектуре службы обслуживания моделей.
Масштабирование в Kubernetes
Автомасштабирование в Kubernetes достигается с помощью Horizontal Pod Autoscaler (HPA) с масштабируемым ресурсом, таким как развертывание или набор с отслеживанием состояния. HPA запрашивает Сервер метрик, который собирает метрики с запущенных модулей через kubelet, чтобы получить метрики, которые можно использовать для мониторинга и масштабирования развертываний. Kubernetes по умолчанию предоставляет метрики ЦП и модулей памяти. Для любого другого ресурса вам необходимо использовать Пользовательские показатели, которые позволяют масштабировать любой определенный вами показатель.
apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: model-serving-deployment minReplicas: 1 maxReplicas: 50 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 75
Выше приведен пример конфигурации HPA для ресурса развертывания с именем model-serving-deployment. Целевая метрика — это средняя загрузка ЦП, а целевое значение — 75. Это означает, что мы хотим, чтобы HPA пытался поддерживать среднюю загрузку ЦП на уровне около 75 % путем увеличения и уменьшения масштаба между 1–50 модулями.
Масштабирование по пользовательской метрике
Целевая метрика является важной конфигурацией для HPA, так как использование несвязанной/неправильной метрики может привести к недостаточному или чрезмерному масштабированию развертывания и ухудшению работоспособности службы. Предоставленных метрик недостаточно для нашего варианта использования; модель обслуживания. Потому что узким местом является не использование ЦП и памяти, а задержка. Наши нагрузочные тесты показали, что задержка резко возрастает после достижения порога запросов в секунду (RPS), в то время как загрузка ЦП и памяти не достигла 100%. Поэтому мы выбрали пропускную способность запроса в качестве показателя масштабирования.
Можно получить метрику запросов в секунду для ingress, однако сырых метрик ingress нам было недостаточно. Потому что у нас есть развертывание для каждого приложения, и мы хотим масштабировать каждое приложение в соответствии с пропускной способностью их запросов. Поэтому нам пришлось использовать API пользовательских метрик, чтобы обеспечить метрику количества запросов в секунду для каждого приложения.
Реализация сервера пользовательских метрик
Чтобы HPA мог считывать целевую метрику из API пользовательских метрик, должна быть реализована реализация сервера пользовательских метрик для считывания и обслуживания требуемых данных метрик. В нашем случае Адаптер Prometheus выполняет эту работу, поскольку мы уже передавали Prometheus метрики запросов Nginx.
Адаптер Prometheus легко устанавливается через Helm, см. файл values.yaml. Конфигурации адаптера Prometheus должны включать строку подключения Prometheus и пользовательские правила. Эти правила извлекают значения метрик из Prometheus и предоставляют их на сервере пользовательских метрик для использования HPA для масштабирования.
Для деталей реализации; прочтите здесь для конфигураций обнаружения, здесь для пошагового руководства по настройке и здесь для полного пошагового руководства по автомасштабированию с использованием пользовательских метрик. Также есть хороший файл README другой реализации, в котором объясняется, как работает Custom Metrics Server в Kubernetes.
rules: default: false custom: - seriesQuery: 'nginx_ingress_controller_requests{namespace!="",service!=""}' resources: overrides: namespace: resource: "namespace" service: resource: "service" name: matches: "nginx_ingress_controller_requests" as: "nginx_ingress_requests_per_second" metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>)'
Приведенное выше специальное правило извлекает серию nginx_ingress_controller_requests из Prometheus, объединяет ее по пространству имен/службе и возвращает запросов в секунду, измеренных за последние 5 минут, используя скорость. функция запроса Prometheus. Переименование в конце позволяет нам использовать выходные данные запроса как nginx_ingress_requests_per_second в конфигурациях HPA.
apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: model-serving-deployment minReplicas: 1 maxReplicas: 50 metrics: - type: Object object: metric: name: nginx_ingress_requests_per_second describedObject: kind: Service name: model-serving-deployment apiVersion: v1 target: type: AverageValue averageValue: 20000m
Последним шагом является развертывание HPA, нацеленного на развертывание (model-serving-deployment в конфигурации) с использованием нашей пользовательской метрики nginx_ingress_requests_per_second. Обратите внимание, что spec.scaleTargetRef используется для таргетинга развертывания для HPA, а spec.metrics.object.desiredObject используется для получения правильных метрик службы из Custom Metrics API.
Используя AverageValue в качестве целевого типа, мы запрашиваем усреднение метрики по всем модулям в службе. Установив для параметра spec.metrics.object.target.averageValue значение 20 000 м, мы требуем, чтобы HPA увеличивалось и уменьшалось, чтобы поддерживать среднее количество запросов в секунду между модулями на уровне около 20 RPS в пределах 1 – Ограничение на 50 реплик pod.
Конечно, поскольку это пример, количество реплик и целевое значение должны быть настроены в соответствии с ограничениями вашего приложения, которые можно измерить, выполнив нагрузочный тест.
Заключение
Существует множество способов развертывания моделей машинного обучения в рабочей среде, и оболочка API — один из них. Удобным способом развертывания контейнерных приложений является использование Amazon EKS для управляемого кластера Kubernetes. Каждое приложение имеет свое узкое место и, следовательно, требует различных стратегий для увеличения и уменьшения масштаба или даже масштабирования вверх и вниз. Пропускная способность сети является надежной метрикой для масштабирования сервисов API, и ее также можно использовать в Kubernetes. Для масштабирования каждой службы в соответствии с пропускной способностью их сети можно определить пользовательскую метрику. Простое решение для реализации пользовательских метрик — использовать адаптер Prometheus, если вы используете Prometheus для журналов временных рядов входных запросов. Затем вы можете использовать заданную пользовательскую метрику для масштабирования любого развертывания в вашем кластере Kubernetes.