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

Не лучше дело обстоит и с эксплуатацией. Например, такие прикладные киберфизические системы, как Промышленный интернет, сети беспилотного транспорта и «умные» города, генерируют огромные потоки данных и выполняют большие объемы специфических вычислений. Как снизить стоимость и энергозатраты на исполнение поддерживающих их приложений реального времени, анализирующих мультимедийные потоки или обрабатывающих числовые ряды (потоки значений со счетчиков)? Сегодня на граничных устройствах таких комплекcов (точки наблюдения, специализированные серверы в микроЦОДе, расположенном в непосредственной близости от базовых станций сети последней мили и пр.) начинают активно применяться решения ИИ. Полезные данные в каналах ввода от подобных устройств сильно разрежены: во времени — параметры изменяются редко; в пространстве кадра — большие участки визуального или звукового пространства кадра не содержат какой-либо информации; в обработке — в любой период львиная часть соединений глубинных нейронных сетей может быть неактивна. «Умное» профилирование нагрузки и конфигурирование FPGA с учетом разреженности всех трех типов позволяют существенно снизить энергоэффективности и стоимость решения.

Использование ИИ как в процессе эксплуатации, так и создания ИТ-активов компании потенциально способно решить проблему сложности, повысив, в частности, скорость разработки ПО на фоне увеличения общей сложности киберфизических систем. Здесь под киберфизической системой понимается программно-аппаратный комплекс из датчиков, приводов, вычислительного оборудования, ПО и коммуникационных сетей. Цель построения такой системы — интеграция механизмов, характерных для программных систем принятия решений, в физические процессы реального мира. Например, такие задачи цифровой трансформации, как гиперавтоматизация, умный город и пр., решаются именно на базе киберфизических систем.

Включение решений ИИ в жизненный цикл прикладных систем, начиная от разработки и заканчивая безопасным выводом приложения из эксплуатации в продуктивных средах, способно преобразовать всю традиционную систему программирования. Под «системой» здесь понимается единый технологический стек, содержащий группу согласованно взаимодействующих программных систем, обеспечивающий исполнение сцепленных между собой операций и субпроцессов для автоматического выполнения процесса как единое целое; под «разработкой» понимается комплекс субпроцессов, таких как кодирование, тестирование, интеграция и размещение программных систем в тестовых средах; под «эксплуатацией» — комплекс субпроцессов, таких как размещение на продуктивных средах, изоляция по данным и контроль доступа в коммунальной среде для арендаторов (тенантов), фиксация инцидентов и аномалий, автомасштабирование приложений и управление отказами. Решения ИИ — это специализированные инструменты, исполняющие одну или более операций, один или более субпроцессов.

Включение ИИ в жизненный цикл программных систем означает изменение процессов управления и новое разделение труда — новые инструменты разработки и эксплуатации, новые ролевые модели команд разработки и эксплуатации, новые навыки и квалификации. Но главное, новую инфраструктуру, управляемую искусственным интеллектом (AI driven) [1, 2].

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

Использование ИИ в разработке возможно по следующим направлениям:

  • автозаполнение кода (code completion);
  • трансляция кода (code translation);
  • генерация заглушек (mock generation);
  • кодогенерация (code generation);
  • выявление уязвимостей (vulnerabilities detection);
  • суммаризация кода (code summarization).
  • Применение ИИ в эксплуатации:
  • масштабирование сервисов (services autoscaling);
  • автоматическая обработка отказов (automatic failover);
  • авторегистрация неисправностей (automatic troubleshooting);
  • выявление утечек конфиденциальной информации (data leak prevention);
  • выявление аномалий (anomaly detection).

«Умная» разработка

Автозаполнение кода — автоматическое завершение блока кода за программиста. Разработчик начинает писать новую строку кода, ИИ-модуль распознает начало конкретной конструкции и предлагает автоматически ее завершить. Автозаполнение реализуется через плагины интегрированных сред разработки, например таких как IntelliJ IDEA или PyCharm, при этом в состав плагина входит ИИ-модуль, обученный на открытых или корпоративных репозиториях конкретного языка программирования. Автозаполнение существенно экономит время программиста и исключает ошибки в параметрах вызовов функций и реализации автоподставляемого блока кода.

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

