writeup.ai - текстовый бот с открытым кодом, который пишет вместе с вами. Он (в основном) работает на OpenAI GPT-2 и имеет дополнительные отлаженные модели:

  • Юридический
  • Копирайтинг и заявления о миссии
  • Текст песни
  • Гарри Поттер
  • Игра престолов
  • Рефераты академических исследований

Основные технические проблемы заключались в создании приложения, которое могло бы предоставить среду OpenAI GPT-2 (модель ML, генерирующую текст) быстро и одновременно для поддержки 10–20 активных пользователей. .

Зарождение:

  • Начал как предлог, чтобы узнать об обучении моделей машинного обучения в NLP (обработка естественного языка). В итоге я узнал в основном о развертывании моделей.
  • Приблизительно месяц на постройку. Неправильный. Поглотил мою жизнь три месяца.
  • Инженерам сложно оценить. Самоуверенным идиотам еще труднее оценивать (кашель).
  • К сожалению, я мало что узнал об обучающих моделях (смеется). По-прежнему ничего не знаю.
  • Многие учебные сценарии с открытым кодом (nsheppard) сделали тяжелую работу. Руководство по GPT2 от gwern оказалось бесценным в качестве учебного пособия. Еще один отличный вариант для быстрого старта - репо Макса gpt-2-simple.
  • Большая часть writeup.ai имеет открытый исходный код. Я добавил соответствующие ссылки, чтобы извлечь уроки из моих ошибок / неудач уроки. Я также добавил прямые ссылки на код в GitHub.

Ссылки. Это с открытым исходным кодом!

Приложение - https://writeup.ai
Frontend Repo
Backend Repo

Задний план:

  • Слишком много лет делал веб-приложения на React, Django, Flask.
  • Новичок в машинном обучении (ML) и MLOps (DevOps), поэтому читайте любые советы со здоровым скептицизмом.

Читатель:

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

Предостережения:

  • Список для краткости.
  • Полные фразы, а затем сокращения. IE. машинное обучение (ML) ›ML
  • В большинстве случаев модель означает модель машинного обучения. Написание «модели машинного обучения» было лишним.
  • Привязка к продавцу реальна. Так понравилась Google Cloud Platform (GCP), расставаться не собираюсь. Некоторые советы ориентированы на GCP.
  • GCP развертывает и масштабирует ресурсы машинного обучения лучше, чем предыдущий опыт AWS.
  • Пишите, пишите в Твиттере, комментируйте все, что хотите уточнить.

Техническая архитектура:

  • Фронтенд (ReactJS) присоединяется к WebSocket на бэкэнде (Django). Обменивается данными с серверной частью через WebSockets. Код Frontend | Бэкэнд-код
  • Бэкэнд анализирует и сериализует запросы внешнего интерфейса. Пакеты сообщения (текст, алгоритм, настройки) и канал WebSocket в балансировщик нагрузки Google. Бэкэнд-код
  • Балансировщик нагрузки передает соответствующие микросервисы (малый, средний, большой, Гарри Поттер, юридический и т. Д.).
  • Микросервисы периодически обновляют веб-сокет предлагаемыми словами в режиме реального времени. Это создает эффект «потокового» воспроизведения.
  • Фронтенд получает обновленные сообщения WebSocket от микросервисов.
  • Каждая модель машинного обучения (малая, средняя, ​​большая, «Гарри Поттер», юридическая, исследовательская) - это микросервис. Автоматическое масштабирование при использовании.
  • Пытался сделать бесчисленное количество итераций быстро (э-э).
  • Я вообще не люблю микросервисные архитектуры (добавляет дополнительную сложность). Несмотря на все усилия, для повышения производительности была необходима микросервисная архитектура.
  • Запросы и вычислительные затраты микросервиса принципиально отличаются от внутреннего сервера. Традиционные веб-серверы легко обрабатывают 500–5000+ запросов в секунду (см. C10K). Однако всего 50 запросов в секунду для экземпляра, на котором запущена модель объемом 1 ГБ, генерирующая 50–100 слов, может привести к поломке машины. (*)
  • Бэкэнд и микросервисы написаны на Python 3.6. Django (DRF) поддерживает серверную часть. Для микросервисов используется отдельный экземпляр сильно урезанной версии Django.
  • Все экземпляры микросервисов имеют подключенный графический процессор или ЦП Cascade Lake для запуска моделей машинного обучения. Подробности ниже.
  • Серверная часть и микросервисы размещаются на Google Cloud Platform.
  • Балансировщик нагрузки Google направляет весь трафик на микросервисы. Он выполняет маршрутизацию на основе постфикса URL-адреса «/ gpt2-medium, / gtp2-medium-hp и т. Д.». Балансировщик нагрузки также выполняет проверки работоспособности для проверки сбоев CUDA.

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

