August 11, 2022

Google AI4Code или мой первый раз на Kaggle

Вчера наконец-то закончилось трехмесячное соревнование от гугла по машинному обучению, где нужно было написать программу, которая умеет понимать взаимосвязь между питоновским кодом и комментариями к нему. На вход вашей программе давался Python ноутбук, который состоит из клеток с кодом и клеток с текстом. Клетки с кодом даны в том же порядке, в котором они были в исходном ноутбуке. А клетки с текстом случайно перемешаны. Цель вашей программы — как можно точнее восстановить исходный порядок.

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

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

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

О чем написать?

За прошедшие три месяца случилось довольно много интересных историй, и уместить их все в один пост явно не получится (ну либо его никто не дочитает до конца). Так что я постараюсь какую-то часть написать в этот пост, а потом, возможно, напишу еще отдельных историй (ставьте лайки и пишите о чем интересно почитать!).

Bad setup

Я потратил очень большое количество времени просто на то, чтобы сделать удобной разработку. Kaggle предоставляет возможность создавать jupyter ноутбуки и даже бесплатно запускать их. Они даже дают возможность пользоваться их gpu (30+ часов в неделю). Это прикольно, потому что можно сразу начать что-то делать, но на самом деле это ужасно не удобно.

  • Во-первых, все тормозит. Запускаешь клетку ноутбука, ждешь секунду пока она исполнится. С одной стороны можно потерпеть, но с другой — это реально существенно замедляет процесс.
  • Во-вторых, когда ноутбук становится длиннее клеток 20, им становится невозможно пользоваться. Начинаешь запускать клетки в неправильном порядке, какие-то инварианты глобальных переменных ломаются, потом очень долго дебажишь.
  • В-третьих, нет нормальной возможности сохранить промежуточные данные куда-то на диск. Есть какое-то временное хранилище пока ноутбук работает, но если хочется переиспользовать данные, их нужно скачать/сохранить куда-то отдельно. По умолчанию, максимально ноутбук может работать 9 часов, а потом выключится.
  • В-четвертых, нет нормальной возможности версионирования и хранения кода. Пусть у меня есть код, который генерирует какую-то модель, и код, который ее проверяет. На Kaggle это должно быть два отдельных ноутбука, чтобы второй мог использовать модель, который сгенерил первый. Но если я хочу переиспользовать часть кода (например, который считывает данные или считает статистику), его нужно будет скопировать.
  • В-пятых, gpu, который Kaggle предоставляет бесплатно, P100, не то чтобы очень крутые.

В общем, если бы я мог путешествовать во времени, и дать себе один совет, это явно был бы "не использовать Kaggle для запуска кода".

Better setup?

Я вряд ли пришел к идеальному варианту, но в итоге получилось так:

  • Весь код лежит в репозитории на github.
    • Общий код лежит в .py файлах.
    • Под каждый отдельный эксперимент есть свой .ipynb файл (в котором желательно не больше ~10 клеток).
    • Чтобы подключать .py файлы из .ipynb, можно пользоваться этими магическими командами:
%load_ext autoreload
%autoreload 2
  • Редактировал и писал новый код я в основном локально (latency гораздо лучше чем на Kaggle!).
  • Чтобы запускать код, я арендовал сервер на https://jarvislabs.ai/
    • Сервер с gpu A6000 (у которого 48Gb памяти вместо 16Gb на Kaggle) стоит ~1$/час. В итоге я суммарно потратил где-то 200$, но я не особо пытался экономить.
    • У них есть persistent storage, так что если сервер выключить, а потом включить — данные будут на месте.
    • На сервер можно заходить по ssh. Оказывается у ssh есть замечательный ключ -A, который форвардит локальные ключи на сервер, к которому подключаешься. Например, если хочешь выкачать приватный github репозиторий на сервер, но не хочешь добавлять в github профиль ключ с этого сервера, то -A это то, что нужно.
  • Когда все-таки хочется скачать с/на cервер что-то большое, можно пользоваться scp, но он тормозит (видимо потому что сервера стоят где-то в Индии), а хорошо работает Google Drive Cli. Правда безопасность этого решения несколько сомнительная.
  • Я не придумал как нормально сабмитить свое решение на Kaggle. Сабмитить нужно один ноутбук, а в репозитории код лежит в нескольких файлах. Если их в тупую собрать в один файл, то могут появиться функции с одинаковыми именами. Или будут какие-то лишние инклуды. В итоге я фиксил это все руками, но скорее всего можно как-то лучше.

Графики!

По жизни я очень люблю визуализировать данные и считаю, что обычно это путь к успеху.

В этот раз я пользовался https://wandb.ai/ и он очень клевый! В нем очень просто логировать данные во время экспериментов, а потом визуализировать и строить дашборды.

Например как-то так выглядели графики с результатами разных моделей:

На самом деле он интерактивный и в нем можно что-то понять, честно-честно!

Если зазумить, то будет так:

Тут на графике каждая линия — какая-то отдельная модель, которую тестируем. А значение — средний скор модели на Х ноутбуках. "Настоящий" скор модели мы бы получили, если бы посмотрели на значение при X=+infinity, но тестирование довольно долгое, поэтому хочется уметь быстрее понимать, получилась ли модель лучше чем другая.

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

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

А еще иногда можно заметить, что график одной модели в точности совпадает с графиком другой, и понять, что в эксперименте явно что-то пошло не так (например, мы почему-то тестируем другую модель).

В следующей серии?

  • Какое в итоге было решение.
  • Как я визуализировал данные и ничего полезного из этого не получил :(
  • Сколько раз я долго искал какие-то баги, потому что привык к нормальным языкам программирования, а не к питону.
  • Как я пробовал сделать что-то более сложное, но ничего не работало :(

Если вы дочитали до сюда, то подписывайтесь на мой канал https://t.me/bminaiev_blog