Поиск по сайту Поиск

NVIDIA + BERT = 🔥

BERT — нейросеть для обработки естественного языка (Natural Language Processing, NLP). Если вы давно мечтали создать свою виртуальную Алису или Олега, то у нас хорошие новости: не так давно NVIDIA выложила в открытый доступ скрипты, позволяющие использовать BERT для рекомендательных систем и приложений «вопрос-ответ». Мы расскажем, в чём преимущество этой нейросети и как её обучить для конкретных задач.

В конце прошлого года команде NVIDIA удалось достичь четырёхкратного ускорения нейронной сети BERT (Bidirectional Encoder Representations from Transformers). С тех пор эта ускоренная реализация была доработана и выложена на GitHub и NGC. TensorFlow-скрипт поддерживает точную настройку SQuAD QA, конфигурации серверов DGX-1 и DGX-2, а также использует новую функцию Automatic Mixed Precision (автоматический режим смешанной точности).

BERT — современная NLP-сеть, способная по воспроизводимой точности превзойти человека. Одна из ключевых инноваций — её двунаправленность (“B” — Biderectional). Предыдущие модели NLP обычно использовали однонаправленное сканирование (слева направо, справа налево или оба) для распознавания слов как в контекстном, так и в контекстно-свободном представлении. Кроме того, BERT может анализировать целые предложения для более точного изучения контекста, основываясь на окружении слова в обоих направлениях. Этот подход повышает точность модели, но предъявляет очень высокие вычислительные требования.

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

Команда разработчиков NVIDIA использовала версию BERT Large, у которой 340 миллионов параметров. Первоначальные результаты ускорения получены после тестирования на одном GPU. Обновлённые скрипты поддерживают системы 8-GPU DGX-1 и 16-GPU DGX-2. Хотя сценарии обычно не используют прямой вывод, они сообщают о скорости прогнозирования, достигнутой при оценке на тестовой выборке. Скрипт можно легко модифицировать для поддержки вывода.

Конфигурация модели

В зависимости от задачи, по умолчанию вам доступны две конфигурации BERT:

МодельСкрытые слоиРазмер скрытой единицы (hidden unit)Слои Attention HeadsРазмер фильтра прямой связиМаксимальная длина последовательностиПараметры
BERTBASE12768124 x 768512110M
BERTLARGE141024164 x 1024512330M

Установка

Требования

Репозиторий с BERT содержит Dockerfile, который расширяет контейнер TensorFlow NGC и инкапсулирует некоторые зависимости. Помимо этого, убедитесь, что у вас присутствуют следующие компоненты:

NVIDIA Docker

— Контейнер TensorFlow 19.03-py3 NGC

Графический процессор на базе NVIDIA Volta

Дополнительная информация о работе с контейнерами NGC доступна в документации по облачным GPU NVIDIA и документации Deep Learning:

Начало работы с облачным графическим процессором NVIDIA

Доступ и извлечение из реестра контейнеров NGC

Запуск TensorFlow

Быстрый старт

Здесь описана предварительная подготовка и настройки модели для задач «вопрос-ответ» с использованием тензорных ядер и смешанной точности, или же с помощью FP32. Выполните следующие шаги с параметрами по умолчанию:

1. Клонируйте репозиторий

git clone https://github.com/NVIDIA/DeepLearningExamples
cd DeepLearningExamples / TensorFlow / LanguageModeling / BERT

2. Соберите контейнер BERT TensorFlow NGC

bash scripts/docker/build.sh

3. Загрузите и подготовьте набор данных

В репозитории есть скрипты, с помощью которых вы можете загрузить, проверить и извлечь датасет SQuaD и предварительно обученные веса для точной настройки, а также набор данных Wikipedia + BookCorpus для предварительного обучения.

h scripts/data_download.sh

Сценарий запускает Docker-контейнер в текущем каталоге и загружает датасеты в папку data/.

4. Запустите интерактивную сессию в контейнере NGS для начала обучения/вывода

После загрузки контейнера и подготовки данных вы можете запустить сессию CLI (Command Line Interface):

bash scripts/docker/launch.sh

Сценарий launch.sh предполагает, что наборы данных находятся в местах по умолчанию:

— Squad v1.1: data/squad/v1.1

— BERT: data/pretrained_models_google/uncased_L-24_H-1024_A-16

— Wikipedia: data/wikipedia_corpus/final_tfrecords_sharded

— BookCorpus: data/bookcorpus/final_tfrecords_sharded