Три недели в Лиме, ​​Перу:

  • Начал серьезно заниматься программированием в начале трехнедельной поездки в Лиму, Перу. Поездка послужила катализатором.
  • Некоторые друзья начали бета-тестирование ближе к концу. Медленно и часто терпит неудачу.
  • 80% своей поездки я кодировал в коворкинге.
  • Две недели на backend и DevOps, последняя неделя на frontend.
  • Переписал DevOps по мере роста сложности.
  • В конце поездки интерфейсная часть общалась с серверной частью через запросы POST, которые ретранслировались на микросервисы.
  • Это было некрасиво и не быстро, но то, что первое сообщение пошло от начала до конца из внешнего интерфейса → внутреннего интерфейса → микросервиса, меня очень взволновало.

Версия MVP

Достижения в Лиме:

  • Разумное количество фронтенда. У него был простой текстовый редактор и варианты решений, созданные с помощью микросервисов.
  • Бэкэнд может создавать WebSockets для связи с внешним интерфейсом. В первой итерации серверная часть связывалась с микросервисом через запрос POST, а затем ретранслировала сообщение в WebSocket. Я отчаянно хотел, чтобы микросервисы были простыми и не работали с WebSockets.
  • Автоматическое развертывание через Ansible (позже переработано / удалено в скрипты запуска Google)
  • Ошибки: запускать раньше! Оглядываясь назад, я должен был начать работу после сборки в течение 4–5 недель. К тому времени это был вроде как работающий MVP, но я был напуган тем, что без всяких наворотов это было издевательством.

Правило 90/90:

Первые 90 процентов кода составляют первые 90 процентов времени разработки. Оставшиеся 10 процентов кода составляют остальные 90 процентов времени разработки. - Том Каргилл, Bell Labs

  • Инженеры плохо оценивают.
  • Сильно недооцененная сложность машинного обучения DevOps (то, что дети называют «MLOps»).
  • Вторым серьезным недооценкой было управление моей собственной нестабильностью.
  • Заставить микросервисы работать с контейнерами Docker, масштабировать и устанавливать драйверы CUDA с соответствующими моделями было неожиданно сложно.

Чтобы ml-микросервисы работали в контейнере Docker, мне пришлось:

  • Используйте собственный загрузочный образ TensorFlow с установленным CUDA.
  • Передайте специальный флаг в Google для установки драйверов nvidia (не всегда необходимо для определенных изображений)
  • Установите Docker на экземпляр GCP
  • Заменить среду выполнения docker по умолчанию на nvidia (упрощает использование docker и docker-compose).
  • Убедитесь, что докер не просто удалил мои изменения конфигурации или не вернул конфигурацию.
  • Синхронизировать GitHub с GCP; Создавайте образы Docker при нажатии.
  • Синхронизируйте ml-модели с Google Cloud Storage. Скорость чтения из хранилища и экземпляров GCP невероятно высока. Быстрее, чем AWS.
  • Извлеките предварительно созданный образ Docker, созданный из Google Cloud Build.
  • Вытащить ml-модели из Cloud Bucket и - смонтировать в Docker отдельными папками.
  • Молитесь, чтобы все требования (TensorFlow / PyTorch) были установлены правильно.
  • Сохраните HD-образ / снимки, чтобы экземпляры могли быстро выполнить «холодную» загрузку из образа.
  • Остальные традиционные DevOps (git, мониторинг, запуск контейнера докеров и т. Д.).
  • Размышляя, гораздо легче исправить эти проблемы, но в то время я понятия не имел, во что ввязываюсь.

