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

Глядя на прогноз Gartner: «Около 10% корпоративных данных создается и обрабатывается за пределами традиционного централизованного центра обработки данных или облака. К 2025 году Gartner прогнозирует, что этот показатель достигнет 75%». Подводя итог, они ожидают, что большая часть обработки данных будет выполняться на периферии. Цифра прогноза настолько высока из-за растущего объема производимых данных — невозможно отправить их все в центральный центр обработки данных для обработки.

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

  • Камеры с обработкой видео с использованием аппаратного ускорения на GPU
  • Обращенные к покупателям помощники по покупкам с чат-ботами и большими языковыми моделями
  • MTL реализован на заводе-изготовителе с использованием сетей 5G и MEC

Несмотря на преимущества и растущую популярность, размещение моделей машинного обучения на периферии сопряжено со многими рисками. Один из главных — безопасность. Вы можете узнать больше о снижении рисков безопасности для моделей машинного обучения в недавней статье.

Полноценный стек MLOps требует много ресурсов и не может вписаться в пограничный сайт, верно? Не совсем так. В этом сообщении в блоге показано, как включить ключевые возможности, необходимые для пограничных сайтов, такие как обслуживание моделей, без необходимости развертывания полного стека MLOps.

Давайте создадим Edge Site!

В этом практическом руководстве мы будем использовать AWS EC2 для предоставления нам виртуальной машины. Давайте создадим экземпляр t2.medium с общедоступным IP-адресом. Для этого пограничного сайта требуется около 2 ГБ памяти, и он готов к размещению нескольких моделей. Чем больше моделей вы размещаете, тем больше памяти и ЦП потребуется. Мы будем использовать Ubuntu 22.04 LTS в качестве ОС и установим большинство необходимых инструментов с помощью оснастки. Snaps работают на основе каналов и обеспечивают автоматические обновления внутри каналов. Таким образом, ваша среда всегда будет актуальной. Удобно, правда?

Кроме того, не забудьте позаботиться о группах безопасности, поскольку вам потребуется доступ к виртуальной машине с использованием порта 22 для SSH и портов 30000–32767 для NodePorts. Вы должны добавить их как правила входа в группу безопасности и прикрепить эту группу безопасности к экземпляру.

Все коды доступны в репозитории Github.

Подготовьте среду

Первый шаг — установить MicroK8s, легкий кластер Kubernetes. Благодаря небольшим требованиям к ресурсам MicroK8s идеально подходит для развертывания на периферии. MicroK8 обеспечивают удобный способ расширения базовых кластеров классом хранения на основе локального диска, поддержки графического процессора или частного реестра. Полный список дополнений доступен здесь: https://microk8s.io/docs/addons.

$ sudo snap install microk8s - channel 1.24/stable - classic
$ sudo usermod -a -G microk8s ubuntu
$ mkdir -p ~/.kube
$ sudo chown -f -R ubuntu ~/.kube
$ newgrp microk8s
$ microk8s enable hostpath-storage dns ingress

Прежде чем перейти к следующему шагу, проверьте, включены ли все ожидаемые плагины и находятся ли поды в состоянии «Работает». Вот ожидаемый результат статуса MicroK8s.

$ microk8s status
microk8s is running
high-availability: no
  datastore master nodes: 127.0.0.1:19001
  datastore standby nodes: none
addons:
  enabled:
    dns                  # (core) CoreDNS
    ha-cluster           # (core) Configure high availability on the current node
    hostpath-storage     # (core) Storage class; allocates storage from host directory
    ingress              # (core) Ingress controller for external access
    storage              # (core) Alias to hostpath-storage add-on, deprecated
  disabled:
    community            # (core) The community addons repository
    dashboard            # (core) The Kubernetes dashboard
    gpu                  # (core) Automatic enablement of Nvidia CUDA
    helm                 # (core) Helm 2 - the package manager for Kubernetes
    helm3                # (core) Helm 3 - Kubernetes package manager
    host-access          # (core) Allow Pods connecting to Host services smoothly
    mayastor             # (core) OpenEBS MayaStor
    metallb              # (core) Loadbalancer for your Kubernetes cluster
    metrics-server       # (core) K8s Metrics Server for API access to service metrics
    prometheus           # (core) Prometheus operator for monitoring and logging
    rbac                 # (core) Role-Based Access Control for authorisation
    registry             # (core) Private image registry exposed on localhost:32000

Второй шаг — установить Juju и загрузить контроллер. Juju — это инструмент автоматизации, который реализует основанный на моделях подход к развертыванию приложений на виртуальных машинах и в кластерах Kubernetes. Он поддерживает развертывание, интеграцию между приложениями и операции второго дня, такие как резервное копирование, изменение конфигурации и обновления.