Трансляция кода предполагает преобразование кода на одном языке программирования или фреймворка в код на другом. Такая трансляция реализуется при помощи утилиты, которая подключается к конвейеру CI/CD и содержит соответствующий ИИ-модуль. Трансляция существенно экономит ресурсы на перенос приложения между технологическими стеками. Например, для ускорения и снижения стоимости разработка выполняется на Python/Django/Postgres, а затем полученный код транслируется на промышленные стеки Java/Spring/Oracle или C#/ASP.NET/SQL для разных аппаратных платформ.

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

Кодогенерация — часть процесса компиляции. Сегодня кодогенерация широко используется в составе инструментального стека разработчиков и может быть определена как процесс автоматического создания программного кода на основе внешнего представления. Самые популярные варианты внешнего представления — это декларативные программы в формальном машинном описании (XML, JSON, YAML и пр.) и CASE-инструменты (ARIS, System Architect, RPA-конструкторы и пр.). Например, компания OpenAI представила проект кодогенератора Codex, созданного на базе архитектуры GPT-3 и обученного на кодовой базе открытых репозиториев GitHab. Codex получает на вход корректные высказывания на английском языке, а выдает готовый к исполнению текст программы на Python или JavaScrip. Результаты публичных тестов Codex вызвали большой интерес в сообществе разработчиков — такой подход кардинально меняет устоявшуюся практику создания программ, когда транслятором низкоуровневой архитектуры в исполняемый код выступает программист, а сам процесс весьма затратен и чреват высокими рисками, вызванными человеческим фактором. В ряде случаев можно полностью заменить традиционное программирование вручную, особенно если речь идет о тиражировании ПО для разных аппаратных платформ или адаптации программы к работе в условиях конкретных граничных условий (например, объема кэш-памяти).

Кодогенерация возможна и с голоса (Natural-language understanding, NLU — «понимание естественного языка»), когда программа формируется путем ее озвучивания специалистом в прикладной области. До полной замены программиста, конечно, пока далеко — за человеком остается функция формализации предметной области, однако NLU позволит сократить число ошибок на пути от идеи (модели) до текста программы реализации конкретного сервиса. Машинное обучения занимает существенную долю в этом процессе, но творческие задачи пока еще остаются за человеком. Кодогенерация все еще требует от человека оценки результата — модели могут обучаться на github и понимать, что можно использовать определенный код, но они еще не могут оценить его качество для решения конкретной задачи.

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

Суммаризация кода — формирование краткого содержательного описания блока кода на естественном языке для формирования комментария к этому блоку, соответствующего индустриальным и/или корпоративным стандартам. Суммаризация помогает упростить и ускорить процесс вовлечения новых сотрудников в поддержку или доработку кода. Такое направление использования ИИ позволяет сохранить инвестиции в унаследованные программы.

«Умная» эксплуатация

Масштабирование сервисов реализуется путем масштабирования по данным и по вычислительной мощности.

Масштабирование по данным («шардирование данных») — горизонтальное разделение данных на разделы, при котором логически независимые блоки, например строки таблиц, хранятся раздельно, заранее сгруппированные в секции. При этом секции размещаются на разных серверах базы данных, а один физический узел вычислительного кластера может содержать несколько логических серверов (инстансов) баз данных. Для реализации шардирования необходимо на прокси-сервере, получающем запросы к базе данных, решать задачу выбора раздела (шарда) для переадресации запроса. Наиболее простым в реализации методом идентификации шарда является применение хеш-функции от идентификационных данных наиболее популярной (важной) сущности, например, хеш от суррогатного идентификатора клиента. При этом вычисленный хеш от идентификатора клиента позволяет однозначно привязать конкретного клиента и все его данные к конкретному шарду, тем самым обеспечив практически независимую от количества клиентов и их данных горизонтальную масштабируемость базы данных.

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