Вышеупомянутые шаги должны быть полностью автоматизированы, иначе масштабирование не удалось. Кажется грязным (в 2019 году) писать сценарии bash как часть автоматизированного развертывания, но это необходимо при использовании автомасштабирования в сценариях запуска Google. Kubernetes - еще один вариант, но я недостаточно умен, чтобы использовать K8. Google startup-scripts запускает сценарий оболочки при запуске машины. Трудно использовать Ansible при автоматическом масштабировании экземпляра.

СОВЕТ: используйте URL-адрес сценария запуска! Это указывает экземпляру запустить сценарий из настраиваемого URL-адреса корзины. Это намного лучше, чем копирование / вставка вашего скрипта в интерфейс командной строки / пользовательский интерфейс GCP. Вы столкнетесь с множеством мелких изменений в сценарии запуска.

  • Настроить серверную часть было несложно. Это был мой первый опыт использования Django Channels, который настраивает WebSockets. Реквизит для Django-каналов.
  • Интерфейс занял дополнительное время из-за нестабильности функций. Я продолжал добавлять еще одну функцию, потому что боялся, что она недостаточно хороша.
  • Изначально микросервисы были написаны на Flask (потому что это то, что все предлагают). Затем я посмотрел на тесты и понял, что могу получить ту же производительность в django-rest-framework, если уберу его. Мне было намного проще иметь все в django-rest-framework (мой опыт - Django).
  • Оптимизация микросервисов заняла немного времени. Я экспериментировал с разными видеокартами, процессорами, конфигурациями памяти, изображениями. Подробнее об этом позже.

Вещи, которые стали шоком:

  • Еще два месяца назад в изображениях TensorFlow по умолчанию использовался питон 2.7.
  • В образах докеров PyTorch используется conda.
  • Переопределения, необходимые для того, чтобы среда выполнения nvidia работала с Docker.
  • Примеры открытого кода ML были повсюду. Много спагетти и клейкой ленты.
  • Образы Google TensorFlow Docker настолько оптимизированы (!), Что запускают PyTorch быстрее, чем PyTorch в официальных образах PyTorch. Это могло быть ошибкой в ​​образах PyTorch из апстрима, которые не исследовались.
  • Сборки могут быть прерваны восходящим потоком при извлечении из контейнеров Docker (TensorFlow / PyTorch). ML движется так быстро, что к этому просто привыкаешь.

СОВЕТ: старайтесь не устанавливать CUDA вручную. Используйте предустановленный загрузочный образ Google.
СОВЕТ: запишите, какая версия CUDA / другая конфигурация. Полезно для Google: нет проблем с версией CUDA + некоторые другие требования. Множество кладбищ CUDA Version Bug + Framework Version.

В целом. Когда вы узнаете, какая конфигурация (загрузочные образы, образы Docker, конфигурации Docker, CUDA) работает, все будет просто. Самое сложное - знать заранее ...

СОВЕТ. В ML есть МНОГО новой терминологии и жаргона, которые нужно усвоить. Полезно вести и писать шпаргалку с терминами. Рекомендую Интервал повторения и анки.

