***** Nouveau 11 mars 2020: Modèles Bert plus petits *****
Il s'agit d'une version de 24 modèles Bert plus petits (l'anglais uniquement, non basés, formés avec un masquage de pièces) référencés chez les étudiants bien lus apprennent mieux: sur l'importance des modèles compacts pré-formation.
Nous avons montré que la recette Bert standard (y compris l'architecture du modèle et l'objectif de formation) est efficace sur une large gamme de tailles de modèles, au-delà de la base Bert-Base et Bert-Large. Les plus petits modèles Bert sont destinés aux environnements avec des ressources de calcul restreintes. Ils peuvent être affinés de la même manière que les modèles Bert d'origine. Cependant, ils sont les plus efficaces dans le contexte de la distillation des connaissances, où les étiquettes de réglage fin sont produites par un enseignant plus grand et plus précis.
Notre objectif est de permettre la recherche dans des institutions avec moins de ressources informatiques et d'encourager la communauté à rechercher des orientations d'innovation alternative à l'augmentation de la capacité du modèle.
Vous pouvez télécharger les 24 à partir d'ici, ou individuellement à partir du tableau ci-dessous:
H = 128 | H = 256 | H = 512 | H = 768 | |
---|---|---|---|---|
L = 2 | 2/128 (Bert-Tiny) | 2/256 | 2/512 | 2/768 |
L = 4 | 4/128 | 4/256 (Bert-min) | 4/512 (Bert-Small) | 4/768 |
L = 6 | 6/128 | 6/256 | 6/512 | 6/768 |
L = 8 | 8/128 | 8/256 | 8/512 (Bert-Medium) | 8/768 |
L = 10 | 10/128 | 10/256 | 10/512 | 10/768 |
L = 12 | 12/128 | 12/256 | 12/512 | 12/768 (Bert-base) |
Notez que le modèle de base Bert dans cette version est inclus uniquement pour l'exhaustivité; Il a été recommandé sous le même régime que le modèle d'origine.
Voici les scores de colle correspondants sur l'ensemble de tests:
Modèle | Score | Cola | SST-2 | MRPC | STS-B | QQP | Mnli-m | Mnli-mm | QNLI (V2) | Rte | WNLI | HACHE |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Bert-tiny | 64.2 | 0.0 | 83.2 | 81.1 / 71.1 | 74.3 / 73.6 | 62.2 / 83.4 | 70.2 | 70.3 | 81.5 | 57.2 | 62.3 | 21.0 |
Bert-min | 65.8 | 0.0 | 85.9 | 81.1 / 71.8 | 75.4 / 73.3 | 66.4 / 86.2 | 74.8 | 74.3 | 84.1 | 57.9 | 62.3 | 26.1 |
Bert-petit | 71.2 | 27.8 | 89.7 | 83.4 / 76.2 | 78.8 / 77.0 | 68.1 / 87.0 | 77.6 | 77.0 | 86.4 | 61.8 | 62.3 | 28.6 |
Bert-médium | 73.5 | 38.0 | 89.6 | 86.6 / 81.6 | 80.4 / 78.4 | 69.6 / 87.9 | 80.0 | 79.1 | 87.7 | 62.2 | 62.3 | 30.5 |
Pour chaque tâche, nous avons sélectionné les meilleurs hyperparamètres de réglage fin dans les listes ci-dessous et formé pour 4 époques:
Si vous utilisez ces modèles, veuillez citer l'article suivant:
@article{turc2019,
title={Well-Read Students Learn Better: On the Importance of Pre-training Compact Models},
author={Turc, Iulia and Chang, Ming-Wei and Lee, Kenton and Toutanova, Kristina},
journal={arXiv preprint arXiv:1908.08962v2 },
year={2019}
}
***** Nouveau 31 mai 2019: Modèles de masquage entiers *****
Il s'agit d'une version de plusieurs nouveaux modèles qui sont le résultat d'une amélioration du code de prétraitement.
Dans le code de prétraitement d'origine, nous sélectionnons au hasard des jetons de pièce de bouche pour masquer. Par exemple:
Input Text: the man jumped up , put his basket on phil ##am ##mon ' s head
Original Masked Input: [MASK] man [MASK] up , put his [MASK] on phil [MASK] ##mon ' s head
La nouvelle technique est appelée masquage entier. Dans ce cas, nous masquons toujours tous les jetons correspondant à un mot à la fois. Le taux de masquage global reste le même.
Whole Word Masked Input: the man [MASK] up , put his basket on [MASK] [MASK] [MASK] ' s head
La formation est identique - nous prédisons toujours chaque jeton de bouche masqué indépendamment. L'amélioration vient du fait que la tâche de prédiction d'origine était trop «facile» pour les mots qui avaient été divisés en parcours de plusieurs bouchons.
Cela peut être activé lors de la génération de données en passant l'indicateur --do_whole_word_mask=True
à create_pretraining_data.py
.
Les modèles pré-formés avec masquage de mots entiers sont liés ci-dessous. Les données et la formation étaient par ailleurs identiques, et les modèles ont une structure et un vocabas identiques pour les modèles originaux. Nous n'incluons que des modèles Bert-Garg. Lorsque vous utilisez ces modèles, veuillez indiquer clairement dans le document que vous utilisez la variante de masquage de mots entiers de Bert-Large.
BERT-Large, Uncased (Whole Word Masking)
: 24 couches, 1024, 16 têtes, 340 m de paramètres
BERT-Large, Cased (Whole Word Masking)
: 24 couches, 1024, 16 têtes, 340 m de paramètres
Modèle | Escouade 1.1 F1 / EM | Précision multi-NLI |
---|---|---|
Bert-large, non (original) | 91.0 / 84.3 | 86.05 |
Bert-large, non (masquage de mot entier) | 92.8 / 86.7 | 87.07 |
Bert-large, en tube (original) | 91.5 / 84.8 | 86.09 |
Bert-large, enveloppé (masquage entier) | 92.9 / 86.7 | 86.46 |
***** Nouveau 7 février 2019: Module TFHUB *****
Bert a été téléchargé sur TensorFlow Hub. Voir run_classifier_with_tfhub.py
pour un exemple d'utilisation du module TF Hub, ou exécutez un exemple dans le navigateur sur Colab.
***** Nouveau 23 novembre 2018: modèle multilingue non normalisé + thaï + mongol *****
Nous avons téléchargé un nouveau modèle multilingue qui n'effectue aucune normalisation sur l'entrée (pas de boîtier inférieur, de décapage d'accent ou de normalisation Unicode), et inclut en outre le thaï et le mongol.
Il est recommandé d'utiliser cette version pour développer des modèles multilingues, en particulier sur les langues avec des alphabets non latins.
Cela ne nécessite aucune modification de code et peut être téléchargé ici:
BERT-Base, Multilingual Cased
: 104 langues, 12 couches, 768, 12 têtes, 110 m de paramètres***** Nouveau 15 novembre 2018: Sota Squad 2.0 Système *****
Nous avons publié des modifications de code pour reproduire notre système Squad 2.0 F1 de 83%, qui est actuellement la 1ère place dans le classement de 3%. Voir la section Squad 2.0 du Readme pour plus de détails.
***** Nouveau 5 novembre 2018: Versions tierces de pytorch et de chaîneur de Bert disponibles *****
Les chercheurs du PNL de HuggingFace ont rendu une version Pytorch de Bert disponible qui est compatible avec nos points de contrôle pré-formés et est capable de reproduire nos résultats. Sosuke Kobayashi a également rendu une version de Chaiper de Bert disponible (merci!) Nous n'étions pas impliqués dans la création ou la maintenance de l'implémentation de Pytorch, veuillez donc diriger toutes les questions vers les auteurs de ce référentiel.
***** Nouveau 3 novembre 2018: Modèles multilingues et chinois disponibles *****
Nous avons rendu deux nouveaux modèles Bert disponibles:
BERT-Base, Multilingual
(non recommandée, utilisez plutôt Multilingual Cased
) : 102 langues, 12 couches, 768, 12 têtes, 110 m de paramètresBERT-Base, Chinese
: chinois simplifié et traditionnel, 12 couches, 768, 12 têtes, 110 m de paramètres Nous utilisons la tokenisation basée sur les caractères pour le chinois et la tokenisation de la pièce pour toutes les autres langues. Les deux modèles devraient fonctionner à l'attente sans aucun changement de code. Nous avons mis à jour la mise en œuvre de BasicTokenizer
dans tokenization.py
pour prendre en charge la tokenisation chinoise de caractère, alors veuillez mettre à jour si vous l'avez alimenté. Cependant, nous n'avons pas changé l'API de tokenisation.
Pour en savoir plus, consultez le réadme multilingue.
***** terminer les nouvelles informations *****
Bert , ou B idirectionnel, les représentations de coder des ransformateurs, est une nouvelle méthode de représentation du langage pré-formation qui obtient des résultats de pointe sur un large éventail de tâches de traitement du langage naturel (NLP).
Notre article académique qui décrit Bert en détail et fournit des résultats complets sur un certain nombre de tâches peut être trouvé ici: https://arxiv.org/abs/1810.04805.
Pour donner quelques chiffres, voici les résultats de la tâche de réponse à la question Squad v1.1:
Squad v1.1 LEADBOED (8 octobre 2018) | Tester | Tester F1 |
---|---|---|
Ensemble de 1ère place - Bert | 87.4 | 93.2 |
Ensemble de 2e place - NLNET | 86.0 | 91.7 |
Modèle unique de 1ère place - Bert | 85.1 | 91.8 |
Modèle unique de 2e place - NLNET | 83.5 | 90.1 |
Et plusieurs tâches d'inférence du langage naturel:
Système | Multination | Question NLI | GUIRLANDE |
---|---|---|---|
Bert | 86.7 | 91.1 | 86.3 |
Openai GPT (Prev. Sota) | 82.2 | 88.1 | 75.0 |
Plus de nombreuses autres tâches.
De plus, ces résultats ont tous été obtenus avec presque aucune conception d'architecture de réseau neuronal spécifique à la tâche.
Si vous savez déjà ce qu'est Bert et que vous voulez simplement commencer, vous pouvez télécharger les modèles pré-formés et exécuter un réglage fin de la pointe de la technologie en seulement quelques minutes.
Bert est une méthode de représentations du langage pré-formation, ce qui signifie que nous formons un modèle de «compréhension du langage» à usage général sur un grand corpus de texte (comme Wikipedia), puis utilisez ce modèle pour les tâches NLP en aval qui nous soucions (comme une question répondre). Bert surpasse les méthodes précédentes car il s'agit du premier système bidirectionnel profondément non supervisé pour la PNL pré-formation.
Non supervisé signifie que Bert a été formé en utilisant uniquement un corpus de texte brut, ce qui est important car une énorme quantité de données de texte brut est accessible au public sur le Web dans de nombreuses langues.
Les représentations pré-formées peuvent également être sans contexte ou contextuelles , et les représentations contextuelles peuvent en outre être unidirectionnelles ou bidirectionnelles . Des modèles sans contexte tels que Word2Vec ou Glove génèrent une seule représentation "Word Embedding" pour chaque mot dans le vocabulaire, de sorte que bank
aurait la même représentation dans bank deposit
et river bank
. Les modèles contextuels génèrent plutôt une représentation de chaque mot basé sur les autres mots de la phrase.
Bert a été construit sur des travaux récents dans les représentations contextuelles pré-formation - y compris l'apprentissage semi-supervisé, la pré-formation générative, l'Elmo et l'ulmFit - mais surtout ces modèles sont tous unidirectionnels ou bidirectionnels unidirectionnels . Cela signifie que chaque mot n'est contextualisé qu'à l'aide des mots à sa gauche (ou à droite). Par exemple, dans la phrase, I made a bank deposit
la représentation unidirectionnelle de bank
est uniquement basée sur I made a
deposit
mais pas. Certains travaux antérieurs combinent les représentations à partir de modèles de contexte gauche et de contexte droit séparés, mais uniquement d'une manière "peu profonde". Bert représente "Bank" en utilisant à la fois son contexte gauche et droit - I made a ... deposit
- à partir du fond d'un réseau neuronal profond, il est donc profondément bidirectionnel .
Bert utilise une approche simple pour ceci: nous masquons 15% des mots dans l'entrée, exécutons la séquence entière à travers un encodeur de transformateur bidirectionnel profond, puis ne prédise que les mots masqués. Par exemple:
Input: the man went to the [MASK1] . he bought a [MASK2] of milk.
Labels: [MASK1] = store; [MASK2] = gallon
Afin d'apprendre des relations entre les phrases, nous nous entraînons également sur une tâche simple qui peut être générée à partir de tout corpus monolingue: compte tenu de deux phrases A
et B
, est B
la phrase suivante qui vient après A
, ou simplement une phrase aléatoire du corpus ?
Sentence A: the man went to the store .
Sentence B: he bought a gallon of milk .
Label: IsNextSentence
Sentence A: the man went to the store .
Sentence B: penguins are flightless .
Label: NotNextSentence
Nous formons ensuite un grand modèle (12 couches à un transformateur 24 couches) sur un grand corpus (Wikipedia + BookCorpus) pendant longtemps (étapes de mise à jour de 1m), et c'est Bert.
L'utilisation de Bert a deux étapes: pré-formation et affinage fin .
La pré-formation est assez coûteuse (quatre jours sur 4 à 16 TPU cloud), mais est une procédure unique pour chaque langue (les modèles actuels sont uniquement en anglais, mais les modèles multilingues seront publiés dans un avenir proche). Nous publions un certain nombre de modèles pré-formés du papier qui ont été pré-formés chez Google. La plupart des chercheurs de la PNL n'auront jamais besoin de pré-entraîner leur propre modèle à partir de zéro.
Le réglage fin est peu coûteux. Tous les résultats du papier peuvent être reproduits au maximum 1 heure sur un seul TPU cloud, ou quelques heures sur un GPU, à partir du même modèle pré-formé exactement. Squad, par exemple, peut être formé dans environ 30 minutes sur un seul TPU cloud pour obtenir un score Dev F1 de 91,0%, ce qui est l'état de l'art unique.
L'autre aspect important de Bert est qu'il peut être adapté très facilement à de nombreux types de tâches PNL. Dans l'article, nous démontrons des résultats de pointe au niveau de la phrase (par exemple, SST-2), au niveau de la phrase (par exemple, Multinli), au niveau des mots (par exemple, NER) et au niveau de l'étendue (par exemple, Squad) Tâches avec presque aucune modification spécifique à la tâche.
Nous publions ce qui suit:
BERT-Base
et BERT-Large
du papier.Tout le code de ce référentiel fonctionne à l'extérieur de la boîte avec CPU, GPU et Cloud TPU.
Nous publions les modèles BERT-Base
et BERT-Large
à partir du papier. Uncased
signifie que le texte a été inférieur à la tokenisation de la pièce, par exemple, John Smith
devient john smith
. Le modèle Uncased
supprime également tous les marqueurs d'accentuation. Cased
signifie que le véritable cas et les marqueurs d'accent sont préservés. En règle générale, le modèle Uncased
est meilleur à moins que vous sachiez que les informations de cas sont importantes pour votre tâche (par exemple, la reconnaissance d'entité nommée ou le marquage d'une partie de la parole).
Ces modèles sont tous publiés sous la même licence que le code source (Apache 2.0).
Pour plus d'informations sur le modèle multilingue et chinois, consultez le Readme multilingue.
Lorsque vous utilisez un modèle en boîtier, assurez-vous de passer --do_lower=False
aux scripts d'entraînement. (Ou passez do_lower_case=False
directement à FullTokenizer
si vous utilisez votre propre script.)
Les liens vers les modèles sont ici (cliquez avec le bouton droit, 'Enregistrer le lien sous ...' sur le nom):
BERT-Large, Uncased (Whole Word Masking)
: 24 couches, 1024, 16 têtes, 340 m de paramètresBERT-Large, Cased (Whole Word Masking)
: 24 couches, 1024, 16 têtes, 340 m de paramètresBERT-Base, Uncased
: 12 couches, 768, 120 m de 120 mBERT-Large, Uncased
: 24 couches, 1024, 16 têtes, 340 m de paramètresBERT-Base, Cased
: 12 couches, 768, 12 têtes, paramètres de 110 mBERT-Large, Cased
: 24 couches, 1024, 16 têtes, 340 m de paramètresBERT-Base, Multilingual Cased (New, recommended)
: 104 langues, 12 couches, 768, coiffures, 12 têtes, 110 m de paramètresBERT-Base, Multilingual Uncased (Orig, not recommended)
(non recommandée, utilisez plutôt Multilingual Cased
) : 102 langues, 12 couches, 768, 12 têtes, 110m paramètresBERT-Base, Chinese
: chinois simplifié et traditionnel, 12 couches, 768, 12 têtes, 110 m de paramètresChaque fichier .zip contient trois éléments:
bert_model.ckpt
) contenant les poids pré-formés (qui sont en fait 3 fichiers).vocab.txt
) pour mapper une pièce de bouchée à Word ID.bert_config.json
) qui spécifie les hyperparamètres du modèle. IMPORTANT : Tous les résultats sur le papier ont été affinés sur un seul TPU cloud, qui a 64 Go de RAM. Il n'est actuellement pas possible de reproduire la plupart des résultats de BERT-Large
sur le papier à l'aide d'un GPU avec 12 Go - 16 Go de RAM, car la taille maximale du lot qui peut s'adapter dans la mémoire est trop petite. Nous travaillons sur l'ajout de code à ce référentiel qui permet une taille de lot efficace beaucoup plus grande sur le GPU. Voir la section sur les problèmes hors mémoire pour plus de détails.
Ce code a été testé avec TensorFlow 1.11.0. Il a été testé avec Python2 et Python3 (mais plus en détail avec Python2, car c'est ce qui est utilisé en interne dans Google).
Les exemples de réglage fin qui utilisent BERT-Base
devraient pouvoir fonctionner sur un GPU qui a au moins 12 Go de RAM en utilisant les hyperparamètres donnés.
La plupart des exemples ci-dessous suppose que vous exécuterez une formation / évaluation sur votre machine locale, en utilisant un GPU comme un Titan X ou GTX 1080.
Cependant, si vous avez accès à un TPU cloud sur lequel vous souhaitez vous entraîner, ajoutez simplement les indicateurs suivants pour run_classifier.py
ou run_squad.py
:
--use_tpu=True
--tpu_name=$TPU_NAME
Veuillez consulter le tutoriel Google Cloud TPU pour utiliser les TPU cloud. Alternativement, vous pouvez utiliser le cahier Google Colab "Bert Finetuning avec des tpus cloud".
Sur les TPU cloud, le modèle pré-entraîné et le répertoire de sortie devront être sur le stockage de Google Cloud. Par exemple, si vous avez un seau nommé some_bucket
, vous pouvez plutôt utiliser les indicateurs suivants:
--output_dir=gs://some_bucket/my_output_dir/
Les fichiers de modèle pré-formés non décompressés peuvent également être trouvés dans le dossier de stockage Google Cloud gs://bert_models/2018_10_18
. Par exemple:
export BERT_BASE_DIR=gs://bert_models/2018_10_18/uncased_L-12_H-768_A-12
Avant d'exécuter cet exemple, vous devez télécharger les données de colle en exécutant ce script et en la déballer dans un répertoire $GLUE_DIR
. Ensuite, téléchargez le point de contrôle BERT-Base
et décompressez-le dans un répertoire $BERT_BASE_DIR
.
Cet exemple de code de code BERT-Base
sur le corpus Microsoft Research Paraphrase Corpus (MRPC), qui ne contient que 3 600 exemples et peut affiner en quelques minutes sur la plupart des GPU.
export BERT_BASE_DIR=/path/to/bert/uncased_L-12_H-768_A-12
export GLUE_DIR=/path/to/glue
python run_classifier.py
--task_name=MRPC
--do_train=true
--do_eval=true
--data_dir= $GLUE_DIR /MRPC
--vocab_file= $BERT_BASE_DIR /vocab.txt
--bert_config_file= $BERT_BASE_DIR /bert_config.json
--init_checkpoint= $BERT_BASE_DIR /bert_model.ckpt
--max_seq_length=128
--train_batch_size=32
--learning_rate=2e-5
--num_train_epochs=3.0
--output_dir=/tmp/mrpc_output/
Vous devriez voir une sortie comme ceci:
***** Eval results *****
eval_accuracy = 0.845588
eval_loss = 0.505248
global_step = 343
loss = 0.505248
Cela signifie que la précision de la définition de développement était de 84,55%. Les petits ensembles comme MRPC ont une grande variance dans la précision des ensembles de développeurs, même en partant du même point de contrôle avant la formation. Si vous réévaluez plusieurs fois (en vous assurant de pointer vers différents output_dir
), vous devriez voir des résultats entre 84% et 88%.
Quelques autres modèles pré-formés sont mis en œuvre standard dans run_classifier.py
, il devrait donc être simple de suivre ces exemples pour utiliser Bert pour toute tâche de classification à une seule phrase ou de phrase.
Remarque: vous pouvez voir un message Running train on CPU
. Cela signifie vraiment que cela fonctionne sur autre chose qu'un TPU cloud, qui comprend un GPU.
Une fois que vous avez formé votre classificateur, vous pouvez l'utiliser en mode d'inférence en utilisant la commande --do_prect = true. Vous devez avoir un fichier nommé test.tsv dans le dossier d'entrée. La sortie sera créée dans un fichier appelé test_results.tsv dans le dossier de sortie. Chaque ligne contiendra la sortie pour chaque échantillon, les colonnes sont les probabilités de classe.
export BERT_BASE_DIR=/path/to/bert/uncased_L-12_H-768_A-12
export GLUE_DIR=/path/to/glue
export TRAINED_CLASSIFIER=/path/to/fine/tuned/classifier
python run_classifier.py
--task_name=MRPC
--do_predict=true
--data_dir= $GLUE_DIR /MRPC
--vocab_file= $BERT_BASE_DIR /vocab.txt
--bert_config_file= $BERT_BASE_DIR /bert_config.json
--init_checkpoint= $TRAINED_CLASSIFIER
--max_seq_length=128
--output_dir=/tmp/mrpc_output/
L'ensemble de données de réponse à la question de Stanford (Squad) est une question populaire répondant à un ensemble de données de référence. Bert (au moment de la version) obtient des résultats de pointe sur Squad avec presque aucune modification d'architecture de réseau spécifique à la tâche ou augmentation des données. Cependant, il nécessite le prétraitement et le post-traitement des données semi-complexes pour traiter (a) la nature variable des paragraphes de contexte d'escouade, et (b) les annotations de réponse au niveau du caractère qui sont utilisées pour la formation de l'escouade. Ce traitement est implémenté et documenté dans run_squad.py
.
Pour fonctionner sur Squad, vous devrez d'abord télécharger l'ensemble de données. Le site Web de l'escouade ne semble plus lier aux ensembles de données V1.1, mais les fichiers nécessaires peuvent être trouvés ici:
Téléchargez-les dans un répertoire $SQUAD_DIR
.
L'équipe de pointe des résultats du document ne peut actuellement pas être reproduite sur un GPU de 12 Go-16 Go en raison de contraintes de mémoire (en fait, même la taille du lot 1 ne semble pas tenir sur un GPU de 12 Go en utilisant BERT-Large
). Cependant, un modèle BERT-Base
raisonnablement fort peut être formé sur le GPU avec ces hyperparamètres:
python run_squad.py
--vocab_file= $BERT_BASE_DIR /vocab.txt
--bert_config_file= $BERT_BASE_DIR /bert_config.json
--init_checkpoint= $BERT_BASE_DIR /bert_model.ckpt
--do_train=True
--train_file= $SQUAD_DIR /train-v1.1.json
--do_predict=True
--predict_file= $SQUAD_DIR /dev-v1.1.json
--train_batch_size=12
--learning_rate=3e-5
--num_train_epochs=2.0
--max_seq_length=384
--doc_stride=128
--output_dir=/tmp/squad_base/
Les prédictions de Dev set seront enregistrées dans un fichier appelé predictions.json
dans le output_dir
:
python $SQUAD_DIR /evaluate-v1.1.py $SQUAD_DIR /dev-v1.1.json ./squad/predictions.json
Qui devrait produire une sortie comme ceci:
{ " f1 " : 88.41249612335034, " exact_match " : 81.2488174077578}
Vous devriez voir un résultat similaire aux 88,5% signalés dans le document pour BERT-Base
.
Si vous avez accès à un TPU cloud, vous pouvez vous entraîner avec BERT-Large
. Voici un ensemble d'hyperparamètres (légèrement différent du papier) qui obtiennent constamment environ 90,5% -91,0% F1 à système unique formé uniquement sur l'escouade:
python run_squad.py
--vocab_file= $BERT_LARGE_DIR /vocab.txt
--bert_config_file= $BERT_LARGE_DIR /bert_config.json
--init_checkpoint= $BERT_LARGE_DIR /bert_model.ckpt
--do_train=True
--train_file= $SQUAD_DIR /train-v1.1.json
--do_predict=True
--predict_file= $SQUAD_DIR /dev-v1.1.json
--train_batch_size=24
--learning_rate=3e-5
--num_train_epochs=2.0
--max_seq_length=384
--doc_stride=128
--output_dir=gs://some_bucket/squad_large/
--use_tpu=True
--tpu_name= $TPU_NAME
Par exemple, une exécution aléatoire avec ces paramètres produit les scores de développement suivants:
{ " f1 " : 90.87081895814865, " exact_match " : 84.38978240302744}
Si vous affinez une époque sur Triviaqa avant cela, les résultats seront encore meilleurs, mais vous devrez convertir Triviaqa au format JSON Squad.
Ce modèle est également implémenté et documenté dans run_squad.py
.
Pour fonctionner sur Squad 2.0, vous devrez d'abord télécharger l'ensemble de données. Les fichiers nécessaires peuvent être trouvés ici:
Téléchargez-les dans un répertoire $SQUAD_DIR
.
Sur Cloud TPU, vous pouvez fonctionner avec Bert-Large comme suit:
python run_squad.py
--vocab_file= $BERT_LARGE_DIR /vocab.txt
--bert_config_file= $BERT_LARGE_DIR /bert_config.json
--init_checkpoint= $BERT_LARGE_DIR /bert_model.ckpt
--do_train=True
--train_file= $SQUAD_DIR /train-v2.0.json
--do_predict=True
--predict_file= $SQUAD_DIR /dev-v2.0.json
--train_batch_size=24
--learning_rate=3e-5
--num_train_epochs=2.0
--max_seq_length=384
--doc_stride=128
--output_dir=gs://some_bucket/squad_large/
--use_tpu=True
--tpu_name= $TPU_NAME
--version_2_with_negative=True
Nous supposons que vous avez tout copié, du répertoire de sortie à un répertoire local appelé ./squad/. Les prévisions initiales de Défilage de développement seront sur ./squad/predictions.json et les différences entre le score de non-réponse ("") et la meilleure réponse non nul pour chaque question seront dans le fichier ./squad/null_odds.json
Exécutez ce script pour régler un seuil pour prédire les réponses NULL contre non nulles:
python $ squad_dir / evaluate-v2.0.py $ squad_dir / dev-v2.0.json ./squad/predictions.json --na-prob-file ./squad/null_odds.json
Supposons que le script sortit "Best_F1_Thresh" Thresh. (Les valeurs typiques se situent entre -1,0 et -5.0). Vous pouvez désormais réintégrer le modèle pour générer des prédictions avec le seuil dérivé ou vous pouvez également extraire les réponses appropriées de ./squad/nbest_predictions.json.
python run_squad.py
--vocab_file= $BERT_LARGE_DIR /vocab.txt
--bert_config_file= $BERT_LARGE_DIR /bert_config.json
--init_checkpoint= $BERT_LARGE_DIR /bert_model.ckpt
--do_train=False
--train_file= $SQUAD_DIR /train-v2.0.json
--do_predict=True
--predict_file= $SQUAD_DIR /dev-v2.0.json
--train_batch_size=24
--learning_rate=3e-5
--num_train_epochs=2.0
--max_seq_length=384
--doc_stride=128
--output_dir=gs://some_bucket/squad_large/
--use_tpu=True
--tpu_name= $TPU_NAME
--version_2_with_negative=True
--null_score_diff_threshold= $THRESH
Toutes les expériences du papier ont été affinées sur un TPU cloud, qui a 64 Go de RAM de l'appareil. Par conséquent, lorsque vous utilisez un GPU avec 12 Go - 16 Go de RAM, vous risquez de rencontrer des problèmes hors mémoire si vous utilisez les mêmes hyperparamètres décrits dans l'article.
Les facteurs qui affectent l'utilisation de la mémoire sont:
max_seq_length
: les modèles libérés ont été entraînés avec des longueurs de séquence jusqu'à 512, mais vous pouvez affiner avec une longueur de séquence maximale plus courte pour économiser une mémoire substantielle. Ceci est contrôlé par l'indicateur max_seq_length
dans notre exemple de code.
train_batch_size
: L'utilisation de la mémoire est également directement proportionnelle à la taille du lot.
Type de modèle, BERT-Base
vs BERT-Large
: Le modèle BERT-Large
nécessite beaucoup plus de mémoire que BERT-Base
.
Optimiseur : L'optimiseur par défaut pour Bert est Adam, qui nécessite beaucoup de mémoire supplémentaire pour stocker les vecteurs m
et v
Le passage à un optimiseur plus efficace de mémoire peut réduire l'utilisation de la mémoire, mais peut également affecter les résultats. Nous n'avons pas expérimenté avec d'autres optimisateurs pour le réglage fin.
En utilisant les scripts d'entraînement par défaut ( run_classifier.py
et run_squad.py
), nous avons comparé la taille maximale du lot sur un seul titan x GPU (12 Go de RAM) avec TensorFlow 1.11.0:
Système | Longueur de seq | Taille du lot maximum |
---|---|---|
BERT-Base | 64 | 64 |
... | 128 | 32 |
... | 256 | 16 |
... | 320 | 14 |
... | 384 | 12 |
... | 512 | 6 |
BERT-Large | 64 | 12 |
... | 128 | 6 |
... | 256 | 2 |
... | 320 | 1 |
... | 384 | 0 |
... | 512 | 0 |
Malheureusement, ces tailles de lots maximales pour BERT-Large
sont si petites qu'elles nuiront en fait à la précision du modèle, quel que soit le taux d'apprentissage utilisé. Nous travaillons sur l'ajout de code à ce référentiel qui permettra d'utiliser des tailles de lots efficaces beaucoup plus importantes sur le GPU. Le code sera basé sur une (ou les deux) des techniques suivantes:
Accumulation de gradient : les échantillons d'un minibatch sont généralement indépendants en ce qui concerne le calcul du gradient (à l'exclusion de la normalisation par lots, qui n'est pas utilisé ici). Cela signifie que les gradients de plusieurs minibatchs plus petits peuvent être accumulés avant d'effectuer la mise à jour du poids, et cela sera exactement équivalent à une seule mise à jour plus grande.
Points de contrôle du gradient : L'utilisation principale de la mémoire GPU / TPU pendant la formation DNN consiste à mettre en cache les activations intermédiaires dans le laissez-passer vers l'avant qui sont nécessaires pour un calcul efficace dans le pass arrière. "Gradient CheckPointing" échange la mémoire contre le temps de calcul en recommandant les activations de manière intelligente.
Cependant, cela n'est pas mis en œuvre dans la version actuelle.
Dans certains cas, plutôt que de remonter l'ensemble de l'ensemble du modèle pré-formé de bout en bout, il peut être bénéfique pour obtenir des incorporations contextuelles pré-formées , qui sont des représentations contextuelles fixes de chaque jeton d'entrée généré à partir des couches cachées du pré -Me modèle formé. Cela devrait également atténuer la plupart des problèmes hors mémoire.
Par exemple, nous incluons le script extract_features.py
qui peut être utilisé comme ceci:
# Sentence A and Sentence B are separated by the ||| delimiter for sentence
# pair tasks like question answering and entailment.
# For single sentence inputs, put one sentence per line and DON'T use the
# delimiter.
echo ' Who was Jim Henson ? ||| Jim Henson was a puppeteer ' > /tmp/input.txt
python extract_features.py
--input_file=/tmp/input.txt
--output_file=/tmp/output.jsonl
--vocab_file= $BERT_BASE_DIR /vocab.txt
--bert_config_file= $BERT_BASE_DIR /bert_config.json
--init_checkpoint= $BERT_BASE_DIR /bert_model.ckpt
--layers=-1,-2,-3,-4
--max_seq_length=128
--batch_size=8
Cela créera un fichier JSON (une ligne par ligne d'entrée) contenant les activations Bert de chaque couche de transformateur spécifiée par layers
(-1 est la couche finale cachée du transformateur, etc.)
Notez que ce script produira de très grands fichiers de sortie (par défaut, environ 15 Ko pour chaque jeton d'entrée).
Si vous avez besoin de maintenir l'alignement entre les mots originaux et tokenisés (pour projeter les étiquettes de formation), consultez la section de tokenisation ci-dessous.
Remarque: Vous pouvez voir un message comme Could not find trained model in model_dir: /tmp/tmpuB5g5c, running initialization to predict.
Ce message est attendu, cela signifie simplement que nous utilisons l'API init_from_checkpoint()
plutôt que l'API du modèle enregistré. Si vous ne spécifiez pas de point de contrôle ou ne spécifiez pas de point de contrôle non valide, ce script se plaindra.
Pour les tâches au niveau de la phrase (ou paire de phrases), la tokenisation est très simple. Suivez simplement l'exemple de code dans run_classifier.py
et extract_features.py
. La procédure de base pour les tâches au niveau de la phrase est:
Instancier une instance de tokenizer = tokenization.FullTokenizer
Tokenize le texte brut avec tokens = tokenizer.tokenize(raw_text)
.
Tronquée à la longueur maximale de séquence. (Vous pouvez utiliser jusqu'à 512, mais vous voulez probablement utiliser plus court si possible pour des raisons de mémoire et de vitesse.)
Ajoutez les jetons [CLS]
et [SEP]
au bon endroit.
Les tâches au niveau des mots et au niveau de la portée (par exemple, Squad et NER) sont plus complexes, car vous devez maintenir l'alignement entre votre texte d'entrée et votre texte de sortie afin que vous puissiez projeter vos étiquettes de formation. L'équipe est un exemple particulièrement complexe car les étiquettes d'entrée sont basées sur les caractères , et les paragraphes d'escouade sont souvent plus longs que notre longueur de séquence maximale. Voir le code dans run_squad.py
pour montrer comment nous gérons cela.
Avant de décrire la recette générale pour la gestion des tâches au niveau des mots, il est important de comprendre ce que fait exactement notre tokenzer. Il a trois étapes principales:
Normalisation du texte : convertissez tous les caractères blancs en espace en espaces, et (pour le modèle Uncased
) en minuscules les marqueurs d'accent d'entrée et de dépression. Par exemple, John Johanson's, → john johanson's,
.
Prise de ponctuation : divisez tous les caractères de ponctuation des deux côtés (c'est-à-dire, ajoutez des espaces blancs autour de tous les caractères de ponctuation). Les caractères de ponctuation sont définis comme (a) tout ce qui avec une classe P*
Unicode, (b) tout caractère non-lettre / numéro / espace ASCII (par exemple, des caractères comme $
qui ne sont techniquement pas la ponctuation). Par exemple, john johanson's, → john johanson ' s ,
Tokenisation de la pièce : appliquez la tokenisation des espaces à la sortie de la procédure ci-dessus et appliquez séparément la tokenisation de la pièce de bouche à chaque jeton. (Notre implémentation est directement basée sur celle de tensor2tensor
, qui est liée). Par exemple, john johanson ' s , → john johan ##son ' s ,
L'avantage de ce schéma est qu'il est "compatible" avec la plupart des tokeniseurs anglais existants. Par exemple, imaginez que vous avez une tâche de marquage de discours qui ressemble à ceci:
Input: John Johanson 's house
Labels: NNP NNP POS NN
La sortie tokenisée ressemblera à ceci:
Tokens: john johan ##son ' s house
Surtout, ce serait la même sortie que si le texte brut était John Johanson's house
(sans espace avant les 's
).
Si vous avez une représentation pré-tentée avec des annotations au niveau des mots, vous pouvez simplement tokeniser chaque mot d'entrée indépendamment et maintenir de manière déterministe un alignement original à tendu:
### Input
orig_tokens = [ "John" , "Johanson" , "'s" , "house" ]
labels = [ "NNP" , "NNP" , "POS" , "NN" ]
### Output
bert_tokens = []
# Token map will be an int -> int mapping between the `orig_tokens` index and
# the `bert_tokens` index.
orig_to_tok_map = []
tokenizer = tokenization . FullTokenizer (
vocab_file = vocab_file , do_lower_case = True )
bert_tokens . append ( "[CLS]" )
for orig_token in orig_tokens :
orig_to_tok_map . append ( len ( bert_tokens ))
bert_tokens . extend ( tokenizer . tokenize ( orig_token ))
bert_tokens . append ( "[SEP]" )
# bert_tokens == ["[CLS]", "john", "johan", "##son", "'", "s", "house", "[SEP]"]
# orig_to_tok_map == [1, 2, 4, 6]
Maintenant, orig_to_tok_map
peut être utilisé pour projeter labels
dans la représentation tokenisée.
Il existe des schémas de tokenisation anglais courants qui entraîneront un léger décalage entre la façon dont Bert a été formé. Par exemple, si votre jeton d'entrée divise les contractions comme do n't
, cela entraînera un décalage. S'il est possible de le faire, vous devez prétraiter vos données pour les convertir en texte brut, mais si ce n'est pas possible, cette inadéquation n'est probablement pas un gros problème.
Nous publions du code pour faire "Masked LM" et "Next phrase Prediction" sur un corpus de texte arbitraire. Notez que ce n'est pas le code exact qui a été utilisé pour l'article (le code d'origine a été écrit en C ++, et avait une complexité supplémentaire), mais ce code génère des données de pré-formation comme décrit dans l'article.
Voici comment exécuter la génération de données. L'entrée est un fichier texte brut, avec une phrase par ligne. (Il est important que ce soit des phrases réelles pour la tâche "prédiction de phrase suivante"). Les documents sont délimités par des lignes vides. La sortie est un ensemble de tf.train.Example
s sérialisé au format de fichier TFRecord
.
Vous pouvez effectuer une segmentation des phrases avec une boîte à outils NLP standard telle que Spacy. Le script create_pretraining_data.py
concaténera les segments jusqu'à ce qu'ils atteignent la longueur maximale de séquence pour minimiser les déchets de calcul du rembourrage (voir le script pour plus de détails). Cependant, vous voudrez peut-être ajouter intentionnellement une légère quantité de bruit à vos données d'entrée (par exemple, tronquer au hasard 2% des segments d'entrée) pour le rendre plus robuste aux entrées non contentes pendant le réglage fin.
Ce script stocke tous les exemples de l'ensemble du fichier d'entrée en mémoire, donc pour les grands fichiers de données, vous devez refléter le fichier d'entrée et appeler le script plusieurs fois. (Vous pouvez passer dans un globe de fichier pour run_pretraining.py
, par exemple, tf_examples.tf_record*
.)
Le max_predictions_per_seq
est le nombre maximal de prédictions LM masquées par séquence. Vous devez le définir sur max_seq_length
* masked_lm_prob
(le script ne le fait pas automatiquement car la valeur exacte doit être transmise aux deux scripts).
python create_pretraining_data.py
--input_file=./sample_text.txt
--output_file=/tmp/tf_examples.tfrecord
--vocab_file= $BERT_BASE_DIR /vocab.txt
--do_lower_case=True
--max_seq_length=128
--max_predictions_per_seq=20
--masked_lm_prob=0.15
--random_seed=12345
--dupe_factor=5
Voici comment exécuter la pré-formation. N'incluez pas init_checkpoint
si vous pré-formation à partir de zéro. La configuration du modèle (y compris la taille du vocabulaire) est spécifiée dans bert_config_file
. Ce code de démonstration ne pré-t-trains que pour un petit nombre d'étapes (20), mais en pratique, vous voudrez probablement définir num_train_steps
à 10000 étapes ou plus. Les paramètres max_seq_length
et max_predictions_per_seq
transmis à run_pretraining.py
doivent être les mêmes que create_pretraining_data.py
.
python run_pretraining.py
--input_file=/tmp/tf_examples.tfrecord
--output_dir=/tmp/pretraining_output
--do_train=True
--do_eval=True
--bert_config_file= $BERT_BASE_DIR /bert_config.json
--init_checkpoint= $BERT_BASE_DIR /bert_model.ckpt
--train_batch_size=32
--max_seq_length=128
--max_predictions_per_seq=20
--num_train_steps=20
--num_warmup_steps=10
--learning_rate=2e-5
Cela produira une sortie comme ceci:
***** Eval results *****
global_step = 20
loss = 0.0979674
masked_lm_accuracy = 0.985479
masked_lm_loss = 0.0979328
next_sentence_accuracy = 1.0
next_sentence_loss = 3.45724e-05
Notez que puisque notre fichier sample_text.txt
est très petit, cet exemple de formation ne surviendra pas sur ces données en quelques étapes et produira des numéros de précision irréaliste.
vocab_size
dans bert_config.json
. Si vous utilisez un vocabulaire plus important sans changer cela, vous obtiendrez probablement des NANS lors de la formation sur GPU ou TPU en raison d'un accès hors limites non coché.max_seq_length
.BERT-Base
sur un seul Cloud TPU V2 préemptable, qui prend environ 2 semaines à un coût d'environ 500 $ USD (sur la base du prix en octobre 2018) . Vous devrez réduire la taille du lot lorsque vous vous entraînez uniquement sur un seul TPU cloud, par rapport à ce qui a été utilisé dans le papier. Il est recommandé d'utiliser la plus grande taille de lot qui s'inscrit dans la mémoire TPU. Nous ne pourrons pas publier les ensembles de données prétraités utilisés dans le document. Pour Wikipedia, le prétraitement recommandé est de télécharger le dernier vidage, d'extraire le texte avec WikiExtractor.py
, puis d'appliquer tout nettoyage nécessaire pour le convertir en texte brut.
Malheureusement, les chercheurs qui ont collecté le BookCorpus ne l'ont plus disponible pour le téléchargement public. L'ensemble de données Project Guttenberg est une collection un peu plus petite (Word) de livres plus anciens qui sont du domaine public.
La rampe commune est une autre très grande collection de texte, mais vous devrez probablement faire un prétraitement et un nettoyage substantiels pour extraire un corpus utilisable pour la pré-formation Bert.
Ce référentiel n'inclut pas le code pour l'apprentissage d'un nouveau vocabulaire de pièce de bouche. The reason is that the code used in the paper was implemented in C++ with dependencies on Google's internal libraries. For English, it is almost always better to just start with our vocabulary and pre-trained models. For learning vocabularies of other languages, there are a number of open source options available. However, keep in mind that these are not compatible with our tokenization.py
library:
Google's SentencePiece library
tensor2tensor's WordPiece generation script
Rico Sennrich's Byte Pair Encoding library
If you want to use BERT with Colab, you can get started with the notebook "BERT FineTuning with Cloud TPUs". At the time of this writing (October 31st, 2018), Colab users can access a Cloud TPU completely for free. Note: One per user, availability limited, requires a Google Cloud Platform account with storage (although storage may be purchased with free credit for signing up with GCP), and this capability may not longer be available in the future. Click on the BERT Colab that was just linked for more information.
Yes, all of the code in this repository works out-of-the-box with CPU, GPU, and Cloud TPU. However, GPU training is single-GPU only.
See the section on out-of-memory issues for more information.
There is no official PyTorch implementation. However, NLP researchers from HuggingFace made a PyTorch version of BERT available which is compatible with our pre-trained checkpoints and is able to reproduce our results. We were not involved in the creation or maintenance of the PyTorch implementation so please direct any questions towards the authors of that repository.
There is no official Chainer implementation. However, Sosuke Kobayashi made a Chainer version of BERT available which is compatible with our pre-trained checkpoints and is able to reproduce our results. We were not involved in the creation or maintenance of the Chainer implementation so please direct any questions towards the authors of that repository.
Yes, we plan to release a multi-lingual BERT model in the near future. We cannot make promises about exactly which languages will be included, but it will likely be a single model which includes most of the languages which have a significantly-sized Wikipedia.
BERT-Large
be released? So far we have not attempted to train anything larger than BERT-Large
. It is possible that we will release larger models if we are able to obtain significant improvements.
All code and models are released under the Apache 2.0 license. Voir le fichier LICENSE
pour plus d'informations.
For now, cite the Arxiv paper:
@article{devlin2018bert,
title={BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding},
author={Devlin, Jacob and Chang, Ming-Wei and Lee, Kenton and Toutanova, Kristina},
journal={arXiv preprint arXiv:1810.04805},
year={2018}
}
If we submit the paper to a conference or journal, we will update the BibTeX.
This is not an official Google product.
For help or issues using BERT, please submit a GitHub issue.
For personal communication related to BERT, please contact Jacob Devlin ( [email protected]
), Ming-Wei Chang ( [email protected]
), or Kenton Lee ( [email protected]
).