$ sudo snap install juju --classic
$ juju bootstrap microk8s micro
$ juju add-model kubeflow

У вас есть готовый кластер Kubernetes и загруженный контроллер Juju, теперь пришло время развернуть пакет. Пакет — это компонуемый набор приложений с определенными взаимодействиями между ними, называемыми отношениями. Ключевым аспектом пакетов juju является их компонуемость. Пакет корректируется для каждой среды и варианта использования. Сейчас мы развертываем пакет, содержащий только самое необходимое для периферийного развертывания: Seldon Core и Istio. Если мы хотим добавить аутентификацию, мы можем добавить дополнительные приложения, такие как dex и oidc-gatekeeper, и связать их с Istio. Один и тот же пакет можно повторно использовать между несколькими пограничными сайтами, чтобы обеспечить согласованную среду для пограничных операций.

$ juju deploy ./bundle.yaml

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

$ juju status
Model     Controller  Cloud/Region        Version  SLA          Timestamp
kubeflow  micro       microk8s/localhost  2.9.42   unsupported  11:41:03Z

App                        Version                Status  Scale  Charm          Channel      Rev  Address         Exposed  Message
istio-gateway                                     active      1  istio-gateway  1.11/stable  285  10.152.183.119  no       
istio-pilot                                       active      1  istio-pilot    1.11/stable  302  10.152.183.254  no       
seldon-controller-manager  res:oci-image@eb811b6  active      1  seldon-core    1.14/stable   92  10.152.183.133  no       

Unit                          Workload  Agent  Address       Ports              Message
istio-gateway/0*              active    idle   10.1.121.233                     
istio-pilot/0*                active    idle   10.1.121.229                     
seldon-controller-manager/0*  active    idle   10.1.121.228  8080/TCP,4443/TCP

Проверьте службы, развернутые в пространстве имен «kubeflow», и запишите порт службы NodePort. Он понадобится вам для создания URL-адреса для доступа к развернутым моделям.

$ microk8s kubectl get svc -n kubeflow
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                 AGE
modeloperator                        ClusterIP   10.152.183.248   <none>        17071/TCP                               40h
istio-gateway                        ClusterIP   10.152.183.119   <none>        65535/TCP                               39h
istio-gateway-endpoints              ClusterIP   None             <none>        <none>                                  39h
istio-pilot                          ClusterIP   10.152.183.254   <none>        65535/TCP                               39h
istio-pilot-endpoints                ClusterIP   None             <none>        <none>                                  39h
istiod                               ClusterIP   10.152.183.156   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP   39h
istio-ingressgateway-workload        NodePort    10.152.183.183   <none>        80:31788/TCP,443:32475/TCP              39h
seldon-controller-manager-operator   ClusterIP   10.152.183.179   <none>        30666/TCP                               39h
seldon-controller-manager            ClusterIP   10.152.183.133   <none>        8080/TCP,4443/TCP                       39h
seldon-webhook-service               ClusterIP   10.152.183.223   <none>        4443/TCP                                39h

Развертывание модели машинного обучения

Мы собираемся использовать Seldon Core для развертывания нашей модели на периферии. Мы можем развернуть ту же модель без использования Seldon Core, но стоит ли Seldon Deployment усилий?

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

Унификация контрактов API

Seldon Core обеспечивает уровень абстракции для API HTTP и gRPC. Это означает, что вы можете свободно изменять базовые платформы машинного обучения без переопределения контракта API. Это дает вам возможность экспериментировать с различными платформами, чтобы получить наилучшие результаты и предоставить согласованный сервис API для людей, использующих эту конечную точку.

Конечная точка метрик

Seldon Core предоставляет конечную точку Metric для каждого из своих развертываний. Он поддерживает базовые метрики, такие как количество обработанных запросов и пользовательские метрики. О том, как определить пользовательские метрики, смотрите здесь.

Пользовательские метрики Seldon — отличный инструмент для определения детальных метрик мониторинга и повторного использования интеграции для их визуализации с помощью Prometheus и Grafana.

Интеграция с Истио

Seldon Core легко интегрируется с Istio, чтобы обеспечить сетевой уровень для доступа к модели. Istio — это ключевой компонент для предоставления таких функций, как A/B-тестирование. Кроме того, для нашего практического опыта это позволит нам предоставлять несколько моделей на одном и том же NodePort без необходимости использования отдельного входного контроллера, такого как NGINX.

