Запускаем MMF

Опубликовано: Последние правки:
Опубликовано: Последние правки:
Drawing a whale with a pencil in sketch book

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

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

Подготовка

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

Архив весит 3.4 гигабайта. После скачки распаковывать его не надо, этим займется одна специальная программа из фейсбуковских инструментов. Инстументарий я ставил из исходников (дока), чтобы иметь доступ к коду и возможность подправить его в случае чего. Для работы на Windows нужно быть аккуратным, т.к. в репозитории находятся символические ссылки.

git clone --config core.symlinks=true https://github.com/facebookresearch/mmf.git
cd mmf
pip install --editable .

Подробности

Лучше чем в официальном читай-меня я нашел дальнейший план в баг-трекере проекта (тут)

mmf_convert_hm --zip_file "E:\Science\MachineLearning\Hateful Memes challenge dataset.zip" --password "<password>"
mmf_run config=projects/hateful_memes/configs/vilbert/from_cc.yaml model=vilbert dataset=hateful_memes
mmf_predict config=projects/hateful_memes/configs/vilbert/from_cc.yaml model=vilbert dataset=hateful_memes run_type=test checkpoint.resume_file=./save/vilbert_final.pth

Но каждая строчка в этом плане покрыта тайной и сопряжена с болью.

Распаковка

Начнем с утилиты mmf_convert_hm. В доках сказано, что распаковка займет время. Я сначала сам распаковал архив, потому что не планировал использовать сторонние иструменты типа MMF, поэтому уже знал сколько времени нужно для этого. Для любознательных советую открыть диспетчер задач, чтобы следить за действиями программы. Сначала она проверяет целостность архива, видно чтение с диска в диспетчере задач. Затем никакой активности на диске, занимаемая память около 116 мегабайт и не растет, только процессоры чем-то заняты. Если посмотреть на то место, где лежал архив - его нет. Программа перемещает архив в кэш C:\Users\<user name>\.cache\torch\mmf\data\datasets\hateful_memes\defaults\images. Для справки: кэш можно переназначить, задав глобальную переменную

set "MMF_CACHE_DIR=D:\mmf_cache"

Короче, это магическое дело заняло больше часа. Я пошел спать, оставив компьютер наедине с этой утилитой.

Вечером следующего дня глянул в код этого "конвертера". Там есть комментарий

Python's zip file module is very slow with password encrypted files

И далее тулза запускает процесс unzip, который только в Линуксе делает то, что нужно. А в Виндоус такой программы нет. В итоге программа идет слишком медленным методом. Вердикт. Эту тулзу нужно использовать через MINGW как минимум. За отсутствие подобных подсказок в выводе терминала я считаю, что программистов нужно наказывать физически. Они тоже должны страдать.

Обучение

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

  • изначальные веса - 800 мегабайт (850МБ)
  • фичи - 7 гигабайт (14 гигабайт в распакованном виде)
  • натренированная модель - 900 мегабайт (950МБ)

Если место на диске закончится и программа оборвется во время распаковки архива, то в последующем программа будет думать, что файл скачен и распакован успешно (хэш распакованного файла не проверяется), попытается использовать незаконченный файл и выдаст ошибку в DataLoader. Исправить можно либо удалив 8 скачанных гигабайт и скачать еще раз, либо распаковать архив вручную (tar xf делает тоже самое, что и decompress в mmf/mmf/utils/download.py)

MINGW64 ~/.cache/torch/mmf/data/datasets/hateful_memes/defaults/features
$ tar xf features.tar.gz

При ошибке

RuntimeError: CUDA out of memory. Tried to allocate 48.00 MiB (GPU 0; 6.00 GiB total capacity; 4.66 GiB already allocated; 34.94 MiB free; 4.82 GiB reserved in total by PyTorch)

следует уменьшить размер выборки (источник)

mmf_run config=projects/hateful_memes/configs/vilbert/from_cc.yaml model=vilbert dataset=hateful_memes run_type=train_val training.batch_size=4

Можно следить за видеокартой еще через консоль C:\Program Files\NVIDIA Corporation\NVSMI>nvidia-smi.exe -l 2, хотя диспетчер задач лучше показывает.

Программа создает контрольные точки каждую тысячу итераций, поэтому всегда можно возобновить обучение. Частоту сохранений можно сократить, но для модели из моего плана программа создает файлы 2,68Гб (файл на каждую тысячу, одна копия равная самому последнему, и другая копия самого лучшего результата), поэтому можно и потерпеть. Мой любимый способ остановки питоновских программ Ctrl+C не сработал. Он сработал частично - все вычисления остановились, но программа не закрылась и не вернула мне контроль над терминалом. Можно из такого поведения сделать вывод, что основной цикл завершился, новая итерация не стартует, однако потоки остались в памяти и программа не завершится пока они живут своей жизнью.

Возобновить обучение можно командой

mmf_run config=projects/hateful_memes/configs/vilbert/from_cc.yaml model=vilbert dataset=hateful_memes checkpoint.resume_file=save\best.ckpt training.batch_size=4

Предсказание

Фиксим дефлтное значение проверенное только на Линуксе

set "MMF_SAVE_DIR=save"
mmf_predict config=projects/hateful_memes/configs/vilbert/from_cc.yaml model=vilbert dataset=hateful_memes run_type=test checkpoint.resume_file=save\best.ckpt

Что может быть хуже символических линков в репозитории? Правильно, двоеточие в именах файлов: save\\hateful_memes_vilbert_27347621\\reports\\hateful_memes_run_test_2020-07-19T21:56:11.csv

Фиксим в mmf/common/test_reporter.py строку 75. Вместо

time_format = "%Y-%m-%dT%H:%M:%S"

ставим

time_format = "%Y-%m-%dT%H_%M_%S"

чем задаем формат такой же как у логов.