AWS запустила Fargate в 2017 году, что позволяет запускать контейнеры без необходимости управлять серверами или кластерами. В марте 2019 года AWS также анонсировала Контейнеры глубокого обучения. Комбинируя эти два, можно построить конвейеры бессерверного машинного обучения (ML) и глубокого обучения (DL). На данный момент Fargate поддерживает только CPU и сделан запрос на поддержку GPU. В рабочих процессах ML и DL обучение и вывод - два основных компонента, где обучение требует больше вычислений, чем вывод. В этом блоге вы познакомитесь с настройкой и запуском бессерверного вывода на AWS fargate на компьютере с ЦП. Блог о бессерверном обучении будет следовать, как только Fargate получит поддержку GPU.

Выполним следующие шаги, чтобы создать бессерверную службу вывода.

Контейнер: вам понадобится контейнер, в который будет помещена ваша обученная модель. В качестве альтернативы вы можете взять стандартный обслуживающий контейнер (например, тензорный поток / обслуживание) и добавить модель в команду при запуске сервера модели, что я сделал ниже.

Кластер: давайте создадим кластер Fargate, выполнив приведенную ниже команду, или вы можете использовать кластер по умолчанию. Это просто логическая сущность, мы еще не создали никаких ресурсов.

aws ecs create-cluster --cluster-name fargate-cluster

Определение задачи: чтобы запустить контейнер в Fargate, вам необходимо подготовить определение задачи. По сути, определение задачи - это файл конфигурации, в котором вы указываете свой контейнер, лимит ресурсов и команду, которую хотите запустить внутри контейнера. Вы также можете использовать определение задачи для подключения вашего контейнера к другим сервисам AWS. Вы можете увидеть многие примеры постановки задачи здесь.

Измените номер своей учетной записи, роль в приведенном ниже определении задачи.

{
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "executionRoleArn": "arn:aws:iam::xxxxx:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
"command": [
            "tensorflow_model_server --port=8500 --rest_api_port=8501 --model_name=saved_model_half_plus_two_cpu  --model_base_path=/models/saved_model_half_plus_two_cpu"
         ],
         "entryPoint": [
            "sh",
            "-c"
         ],
      "name": "FargateTFInference",
      "image": "tensorflow/serving", 
      "memory": 10240,
      "cpu": 0,
      "essential": true,
      "portMappings": [
        {
          "hostPort": 8500,
          "protocol": "tcp",
          "containerPort": 8500
        },
        {
          "hostPort": 8501,
          "protocol": "tcp",
          "containerPort": 8501
        },
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
          "logDriver": "awslogs",
          "options": {
             "awslogs-group": "/ecs/TFInference",
             "awslogs-region": "us-west-2",
             "awslogs-stream-prefix": "ecs"
          }
      }
    }
  ],
  "volumes": [],
  "networkMode": "awsvpc",
  "cpu": "4096",
  "memory": "10240",
  "placementConstraints": [],
  "family": "FargateTFInference"
}

Я использовал официальный контейнер TensorFlow serve и добавил очень простую модель под названием половина плюс два, которая берет число, делит его на два и добавляет два.

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

aws ecs register-task-definition --cli-input-json    file://task_definition.json

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

aws ecs create-service --cluster fargate-cluster
                       --service-name tensorflow_inference 
                       --task-definition FargateTFInference:1 
                       --desired-count 1 
                       --launch-type "FARGATE" 
                       --network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxx],securityGroups=[sg-yyyy], assignPublicIp='ENABLED'}"

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

Получите внешний IP-адрес: перейдите к кластеру ECS fargate-cluster в разделе службы вы увидите службу под названием tensorflow_inference → нажмите на нем будет вкладка Задачи, в которой будет список запущенных задач. Нажмите на задачу, и у вас будет публичный IP-адрес, связанный с ней.

Выполнить вывод. Давайте выполним очень простой вывод.

curl -d '{"instances": [1.0, 2.0, 5.0]}' -X POST http://<external_ip>:8501/v1/models/saved_model_half_plus_two:predict
{
    "predictions": [2.5, 3.0, 4.5
    ]
}

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

Что дальше? Вы можете добавить приложение Elastic Load Balancer (ELB) и увеличить желаемое количество задач. Таким образом, ваш сервис будет доступен из единого ELB DNS. Вы также можете добавить в службу автомасштабирование для горизонтального масштабирования.