e
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 | Размер фильтра прямой связи | Максимальная длина последовательности | Параметры |
BERTBASE | 12 | 768 | 12 | 4 x 768 | 512 | 110M |
BERTLARGE | 14 | 1024 | 16 | 4 x 1024 | 512 | 330M |
Требования
Репозиторий с BERT содержит Dockerfile, который расширяет контейнер TensorFlow NGC и инкапсулирует некоторые зависимости. Помимо этого, убедитесь, что у вас присутствуют следующие компоненты:
— Контейнер TensorFlow 19.03-py3 NGC
— Графический процессор на базе NVIDIA Volta
Дополнительная информация о работе с контейнерами NGC доступна в документации по облачным GPU NVIDIA и документации Deep Learning:
— Начало работы с облачным графическим процессором NVIDIA
— Доступ и извлечение из реестра контейнеров NGC
Здесь описана предварительная подготовка и настройки модели для задач «вопрос-ответ» с использованием тензорных ядер и смешанной точности, или же с помощью 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):
— <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 для обучающего скрипта run_squad.py были получены с контейнером TensorFlow 19.03-py3 NGC на NVIDIA DGX-1 с 8 видеокартами Tesla V100 32ГБ.
Количество графических процессоров | Размер партии на один графический процессор | Время обучения с FP16 (в минутах) | Время обучения с FP32 (в минутах) |
8 | 4 | 31 | 46 |
В следующих таблицах сравниваются F1-меры для 5 запусков обучения с различными начальными значениями для FP16 и FP32 соответственно:
FP16, 8 GPU | seed #1 | seed #2 | seed #3 | seed #4 | seed #5 | mean | std |
F1 | 91.16 | 90.69 | 90.99 | 90.94 | 91.17 | 90.99 | 0.196 |
Полное совпадение | 84.2 | 83.68 | 84.14 | 83.95 | 84.34 | 84.06 | 0.255 |
FP32, 8 GPU | seed #1 | seed #2 | seed #3 | seed #4 | seed #5 | mean | std |
F1 | 90.67 | 90.8 | 90.94 | 90.83 | 90.93 | 90.83 | 0.11 |
Полное совпадение | 83.56 | 83.96 | 83.99 | 83.95 | 84.12 | 83.92 | 0.21 |
Таблица с результатами производительности (в предложениях в секунду). Числа усреднены для всех эпох обучения:
Число GPU | Размер партии на один GPU | FP32 предл / сек | FP16 предл / сек | Ускорение со смешанной точностью | Multi-GPU слабая масштабируемость с FP32 | Multi-GPU слабая масштабируемость с FP16 |
1 | 4 | 8,55 | 18,14 | 2,12 | 1,0 | 1,0 |
4 | 4 | 32,13 | 52,85 | 1,64 | 3,76 | 2,91 |
8 | 4 | 62,83 | 95,28 | 1,51 | 7,35 | 5,25 |
Максимальная точность модели составила 91.17% для F1-меры и 84.34% для оценки полного совпадения.
BERT — большой шаг вперёд для NLP, и NVIDIA продолжает ускорять современные нейросети для любых применений Deep Learning. Теперь, используя открытый исходный код, любой может обучить свою вопросно-ответную систему для разных задач. Это должно послужить толчком к созданию не только развлекательных ботов, но и полноценных голосовых помощников.
С оригинальными материалами можно ознакомиться на сайте и в репозитории NVIDIA.
Многие предприниматели жалуются на сложный и слишком изобильный документооборот: много документов приходится оформлять. Но при…
Чтобы легально пользоваться результатами чужого труда в своем бизнесе, нужно за это заплатить. И неважно,…
Франшизы предоставляют предпринимателям возможность использовать популярные бренды, эффективные бизнес-модели и поддержку со стороны материнской компании.…
Некоторые компании сосредотачивают в своих руках и производственные мощности, и права на то, что на…
У любой компании есть адрес, по которому она «прописана», то есть зарегистрирована в ЕГРЮЛ. Но…
Подросток может заниматься бизнесом, но с учетом важных условий, прописанных в законе. Разбираемся, как несовершеннолетнему…