Istio позволяет нам интегрироваться с компонентами oidc-gatekeeper и dex-auth для обеспечения аутентификации и интеграции с внешними поставщиками удостоверений LDAP и OIDC.

Мультимодельные развертывания

Seldon Core известен как развертывание на основе графа. Это означает, что в Seldon Deployment вы можете развернуть не только одну модель, но и набор преобразователей, моделей и объединителей для создания расширенных и автономных развертываний с несколькими моделями. Все развернутые модели позволяют установить интеграцию с Jaeger или обеспечить слышимость с интеграцией Open Search.

Документация OpenAPI для каждой конечной точки

Для каждого развертывания Seldon доступны 3 функции. «Прогноз» для создания выводов о модели, «Обратная связь» для отправки отзыва или расчета показателей, а «Документация» предоставляет документацию на вашу конечную точку в формате OpenAPI/Swagger.

Вы развертываете модели с помощью Seldon Core, применяя файл yaml с подробностями Seldon Deployment. Далее, пусть CRD делают всю работу.

$ microk8s kubectl apply -f - << END
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
  name: seldon-deployment-example
spec:
  name: sklearn-iris-deployment
  predictors:
  - componentSpecs:
    - spec:
        containers:
        - image: seldonio/sklearn-iris:0.3
          imagePullPolicy: IfNotPresent
          name: sklearn-iris-classifier
    graph:
      children: []
      endpoint:
        type: REST
      name: sklearn-iris-classifier
      type: MODEL
    name: default
    replicas: 1
END

Развернутая модель недоступна снаружи кластера. Мы будем повторно использовать шлюз Istio, чтобы предоставить его с префиксом. Префикс позволяет нам выставлять несколько моделей, используя один и тот же шлюз. Каждая из виртуальных служб указывает на другую развернутую модель. Модели выбираются на основе записи DNS службы Seldon Deployment, что позволяет нам использовать сине-зеленый механизм развертывания Kubernetes.

$ microk8s kubectl apply -f - << END
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: iris-server
  namespace: default
spec:
  gateways:
    - kubeflow/kubeflow-gateway
  hosts:
    - '*'
  http:
    - match:
        - uri:
            prefix: /model/iris/
      rewrite:
        uri: /
      route:
        - destination:
            host: seldon-deployment-example-default.default.svc.cluster.local
            port:
              number: 8000
END

Позвоните модели

Прежде чем мы вызовем модель, нам нужно создать правильный URL. Мы создадим URL в три шага. Первый — получить IP-адрес виртуальной машины, используемой в качестве пограничного сайта. Второй — проверить порт, используемый для службы шлюза Istio. В комплекте мы выбрали способ предоставления сервиса как NodePort. Если вы хотите узнать больше о способах раскрытия приложения Kubernetes, отметьте здесь.

Получите общедоступный IP-адрес для экземпляра EC2.

Получите порт шлюза Istio.

$ microk8s kubectl get svc istio-ingressgateway-workload -n kubeflow
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                 AGE
istio-ingressgateway-workload        NodePort    10.152.183.183   <none>        80:31788/TCP,443:32475/TCP              26m

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

# URL: http(s)://<NodeIP>:<NodePort>/<IstioVirtualServerPrefix>/api/v0.1/predictions
$ curl  -s https://3.249.66.169:31788/model/iris/api/v0.1/predictions  \
  -H "Content-Type: application/json"  \
  -d '{"data":{"ndarray":[[5.964,4.006,2.081,1.031]]}}'

{"data":{"names":["t:0","t:1","t:2"],"ndarray":[[0.9548873249364059,0.04505474761562512,5.7927447968953825e-05]]},"meta":{"requestPath":{"sklearn-iris-classifier":"seldonio/sklearn-iris:0.3"}}}

Вуаля!

Краткое содержание

Мы создали полностью работающий пограничный сайт, способный размещать несколько моделей без дополнительных ресурсов для ненужных функций, таких как среда для экспериментов. Развернутые модели доступны внешнему миру, все они имеют стандартную структуру API и позволяют вносить изменения в используемые для их реализации фреймворки без изменения API.

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

Вот несколько идей по расширению возможностей пограничного сайта с помощью возможности компоновки пакета Juju:

  • Наблюдаемость с помощью COS
  • Аутентификация с помощью шармов dex-auth и oidc-gatekeeper
  • Бессерверные контейнеры с использованием шарма KNative и реализация Data Drift на этом примере

Продолжайте экспериментировать с инструментами с открытым исходным кодом и делитесь своими результатами!

Свяжитесь со мной через каналы социальных сетей, указанные здесь.