Профилирование логических выводов: названия GPU звучат устрашающе!

  • При запуске моделей машинного обучения в Интернете у вас есть два варианта аппаратного обеспечения: графический процессор (видеокарта) или процессор.
  • ПЛЮСЫ: графические процессоры быстрее, а производительность обычно в 5–15 раз выше, чем у процессоров. МИНУСЫ: дороже и усложняется развертывание.
  • Многие задачи машинного обучения занимают всего доли секунды (также называемые классификацией изображений). Идеально подходит для использования процессора.
  • Большинство пользователей не заметят разницы между 0,05 секунды и 0,5 секунды в асинхронной задаче. Ваша веб-страница должна загружаться БЫСТРО, но лениво загружать результат задачи.
  • Запуск средних моделей GPT-2 (1,2–1,5 ГБ) не требует быстрой загрузки ЦП. В среднем ЦП генерирует около 3–7 слов в секунду, что не является идеальным UX.
  • Выбор между Cascade Lake (процессоры Xeon последнего поколения, оптимизированные для машинного обучения), K80s, V100s или P100s в Google Cloud.
  • Эти контрольные показатели не были научной базой. Это была скорее эвристика быстрого ранжирования… написанная на салфетке.
  • Таблицы не отображаются на Medium (извините!). Cascade Lake: 8–10 слов в секунду (слов в секунду), K80: 12–24 слов в секунду, P100 слов в секунду: 32–64 слов в секунду, V100: 32–64 слов в секунду.
  • ПРИМЕЧАНИЕ. Это происходит при запуске нескольких экземпляров PyTorch. Я сделал это, чтобы сгладить использование операций блокировки CPU / GPU. Например, на одной машине с графическим процессором два экземпляра PyTorch могут сгенерировать в 1,5 раза больше, чем один экземпляр PyTorch, из-за сглаживания узких мест в ЦП / графическом процессоре. Экземпляр, работающий с одним приложением PyTorch, может генерировать 15 слов в секунду, но при наличии двух приложений Python оба могут генерировать 10 слов в секунду.
  • ПРИМЕЧАНИЕ. Я сделал огромную ошибку, но я не пробовал использовать последние версии драйверов MKL-DNN. Вы можете увидеть хороший скачок производительности. Или нет.
  • Более высокая память была полезна, поскольку количество вводимых текста увеличивалось.
  • С точки зрения стоимости цикла Cascade Lakes более экономичны по сравнению с графическими процессорами. Felt Cascade Lakes были чуть ниже порога скорости, достаточной для UX. Cascade Lakes не генерировал подсказки так быстро, как я хотел.
  • Я нашел приемлемым влияние на UX компромисса между K80s и P100 при генерации
  • Закончилось использованием в основном Cascade Lakes и K80, за исключением GPT-2 Large. Расходы.

СОВЕТ. Большинство из них можно использовать как вытесняемые, что стоит в два раза меньше. Я использовал вытесняемые компоненты большую часть времени, за исключением запуска новых продуктов.
СОВЕТ. При использовании вытесняемой программы Google будет выполнять принудительный перезапуск каждые 24 часа. Создавайте их в нечетный час, например, в 2 часа ночи, чтобы это повлияло на наименьшее количество посетителей.
СОВЕТ. Каскадные озера - вполне разумный компромисс.
CAVEAT : Эти «тесты» предназначены только для вывода (запуск модели в реальном времени). Большую часть обучения следует проводить на графических процессорах.

Правило Томсона для начинающих создателей телескопов:

«Лучше сделать четырехдюймовое зеркало, чем шестидюймовое, чем шестидюймовое». - Жемчужины программирования, сообщения ACM, сентябрь 1985 г.

  • Началось с простого: конечная точка API генерирует слова из gpt2-medium. Медленный. Задача синхронизации. Б / у Flask. Единая конечная точка.
  • Добавлен интерфейс. Будет ли запрашивать конечную точку API. Медленный. Повторяющиеся запросы могут привести к повреждению API.
  • Добавлен бэкэнд в качестве привратника для конечных точек API.
  • Конечные точки Flask переписаны в Django-DRF.
  • Встроенные django-каналы в бэкэнд для обработки веб-сокетов. Добавлен redis-cache для проверки дублирующихся запросов перед передачей на микросервисы.
  • Изменен интерфейс для связи через WebSockets.
  • Переписал сценарии развертывания из Ansible для обработки парадигмы сценариев запуска Google Cloud.
  • Интегрированные микросервисы для связи через WebSockets, также известные как «потоковая передача».
  • Обучены и добавлены дополнительные микросервисы (малый, средний, большой, юридический, письмо, гарри поттер, тексты песен, компании, xlnet)
  • Из первоначальной идеи простой конечной точки постепенно выросла сложность.