5. Начните предварительное обучение

Следующие скрипты выполняют предварительное обучение BERT на датасете Wikipedia+Book Corpus. Вы можете использовать любой другой набор данных на ваш выбор.

bash scripts/run_pretraining.sh < train_batch_size_per_gpu >  < eval_batch_size >  < learning_rate_per_gpu >  < precision >  < num_gpus >  < warmup_steps >  < train_steps >  < save_checkpoint_steps >  < create_logfile >

Для обучения FP16 с XLA с использованием DGX-1 V100 32G выполните:

bash scripts/run_pretraining.sh 14 8 5e-5 fp16_xla 8 5000 2285000 5000 true

Для обучения FP32 без XLA с использованием DGX-1 V100 32G выполните:

bash scripts/run_pretraining.sh 6 6 2e-5 fp32 8 2000 5333333 5000 true

6. Начните точную настройку

Предварительно обученные представления BERT можно точно настроить с помощью одного дополнительного выходного слоя для системы «вопрос-ответ». Вы можете использовать следующий скрипт внутри контейнера для настройки SQuaD:

bash scripts/run_squad.sh <batch_size_per_gpu> <learning_rate_per_gpu> <precision> <use_xla> <num_gpus> <checkpoint>

Для обучения FP16 с XLA с использованием DGX-1 V100 32G:

bash scripts/run_squad.sh 10 5e-6 fp16 true 8 /bert/bert_model.ckpt

Для обучения FP32 без XLA с использованием DGX-1 V100 32G:

bash scripts/run_squad.sh 5 5e-6 fp32 false 8 /bert/bert_model.ckpt

7. Начните проверку/оценку

Скрипт run_squad_inference.sh запускает вывод SQuaD на контрольной точке и оценивает прогнозирование с помощью полных совпадений и F1-меры.

bash scripts/run_squad_inference.sh <init_checkpoint> <batch_size> <precision> <use_xla>

Для вывода FP16 с XLA с использованием DGX-1 V100 32G:

bash scripts/run_squad_inference.sh/results/model.ckpt 8 fp16 true 

Для вывода FP32 без XLA с использованием DGX-1 V100 32G:

bash scripts/run_squad_inference.sh/results/model.ckpt 8 fp32 false

Подробности

В этом разделе вы можете подробнее узнать о наборах данных, обучении, выводе и результатах.

Параметры командной строки

Для просмотра полного списка доступных параметров и их описания, введите в командной строке -h или -help, например:

python run_pretraining.py --help
python run_squad.py --help

Помимо опций для настройки гиперпараметров скрипта run_pretraining.py также можно использовать:

--[no]amp: [не] включать функцию AMP (по умолчанию: 'false')
--[no]amp_fastmath: [не] включать AMP fasthmath (по умолчанию: 'false')
--bert_config_file: файл конфигурации json, соответствующий предварительно обученной модели BERT. Определяет архитектуру модели.
--[no]do_eval: [не] запускать оценку на наборе dev (по умолчанию: 'false')
--[no]do_train: [не] запускать обучение (evaluation: 'false')
--eval_batch_size: общий размер пакета для eval. (по умолчанию: '8') (целое число)
--[no]fastmath: [не] включать масштабирование потерь для операций fasthmath (по умолчанию:'false')
--[no]horovod: [не] использовать Horovod для нескольких графических процессоров (по умолчанию: 'false')
--init_checkpoint: начальная контрольная точка (обычно из предварительно обученной модели BERT).
--input_file: входные файлы примеров TF (могут быть перечислены через запятую или заданы маской).
--iterations_per_loop: Сколько шагов выполнять для каждого оценивания (по умолчанию: '1000')

Для скрипта run_squad.py:

