***** NEU 11. März 2020: kleinere Bert -Modelle *****
Dies ist eine Veröffentlichung von 24 kleineren Bert-Modellen (nur englisch, ungezogen, mit Wortstücksmaskierung ausgebildet), auf die gut gelesene Schüler besser lernen: über die Bedeutung von Kompaktmodellen vor dem Training.
Wir haben gezeigt, dass das Standard-Bert-Rezept (einschließlich Modellarchitektur und Schulungsziel) auf einer Vielzahl von Modellgrößen über Bert-Base und Bert-Large wirksam ist. Die kleineren Bert -Modelle sind für Umgebungen mit eingeschränkten Rechenressourcen vorgesehen. Sie können auf die gleiche Weise wie die ursprünglichen Bert-Modelle fein abgestimmt werden. Sie sind jedoch im Kontext der Wissensdestillation am effektivsten, wo die Feinabstimmungsetiketten von einem größeren und genaueren Lehrer erzeugt werden.
Unser Ziel ist es, Forschung in Institutionen mit weniger Rechenressourcen zu ermöglichen und die Gemeinschaft zu ermutigen, eine Innovations -Alternative zur Erhöhung der Modellkapazität zu suchen.
Sie können alle 24 von hier oder einzeln aus der folgenden Tabelle herunterladen:
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-Mini) | 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) |
Beachten Sie, dass das Bert-Base-Modell in dieser Version nur zur Vollständigkeit enthalten ist. Es wurde unter demselben Regime wie das ursprüngliche Modell erneut ausgestattet.
Hier sind die entsprechenden Kleberwerte im Testsatz:
Modell | Punktzahl | Cola | SST-2 | MRPC | STS-B | QQP | Mnli-m | Mnli-mm | Qnli (v2) | Rte | Wnli | AXT |
---|---|---|---|---|---|---|---|---|---|---|---|---|
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-Mini | 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-Small | 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-Medium | 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 |
Für jede Aufgabe haben wir die besten Feinabstimmungshyperparameter aus den folgenden Listen ausgewählt und für 4 Epochen trainiert:
Wenn Sie diese Modelle verwenden, zitieren Sie bitte das folgende Papier:
@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}
}
***** NEU 31. Mai 2019: Ganzes Wortmaskierungsmodelle *****
Dies ist eine Veröffentlichung mehrerer neuer Modelle, die das Ergebnis einer Verbesserung des Vorverarbeitungscodes waren.
Im ursprünglichen Vorverarbeitungscode wählen wir zufällig Wektion-Token für die Maske aus. Zum Beispiel:
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
Die neue Technik heißt Whole Word -Maskierung. In diesem Fall maskieren wir immer alle Token, die einem Wort gleichzeitig entsprechen. Die Gesamtmaskierungsrate bleibt gleich.
Whole Word Masked Input: the man [MASK] up , put his basket on [MASK] [MASK] [MASK] ' s head
Das Training ist identisch - wir prognostizieren immer noch jedes maskierte Wortstück unabhängig. Die Verbesserung ergibt sich aus der Tatsache, dass die ursprüngliche Vorhersageaufgabe für Wörter zu „einfach“ war, die in mehrere Wortbilder aufgeteilt worden waren.
Dies kann während der Datenerzeugung aktiviert werden, indem das Flag --do_whole_word_mask=True
to create_pretraining_data.py
übergeben wird.
Vorausgebildete Modelle mit ganzem Wortmaskieren sind unten verknüpft. Die Daten und das Training waren ansonsten identisch, und die Modelle haben eine identische Struktur und ein Vokabel mit den ursprünglichen Modellen. Wir enthalten nur Bert-Large-Modelle. Machen Sie bei der Verwendung dieser Modelle bitte in dem Papier klar, dass Sie die gesamte Wortmaskierungsvariante von Bert-Large verwenden.
BERT-Large, Uncased (Whole Word Masking)
BERT-Large, Cased (Whole Word Masking)
: 24 -schichtige, 1024 versteckte, 16-köpfige, 340m Parameter
Modell | Kader 1.1 F1/em | Multi -NLI -Genauigkeit |
---|---|---|
Bert-Large, ungezogen (Original) | 91.0/84.3 | 86.05 |
Bert-Large, ungezogen (ganze Wortmaskierung) | 92.8/86.7 | 87.07 |
Bert-Large, gedeckt (original) | 91.5/84.8 | 86.09 |
Bert-Large, Gehäuse (ganze Wortmaskierung) | 92.9/86.7 | 86,46 |
***** Neues 7. Februar 2019: TFHUB -Modul *****
Bert wurde auf den TensorFlow Hub hochgeladen. In run_classifier_with_tfhub.py
finden Sie ein Beispiel für die Verwendung des TF -Hub -Moduls oder ein Beispiel im Browser auf Colab.
***** NEU 23. November 2018: Unormalisiertes mehrsprachiges Modell + Thai + Mongolian *****
Wir haben ein neues mehrsprachiges Modell hochgeladen, das keine Normalisierung auf der Eingabe durchführt (kein niedrigeres Gehäuse, ein Akzentstreifen oder eine Unicode -Normalisierung) und zusätzlich thailändisch und mongolisch.
Es wird empfohlen, diese Version für die Entwicklung mehrsprachiger Modelle zu verwenden, insbesondere in Sprachen mit Nicht-Latin-Alphabeten.
Dies erfordert keine Codeänderungen und kann hier heruntergeladen werden:
BERT-Base, Multilingual Cased
: 104 Sprachen, 12 -schichtige, 768 versteckte, 12-Heads, 110 m Parameter***** NEU 15. November 2018: Sota Squad 2.0 System *****
Wir haben Codeänderungen veröffentlicht, um unser 83% iger F1 Squad 2.0 -System zu reproduzieren, das derzeit um 3% auf der Rangliste auf der Rangliste liegt. Einzelheiten finden Sie im Abschnitt Kader 2.0 des Readme.
***** NEU 5. November 2018: Drittanbieter Pytorch- und Chainer-Versionen von Bert verfügbar *****
NLP-Forscher von Huggingface haben eine Pytorch-Version von Bert verfügbar gemacht, die mit unseren vorgeborenen Kontrollpunkten kompatibel ist und unsere Ergebnisse reproduzieren kann. Sosuke Kobayashi hat auch eine Chainer -Version von Bert zur Verfügung gestellt (danke!). Wir waren nicht an der Erstellung oder Wartung der Pytorch -Implementierung beteiligt. Richten Sie also bitte alle Fragen an die Autoren dieses Repositorys.
***** Neues 3. November 2018: Mehrsprachige und chinesische Modelle erhältlich *****
Wir haben zwei neue Bert -Modelle zur Verfügung gestellt:
BERT-Base, Multilingual
(nicht empfohlen, stattdessen Multilingual Cased
verwenden) : 102 Sprachen, 12 -schichtige, 768 versteckte, 12-Heads, 110 m ParameterBERT-Base, Chinese
: Chinesisch vereinfacht und traditionell, 12-Schicht, 768 versteckte, 12-Heads, 110 m Parameter Wir verwenden eine charakterbasierte Tokenisierung für chinesische und Wortstücks-Tokenisierung für alle anderen Sprachen. Beide Modelle sollten ohne Code-Änderungen außerhalb des Boxs funktionieren. Wir haben die Implementierung von BasicTokenizer
in tokenization.py
aktualisiert, um die chinesische Charakter -Tokenisierung zu unterstützen. Wir haben die Tokenization -API jedoch nicht geändert.
Weitere Informationen finden Sie in der mehrsprachigen Readme.
***** beenden neue Informationen *****
Bert , oder die idirektionale E- NCODER - EPRESETATIONEN von T -Ransformers ist eine neue Methode für die Repräsentationen vor dem Training, die hochmoderne Ergebnisse zu einer Vielzahl von Aufgaben der natürlichen Sprachverarbeitung (NLP) erzielt.
Unser akademisches Papier, das Bert im Detail beschreibt und die vollständigen Ergebnisse zu einer Reihe von Aufgaben liefert, finden Sie hier: https://arxiv.org/abs/1810.04805.
Um ein paar Zahlen zu geben, finden Sie hier die Ergebnisse im Kader V1.1 Fragenbeantwortungsaufgabe:
Squad V1.1 Rangliste (8. Oktober 2018) | Teste em | Test F1 |
---|---|---|
1. Platz Ensemble - Bert | 87,4 | 93.2 |
2. Platz Ensemble - NLNET | 86.0 | 91.7 |
1st Place Einzelmodell - Bert | 85.1 | 91.8 |
2nd Place Einzelmodell - NLNET | 83,5 | 90.1 |
Und mehrere natürliche Sprachinferenzaufgaben:
System | Multinli | Frage nli | BEUTE |
---|---|---|---|
Bert | 86,7 | 91.1 | 86,3 |
Openai GPT (Prev. Sota) | 82.2 | 88.1 | 75,0 |
Plus viele andere Aufgaben.
Darüber hinaus wurden diese Ergebnisse mit fast keinem aufgabenspezifischen Design der neuronalen Netzwerkarchitektur erhalten.
Wenn Sie bereits wissen, was Bert ist und Sie nur loslegen möchten, können Sie die vorgebauten Modelle herunterladen und in nur wenigen Minuten eine hochmoderne Feinabstimmung ausführen.
Bert ist eine Methode der Repräsentationen vor dem Training, was bedeutet, dass wir ein allgemeines "Sprachverständnis" -Modell auf einem großen Textkorpus (wie Wikipedia) trainieren und dieses Modell dann für nachgeschaltete NLP-Aufgaben verwenden (wie Frage Antwort). Bert übertrifft frühere Methoden, da es sich um das erste unbeaufsichtigte , zutiefst bidirektionale System für NLP vor dem Training handelt.
Unüberständiger bedeutet, dass Bert nur mit einem einfachen Textkorpus trainiert wurde, was wichtig ist, da eine enorme Menge an einfachen Textdaten in vielen Sprachen im Internet öffentlich verfügbar ist.
Vorausgebildete Darstellungen können entweder kontextfrei oder kontextbezogen sein, und kontextbezogene Darstellungen können weiter unidirektional oder bidirektional sein. Kontextfreie Modelle wie Word2VEC oder Handschuh erzeugen für jedes Wort im Wortschatz eine einzelne "Worteinbettung" -Darstellung, sodass bank
die gleiche Darstellung in bank deposit
und river bank
hat. Kontextmodelle erzeugen stattdessen eine Darstellung jedes Wortes, das auf den anderen Wörtern im Satz basiert.
Bert wurde auf den jüngsten Arbeiten in kontextbezogenen Darstellungen vor dem Training basiert-einschließlich des semi-überprüften Sequenzlernens, generativen Voraussetzungen, ELMO und Ulmfit-, aber entscheidend sind diese Modelle alle unidirektionale oder flach bidirektionale . Dies bedeutet, dass jedes Wort nur mit den Wörtern links (oder rechts) kontextualisiert wird. Zum Beispiel basiert I made a bank deposit
die unidirektionale Vertretung der bank
nur darauf, dass I made a
jedoch keine deposit
vorgenommen habe. Einige frühere Arbeiten kombinieren die Darstellungen aus separaten Modellen für linke Kontexten und rechte Kontext, jedoch nur auf "flache" Weise. Bert repräsentiert "Bank", die sowohl den linken als auch den rechten Kontext verwendet - I made a ... deposit
- angefangen von ganz unten in einem tiefen neuronalen Netzwerk, sodass es zutiefst bidirektional ist.
Bert verwendet dafür einen einfachen Ansatz: Wir maskieren 15% der Wörter in der Eingabe, führen die gesamte Sequenz durch einen tiefen bidirektionalen Transformator -Encoder aus und prognostizieren dann nur die maskierten Wörter. Zum Beispiel:
Input: the man went to the [MASK1] . he bought a [MASK2] of milk.
Labels: [MASK1] = store; [MASK2] = gallon
Um Beziehungen zwischen Sätzen zu lernen, schulen wir auch eine einfache Aufgabe, die von jedem einsprachigen Korpus erstellt werden kann: Angesichts der zwei Sätze A
und B
ist B
der tatsächliche nächste Satz, der nach A
oder nur ein zufälliger Satz aus dem Korpus erfolgt ?
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
Anschließend trainieren wir ein großes Modell (12-Schicht bis 24-Schicht-Transformator) für einen großen Korpus (Wikipedia + Bookcorpus) für lange Zeit (1M-Update-Schritte), und das ist Bert.
Die Verwendung von Bert hat zwei Stufen: Vorausbildung und Feinabstimmung .
Die Vorausbildung ist ziemlich teuer (vier Tage auf 4 bis 16 Cloud-TPUs), ist jedoch ein einmaliges Verfahren für jede Sprache (aktuelle Modelle sind nur Englisch, aber in naher Zukunft werden mehrsprachige Modelle veröffentlicht). Wir veröffentlichen eine Reihe von vorgeborenen Modellen aus dem Papier, die bei Google ausgebildet wurden. Die meisten NLP-Forscher müssen ihr eigenes Modell niemals von Grund auf neu verarbeiten.
Feinabstimmung ist kostengünstig. Alle Ergebnisse des Papiers können in einer einzelnen Wolken-TPU oder einige Stunden auf einer GPU in einer einzelnen Cloud-TPU repliziert werden, beginnend mit genau dem gleichen vorgebildeten Modell. Squad kann beispielsweise in einer einzelnen Wolken-TPU in etwa 30 Minuten trainiert werden, um einen Dev F1-Score von 91,0%zu erzielen, was das einzelne System auf dem neuesten Stand der Technik ist.
Der andere wichtige Aspekt von Bert ist, dass er sehr leicht an viele Arten von NLP -Aufgaben angepasst werden kann. In der Arbeit demonstrieren wir hochmoderne Ergebnisse auf Satzebene (z. B. SST-2), Satzpaarebene (z. B. Multinli), Wortebene (z. (z. B. Kader) Aufgaben mit fast ohne aufgabenspezifischen Modifikationen.
Wir veröffentlichen Folgendes:
BERT-Base
und BERT-Large
aus dem Papier.Der gesamte Code in diesem Repository arbeitet mit CPU, GPU und Cloud TPU.
Wir veröffentlichen die BERT-Base
und BERT-Large
-Modelle aus dem Papier. Uncased
bedeutet, dass der Text vor der Wortstücks -Tokenisierung verringert wurde, z. B. John Smith
wird zu john smith
. Das Uncased
Modell streift auch alle Akzentmarker aus. Cased
bedeutet, dass der wahre Fall und die Akzentmarkierungen erhalten bleiben. In der Regel ist das Uncased
Modell besser, es sei denn, Sie wissen, dass Fallinformationen für Ihre Aufgabe wichtig sind (z. B. benannte Entitätserkennung oder Speech-Tagging).
Diese Modelle werden alle unter derselben Lizenz wie der Quellcode (Apache 2.0) veröffentlicht.
Informationen zum mehrsprachigen und chinesischen Modell finden Sie im mehrsprachigen Readme.
Stellen Sie bei Verwendung eines Gehäusemodells sicher, dass Sie --do_lower=False
an die Trainingsskripte bestehen. (Oder übergeben Sie do_lower_case=False
direkt an FullTokenizer
, wenn Sie Ihr eigenes Skript verwenden.)
Die Links zu den Modellen finden Sie hier (klicken Sie mit der rechten Maustaste, "Link als ..." im Namen):
BERT-Large, Uncased (Whole Word Masking)
BERT-Large, Cased (Whole Word Masking)
: 24 -schichtige, 1024 versteckte, 16-köpfige, 340m ParameterBERT-Base, Uncased
BERT-Large, Uncased
: 24 -schichtige, 1024 versteckte, 16-köpfige, 340m ParameterBERT-Base, Cased
: 12-Layer, 768 versteckte, 12-Heads, 110 m ParameterBERT-Large, Cased
: 24-Layer, 1024 versteckte, 16-köpfige, 340m ParameterBERT-Base, Multilingual Cased (New, recommended)
: 104 Sprachen, 12 -schichtige, 768 versteckte, 12-Heads, 110m ParameterMultilingual Cased
BERT-Base, Multilingual Uncased (Orig, not recommended)
BERT-Base, Chinese
: Chinesisch vereinfacht und traditionell, 12-Schicht, 768 versteckte, 12-Heads, 110 m ParameterJede .zip -Datei enthält drei Elemente:
bert_model.ckpt
), das die vorgebreiteten Gewichte enthält (was tatsächlich 3 Dateien ist).vocab.txt
), um Wordstück auf Word -ID zuzuordnen.bert_config.json
), die die Hyperparameter des Modells angibt. Wichtig : Alle Ergebnisse auf dem Papier wurden auf einer einzelnen Cloud-TPU mit 64 GB RAM fein abgestimmt. Derzeit ist es nicht möglich, die meisten BERT-Large
-Ergebnisse auf dem Papier mit einer GPU mit 12 GB 16 GB RAM neu zu produzieren, da die maximale Chargengröße, die in den Speicher passt, zu klein ist. Wir arbeiten daran, dieses Repository Code hinzuzufügen, das eine viel größere effektive Stapelgröße für die GPU ermöglicht. Weitere Informationen finden Sie im Abschnitt zu außerfeiligen Fragen.
Dieser Code wurde mit TensorFlow 1.11.0 getestet. Es wurde mit Python2 und Python3 getestet (aber gründlicher mit Python2, da dies das interne in Google verwendet wird).
Die Feinabstimmungsbeispiele, die BERT-Base
verwenden, sollten in der Lage sein, auf einer GPU mit mindestens 12 GB RAM mit den angegebenen Hyperparametern auszuführen.
In den meisten folgenden Beispielen wird davon ausgegangen, dass Sie Schulungen/Bewertungen auf Ihrer lokalen Maschine mit einer GPU wie einem Titan X oder GTX 1080 ausführen.
Wenn Sie jedoch Zugriff auf eine Cloud -TPU haben, die Sie trainieren möchten, fügen Sie einfach die folgenden Flags zum run_classifier.py
oder run_squad.py
hinzu:
--use_tpu=True
--tpu_name=$TPU_NAME
In der Google Cloud TPU -Tutorial finden Sie die Verwendung von Cloud -TPUs. Alternativ können Sie das Google Colab -Notebook "Bert Fonetuning mit Cloud -TPUs" verwenden.
Bei Cloud TPUs muss das vorgezogene Modell und das Ausgabemittel im Google Cloud -Speicher sein. Wenn Sie beispielsweise einen Eimer namens some_bucket
haben, verwenden Sie möglicherweise stattdessen die folgenden Flags:
--output_dir=gs://some_bucket/my_output_dir/
Die entlarnten vorgeborenen Modelldateien finden Sie auch im Google Cloud Storage-Ordner gs://bert_models/2018_10_18
. Zum Beispiel:
export BERT_BASE_DIR=gs://bert_models/2018_10_18/uncased_L-12_H-768_A-12
Bevor Sie dieses Beispiel ausführen, müssen Sie die Klebendaten herunterladen, indem Sie dieses Skript ausführen und auf ein Verzeichnis $GLUE_DIR
auspacken. Laden Sie als Nächstes den BERT-Base
Checkpoint herunter und entpacken Sie ihn in ein Verzeichnis $BERT_BASE_DIR
.
In diesem Beispiel für Codes-Fine-Tunes BERT-Base
auf dem Microsoft Research Paraphrase Corpus (MRPC) Corpus, das nur 3.600 Beispiele enthält und bei den meisten GPUs in wenigen Minuten eine Feinabstimmung.
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/
Sie sollten die Ausgabe wie diese sehen:
***** Eval results *****
eval_accuracy = 0.845588
eval_loss = 0.505248
global_step = 343
loss = 0.505248
Dies bedeutet, dass die Genauigkeit der Dev Set 84,55%betrug. Kleine Sets wie MRPC haben eine hohe Abweichung in der Genauigkeit des Entwicklersatzes, selbst wenn sie mit dem gleichen Checkpoint vor dem Training beginnen. Wenn Sie mehrmals erneut ausgeführt werden (achten Sie darauf, dass Sie auf unterschiedliche output_dir
verweisen), sollten Sie Ergebnisse zwischen 84% und 88% sehen.
Einige andere vorgeborene Modelle werden in run_classifier.py
außerhalb des Schusses implementiert. Daher sollte es unkompliziert sein, diesen Beispielen zu befolgen, um Bert für jede Ein- oder Satz-Pair-Klassifizierungsaufgabe zu verwenden.
Hinweis: Möglicherweise sehen Sie eine Nachricht Running train on CPU
. Dies bedeutet wirklich nur, dass es auf etwas anderem als einer Cloud -TPU läuft, die eine GPU enthält.
Sobald Sie Ihren Klassifikator trainiert haben, können Sie ihn im Inferenzmodus verwenden, indem Sie den Befehl - -do_prredict = true verwenden. Sie müssen eine Datei namens test.tsv im Eingabedordner haben. Die Ausgabe wird in der Datei test_results.tsv im Ausgabeordner erstellt. Jede Zeile enthält Ausgang für jede Probe, Spalten sind die Klassenwahrscheinlichkeiten.
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/
Der Stanford -Frage, der den Datensatz (Squad) beantwortet hat, ist eine beliebte Frage, die den Benchmark -Datensatz beantwortet. Bert (zum Zeitpunkt der Veröffentlichung) erzielt hochmoderne Ergebnisse im Kader ohne aufgabenspezifische Netzwerkarchitekturänderungen oder Datenvergrößerungen. Es erfordert jedoch eine semi-komplexe Datenvorverarbeitung und Nachbearbeitung, um mit (a) die Natur der variablen Länge der Squad-Kontextabsätze und (b) die Annotationen auf Charakterebene, die für das Squad-Training verwendet werden, umzugehen. Diese Verarbeitung wird in run_squad.py
implementiert und dokumentiert.
Um im Kader auszuführen, müssen Sie zunächst den Datensatz herunterladen. Die Squad -Website scheint nicht länger mit den Datensätzen v1.1 zu verlinken, aber die erforderlichen Dateien finden Sie hier:
Laden Sie diese in ein Verzeichnis $SQUAD_DIR
herunter.
Die hochmodernen Kaderergebnisse des Papiers können derzeit nicht auf einer 12-GB-16 GB-GPU aufgrund von Speicherbeschränkungen reproduziert werden (in der Tat scheint selbst die Stapelgröße 1 nicht in eine 12-GB-GPU mit BERT-Large
zu passen). Ein einigermaßen starker BERT-Base
Modell kann jedoch mit diesen Hyperparametern auf der GPU trainiert werden:
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/
Die Dev -Set -Vorhersagen werden in einer Datei namens predictions.json
im output_dir
gespeichert:
python $SQUAD_DIR /evaluate-v1.1.py $SQUAD_DIR /dev-v1.1.json ./squad/predictions.json
Was eine solche Ausgabe erzeugen sollte:
{ " f1 " : 88.41249612335034, " exact_match " : 81.2488174077578}
Sie sollten ein ähnliches Ergebnis wie die in der Arbeit für BERT-Base
angegebenen 88,5% sehen.
Wenn Sie Zugriff auf eine Cloud-TPU haben, können Sie mit BERT-Large
trainieren. Hier finden Sie eine Reihe von Hyperparametern (etwas anders als das Papier), die durchweg rund 90,5% -91,0% F1-Einzelsystem erhalten, die nur im Kader trainiert sind:
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
Beispielsweise erzeugt ein zufälliger Lauf mit diesen Parametern die folgenden Entwicklerwerte:
{ " f1 " : 90.87081895814865, " exact_match " : 84.38978240302744}
Wenn Sie vor diesem Einsatz für eine Epoche auf Triviaqa gut abgestimmen, sind die Ergebnisse noch besser, aber Sie müssen Triviaqa in das Squad JSON-Format umwandeln.
Dieses Modell wird auch in run_squad.py
implementiert und dokumentiert.
Um auf Squad 2.0 auszuführen, müssen Sie zunächst den Datensatz herunterladen. Die erforderlichen Dateien finden Sie hier:
Laden Sie diese in ein Verzeichnis $SQUAD_DIR
herunter.
Auf Cloud TPU können Sie wie folgt mit Bert-Large ausführen:
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
Wir gehen davon aus, dass Sie alles vom Ausgabeverzeichnis zu einem lokalen Verzeichnis namens ./Squad/ kopiert haben. Die anfänglichen Entwicklungsvorhersagen werden unter ./Squad/Predictions.json und die Unterschiede zwischen der Punktzahl von NO-Antwort ("") und der besten Nicht-Null-Antwort für jede Frage sein.
Führen Sie dieses Skript aus, um einen Schwellenwert für die Vorhersage von NULL gegenüber Nicht-Null-Antworten zu stimmen:
python $ squad_dir/evaluate-v2.0.py $ squad_dir/dev-v2.0.json ./squad/prredictions.json --na-prob-file ./squad/null_odds.json
Nehmen wir an, das Skript gibt "Best_f1_thresh" Thresh aus. (Typische Werte liegen zwischen -1.0 und -5.0). Sie können das Modell nun neu ausführen, um Vorhersagen mit dem abgeleiteten Schwellenwert zu generieren, oder alternativ können Sie die entsprechenden Antworten von ./Squad/nbest_Predictions.json extrahieren.
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
Alle Experimente in der Arbeit wurden auf einer Cloud-TPU mit 64 GB Geräte-RAM fein abgestimmt. Wenn Sie daher eine GPU mit 12 GB-16 GB RAM verwenden, werden Sie daher wahrscheinlich auf Außenprobleme stoßen, wenn Sie dieselben Hyperparameter verwenden, die im Papier beschrieben sind.
Die Faktoren, die die Speicherverwendung beeinflussen, sind:
max_seq_length
: Die freigegebenen Modelle wurden mit Sequenzlängen von bis zu 512 trainiert, aber Sie können mit einer kürzeren Max-Sequenzlänge fein stimmen, um einen wesentlichen Speicher zu sparen. Dies wird durch das Flag max_seq_length
in unserem Beispielcode gesteuert.
train_batch_size
: Die Speicherverwendung ist auch direkt proportional zur Stapelgröße.
Modelltyp, BERT-Base
vs. BERT-Large
: Das BERT-Large
-Modell erfordert deutlich mehr Speicher als BERT-Base
.
Optimierer : Der Standardoptimierer für Bert ist Adam, für den viel zusätzlicher Speicher erforderlich ist, um die m
und v
zu speichern. Wenn Sie auf einen speicher effizienteren Optimierer umstellen, können Sie die Speicherverwendung reduzieren, die Ergebnisse jedoch auch beeinflussen. Wir haben nicht mit anderen Optimierern zur Feinabstimmung experimentiert.
Verwenden der Standard -Trainingsskripte ( run_classifier.py
und run_squad.py
) haben wir die maximale Chargengröße für Single Titan X GPU (12 GB RAM) mit TensorFlow 1.11.0 bewertet:
System | SEQ Länge | Max Batchgröße |
---|---|---|
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 |
Leider sind diese Max-Chargengrößen für BERT-Large
so klein, dass sie die Modellgenauigkeit tatsächlich schädigen, unabhängig von der verwendeten Lernrate. Wir arbeiten daran, dieses Repository Code hinzuzufügen, mit dem viel größere effektive Stapelgrößen für die GPU verwendet werden können. Der Code basiert auf einem (oder beiden) der folgenden Techniken:
Gradientenakkumulation : Die Proben in einer Minibatch sind in Bezug auf die Gradientenberechnung typischerweise unabhängig (mit Ausnahme der hier nicht verwendeten Batch -Normalisierung). Dies bedeutet, dass die Gradienten mehrerer kleinerer Minibatches vor der Durchführung des Gewichts -Update akkumuliert werden können, und dies entspricht genau einem einzigen größeren Update.
Gradientenprüfung : Die Hauptverwendung des GPU/TPU -Speichers während des DNN -Trainings besteht darin, die Zwischenaktivierungen im Vorwärtspass zu zwischenstrichen, die für eine effiziente Berechnung im Rückwärtspass erforderlich sind. "Gradient Checkpointing" handelt den Speicher für die Berechnung der Zeit, indem die Aktivierungen auf intelligente Weise neu berechnet werden.
Dies wird jedoch in der aktuellen Version nicht implementiert.
In bestimmten Fällen kann es nicht vorteilhaft sein, das gesamte vorgeborene Modell von End-to-End zu fällen -ausgeschaltetes Modell. Dies sollte auch die meisten außerhalb des Memory-Themen mildern.
Als Beispiel schließen wir das Skript extract_features.py
ein, das so verwendet werden kann:
# 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
Dadurch wird eine JSON-Datei (eine Zeile pro Eingabezeile) erstellt, die die Bert-Aktivierungen aus jeder Transformatorschicht enthält, die von layers
angegeben ist (-1 ist die endgültige versteckte Schicht des Transformators usw.)
Beachten Sie, dass dieses Skript sehr große Ausgabedateien erzeugt (standardmäßig etwa 15 KB für jeden Eingangs -Token).
Wenn Sie die Ausrichtung zwischen den ursprünglichen und tokenisierten Wörtern (zum projizierenden Trainingsetiketten) beibehalten müssen, finden Sie im Abschnitt Tokenization unten.
HINWEIS: Möglicherweise sehen Sie, wie eine Meldung wie Could not find trained model in model_dir: /tmp/tmpuB5g5c, running initialization to predict.
Diese Nachricht wird erwartet, dass wir nur die API init_from_checkpoint()
als die gespeicherte Modell -API verwenden. Wenn Sie keinen Kontrollpunkt angeben oder einen ungültigen Kontrollpunkt angeben, beschwert sich dieses Skript.
Bei Aufgaben auf Satzebene (oder Satzpaar) ist die Tokenisierung sehr einfach. Befolgen Sie einfach den Beispielcode in run_classifier.py
und extract_features.py
. Das Grundverfahren für Aufgaben auf Satzebene lautet:
Instanz einer Instanz von tokenizer = tokenization.FullTokenizer
instanziieren
Tokenize den rohen Text mit tokens = tokenizer.tokenize(raw_text)
.
Abschnitten auf die maximale Sequenzlänge. (Sie können bis zu 512 verwenden, möchten jedoch wahrscheinlich aus Speicher- und Geschwindigkeitsgründen kürzere verwenden.)
Fügen Sie die [CLS]
und [SEP]
-Token an der richtigen Stelle hinzu.
Aufgaben auf Wortebene und Spannebene (z. B. Squad und NER) sind komplexer, da Sie die Ausrichtung zwischen Ihrem Eingabetxt und Ausgabetext beibehalten müssen, damit Sie Ihre Trainingsbezeichnungen projizieren können. Squad ist ein besonders komplexes Beispiel, da die Eingangsbezeichnungen auf Zeichen basieren und die Squad -Absätze oft länger sind als unsere maximale Sequenzlänge. Siehe den Code in run_squad.py
um zu zeigen, wie wir damit umgehen.
Bevor wir das allgemeine Rezept für die Umführung von Aufgaben auf Wortebene beschreiben, ist es wichtig zu verstehen, was genau unser Tokenizer tut. Es hat drei Hauptschritte:
Textnormalisierung : Umwandeln Sie alle Whitespace -Zeichen in Leerzeichen und (für das Uncased
Modell) Untergrund der Eingabe- und Streifen -Akzentmarkierungen. ZB, John Johanson's, → john johanson's,
.
Zeichensetzung Aufteilung : Teilen Sie alle Interpunktionszeichen auf beiden Seiten auf (dh Whitespace um alle Interpunktionszeichen hinzufügen). Die Interpunktionszeichen sind definiert als (a) alles mit einer P*
Unicode-Klasse, (b) ein beliebiger Nicht-Letter/-zahl/Space ASCII-Zeichen (z. B. Zeichen wie $
, die technisch gesehen nicht Interpunktion sind). ZB, john johanson's, → john johanson ' s ,
Wortstück -Tokenisierung : Wenden Sie die Whitespace -Tokenisierung auf die Ausgabe des obigen Prozedur an und wenden Sie eine Wortstück -Tokenisierung auf jeden Token getrennt an. (Unsere Implementierung basiert direkt auf der von tensor2tensor
, die verknüpft ist). ZB, john johanson ' s , → john johan ##son ' s ,
Der Vorteil dieses Schemas ist, dass es mit den meisten vorhandenen englischen Tokenizern "kompatibel" ist. Stellen Sie sich beispielsweise vor, Sie haben eine Teil-von-Speech-Tagging-Aufgabe, die so aussieht:
Input: John Johanson 's house
Labels: NNP NNP POS NN
Die tokenisierte Ausgabe sieht so aus:
Tokens: john johan ##son ' s house
Entscheidend ist, dass dies die gleiche Ausgabe wäre, als wäre der Rohtext John Johanson's house
(ohne Platz vor dem 's
).
Wenn Sie eine vorgefängerte Darstellung mit Annotationen auf Wortebene haben, können Sie einfach jedes Eingabebuchwort unabhängig voneinander token und eine ursprüngliche Ausrichtung determinalistisch beibehalten:
### 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]
Jetzt kann orig_to_tok_map
verwendet werden, um labels
an die tokenisierte Darstellung zu projizieren.
Es gibt gemeinsame englische Tokenisierungsschemata, die eine leichte Nichtübereinstimmung zwischen der Vorbereitung von Bert verursachen. Wenn Ihre Eingangs -Tokenisierung beispielsweise die Kontraktionen wie do n't
, wird dies zu einer Nichtübereinstimmung führen. Wenn dies möglich ist, sollten Sie Ihre Daten vorbereiten, um diese zurück in den roh aussehenden Text umzuwandeln. Wenn dies jedoch nicht möglich ist, ist diese Nichtübereinstimmung wahrscheinlich keine große Sache.
Wir veröffentlichen Code, um "maskierte LM" und "nächste Satzvorhersage" auf einem willkürlichen Textkorpus durchzuführen. Beachten Sie, dass dies nicht der genaue Code ist, der für das Papier verwendet wurde (der ursprüngliche Code wurde in C ++ geschrieben und eine zusätzliche Komplexität hatte), aber dieser Code generiert Voraussetzungsdaten, wie im Papier beschrieben.
Hier erfahren Sie, wie Sie die Datenerzeugung ausführen. Die Eingabe ist eine einfache Textdatei mit einem Satz pro Zeile. (Es ist wichtig, dass diese tatsächlichen Sätze für die Aufgabe "nächster Satzvorhersage" sind). Dokumente werden durch leere Zeilen abgegrenzt. Die Ausgabe ist ein Satz von tf.train.Example
s, das in TFRecord
-Dateiformat serialisiert ist.
Sie können eine Satzsegmentierung mit einem Off-the-Shelf-NLP-Toolkit wie Spacy durchführen. Das Skript create_pretraining_data.py
verkettet Segmente, bis sie die maximale Sequenzlänge erreichen, um Rechenabfälle aus der Polsterung zu minimieren (weitere Details finden Sie im Skript). Möglicherweise möchten Sie Ihren Eingangsdaten (z. B. zufällig 2% der Eingangssegmente zufällig abschneiden), um die Nicht-Sententialeingabe während der Feinabstimmung robuster zu machen.
Dieses Skript speichert alle Beispiele für die gesamte Eingabedatei im Speicher. Für große Datendateien sollten Sie die Eingabedatei und das Skript mehrmals aufrufen. (Sie können in einer Datei GLIBE an run_pretraining.py
, tf_examples.tf_record*
.
Das max_predictions_per_seq
ist die maximale Anzahl maskierter LM -Vorhersagen pro Sequenz. Sie sollten dies auf max_seq_length
* masked_lm_prob
einstellen (das Skript tut dies nicht automatisch, da der genaue Wert an beide Skripte übergeben werden muss).
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
Hier erfahren Sie, wie man die Vorausbildung betreibt. Fügen Sie init_checkpoint
nicht hinzu, wenn Sie von Grund auf neu trainieren. Die Modellkonfiguration (einschließlich Vokabellengröße) ist in bert_config_file
angegeben. Dieser Demo-Code nur für eine kleine Anzahl von Schritten (20), aber in der Praxis möchten Sie wahrscheinlich num_train_steps
auf 10000 Schritte oder mehr festlegen. Die Parameter max_seq_length
und max_predictions_per_seq
create_pretraining_data.py
an run_pretraining.py
übergeben wurden
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
Dies erzeugt eine solche Ausgabe:
***** 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
Beachten Sie, dass dieses Beispiel -Training, da unsere Datei sample_text.txt
sehr klein ist, diese Daten in nur wenigen Schritten übertreffen und unrealistisch hohe Genauigkeitsnummern erzeugen.
vocab_size
in bert_config.json
. Wenn Sie ein größeres Vokabular verwenden, ohne dies zu ändern, erhalten Sie wahrscheinlich NANS, wenn Sie bei GPU oder TPU trainieren, da Sie den Zugang nicht überprüft haben.max_seq_length
zu generieren.BERT-Base
auf einer einzelnen präventiblen Cloud-TPU V2 vorzubeugen, die etwa 2 Wochen dauert, was etwa 500 USD (basierend auf den Preisen im Oktober 2018) dauert, die etwa 2 Wochen dauert). . Sie müssen die Chargengröße skalieren, wenn Sie nur auf einer einzelnen Cloud -TPU trainieren, verglichen mit dem, was im Papier verwendet wurde. Es wird empfohlen, die größte Chargengröße zu verwenden, die in den TPU -Speicher passt. Wir werden nicht in der Lage sein, die im Papier verwendeten vorverarbeiteten Datensätze zu veröffentlichen. Für Wikipedia besteht die empfohlene Vorverarbeitung darin, den neuesten Dump herunterzuladen, den Text mit WikiExtractor.py
zu extrahieren und dann die erforderliche Reinigung anzuwenden, um ihn in einfachen Text umzuwandeln.
Leider haben die Forscher, die den Bookcorpus gesammelt haben, nicht mehr zum öffentlichen Download zur Verfügung. Das Projekt Guttenberg Dataset ist eine etwas kleinere Sammlung älterer Bücher, die gemeinfrei sind.
Common Crawl ist eine weitere sehr große Textsammlung, aber Sie müssen wahrscheinlich eine wesentliche Vorverarbeitung und Reinigung durchführen, um einen verwendbaren Korpus für Bert vor der Trainierung zu extrahieren.
Dieses Repository enthält keinen Code zum Erlernen eines neuen Wortstücksvokabulars. 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. See the LICENSE
file for more information.
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]
).