PRO: после всех этих махинаций я значительно улучшил развертывание машинного обучения.
ПРОТИВ: тесная связь с основными продуктами GCP (в частности, с хранилищем, облачной сборкой, автомасштабированием, изображениями). Тесная связь с одним поставщиком услуг не всегда идеальна (технически или стратегически).
СОВЕТ. Если вас устраивает тесная связь с продуктами GCP, вы можете создавать быстрее. Как только я согласился использовать сценарии запуска, все стало проще.
В целом: наверное, я был бы разочарован / запуган, если бы знал сложность окончательной архитектуры (и мое собственное незнание DevOps). Признать отсутствие планирования и не знаю, что я не знаю риска. Среди моих многочисленных ошибок я сделал правильно, создав приложение с простой архитектурой и постепенно усложняя его рефакторинг.

Докер! Где моя видеокарта ?! И другие сложности с развертыванием.

Примечание. И в GCP, и в Docker есть понятие образов. Во избежание путаницы я всегда объявляю GCP как загрузочные образы.

Как правило, использование контейнеров Docker помогает упростить развертывание, настройку служб и воспроизводимость кода («iuno, работал над проблемами моей машины»).

Использовать Docker в машинном обучении сложнее. Проблемы:

  • Изображения могут становиться до гротескно большими. Официальные образы TensorFlow Docker имеют размер от 500 МБ до 1,5 ГБ.
  • Большинство загрузочных образов GCP для машинного обучения не поставляются с Docker / Compose.
  • Счетчик: многие загрузочные образы, включающие Docker, не имеют CUDA.
  • Если у вас хватит смелости установить TensorFlow и CUDA с нуля, я вам аплодирую.
  • Уловка состоит в том, чтобы найти достаточно хороший загрузочный образ и установить менее сложный из двух (CUDA, Docker). В большинстве случаев Docker + Docker Tools проще установить, чем CUDA.
  • Многие модели часто имеют размер 1+ ГБ, что недопустимо для системы управления версиями. Нужны сценарии, которые синхронизируют большие модели при запуске / развертывании.
  • Легко забыть о передаче среды выполнения nvidia в Docker по командам.
  • Циклы обратной связи в DevOps намного медленнее, чем программирование. Вы можете внести изменения, понять, что допустили опечатку, и потратить еще 10 минут на развертывание. При использовании скользящего развертывания Google может потребоваться еще больше времени.

PRO: после настройки контейнеров становится на удивление надежным.
ПРОТИВ: Docker усложняет развертывание. Разумный контраргумент: если так много, почему бы не добавить Kubernetes? Ответ: я недостаточно умен для Kubernetes.
СОВЕТ: будьте внимательны и заносите каждую выполняемую вами команду оболочки в журнал Quiver (или какой-нибудь другой способ ведения записей). Скорее всего, вы скопируете и вставите свои команды десятки раз. Позже вы автоматизируете большую часть этого. Сложнее автоматизировать, если вы «вроде как» помните порядок команд.
СОВЕТ: запускайте / сохраняйте команды как абсолютные пути, чтобы избежать перезаписи неправильных каталогов. т.е. «Rsync / path1 / path2» вместо «rsync path1 path2», о, е.
СОВЕТ: если вы знаете Ansible, используйте Ansible для повторного запуска скриптов запуска Google в инвентаре. Намного быстрее, чем прокатка-развёртывание GCP.