--bert_config_file: файл конфигурации json, соответствующий предварительно обученной модели BERT. Определяет архитектуру модели.
--[no] do_predict: [не] запускать оценку на наборе dev (по умолчанию: 'false')
--[no]do_train: [не] запускать обучение (по умолчанию: 'false')
--learning_rate: начальная скорость обучения для Adam (по умолчанию: '5e-06') (число)
--max_answer_length: максимальная длина генерируемого ответа. Необходимый параметр, так как погнозы в начале и в конце не связаны друг с другом (по умолчанию: '30') (целое число)
--max_query_length: максимальное количество символов для вопроса. Если вопрос длиннее, он будет усечён до этой длины (по умолчанию: '64') (целое число)
--max_seq_length: максимальная длина входной последовательности после лексического анализа WordPiece. Более длинные последовательности обрезаются, а короткие — дополняются (по умолчанию: '384') (целое число)
--predict_batch_size: общий размер пакета для прогнозов (по умолчанию: '8') (целое число)
--train_batch_size: общий размер пакета для обучения (по умолчанию: '8') (целое число)
--[no]use_fp16: [не] использовать арифметику fp16 в GPU (по умолчанию: 'false')
--[no]use_xla: [не] включать компиляцию XLA JIT (по умолчанию: 'false')
--[no]verbose_logging: если true, выводятся все предупреждения, связанные с обработкой данных (по умолчанию: 'false').
--[no]version_2_with_negative: если true, в SQuAD будут включены примеры вопросов, на которые нет ответа (по умолчанию: 'false')

Получение данных

Для предварительного обучения BERT используются совмещённые датасеты Википедии (2500 млн слов) и Book Corpus (800 млн слов). Из Википедии извлекаются только текстовые блоки без заголовков, списков и таблиц. Они структурированы в виде единого набора документов, а не набора предложений, поскольку важно сохранять контекст.

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

Для использования BERT в качестве модели «вопрос-ответ» можно взять датасет SQuaD. SQuaD v1.1 содержит более 100 000 пар вопросов и ответов в более чем 500 статьях. SQuaD v2.0 дополняет v1.1 50 000 вопросами без ответа и должен не только отвечать на вопросы, но и определять, когда это невозможно.

Обучение

Процесс обучения состоит из двух этапов: предварительное обучение и точная настройка.

Предварительное обучение

Предварительное обучение выполняется с помощью run_pretraining.py вместе с параметрами, определёнными в scripts/run_pretraining.sh.

run_pretraining.sh запускает процесс обучения модели BERT-Large с нуля, используя датасеты Wikipedia и Book corpus. По умолчанию он:

— работает на 8 GPU с размером обучающего пакета 14 и размером оценочного пакета 8 на каждом GPU

— использует точность FP16

— использует XLA

— работает за 1144000 шагов с 10000 предварительных шагов

— сохраняет контрольную точку каждые 5000 итераций и в конце обучения. Все контрольные точки, результаты оценки и логи обучения сохраняются в каталоге /results (в контейнере, который можно установить в локальный каталог)

— создаёт лог-файл, содержащий все выходные данные

— оценивает модель в конце обучения. Чтобы пропустить оценку, измените --do_eval на False.

С этими параметрами можно обучить модель до приемлемой точности на DGX1 с графическими процессорами V100 32 ГБ. Если вы хотите добиться лучших результатов, продемонстрированных Google, нужно либо удвоить число шагов (до 2288000) на DGX1, либо проводить обучение с 16-ю графическими процессорами на DGX2.

Пример:

run_pretraining.sh <node_type> <training_batch_size> <eval_batch_size> <learning-rate> <precision> <num_gpus> <warmup_steps> <training_steps> <save_checkpoint_steps> <create_logfile>

Где:

<training_batch_size>: размер пакета для каждого процессора во время обучения. Чем больше размер пакета, тем эффективнее обучение, но это требует больше памяти

<eval_batch_size>: размер пакета для каждого GPU во время оценки

<learning_rate>: скорость обучения, по умолчанию 1e-4 (подходит для пакета размером 256)

<precision>: тип арифметики вашей модели (fp32, fp16, fp16_xla, fastmath, amp_fm, amp_fm_xla, amp или amp_xla):

  1. fp32: 32-битное число IEEE с плавающей запятой одинарной точности
  2. fp16: заданное вручную 16- и 32-битное число с плавающей запятой смешанной точности
  3. fp16_xla: заданное вручную число с плавающей запятой смешанной точности, JIT-скомпилированное с XLA
  4. fastmath: Matmuls выполняется тензорными ядрами со смешанной точностью, остальное - в FP32
  5. amp_fm: альтернативная реализация FastMath, которая работает с вычислительным графом TensorFlow
  6. amp_fm_xla: amp_fm и компиляция XLA JIT
  7. amp: автоматически переназначает вычислительному графу TensorFlow использовать 16-битную арифметику всякий раз, когда это допустимо.
  8. amp_xla: amp и компиляция XLA JIT

<num_gpus>: количество графических процессоров для обучения. Должно быть равно или меньше количества GPU, подключенных к вашему узлу

<warmup_steps>: количество предварительных шагов в начале обучения

<training_steps>: общее число шагов обучения