Масштабирование по вычислительной мощности — основная задача эластичных ИТ-инфраструктур. Традиционный подход здесь — настройка политик масштабирования на вычислительном кластере. Допустим, задаетcя политика — при превышении на прокси-сервере вычислительного кластера количества входящих запросов до значения 'N/с' необходимо запустить еще одну реплику определенной группы сервисов. Для пользователей приложение отвечает быстро, и все выглядит хорошо, пока нагрузка растет или снижается плавно, а для «прогрева» сервисов приложения не требуется много времени. Однако когда нагрузка стремительно изменяется и вновь запущенным сервисам необходимо загрузить данные в свою кэш-память, а подсистемам ИИ, используемым в сервисах, загрузить свои файлы весов и инициализироваться, это может занять достаточно продолжительное время. Поэтому для обеспечения требуемого качества услуги необходимо заранее спрогнозировать момент запуска новых реплик сервисов. Для этого используют ИИ-модули. Для наполнения кэш-памяти актуальными данными необходима «прогревающая» нагрузка, которая по составу и разнообразию данных должна быть похожа на рабочую. Для генерации такой нагрузки также могут быть использованы ИИ-модули.

Автоматическая обработка отказов — аварийный перевод трафика или нагрузки на заведомо работоспособный альтернативный ресурс. При авариях оборудования или сбоях в инфраструктуре высока вероятность потери запросов от пользователей и отката активных транзакций баз данных. Чтобы этого избежать и обеспечить требуемый уровень сервиса, используется прогнозирование наступления аварий на основе анализа аномалий в поведении оборудования, приложения и инфраструктуры в целом. Для этого используются ИИ-модули. Еще до момента сбоя запускается сценарий обработки отказа — старт новой реплики приложения или группы сервисов, после «прогрева» которых прикладной трафик переводится с аварийного ресурса на новую реплику. После полного перевода трафика и фиксации всех транзакций аварийный ресурс исключается из сценария использования.

Авторегистрация неисправностей — автоматическое выполнение следующих процессов: сбор доступной контекстной информации об аномалии после получения уведомления от детектора аномалий; квалификация аномалии на предмет наличия инцидента; регистрация инцидента в системе ITSM; уведомление исполнителя об инциденте. Для квалификации аномалии в инцидент может быть использован детектор инцидентов на основе ИИ-модуля, как и для маршрутизации уведомления об инциденте может быть использован классификатор также на основе ИИ-модуля, который по содержанию уведомления определяет конкретного исполнителя, ответственного за данный узел или сервис.

Выявление утечек конфиденциальной информации — классическая задача информационной безопасности, но в случае, когда в компании используется более двух систем DLP, специализирующихся на конкретных типах утечек (в офисных файлах, мультимедиа, BIM-моделях, программном коде и др.), может потребоваться классификация, выполняемая ИИ-модулем, назначающим целевую DLP и уведомляющим ее о рисках утечки конкретного вида.

Выявление аномалий — классическая задача для машинного обучения, решаемая при автоматической обработке отказов и авторегистрации неисправностей. На предмет первичных признаков аномалий анализируется максимум доступных данных: метрики потребления ресурсов арендаторами, приложениями или отдельными сервисами; записи логов с прикладных или инфраструктурных сервисов; телеметрия ИТ-оборудования. После выявления первичные признаки аномалий агрегируются, выравниваются по шкале времени и передаются детектору аномалий для точной идентификации аномалии и генерации соответствующего события. Детектирование аномалий и выполнение анализа первого уровня — это задача ИИ-модулей. Событие об аномалии используется для старта политик обработки сбоев и авторегистрации неисправностей.

***

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

Литература

1. Александр Прозоров, Роман Шнырев, Дмитрий Волков. Архитектура цифровых платформ будущего // Открытые системы.СУБД. — 2021. — № 2. — С. 24–28. URL: https://www.osp.ru/os/2021/02/13055934 (дата обращения: 20.03.2022).

2. Александр Прозоров, Роман Шнырев, Илья Алексеев. Базовая инфраструктура современных цифровых платформ // Открытые системы.СУБД. — 2021. — № 4. — С. 15–19. URL: https://www.osp.ru/os/2021/04/13056073 (дата обращения: 21.03.2022).

Александр Прозоров (aalprozorov@sberbank.ru) — научный сотрудник, МФТИ; Роман Шнырев (rvshnyrev@sberbank.ru) — руководитель направления, Лаборатория новых технологических решений «Сбер»; Дмитрий Волков (vlk@keldysh.ru) — старший научный сотрудник, ИПМ им.  М. В.  Келдыша РАН (Москва).

DOI: 10.51793/OS.2022.65.68.002