- name: Deploy to Open
  # startup scripts does most of the hard work, but make sure 
  # you're only deploying to things that finished from startup scripts
  hosts: open_django:&finished_startup
  gather_facts: true
  become: true

  post_tasks:
    - name: Run Startup Script
      shell: |
        google_metadata_script_runner --script-type startup --debug
      args:
        chdir: /
      become: yes

СОВЕТ: уделите дополнительные часы и набросайте план

  1. где модели должны храниться на каком ведре. Рекомендуется разделять облачные сегменты для обучения и производства.
  2. где каталог bucket / должен синхронизироваться с экземплярами.
  3. если возможно, сделайте так, чтобы экземпляр имел то же местоположение, что и каталог монтирования вашего контейнера докеров. т.е. / models экземпляра монтируется на путь / models контейнера докеров
  4. напишите в корзину правильные команды rsync. Используйте rsync! (не cp). Более эффективен при перезагрузке, чем получение тех же файлов через cp.

СОВЕТ. Быстрая автоматическая проверка PyTorch (torch.cuda.is_available) или TensorFlow (tf.test.is_gpu_available) избавляет от головной боли, чтобы убедиться, что Docker использует nvidia.
В целом : в этой области, вероятно, многие веб-инженеры испытывают трудности при развертывании предварительно обученных приложений машинного обучения.

Поиск узких мест. Что ты имеешь в виду, у меня закончилась память?

  • Мониторинг загрузки традиционных веб-серверов, как правило, прост. % Использования ЦП указан на всех страницах GCP. Для памяти команда top быстро сообщает, сколько памяти используют программы. Google StackDriver автоматически перенаправляет использование памяти в Google Cloud.
  • DevOps позаботился о мониторинге ЦП, памяти, использования диска, сети в течение ДЕСЯТИЛЕТИЙ.
  • Однако только люди, заботящиеся об использовании графического процессора, разгоняли геймеров (также известного как crysis-99-fps-watercooled-noobmaster). Инструменты мониторинга рабочих процессоров не на должном уровне со времен AlexNet (сообщество научилось использовать графические процессоры для машинного обучения).
  • Чтобы правильно отслеживать использование графического процессора, вы должны использовать nvidia-smi, выводить результаты с заданным интервалом, писать скрипт для чтения Prometheus и затем передавать его в StackDriver. Короче говоря, вам нужно написать микросервис для мониторинга микросервиса.
  • Во время использования загрузка ЦП и ГП несколько линейно увеличивается. В качестве взлома я обнаружил наименьшее количество виртуальных ЦП, которое может увеличиваться до 80–100% и автоматически масштабироваться в зависимости от загрузки ЦП. Слишком много виртуальных ЦП и% использования ЦП не сдвинутся с места, пока GPU загружен.
  • Проблемы могут возникнуть, когда графическому процессору не хватает памяти. Это произошло, когда пользователи передавали более длинные подсказки (›200 слов). PyTorch вызывает исключение, но, к сожалению, содержит большую утечку памяти. Чтобы справиться с этим, я перехватил исключения PyTorch и принудительно освободил неиспользуемую память. nvidia-smi бесполезен, поскольку статистика использования памяти не точна в реальном времени (IIRC, она показывает только пиковое использование памяти процессом).