<save_checkpoint_steps>: управляет частотой сохранения контрольных точек (по умолчанию каждые 5000 шагов)

<create_logfile>: должен ли вывод быть записан в лог-файл (допустимые значения — "true" или "false")

Например:

bert_tf/scripts/run_pretraining.sh 14 8 1e-4 fp16_xla 16 10000 1144000 5000 true

Эта команда запускает обучение BERT-Large с нуля на одном DGX-2 с использованием арифметики FP16. Это займёт около 156 часов (6,5 дней). Контрольные точки записываются каждые 5000 шагов, и все выводы сохраняются в лог-файл.

Точная настройка

Точная настройка выполняется с помощью run_squad.py вместе с параметрами, определёнными в scripts/run_squad.sh.

Скрипт run_squad.sh обучает модель и подготавливает оценку на датасете SQuaD v1.1. По умолчанию он:

— использует 8 графических процессоров и размер пакета 10 на каждом GPU

— использует точность FP16

— использует XLA

— работает в течение 2 эпох

— сохраняет контрольную точку каждые 1000 итераций и в конце обучения. Все контрольные точки, результаты оценки и логи обучения сохраняются в каталоге /results (в контейнере, который можно установить в локальный каталог)

— оценивает модель в конце обучения. Чтобы пропустить оценку, измените --do_predict на False.

Лог обучения содержит:

— потери на последнем шаге

— эффективность обучения и оценки

— F1-меру и оценку полного совпадения на наборе Dev.

Результат обучения выводится в следующем формате:

I0312 23:10:45.137036 140287431493376 run_squad.py:1332] 0 Total Training Time = 3007.00 Training Time W/O start up overhead = 2855.92 Sentences processed = 175176
I0312 23:10:45.137243 140287431493376 run_squad.py:1333] 0 Training Performance = 61.3378 sentences/sec
I0312 23:14:00.550846 140287431493376 run_squad.py:1396] 0 Total Inference Time = 145.46 Inference Time W/O start up overhead = 131.86 Sentences processed = 10840
I0312 23:14:00.550973 140287431493376 run_squad.py:1397] 0 Inference Performance = 82.2095 sentences/sec
{"exact_match": 83.69914853358561, "f1": 90.8477003317459}

Мультипроцессорное обучение можно включить с помощью модуля Horovod TensorFlow. Пример обучения на 8 GPU:

mpi_command = " mpirun -np 8 -H localhost: 8 \
     --allow-run-as-root -bind-to none -map-by slot \
     -x NCCL_DEBUG = INFO \
     -x LD_LIBRARY_PATH \
     -x PATH -mca pml ob1 -mca btl ^ openib " \
     python run_squad.py --horovod

Обучение со смешанной точностью

Такое обучение значительно ускоряет вычисление, поскольку операции выполняются с половинной точностью, но при этом сохраняется минимальная информация с единичной точностью для критических участков сети. Это возможно благодаря тензорным ядрам в архитектурах Volta и Turing, которые обеспечивают ускорение до трёх раз.

Для обучения со смешанной точностью нужно:

1. Портировать модель для использования типа данных FP16 там, где это необходимо.

2. Добавить масштабирование потерь для сохранения малых значений градиента. Теперь это можно сделать автоматически с помощью механизма AMP (Automatic Mixed Precision) для Tensorflow (TF-AMP).

Более подробная информация:

— как обучить модель со смешанной точностью

— как получить доступ к AMP для TensorFlow и включить его

методы обучения со смешанной точностью

Вывод

Вывод выполняется скриптом run_squad.py вместе с параметрами, определёнными в scripts/run_squad_inference.sh. Вывод поддерживает только один GPU.

Скрипт run_squad_inference.sh обучает модель и выполняет оценку на датасете SQuaD v1.1. По умолчанию он:

— использует точность FP16

— использует XLA

— оценивает последнюю контрольную точку в /results с размером пакета 8.

Скрипт создаёт файл прогнозов /results/predictions.json и вычисляет F1-меру и полные совпадения с помощью evaluate-v1.1.py.

Выходной лог содержит:

— оценку эффективности модели

— F1-меру и оценку полного совпадения на наборе Dev.

Результат вывода выглядит следующим образом:

I0312 23: 14: 00.550846 140287431493376 run_squad.py:1396] 0 Общее время вывода = 145,46 Время вывода без накладных расходов при запуске = 131,86 Обработанные предложения = 10840
I0312 23: 14: 00.550973 140287431493376 run_squad.py:1397] 0 Производительность логического вывода = 82,2095 предложений в секунду
{ " correct_match " : 83.69914853358561, " f1 " : 90.8477003317459}

