Как мы в Банке «Санкт-Петербург» внедряли платформу машинного обучения

Антон Недосеков
Архитектор цифровых решений управления корпоративной архитектуры Банка «Санкт-Петербург»

Работа с моделями машинного обучения в Банке «Санкт-Петербург» ведется с 2010 года. Первопроходцами в этой области были подразделения по работе с кредитными и банковскими рисками, которые реализуют и поддерживают модели кредитного скоринга физических и юридических лиц. Самые первые модели в виде логистической регрессии реализовывались буквально на коленке: в Excel на встроенном Visual Basic. Расчет шел долго, но работал. Потом в банке начали появляться специалисты по скорингу, которые работают на R, и банк начал искать новые решения.

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

Как мы в Банке «Санкт-Петербург» внедряли платформу машинного обучения

С чего мы начали

Банк стремился взглянуть на клиента и его окружение со всех сторон. Важную роль в этом процессе играло машинное обучение: необходимо было научиться прогнозировать ряд метрик, а также понять, что предложить клиенту в будущем и в какой момент (Next Best Offer). В связи с этим мы с моим коллегой вызвались возглавить это направление и собрать всех причастных к ML, чтобы обменяться опытом, знаниями и, возможно, объединить вычислительные ресурсы.

Первым делом мы провели опрос по банку: необходимо было выявить, какие подразделения занимаются машинным обучением или хотели бы использовать результаты машинного обучения as a service в рамках проекта, а также с какими трудностями они встречаются при работе в направлении. Первым же отмеченным пунктом стали низкое качество данных и разрозненность источников.

И действительно, формализованных процедур Data Governance на тот момент в банке не было, в случае ошибок данных исправления становились в очередь доработок исходных систем-источников (а чаще исправлялись уже после перегрузки в аналитические системы), у самих же данных не было обозначенных владельцев, которые бы отвечали за качество. Было важно разобраться и с хранилищем данных. Помимо корпоративного хранилища, банк использовал хранилище аналитического CRM, где данные частично дублировались. При этом у подразделений имелись собственные базы данных «под столом», где они хранили свою специфическую для работы информацию. Логично было предположить, что для составления перечня фичей для той или иной модели приходилось объединять данные из нескольких систем и заниматься длительным анализом в попытках понять, что это вообще тут за цифры и почему они такие.

По результатам проведенного анализа банк принял решение внедрять единую платформу управления данными на основе Hadoop и платформу по работе с данными. (Про Hadoop рассказывать не буду, это тема для отдельного цикла статей. Скажу только, что Платформа Управления Данными (ПУД) на основе Hadoop должна была поcлужить основным источником витрин данных для Платформы Машинного Обучения (PML)).

Что мы хотели от PML и какие решения выбрали

Во-первых, перейти от хаоса в жизненном цикле моделей к вменяемому ModelOps с описанием, гайдлайнами и методологией без сильной привязки к языку программирования. Во-вторых, иметь четкую и прозрачную ролевую модель и разграничение ресурсов, дабы никто не смог положить работу всех подразделений или убить Prod одной неудачной строчкой кода. Ну и напоследок, бесперебойно работать и иметь SLA с поддержкой более компетентных товарищей. Из дополнительных требований со стороны информационной безопасности была работа on-prem. Ряд моделей работал на персональных данных и производных из них, поэтому их передача в облако была невозможна (или сопряжена с долгими циклами согласования и процедурами обезличивания).

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

Все эти требования, и по нашему мнению, и по мнению привлеченных для анализа контрагентов, вполне закрывались решением на основе Kubernetes: OKD (как бесплатная замена OpenShift) в качестве оркестратора, KubeFlow + Jupyter как среда ModelOps. KubeFlow прекрасно интегрируется с системами версионирования кода, что позволит нам закрыть такие задачи, как ускоренный повторный запуск и Code Review. Кроме того, функционал Pipelines позволяет проводить множество параллельных экспериментов, не отвлекаясь на ожидание завершения расчетов. Интегрированный Katib также позволяет не ждать и заниматься подбором гиперпараметров моделей в параллели с основной работой. Jupyter - де-факто стандартная IDE при работе с машинным обучением, к тому же, поддерживающая расширение функционала через плагины и сниппеты.

Как мы в Банке «Санкт-Петербург» внедряли платформу машинного обучения

Что дальше?

Итак, архитектура выбрана (KubeFlow на OKD), подрядчик выбран (GlowByte), серверы куплены. Серверы представляли из себя Supermicro на 96 ядер, 512 гигабайт оперативки, 8 десятитерабайтных медленных дисков с Nvidia Tesla T4 на борту. Под проект было решено использовать три таких сервера. Один из них к моменту начала проекта уже был занят полезной нагрузкой: на нем был собственными силами банка развернут Linux, JupyterHub и настроены подключения к базам данных для работы с имеющимися моделями. Он должен был войти в кластер после приемо-сдаточных испытаний. Два других были отданы подрядчику для установки OKD.