Тренировочные модели

  • Доработаны дополнительные модели на P100 от gpt2-medium. Обучающие итерации (циклы) варьировались от 60 тыс. В «Игре престолов» (GoT) и Гарри Поттере (HP)… до 600 тыс. (Академические исследования, обучение на 200 тыс. Бумажных рефератов).
  • Для обучения использовал TensorFlow 1.13.
  • Время обучения варьировалось от нескольких часов (60 тысяч) до нескольких дней (600 тысяч).
  • Кросс-энтропийные потери составляли ~ 2–3. Метрика бесполезна при перетренированности.
  • Разветвил репозиторий gpt2 nsheppard, внес незначительные изменения для ускорения запуска для больших наборов данных.
  • Если вы понимаете жаргон машинного обучения (хотя, возможно, это самая сложная часть), следовать руководству gwern очень просто.
  • Используется контрольная точка градиента для решения проблем с памятью. Тонкая настройка gpt2-large (774M параметров, 1,5 ГБ) невозможна на отдельных графических процессорах без проблем с памятью.
  • Поиск и очистка наборов данных варьировались от слегка утомляющей боли до утомительного разочарования.
  • И снова очистка данных - это 80% работы.
  • Взял наборы данных из Kaggle, Google и прочего. бесплатные наборы данных для заполнения. Такие проблемы, как особенности набора данных, новые строки (\ r, \ n \, возврат каретки), обнаружение юникода и определение языка, занимали больше всего времени во время очистки.
  • Гверн использовал множество команд bash / команд для очистки своего корпуса Шекспира. Я рекомендую использовать Python. Проще повторно использовать код в разных наборах данных.
  • Не удалось заставить 16-битное обучение (апекс) правильно работать в Docker. Тесты Nvidia (хотя и маркетинговые) показывают, что 16-битная версия может сократить циклы обучения в 2 раза (и более). Не очень старался (устал) сделать 16-битную работу.
  • После обучения преобразовал модели в PyTorch с помощью скрипта huggingface. Развертывание на пыточных трансформаторах несложно.
  • Хотел избежать перетренированности в корпусе Гарри Поттера, но, оглядываясь назад, чувствую, что было бы лучше перетренироваться, чем недотренироваться. Ваши результаты могут отличаться при балансировке риска избыточного / недостаточного обучения для небольших наборов данных.

СОВЕТ. Создав необработанный набор данных для обучения, сделайте его копию. Никогда не изменяйте исходный набор данных. Скопируйте измененный вывод в отдельную папку. Храните измененные и необработанные наборы данных в отдельных папках, чтобы избежать ошибок / путаницы.
СОВЕТ: если вы обнаружите, что какое-то время очищаете определенный набор данных, сделайте шаг назад и поищите аналогичный набор данных w / из вопросов. Это произошло с наборами данных о Гарри Поттере.
СОВЕТ: изучите tmux! Использование tmux значительно упрощает начало обучения на удаленной машине, и вы можете выйти, не беспокоясь.
СОВЕТ: используйте Quiver для хранения всех ваших команд. Очень легко делать опечатки.

Беговые модели

  • Использовал PyTorch. pytorch-transformers создает удобные сайты вызова API к моделям. Подражали примерам run_gpt2.py в huggingface. Затем применил масштабный рефакторинг.
  • Загрузка моделей GPT-2 в PyTorch выполняется медленно (1-2 минуты).
  • Чтобы сократить время загрузки, при запуске микросервисов WSGI загружает соответствующую модель (gpt2-small, medium, large и т. д.) и сохраняет экземпляр PyTorch как синглтон.
  • Все последующие запросы используют одноэлементный экземпляр PyTorch.
  • Ограничения конфигурации на количество запущенных процессов WSGI в зависимости от размера модели. Слишком много процессов WSGI и CUDA не хватает памяти. Слишком мало - и графический процессор не используется.
  • Перехватить исключения, когда PyTorch исчерпывает память; освободить утечку памяти.
def get_process_prompt_response(request, validated_data):
    try:
        output = generate_sequences_from_prompt(**validated_data)
    except RuntimeError as exc:
        if "out of memory" in str(exc):
            logger.exception(
                f"Ran Out of Memory When Running {validated_data}. Clearing Cache."
            )
            torch.cuda.empty_cache()

            oom_response = get_oom_response(validated_data)
            return oom_response

    response = serialize_sequences_to_response(
        output,
        validated_data["prompt"],
        validated_data["cache_key"],
        WebsocketMessageTypes.COMPLETED_RESPONSE,
        completed=validated_data["length"],
        length=validated_data["length"],
    )

    # clear cache on all responses (maybe this is overkill)
    torch.cuda.empty_cache()
    return response
  • 95% времени запроса тратится на прогнозирование логитов. Другое - маршрутизация и де / сериализация из внешнего интерфейса - ›серверная часть -› балансировщик нагрузки.
  • На каждом пятом слове микросервис обновляет WebSocket обновленным текстом.
  • Помогло добавление кеша в бэкэнд для предотвращения дублирования запросов.
  • Чтобы упростить получение одних и тех же ответов от разных экземпляров, я использую начальное число 42 для всех запросов.