Результаты

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

Тест эффективности обучения

scripts/finetune_train_benchmark.sh squad <fp16/fp32> <use_xla> <num_gpu> <batch_size/gpu> <lr> 

Тест эффективности вывода

scripts/finetune_inference_benchmark.sh squad <fp16/fp32> <use_xla> <batch_size> <path-to-checkpoint> 

Результаты Google

Результаты Google для обучающего скрипта run_squad.py были получены с контейнером TensorFlow 19.03-py3 NGC на NVIDIA DGX-1 с 8 видеокартами Tesla V100 32ГБ.

Количество графических процессоровРазмер партии на один графический процессорВремя обучения с FP16 (в минутах)Время обучения с FP32 (в минутах)
843146

В следующих таблицах сравниваются F1-меры для 5 запусков обучения с различными начальными значениями для FP16 и FP32 соответственно:

FP16, 8 GPUseed #1seed #2seed #3seed #4seed #5meanstd
F191.1690.6990.9990.9491.1790.990.196
Полное совпадение84.283.6884.1483.9584.3484.060.255

FP32, 8 GPUseed #1seed #2seed #3seed #4seed #5meanstd
F190.6790.890.9490.8390.9390.830.11
Полное совпадение83.5683.9683.9983.9584.1283.920.21

Таблица с результатами производительности (в предложениях в секунду). Числа усреднены для всех эпох обучения:

Число GPUРазмер партии на один GPUFP32 предл / секFP16 предл / секУскорение со смешанной точностьюMulti-GPU слабая масштабируемость с FP32Multi-GPU слабая масштабируемость с FP16
148,5518,142,121,01,0
4432,1352,851,643,762,91
8462,8395,281,517,355,25

Максимальная точность модели составила 91.17% для F1-меры и 84.34% для оценки полного совпадения.

BERT — большой шаг вперёд для NLP, и NVIDIA продолжает ускорять современные нейросети для любых применений Deep Learning. Теперь, используя открытый исходный код, любой может обучить свою вопросно-ответную систему для разных задач. Это должно послужить толчком к созданию не только развлекательных ботов, но и полноценных голосовых помощников.

С оригинальными материалами можно ознакомиться на сайте и в репозитории NVIDIA.

Как создать свой сайт, даже если не знаете с чего начать

Сайт — хороший способ заявить о себе или своём бизнесе в онлайне. В этой статье расскажем, как создать крутой сайт...
Read More

Безопасность личных данных: 10 лучших менеджеров паролей

Как часто вы задумывались над тем, сколько же всего у вас аккаунтов на различных ресурсах? Методы держать в памяти или...
Read More

Домены — оригинальные подарки на 23 февраля

В День защитника Отечества многие мужчины получают стандартные подарки. Все вы их знаете :). Сегодня редакция предлагает вам оригинальную альтернативу...
Read More

Приём платежей по ссылке: что это и как подключить?

Современные технологии помогают забыть о сложностях и мгновенно (в режиме 24/7) переводить и получать деньги. Сегодня расскажем о том, как...
Read More

Как правильный домен поможет вашему бизнесу: 4 совета

Первое знакомство клиента с организацией сегодня чаще всего происходит в интернете. Совместно с Регистратурой Radix мы расскажем о том, как...
Read More

Домен .IO может исчезнуть? Разбираем ситуацию

.IO — один из популярных в IT-отрасли доменов. Кому он принадлежит, какие споры вокруг него возникали, правда ли, что доменная...
Read More

Лёгкое изучение программирования: 13 бесплатных онлайн-игр

Вы думаете, что программирование это сложно и скучно? А что если мы скажем, что можно учиться играючи? Мы составили для...
Read More

Как придумать крутое название или гайд по неймингу

Имя бренда или продукта влияет не только на его узнаваемость, но и на спрос и доверие потребителей. Именно название продукта...
Read More

Что может ИИ и машинное обучение в 2021 году

В последние годы на IT-рынке произошёл настоящий бум из-за искусственного интеллекта. И в этом нет ничего удивительного: современные вычислительные и...
Read More

Почему они уходят: 6 разочарований пользователей на сайте

Вы когда-нибудь задумывались, как казалось бы крошечные и незаметные вещи на сайте могут раздражать его посетителей? Сегодня пользователи ждут, что...
Read More