Работа закипела. Коллеги из GlowByte постоянно выкатывали релизы, которые проверялись на стороне банка практически в режиме онлайн. Достаточно быстро стало понятно, что вариант с OKD в качестве оркестратора нам не подходит. По большей части все уперлось в несовместимость версий: выбранная стабильная и проверенная версия OKD 3.11 не работала с нужной версией KubeFlow. Старая версия KubeFlow не работала с Argo CD. Кроме того, в OKD не заводилось вменяемое хранилище: Ceph и Gluster на OKD 3.11 отказались работать в режиме ReadWriteMany, и пришлось временно поставить NFS (a.k.a. No File Security). В общем, нас предупреждали, что это RND, а RND иногда имеет отрицательный результат.

Вторая версия архитектуры не заставила себя долго ждать. GlowByte успешно протестировали на собственном стенде OKD 4.4 и предложили реализовать платформу на этой версии оркестратора. С единственной оговоркой: OKD 4.4 требует больше двух машин, а у нас только две железки под эксперименты и одна под рабочей нагрузкой. Отступать нам было некуда, сильно менять архитектуру - некогда. Выход из проблемы - виртуализация. Две железки были нарезаны на несколько виртуальных машин. Тут всплыло второе концептуальное ограничение: среда виртуализации в банке только MS Hyper-V. Это в какой-то мере негативно повлияло на дальнейшую архитектуру, но об этом позже.

Опять пропущу TL/DR по технической части, заменив на краткое резюме. Установка OKD в облаке (будь то AWS или Azure) проводится легко, только если это классическое облако. У нас же baremetal с виртуализацией и рядом ограничений по политикам безопасности. После месяца безуспешных попыток инициализировать кластер не удалось. Логи инсталлятора давали мало информации, произвольные версии компонентов под OKD не заводились, в нем жесткая привязка к версиям. Время идет, бизнес ждет и перебивается одним сервером, на котором уже все пользователи друг другу стали основательно мешать, задачи реализуются медленно и пробуксовывают.

Выходом для всех стала чистая установка Kubeflow с оркестратором на чистом же Kubernetes и средой исполнения Docker. Только заручившись поддержкой со стороны IT-блока, мы решились на этот шаг, т.к. чистый Kubernetes требует специфических скиллов от поддержки.

На этот раз никаких чудес, всё завелось достаточно быстро из коробки. Кроме самого KubeFlow был установлен Rancher в качестве UI администраторов, подключен корпоративный Zabbix для мониторинга событий узлов кластера, на самом кластере подняты Nexus для хранения контейнеров, Minio для артефактов, Grafana и Prometheus. Провизионингом занимался Gluster, развернутый на трех нодах. Для простого управления доступом без запоминания десятка паролей от десятка учетных записей мы провели интеграцию системы с ActiveDirectory. Что касается доступов к данным, все образы имеют на борту прописанные odbcinst.ini и odbc.ini плюс настройки kerberos.

Также мы имеем по Tesla T4 на каждом хосте. Вспоминаем, что у нас используется для виртуализации MS Hyper-V. Гипервизор не поддерживает нарезку GPU через Nvidia Grid, поэтому на каждом хосте мы сделали по толстому воркеру, в которые пробросили по одной GPU. Благо, функционал Kubeflow Pipelines позволяет забирать и отпускать ресурсы GPU динамически. Для дисковой подсистемы мы решили организовать Raid-10 на каждом хосте, что дает прирост 8x на чтение и 4x на запись.

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

Какие задачи мы успешно решили

Мы реализовали подходы к ModelOps: внедряем методологию ModelOps с версионированием кода, ревью, сборками, экспериментами и мониторингом метрик. Пользователи могут писать код на любом языке: собраны дефолтные образы под Python и R, но функционал conda и Jupyter позволяют установить любое ядро в Jupyter и использовать его.

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

Мы наладили процесс поддержки пользователей через выделенных администраторов системы с интеграцией с поддержкой контрагента через JIRA.

77
2 комментария

Комментарий недоступен

Ответить

Интересный опыт. Изначально облачную платформу раскатывать на простых виртуалках для задач энтерпрайза - это нужно быть или отбитым или сильно уверенным в успехе. Судя по тому, что вам удалось - второе. Поздравляю.
Подача тоже качественная, с долей самоиронии. Сильно в лучшую сторону отличается от слащавых историй успеха, когда рассказывают, как с пол-пинка удается завести условный Белаз, собранный из говна и палок. Честно, наглядно и назидательно.
Напоследок. А архитекторы у вас тоже в ML умеют, или это закономерный рост?

Ответить