Другие улучшения развертывания, дистилляция, мысли

  • В TensorFlow есть TensorFlow Serve, а в PyTorch есть TorchScript для преобразования моделей в производственный уровень. Преимущества включают разумное улучшение скорости (редактор Reddit сообщил об улучшении на 30%) и более простое развертывание на устройствах без Python. Я проследил (процесс преобразования PyTorch) на нескольких моделях, но обнаружил, что выигрыш в скорости не так очевиден, но добавил гораздо больше сложности.
  • В последние несколько месяцев набирает обороты дистилляция моделей (извлечение 90–95% + модели при
  • Недавно была опубликована статья о Экстремальном сжатии модели языка, которая сжала BERT в 60 раз. Если это применимо к GPT2, будет много последствий!
  • Немного антипаттерн, но наличие PyTorch и TensorFlow было чрезвычайно полезно для одного и того же образа Docker. Я смог гораздо быстрее диагностировать и опробовать потенциальные решения.
  • Первоначально я интегрировал XLNet, но не обнаружил, что генеративный вывод столь же силен, как GPT2. Я также попытался сделать так, чтобы он предлагал отдельные слова (аналогично его языковой модели с масками), но я не смог найти хорошего сценария использования / пользовательского интерфейса для написания.

Другие бесценные инструменты

  • Некоторые повторяются сверху.
  • Sentry бесценен для сообщения об ошибках. Использовать его с ASGI (Django-Channels) было немного сложнее, чем обычно.
  • Tmux - используйте его, чтобы держать удаленные сеансы открытыми. Альтернатива - экран.
  • Использование django-rest-framework - это радость. Похоже на чит-код.
  • Netlify отлично подходит для развертывания.

Как справиться с выгоранием

  • Ударься о стену перед финишем.
  • Начал сильно выгорать примерно через 2–2,5 месяца.
  • Душевные страдания от ощущения, что я должен был начать, и что он был недостаточно хорош для запуска. Одержимый отсутствующими функциями.
  • Действительно полезно позвонить близкому другу, чтобы поговорить (спасибо, Джеймс С.).
  • Самостоятельный стресс, вызванный «запуском!» заставил меня не звонить семье. Это была ошибка. Обнаружено, что звонок моей матери просто чтобы спросить о ее жизни заставил меня снова вздохнуть.
  • Горжусь тем, что закончил. Узнал много неожиданного о развертывании машинного обучения. Пригодится для моего следующего проекта.

Огромное спасибо

  • OpenAI для GPT2; HuggingFace для пыторч-трансформеров.
  • GCP за кредиты, иначе не мог себе позволить. Предвзято, но я обнаружил, что показатели GCP лучше по всем параметрам (сегмент, сети, простота использования), чем AWS.
  • Мои друзья, которые помогли мне провести бета-тестирование и дали бесценные отзывы. Спасибо (в произвольном порядке): Кристине Ли, Джеймсу Стюарт, Кейт Аксай, Золтану Саласу, Стеффану Линссену и Харини Бабу, которые дали неоценимые отзывы.
  • Многие Redditors / ProductHunt, которые действительно подталкивали и играли с продуктом, вместе с отличными отзывами и веселыми подсказками для написания.

Что дальше?

  • Работают на перегонке ГПТ-2. Я открою его исходный код, если смогу разобраться.
  • Работа над созданием маркетинговых изображений с использованием GAN. Будьте на связи!
  • Недостаточно глуп, чтобы снова (пока) сделать неточную оценку временной шкалы.

Первоначально опубликовано на https://senrigan.io.