***** Novo 11 de março de 2020: modelos menores de Bert *****
Este é um lançamento de 24 modelos menores de Bert (apenas em inglês, não baseados, treinados com mascaramento de palavras) mencionados em estudantes bem lidos, aprendem melhor: sobre a importância dos modelos compactos pré-treinamento.
Mostramos que a receita BERT padrão (incluindo arquitetura de modelo e objetivo de treinamento) é eficaz em uma ampla gama de tamanhos de modelo, além de Bert-Base e Bert-Large. Os modelos menores de Bert são destinados a ambientes com recursos computacionais restritos. Eles podem ser ajustados da mesma maneira que os modelos originais de Bert. No entanto, eles são mais eficazes no contexto da destilação do conhecimento, onde os rótulos de ajuste fino são produzidos por um professor maior e mais preciso.
Nosso objetivo é permitir pesquisas em instituições com menos recursos computacionais e incentivar a comunidade a buscar instruções de inovação alternativa ao aumento da capacidade do modelo.
Você pode baixar todos os 24 daqui, ou individualmente da tabela abaixo:
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) |
Observe que o modelo Bert-Base nesta versão está incluído apenas para completude; Foi re-treinado sob o mesmo regime que o modelo original.
Aqui estão as pontuações de cola correspondentes no conjunto de testes:
Modelo | Pontuação | Cola | SST-2 | Mrpc | STS-B | Qqp | Mnli-m | Mnli-mm | Qnli (v2) | Rte | Wnli | MACHADO |
---|---|---|---|---|---|---|---|---|---|---|---|---|
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-metrado | 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 |
Para cada tarefa, selecionamos os melhores hiperparâmetros de ajuste fino das listas abaixo e treinamos para 4 épocas:
Se você usar esses modelos, cite o seguinte artigo:
@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}
}
***** Novo 31 de maio de 2019: modelos de mascaramento de palavras inteiras *****
Este é o lançamento de vários novos modelos que foram o resultado de uma melhoria do código de pré-processamento.
No código original de pré-processamento, selecionamos aleatoriamente os tokens do WordPiece para mascarar. Por exemplo:
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
A nova técnica é chamada de mascaramento de palavras inteiras. Nesse caso, sempre mascaramos todos os tokens correspondentes a uma palavra de uma só vez. A taxa geral de mascaramento permanece a mesma.
Whole Word Masked Input: the man [MASK] up , put his basket on [MASK] [MASK] [MASK] ' s head
O treinamento é idêntico - ainda prevemos cada token de palavras mascarado de forma independente. A melhoria vem do fato de que a tarefa de previsão original foi muito 'fácil' para palavras que foram divididas em várias peças de palavras.
Isso pode ser ativado durante a geração de dados, passando o sinalizador --do_whole_word_mask=True
para create_pretraining_data.py
.
Modelos pré-treinados com mascaramento de palavras inteiros estão vinculados abaixo. Os dados e o treinamento eram idênticos e os modelos têm estrutura e vocabulário idênticos aos modelos originais. Incluímos apenas modelos Bert-Large. Ao usar esses modelos, deixe claro no papel que você está usando a variante de mascaramento de palavras de Bert-Large.
BERT-Large, Uncased (Whole Word Masking)
: parâmetros de 24 camadas, 1024-Hidden, 16 cabeças, 340m
BERT-Large, Cased (Whole Word Masking)
: parâmetros de 24 camadas, 1024-Hidden, 16 cabeças, 340m
Modelo | Esquadrão 1.1 F1/em | Precisão multi -NLI |
---|---|---|
Bert-Large, não baseado (original) | 91.0/84.3 | 86.05 |
Bert-Large, não baseado (mascaramento de palavras inteiras) | 92.8/86.7 | 87.07 |
Bert-Large, CASED (original) | 91.5/84.8 | 86.09 |
Bert-Large, CASED (máscara de palavra inteira) | 92.9/86.7 | 86.46 |
***** Novo 7 de fevereiro de 2019: módulo tfhub *****
Bert foi enviado para o Tensorflow Hub. Consulte run_classifier_with_tfhub.py
para um exemplo de como usar o módulo Hub TF ou executar um exemplo no navegador no COLAB.
***** Novo 23 de novembro de 2018: Modelo multilíngue não normalizado + tailandês + mongol *****
Carregamos um novo modelo multilíngue que não realiza nenhuma normalização na entrada (sem caixa mais baixa, remoção de sotaque ou normalização unicode) e inclui adicionalmente tailandês e mongol.
Recomenda-se usar esta versão para desenvolver modelos multilíngues, especialmente em idiomas com alfabetos não de latina.
Isso não requer alterações de código e pode ser baixado aqui:
BERT-Base, Multilingual Cased
: 104 Idiomas, 12 camadas, 768 parâmetros de 12 cabeças, 110m***** Novo 15 de novembro de 2018: Sistema SOTA Squad 2.0 *****
Lançamos alterações de código para reproduzir nosso sistema de 83% do Squad 2.0, que atualmente é o 1º lugar na tabela de classificação em 3%. Consulte a seção Squad 2.0 do ReadMe para obter detalhes.
***** Novo 5 de novembro de 2018: Pytorch de terceiros e versões da cadeia de Bert disponível *****
Os pesquisadores do PNL da HuggingFace disponibilizaram uma versão pytorch do BERT, que é compatível com nossos pontos de verificação pré-treinados e é capaz de reproduzir nossos resultados. Sosuke Kobayashi também disponibilizou uma versão em cadeia de Bert (obrigado!) Não estávamos envolvidos na criação ou manutenção da implementação de Pytorch, portanto, direcione qualquer dúvida para os autores desse repositório.
***** Novo 3 de novembro de 2018: Modelos multilíngues e chineses disponíveis *****
Nós disponibilizamos dois novos modelos Bert:
BERT-Base, Multilingual
(não recomendado, use Multilingual Cased
) : 102 idiomas, 12 camadas, 768-ocultos, 12 cabeças, parâmetros 110mBERT-Base, Chinese
: chinês simplificado e tradicional, 12 camadas, 768 parâmetros de 12 cabeças, 110m Utilizamos tokenização baseada em caracteres para chinês e tokenização de palavras para todos os outros idiomas. Ambos os modelos devem funcionar fora da caixa sem alterações de código. Atualizamos a implementação do BasicTokenizer
no tokenization.py
para apoiar a tokenização de caracteres chineses; portanto, atualize se você o bifurcar. No entanto, não alteramos a API de tokenização.
Para mais informações, consulte o Readme multilíngue.
***** TERMINE NOVAS INFORMAÇÕES *****
Bert , ou B Idirecional e atualizações de reprodutores , é um novo método de representações de idiomas pré-treinamento que obtém resultados de ponta em uma ampla variedade de tarefas de processamento de linguagem natural (PNL).
Nosso artigo acadêmico que descreve Bert em detalhes e fornece resultados completos em várias tarefas pode ser encontrado aqui: https://arxiv.org/abs/1810.04805.
Para dar alguns números, aqui estão os resultados da tarefa de resposta a perguntas do esquadrão v1.1:
Squad v1.1 Lideronding (8 de outubro de 2018) | Teste eles | Teste F1 |
---|---|---|
1º lugar de conjunto - Bert | 87.4 | 93.2 |
2º Ensemble - NLNET | 86.0 | 91.7 |
1º modelo único - Bert | 85.1 | 91.8 |
2º Modelo único de lugar - NLNET | 83.5 | 90.1 |
E várias tarefas de inferência de linguagem natural:
Sistema | Multinli | Pergunta nli | SWAG |
---|---|---|---|
Bert | 86.7 | 91.1 | 86.3 |
Openai GPT (Anterior. SOTA) | 82.2 | 88.1 | 75.0 |
Além de muitas outras tarefas.
Além disso, esses resultados foram todos obtidos com quase nenhum design de arquitetura de rede neural específica para tarefas.
Se você já sabe o que é Bert e só deseja começar, pode baixar os modelos pré-treinados e executar um ajuste fino de ponta em apenas alguns minutos.
Bert é um método de representações de idiomas pré-treinamento, o que significa que treinamos um modelo de "compreensão de idiomas" de uso geral em um grande corpus de texto (como a Wikipedia) e depois usamos esse modelo para tarefas de PNL a jusante com as quais nos preocupamos (como a pergunta respondendo). Bert supera os métodos anteriores porque é o primeiro sistema não supervisionado e profundamente bidirecional para a PNL pré-treinamento.
Não supervisionado significa que Bert foi treinado usando apenas um corpus de texto simples, o que é importante porque uma quantidade enorme de dados de texto simples está disponível publicamente na Web em vários idiomas.
As representações pré-treinadas também podem ser livres de contexto ou contextuais , e as representações contextuais podem ainda ser unidirecionais ou bidirecionais . Modelos sem contexto, como o Word2Vec ou a luva, geram uma única representação de "incorporação de palavras" para cada palavra no vocabulário, para que bank
teria a mesma representação no bank deposit
e river bank
. Os modelos contextuais geram uma representação de cada palavra que se baseia nas outras palavras na frase.
Bert foi construído sobre trabalhos recentes em representações contextuais pré-treinamento-incluindo aprendizado de sequência semi-supervisionado, pré-treinamento generativo, Elmo e UlMfit-mas, crucialmente, esses modelos são todos unidirecionais ou superficiais bidirecionais . Isso significa que cada palavra é apenas contextualizada usando as palavras à sua esquerda (ou à direita). Por exemplo, na sentença, I made a bank deposit
a representação unidirecional do bank
é baseada apenas em que I made a
deposit
mas não. Alguns trabalhos anteriores combinam as representações de modelos separados de contexto esquerdo e de contexto direito, mas apenas de maneira "superficial". Bert representa o "banco" usando seu contexto esquerdo e direito - I made a ... deposit
- a partir do fundo de uma rede neural profunda, por isso é profundamente bidirecional .
Bert usa uma abordagem simples para isso: mascaramos 15% das palavras na entrada, executam toda a sequência através de um codificador de transformador bidirecional profundo e, em seguida, prevê apenas as palavras mascaradas. Por exemplo:
Input: the man went to the [MASK1] . he bought a [MASK2] of milk.
Labels: [MASK1] = store; [MASK2] = gallon
Para aprender relações entre frases, também treinamos em uma tarefa simples que pode ser gerada a partir de qualquer corpus monolíngue: dadas duas frases A
e B
, é B
a próxima frase que vem após A
, ou apenas uma frase aleatória do 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
Em seguida, treinamos um modelo grande (transformador de 12 camadas a 24 camadas) em um grande corpus (Wikipedia + Bookcorpus) por um longo tempo (1M de etapas de atualização), e isso é Bert.
O uso de Bert tem dois estágios: pré-treinamento e ajuste fino .
O pré-treinamento é bastante caro (quatro dias em 4 a 16 TPUs em nuvem), mas é um procedimento único para cada idioma (os modelos atuais são somente em inglês, mas os modelos multilíngues serão lançados em um futuro próximo). Estamos lançando vários modelos pré-treinados do artigo que foram pré-treinados no Google. A maioria dos pesquisadores da PNL nunca precisará pré-treinar seu próprio modelo do zero.
O ajuste fino é barato. Todos os resultados no papel podem ser replicados no máximo 1 hora em uma única TPU em nuvem ou algumas horas em uma GPU, começando pelo mesmo modelo pré-treinado. O esquadrão, por exemplo, pode ser treinado em cerca de 30 minutos em uma única TPU em nuvem para obter uma pontuação de Dev F1 de 91,0%, que é o sistema único de última geração.
O outro aspecto importante de Bert é que ele pode ser adaptado a muitos tipos de tarefas de PNL com muita facilidade. No artigo, demonstramos resultados de última geração no nível da sentença (por exemplo, SST-2), nível de sentença (por exemplo, multinli), nível de palavra (por exemplo, ner) e no nível da abrangência (por exemplo, esquadrão) tarefas quase sem modificações específicas da tarefa.
Estamos lançando o seguinte:
BERT-Base
e BERT-Large
do papel.Todo o código deste repositório trabalha fora da caixa com CPU, GPU e TPU em nuvem.
Estamos liberando os modelos BERT-Base
e BERT-Large
do papel. Uncased
significa que o texto foi baseado antes da tokenização de palavras, por exemplo, John Smith
se torna john smith
. O modelo Uncased
também retira quaisquer marcadores de destaque. Cased
significa que os verdadeiros marcadores de caso e acento são preservados. Normalmente, o modelo Uncased
é melhor, a menos que você saiba que as informações de caso são importantes para sua tarefa (por exemplo, reconhecimento de entidade chamado ou marcação de parte da fala).
Todos esses modelos são lançados na mesma licença que o código -fonte (Apache 2.0).
Para obter informações sobre o modelo multilíngue e chinês, consulte o Readme multilíngue.
Ao usar um modelo CASED, aproveite --do_lower=False
para os scripts de treinamento. (Ou passe do_lower_case=False
diretamente para FullTokenizer
se você estiver usando seu próprio script.)
Os links para os modelos estão aqui (clique com o botão direito do mouse, 'Salvar link como ...' no nome):
BERT-Large, Uncased (Whole Word Masking)
: parâmetros de 24 camadas, 1024-Hidden, 16 cabeças, 340mBERT-Large, Cased (Whole Word Masking)
: parâmetros de 24 camadas, 1024-Hidden, 16 cabeças, 340mBERT-Base, Uncased
: 12 camadas, 768 parâmetros de 12 cabeças, 110mBERT-Large, Uncased
: parâmetros de 24 camadas, 1024 ocultos, 16 cabeças, 340mBERT-Base, Cased
: parâmetros de 12 camadas, 768 ocultos, 12 cabeças, 110mBERT-Large, Cased
: parâmetros de 24 camadas, 1024-Hidden, 16 cabeças, 340mBERT-Base, Multilingual Cased (New, recommended)
: 104 idiomas, parâmetros de 12 camadas, 768-Hidden, 12 cabeças, 110mBERT-Base, Multilingual Uncased (Orig, not recommended)
(não recomendado, use com Multilingual Cased
) : 102 idiomas, parâmetros de 12 camadas, 768 ocultos, 12 cabeças, 110mBERT-Base, Chinese
: chinês simplificado e tradicional, 12 camadas, 768 parâmetros de 12 cabeças, 110mCada arquivo .zip contém três itens:
bert_model.ckpt
) contendo os pesos pré-treinados (que na verdade são 3 arquivos).vocab.txt
) para mapear o wordpiece para o word id.bert_config.json
) que especifica os hiperparâmetros do modelo. IMPORTANTE : Todos os resultados no papel foram ajustados em uma única TPU em nuvem, que possui 64 GB de RAM. Atualmente, não é possível reproduzir a maioria dos resultados de BERT-Large
no papel usando uma GPU com 12 GB-16 GB de RAM, porque o tamanho máximo do lote que pode caber na memória é muito pequeno. Estamos trabalhando para adicionar código a este repositório, o que permite um tamanho de lote muito maior eficaz na GPU. Veja a seção sobre questões fora da memória para obter mais detalhes.
Este código foi testado com o TensorFlow 1.11.0. Foi testado com Python2 e Python3 (mas mais detalhadamente com o Python2, pois é isso que é usado internamente no Google).
Os exemplos de ajuste fino que usam BERT-Base
devem ser capazes de executar em uma GPU que possui pelo menos 12 GB de RAM usando os hiperparâmetros fornecidos.
A maioria dos exemplos abaixo pressupõe que você executará treinamento/avaliação em sua máquina local, usando uma GPU como um Titan X ou GTX 1080.
No entanto, se você tiver acesso a uma TPU em nuvem em que deseja treinar, basta adicionar os seguintes sinalizadores a run_classifier.py
ou run_squad.py
:
--use_tpu=True
--tpu_name=$TPU_NAME
Consulte o tutorial do Google Cloud TPU sobre como usar o Cloud TPUS. Como alternativa, você pode usar o Notebook do Google Colab "Bert Finetuning com TPUs em nuvem".
No Cloud TPUs, o modelo pré -terenciado e o diretório de saída precisarão estar no Google Cloud Storage. Por exemplo, se você tiver um balde chamado some_bucket
, poderá usar os seguintes sinalizadores:
--output_dir=gs://some_bucket/my_output_dir/
Os arquivos de modelo pré-treinado descompactados também podem ser encontrados na pasta de armazenamento do Google Cloud gs://bert_models/2018_10_18
. Por exemplo:
export BERT_BASE_DIR=gs://bert_models/2018_10_18/uncased_L-12_H-768_A-12
Antes de executar este exemplo, você deve baixar os dados de cola executando este script e descompacte em algum diretório $GLUE_DIR
. Em seguida, faça o download do ponto de verificação BERT-Base
e descompacte-o em algum diretório $BERT_BASE_DIR
.
Este exemplo de código Fine Tunes BERT-Base
no Corpus da Microsoft Research parafrase Corpus (MRPC), que contém apenas 3.600 exemplos e pode ajustar em alguns minutos na maioria das GPUs.
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/
Você deve ver a saída assim:
***** Eval results *****
eval_accuracy = 0.845588
eval_loss = 0.505248
global_step = 343
loss = 0.505248
Isso significa que a precisão do conjunto de desenvolvedores foi de 84,55%. Pequenos conjuntos como o MRPC têm uma alta variação na precisão do Dev Define, mesmo quando começam no mesmo ponto de verificação de pré-treinamento. Se você executar novamente várias vezes (certifique-se de apontar para diferentes output_dir
), verá os resultados entre 84% e 88%.
Alguns outros modelos pré-treinados são implementados no m-shelf em run_classifier.py
; portanto, deve ser simples seguir esses exemplos para usar o BERT para qualquer tarefa de classificação de frase única ou pares de frases.
Nota: Você pode ver uma mensagem Running train on CPU
. Isso realmente significa apenas que está funcionando em algo diferente de uma TPU em nuvem, que inclui uma GPU.
Depois de treinar seu classificador, você pode usá -lo no modo de inferência usando o comando ---do_predict = true. Você precisa ter um arquivo chamado test.tsv na pasta de entrada. A saída será criada no arquivo chamado test_results.tsv na pasta de saída. Cada linha conterá a saída para cada amostra, as colunas são as probabilidades 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/
O conjunto de dados de resposta a Stanford para resposta (Esquadrão) é um conjunto de dados popular de resposta à referência. Bert (no momento da liberação) obtém resultados de última geração na equipe, com quase nenhuma modificação de arquitetura de rede específica para tarefas ou aumento de dados. No entanto, requer dados semi-complexos de pré-processamento e pós-processamento para lidar com (a) a natureza de um comprimento de variável dos parágrafos de contexto de esquadrão e (b) as anotações de resposta do nível de caracteres que são usadas para treinamento de esquadrões. Esse processamento é implementado e documentado em run_squad.py
.
Para executar no esquadrão, você precisará primeiro baixar o conjunto de dados. O site da equipe não parece mais vincular aos conjuntos de dados v1.1, mas os arquivos necessários podem ser encontrados aqui:
Faça o download de algum diretório $SQUAD_DIR
.
O esquadrão de última geração do artigo atualmente não pode ser reproduzido em uma GPU de 12 GB-16 GB devido a restrições de memória (de fato, mesmo o tamanho 1 do lote 1 não parece se encaixar em uma GPU de 12 GB usando BERT-Large
). No entanto, um modelo razoavelmente forte BERT-Base
pode ser treinado na GPU com estes hiperparâmetros:
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/
As previsões do Detect Set serão salvas em um arquivo chamado predictions.json
no output_dir
:
python $SQUAD_DIR /evaluate-v1.1.py $SQUAD_DIR /dev-v1.1.json ./squad/predictions.json
Que deve produzir uma saída como esta:
{ " f1 " : 88.41249612335034, " exact_match " : 81.2488174077578}
Você deve ver um resultado semelhante aos 88,5% relatados no artigo para BERT-Base
.
Se você tiver acesso a uma TPU em nuvem, poderá treinar com BERT-Large
. Aqui está um conjunto de hiperparâmetros (ligeiramente diferentes do papel) que obtém consistentemente cerca de 90,5% -91,0% de sistema único F1 treinado apenas no esquadrão:
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
Por exemplo, uma execução aleatória com estes parâmetros produz as seguintes pontuações de desenvolvimento:
{ " f1 " : 90.87081895814865, " exact_match " : 84.38978240302744}
Se você ajustar uma época em triviaqa antes disso, os resultados serão ainda melhores, mas precisará converter triviaqa no formato JSON do esquadrão.
Este modelo também é implementado e documentado em run_squad.py
.
Para executar no Squad 2.0, você primeiro precisará baixar o conjunto de dados. Os arquivos necessários podem ser encontrados aqui:
Faça o download de algum diretório $SQUAD_DIR
.
Na Cloud TPU, você pode correr com Bert-Large da seguinte forma:
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
Assumimos que você copiou tudo, desde o diretório de saída até um diretório local chamado ./squad/. As previsões iniciais do Dev Set estarão em ./squad/predictions.json e as diferenças entre a pontuação de nenhuma resposta ("") e a melhor resposta não nula para cada pergunta estará no arquivo ./squad/null_odds.json
Execute este script para ajustar um limite para prever respostas nulas versus não nulas:
python $ squad_dir/avaliar-v2.0.py $ squad_dir/dev-v-v-v-v2.json ./squad/predictions.json ---na-prob-file ./squad/null_odds.json
Suponha que o script sai "Best_F1_thresh" Thresh. (Os valores típicos estão entre -1,0 e -5,0). Agora você pode executar novamente o modelo para gerar previsões com o limite derivado ou, alternativamente, pode extrair as respostas apropriadas 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
Todas as experiências no papel foram ajustadas em uma TPU de nuvem, que possui 64 GB de RAM de dispositivo. Portanto, ao usar uma GPU com 12 GB-16 GB de RAM, é provável que você encontre problemas fora da memória se usar os mesmos hiperparâmetros descritos no papel.
Os fatores que afetam o uso da memória são:
max_seq_length
: os modelos liberados foram treinados com comprimentos de sequência até 512, mas você pode ajustar com um comprimento mais curto da sequência máxima para economizar memória substancial. Isso é controlado pelo sinalizador max_seq_length
em nosso código de exemplo.
train_batch_size
: O uso da memória também é diretamente proporcional ao tamanho do lote.
Tipo de modelo, BERT-Base
vs. BERT-Large
: O modelo BERT-Large
requer significativamente mais memória que BERT-Base
.
Otimizador : O otimizador padrão para Bert é Adam, que requer muita memória extra para armazenar os vetores m
e v
Mudar para um otimizador mais eficiente em memória pode reduzir o uso da memória, mas também pode afetar os resultados. Não experimentamos outros otimizadores para ajuste fino.
Usando os scripts de treinamento padrão ( run_classifier.py
e run_squad.py
), comparamos o tamanho máximo do lote em um único titan x GPU (12 GB de RAM) com Tensorflow 1.11.0:
Sistema | Comprimento seq | Tamanho máximo em lote |
---|---|---|
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 |
Infelizmente, esses tamanhos de lote máximo para BERT-Large
são tão pequenos que realmente prejudicarão a precisão do modelo, independentemente da taxa de aprendizagem usada. Estamos trabalhando para adicionar código a este repositório, que permitirá que tamanhos de lote muito maiores eficazes sejam usados na GPU. O código será baseado em uma (ou ambas) das seguintes técnicas:
Acumulação de gradiente : as amostras em um minibatch são tipicamente independentes em relação à computação de gradiente (excluindo a normalização do lote, que não é usada aqui). Isso significa que os gradientes de vários minibatches menores podem ser acumulados antes de executar a atualização de peso, e isso será exatamente equivalente a uma única atualização maior.
Ponto de verificação de gradiente : o principal uso da memória GPU/TPU durante o treinamento em DNN é armazenar em cache as ativações intermediárias no passe direto necessário para a computação eficiente no passe para trás. O "gradiente de checagem" negocia a memória por tempo de computação, recompra as ativações de maneira inteligente.
No entanto, isso não é implementado na versão atual.
Em certos casos, em vez de ajustar todo o modelo pré-treinado de ponta a ponta, pode ser benéfico para obter incorporações contextuais pré-treinadas obtidas, que são representações contextuais fixas de cada token de entrada gerado a partir das camadas ocultas do pré Modelo treinado. Isso também deve mitigar a maioria dos problemas fora da memória.
Como exemplo, incluímos o Script extract_features.py
, que pode ser usado assim:
# 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
Isso criará um arquivo JSON (uma linha por linha de entrada) contendo as ativações de Bert de cada camada de transformador especificada por layers
(-1 é a camada oculta final do transformador, etc.)
Observe que este script produzirá arquivos de saída muito grandes (por padrão, cerca de 15kb para cada token de entrada).
Se você precisar manter o alinhamento entre as palavras originais e tokenizadas (para projetar rótulos de treinamento), consulte a seção de tokenização abaixo.
NOTA: Você pode ver uma mensagem como Could not find trained model in model_dir: /tmp/tmpuB5g5c, running initialization to predict.
Esta mensagem é esperada, significa apenas que estamos usando a API init_from_checkpoint()
em vez da API do modelo salvo. Se você não especificar um ponto de verificação ou especificar um ponto de verificação inválido, este script reclamará.
Para tarefas (ou par de frases) no nível da frase, a tokenização é muito simples. Basta seguir o código de exemplo em run_classifier.py
e extract_features.py
. O procedimento básico para tarefas no nível da sentença é:
Instanciar uma instância de tokenizer = tokenization.FullTokenizer
Tokenize o texto bruto com tokens = tokenizer.tokenize(raw_text)
.
Truncar com o comprimento máximo da sequência. (Você pode usar até 512, mas provavelmente deseja usar mais curto, se possível, por motivos de memória e velocidade.)
Adicione os tokens [CLS]
e [SEP]
no lugar certo.
As tarefas no nível da palavra e no nível da span (por exemplo, esquadrão e NER) são mais complexas, pois você precisa manter o alinhamento entre o texto de entrada e o texto de saída para que você possa projetar seus rótulos de treinamento. O esquadrão é um exemplo particularmente complexo, porque os rótulos de entrada são baseados no caractere e os parágrafos do esquadrão geralmente são mais longos que o comprimento máximo da sequência. Veja o código em run_squad.py
para mostrar como lidamos com isso.
Antes de descrevermos a receita geral para lidar com tarefas no nível da palavra, é importante entender o que exatamente o nosso tokenizador está fazendo. Tem três etapas principais:
Normalização do texto : converta todos os caracteres em branco em espaços e (para o modelo Uncased
) minúsculas os marcadores de sotaques de entrada e desvio. Por exemplo, John Johanson's, → john johanson's,
.
Divisão de pontuação : divida todos os caracteres de pontuação de ambos os lados (ou seja, adicione espaço em branco em torno de todos os caracteres de pontuação). Os caracteres de pontuação são definidos como (a) qualquer coisa com uma classe P*
unicode, (b) qualquer caractere ASCII não-letra/número/espaço (por exemplo, caracteres como $
que tecnicamente não são pontuação). Por exemplo, john johanson's, → john johanson ' s ,
Tokenização do Wordpiece : Aplique a tokenização do espaço em branco à saída do procedimento acima e aplique a tokenização do Wordpiece a cada token separadamente. (Nossa implementação é diretamente baseada na do tensor2tensor
, que está vinculada). Por exemplo, john johanson ' s , → john johan ##son ' s ,
A vantagem desse esquema é que ele é "compatível" com a maioria dos tokenizadores em inglês existentes. Por exemplo, imagine que você tem uma tarefa de marcação de parte da fala que se parece com a seguinte:
Input: John Johanson 's house
Labels: NNP NNP POS NN
A saída tokenizada ficará assim:
Tokens: john johan ##son ' s house
Fundamentalmente, essa seria a mesma saída como se o texto bruto fosse John Johanson's house
(sem espaço antes do 's
).
Se você tiver uma representação pré-tacenada com anotações no nível da palavra, poderá simplesmente tokenizar cada palavra de entrada de forma independente e manter deterministicamente um alinhamento original para tocar:
### 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]
Agora orig_to_tok_map
pode ser usado para projetar labels
na representação tokenizada.
Existem esquemas de tokenização em inglês comuns que causarão uma ligeira incompatibilidade entre como Bert foi pré-treinado. Por exemplo, se a sua tokenização de entrada divide contrações como do n't
, isso causará uma incompatibilidade. Se for possível, você deve pré-processar seus dados para convertê-los em texto de aparência crua, mas se não for possível, essa incompatibilidade provavelmente não será grande coisa.
Estamos lançando código para fazer "LM mascarado" e "Precisa da próxima frase" em um corpus de texto arbitrário. Observe que este não é o código exato usado para o documento (o código original foi escrito em C ++ e tinha alguma complexidade adicional), mas esse código gera dados de pré-treinamento, conforme descrito no artigo.
Veja como executar a geração de dados. A entrada é um arquivo de texto simples, com uma frase por linha. (É importante que essas sejam frases reais para a tarefa "Próxima previsão de frases"). Os documentos são delimitados por linhas vazias. A saída é um conjunto de tf.train.Example
s serializado no formato de arquivo TFRecord
.
Você pode executar a segmentação de frases com um kit de ferramentas de NLP pronta para uso, como o Spacy. O script create_pretraining_data.py
concatenará segmentos até que atinjam o comprimento máximo da sequência para minimizar o desperdício computacional do preenchimento (consulte o script para obter mais detalhes). No entanto, você pode querer adicionar intencionalmente uma pequena quantidade de ruído aos seus dados de entrada (por exemplo, truncam aleatoriamente 2% dos segmentos de entrada) para torná-los mais robustos a entradas não contenciosas durante o ajuste fino.
Esse script armazena todos os exemplos para todo o arquivo de entrada na memória; portanto, para grandes arquivos de dados, você deve encharcar o arquivo de entrada e chamar o script várias vezes. (Você pode passar em um arquivo glob para run_pretraining.py
, por exemplo, tf_examples.tf_record*
.)
O max_predictions_per_seq
é o número máximo de previsões de LM mascaradas por sequência. Você deve definir isso como max_seq_length
* masked_lm_prob
(o script não faz isso automaticamente porque o valor exato precisa ser transmitido para os dois 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
Veja como executar o pré-treinamento. Não inclua init_checkpoint
se você estiver pré-treinamento do zero. A configuração do modelo (incluindo o tamanho do vocabulário) é especificada em bert_config_file
. Esse código de demonstração é pré-treino apenas para um pequeno número de etapas (20), mas, na prática, você provavelmente desejará definir num_train_steps
para 10000 etapas ou mais. Os parâmetros max_seq_length
e max_predictions_per_seq
passados para run_pretraining.py
devem ser os mesmos 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
Isso produzirá uma saída como esta:
***** 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
Observe que, como nosso arquivo sample_text.txt
é muito pequeno, este treinamento de formação excessivo será suficiente para o uso desses dados em apenas algumas etapas e produzirá números de precisão irrealisticamente altos.
vocab_size
em bert_config.json
. Se você usar um vocabulário maior sem alterar isso, provavelmente receberá Nans ao treinar na GPU ou TPU devido ao acesso desmarcado fora dos limites.max_seq_length
.BERT-Base
em uma única nuvem premiável TPU V2, que leva cerca de 2 semanas a um custo de cerca de US $ 500 (com base nos preços em outubro de 2018) . Você precisará diminuir o tamanho do lote ao treinar apenas em uma única TPU em nuvem, em comparação com o que foi usado no papel. Recomenda -se usar o maior tamanho em lote que se encaixa na memória da TPU. Não poderemos liberar os conjuntos de dados pré-processados usados no papel. Para a Wikipedia, o pré-processamento recomendado é baixar o dump mais recente, extrair o texto com WikiExtractor.py
e aplicar qualquer limpeza necessária para convertê-lo em texto simples.
Infelizmente, os pesquisadores que coletaram o bookcorpus não o possuem mais disponível para download público. O conjunto de dados do projeto Guttenberg é uma coleção um pouco menor (200m Word) de livros mais antigos que são de domínio público.
O rastreamento comum é outra coleção muito grande de texto, mas você provavelmente terá que fazer um pré-processamento e limpeza substanciais para extrair um corpus utilizável para Bert pré-treinamento.
Este repositório não inclui código para aprender um novo vocabulário de palavras. 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. Consulte o arquivo LICENSE
para obter mais informações.
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]
).