* A partir de agosto de 2021, o código não será mais mantido. Ele é preservado aqui em formato de arquivo para pessoas que desejam continuar a usá-lo.
? 1T ou prender meus caras?
Uma implementação de modelos paralelos de modelos e dados do tipo GPT3 usando a biblioteca mesh-tensorflow.
Se você está aqui apenas para brincar com nossos modelos pré-treinados, recomendamos fortemente que você experimente a integração do HuggingFace Transformer.
Treinamento e inferência são oficialmente suportados em TPU e também devem funcionar em GPU. Este repositório será (principalmente) arquivado à medida que mudarmos o foco para nosso repositório específico de GPU, GPT-NeoX.
Além das funcionalidades oferecidas pelo GPT-3, também oferecemos o seguinte:
Observação: embora o neo possa tecnicamente executar uma etapa de treinamento com parâmetros de 200B+, ele é muito ineficiente nessas escalas. Isso, bem como o fato de muitas GPUs terem sido disponibilizadas para nós, entre outras coisas, nos levou a migrar o desenvolvimento para GPT-NeoX.
Atualização 21/03/2021:
Temos orgulho de lançar dois modelos GPT-Neo pré-treinados treinados no The Pile, os pesos e configurações podem ser baixados gratuitamente em the-eye.eu.
1.3B: https://mystic.the-eye.eu/public/AI/gptneo-release/GPT3_XL/
2.7B: https://mystic.the-eye.eu/public/AI/gptneo-release/GPT3_2-7B/
Para obter mais informações sobre como configurá-los, consulte o notebook colab ou leia o restante do leia-me.
Modelo e Tamanho | Pilha BPB | Pilha PPL | Wikitexto PPL | Lambada PPL | Conta Lambada | Winogrande | Hellaswag |
---|---|---|---|---|---|---|---|
GPT-Neo 125M | ----- | ----- | 32.285 | 30.266 | 37,36% | 50,43% | 28,67% |
GPT-3 125M | ----- | ----- | ----- | 18,6 | 42,7% | 52,0% | 33,7% |
GPT-Neo 350M | ----- | ----- | 22.5657 | 13.876 | 47,27% | 51,14% | 32,16% |
GPT-3 350M | ----- | ----- | ----- | 9.09 | 54,3% | 52,1% | 43,6% |
GPT-3 Ada | 0,9631 | ----- | ----- | 9.954 | 51,60% | 52,90% | 35,93% |
GPT-Neo 1.3B | 0,7527 | 6.159 | 13h10 | 7.498 | 57,23% | 55,01% | 38,66% |
GPT-3 1.3B | ----- | ----- | ----- | 5,44 | 63,6% | 58,7% | 54,7% |
GPT-2 1.5B | 1,0468 | ----- | 17h48 | 10.634 | 51,21% | 59,40% | 40,03% |
GPT-Neo 2.7B | 0,7165 | 5.646 | 11h39 | 5.626 | 62,22% | 56,50% | 42,73% |
GPT-3 2.7B | ----- | ----- | ----- | 4,60 | 67,1% | 62,3% | 62,8% |
Modelo e Tamanho | MatemáticaQA | PubMedQA | Piqa |
---|---|---|---|
GPT-Neo 125M | 22,78% | 55,10% | 63,06% |
GPT-3 125M | ----- | ----- | 64,6% |
GPT-Neo 350M | 23,45% | 53,80% | 65,07% |
GPT-3 350M | ----- | ----- | 70,2% |
GPT-3 Ada | 24,29% | 52,80% | 68,88% |
GPT-Neo 1.3B | 24,05% | 54,40% | 71,11% |
GPT-3 1.3B | ----- | ----- | 75,1% |
GPT-2 1.5B | 23,64% | 58,33% | 70,78% |
GPT-Neo 2.7B | 24,72% | 57,54% | 72,14% |
GPT-3 2.7B | ----- | ----- | 75,6% |
Nota: Todas as avaliações foram feitas usando nosso equipamento de avaliação. Alguns resultados para GPT-2 e GPT-3 são inconsistentes com os valores relatados nos respectivos artigos. No momento, estamos investigando o porquê e gostaríamos muito de receber comentários e mais testes de nosso equipamento de avaliação.
git clone https://github.com/EleutherAI/GPTNeo
cd GPTNeo
pip3 install -r requirements.txt
Cadastre-se no Google Cloud Platform e crie um bucket de armazenamento.
Crie sua VM por meio de um shell do Google ( https://ssh.cloud.google.com/
) com ctpu up --vm-only
para que ela possa se conectar ao seu bucket do Google e TPUs e instalar os requisitos com pip (veja acima) .
O Google Colab fornece tpu-v8s gratuitamente, o que deve ser suficiente para ajustar nossos modelos até tamanhos GPT3XL (parâmetro 1,5B). Clique para percorrer nosso exemplo de notebook colab.
Para obter instruções mais detalhadas, consulte nosso Guia de treinamento abaixo.
Você também pode optar por treinar GPTNeo localmente em suas GPUs. Para fazer isso, você pode omitir as etapas de configuração da nuvem do Google acima e clonar o repositório localmente. Execute o Guia de treinamento abaixo e, ao executar main.py, você simplesmente precisa omitir o sinalizador tpu
e passar os IDs da GPU.
Nota: Alguns usuários relataram ter dificuldade em fazer com que o MTF reconhecesse suas GPUs. Veja aqui detalhes e instruções sobre como corrigi-lo.
Depois de ter um modelo treinado ou de ter baixado um de nossos modelos pré-treinados, gerar texto é tão simples quanto executar o script main.py com o sinalizador --predict
ativado. Você pode passar um caminho para o seu arquivo txt de prompt com o sinalizador --prompt
, assim:
python3 main.py --predict --prompt < example_prompt.txt > --tpu < tpu_name > --model < config_name >
ou, se estiver usando GPUs:
python3 main.py --predict --prompt < example_prompt.txt > --gpu_ids < device:GPU:0 device:GPU: 1> --model < config_name >
Recomendamos que você use o tokenizer GPT2 pré-treinado do Huggingface com nosso repositório (instruções fornecidas abaixo), mas se você quiser treinar um modelo com um tamanho de vocabulário diferente, oferecemos recursos para treinar seu próprio tokenizer da seguinte forma:
python data/train_tokenizer.py
--base_dir ./path/to/your/txt/files
--output_dir ./output/path
--file_type txt
--vocab_size 50257
# if it succeeded, you should see the message
# 'tokenizer saved at ./output/path/byte-level-bpe.tokenizer.json'
Se você quiser apenas testar o treinamento, você pode pular esta etapa e baixar alguns dados fictícios como estes:
wget https://storage.googleapis.com/connors-datasets/bundestag/bundestag_0.tfrecords
Em seguida, copie os dados para seu bucket ou, se estiver usando GPUs, para um diretório local:
gsutil cp bundestag_0.tfrecords gs://<your bucket>/
Se estiver usando seus próprios dados para treinar, você pode usar o script data/create_tfrecords.py
para codificar seus dados de texto em tfrecords.
Seus dados devem estar na forma de vários arquivos .txt normais (um documento por arquivo) ou em qualquer formato compatível com lm_dataformat.
Você pode executar o script sem parâmetros para ver a ajuda de todas as opções.
No modo de documento Cada exemplo nos tfrecords é um documento (tamanho variável). Isso deve ser usado com os modos de documents_fixed
documents_random
(para obter mais detalhes, consulte a seção de referência de parâmetros). O modo de documento é o modo padrão.
O comando abaixo irá tokenizar todos os arquivos em formatos aceitáveis em base_dir usando o tokenizer gpt2 e salvá-los em output_dir
python3 create_tfrecords.py --mode documents --input_dir <base> --name <name> --output_dir <output> --use_gpt2_tokenizer --minimum_size <min>
input_dir
: Define a pasta onde seus dados estão localizados. O script codificará todos os arquivos presentes nesta pasta.name
: O nome dos arquivos de saída será name_i.tfrecords
onde i é o número do arquivo.output_dir
: Onde salvar os tfrecordsuse_gpt2_tokenizer
: se deve usar o tokenizer HuggingFace GPT2 pré-treinado; nesse caso, o separador será definido como [50256].encoder_path
: se não estiver usando o tokenizer gpt2 pré-treinado, use este sinalizador para fornecer um caminho para o json do tokenizer gerado.separator
: Escrito em formato de lista, o(s) token(s) separador(es) a serem inseridos entre documentos (por exemplo, "[0]"). Dependerá do seu codificador.minimum_size
: O tamanho mínimo (em tokens) que um documento deve ter, caso contrário será descartado. Isto é o que determinará posteriormente o seu parâmetro stitch
: stitch * minimum_size
deve ser sempre maior ou igual n_ctx
(para mais detalhes consulte a seção de referência de parâmetros). Para usar um conjunto de dados em um modelo, primeiro você deve registrar esse conjunto de dados na pasta ./configs/dataset_configs
. Primeiro escolha um nome de arquivo com extensão .json
. Esse nome de arquivo servirá como identificação do conjunto de dados. A configuração deve ser preenchida da seguinte maneira.
Se você tiver um conjunto de dados codificado usando o tokenizer gpt2 pré-treinado, poderá especificá-lo da seguinte forma:
{
"n_vocab" : 50257 ,
"path" : " gs://neo-datasets/openwebtext-documents/openwebtext_*.tfrecords " ,
"eval_path" : " gs://neo-datasets/openwebtext-documents/openwebtext_*.tfrecords " ,
"tokenizer_is_pretrained" : true ,
"tokenizer_path" : " gpt2 "
}
ou se você treinou um tokenizer personalizado, assim:
{
"n_vocab" : 32768 ,
"path" : " ./path/to/your/*.tfrecords " ,
"eval_path" : " ./path/to/your/eval/*.tfrecords " ,
"tokenizer_path" : " ./path/to/your/byte-level-bpe.tokenizer.json "
}
Finalmente, na configuração do seu modelo, adicione o nome do arquivo que você criou acima à matriz datasets
.
O <dataset id>
será o nome do arquivo, excluindo o .json
, que você criou acima
"datasets": [[<dataset id>, <stitch>, <datatype>, <weight>]] # datasets key defines at run time how each dataset is processed for training
Depois de configurar seus conjuntos de dados, encontre uma configuração adequada em /configs
.
Aqui usamos um modelo de tamanho GPT3-XL como exemplo, mas há muitos mais em ./configs
, todos com breves resumos na seção Configurações disponíveis.
Tudo o que você precisa fazer é editar o ID do conjunto de dados conforme descrito acima e editar model_path
(onde os logs e pontos de verificação serão salvos) para apontar para um bucket de nuvem ao qual você tem acesso de gravação (ou caminho local, se estiver usando GPUs).
{
"n_head" : 32 ,
"n_vocab" : 50257 ,
"embed_dropout" : 0.1 ,
"lr" : 0.0002 ,
"lr_decay" : " cosine " ,
"warmup_steps" : 3000 ,
"beta1" : 0.9 ,
"beta2" : 0.95 ,
"epsilon" : 1e-8 ,
"opt_name" : " adam " ,
"weight_decay" : 0.1 ,
"train_batch_size" : 512 ,
"attn_dropout" : 0.1 ,
"train_steps" : 286150 ,
"eval_steps" : 0 ,
"predict_steps" : 1 ,
"res_dropout" : 0.1 ,
"eval_batch_size" : 128 ,
"predict_batch_size" : 1 ,
"iterations" : 2500 ,
"n_embd" : 2048 ,
"datasets" : [[ " your_dataset_name " , 25 , " documents_random " , 1.0 ]],
"model_path" : " gs://neo-models/GPT3_XL " ,
"n_ctx" : 2048 ,
"n_layer" : 24 ,
"scale_by_depth" : true ,
"scale_by_in" : false ,
"attention_types" : [[[ " global " ], 24 ]],
"mesh_shape" : " x:128,y:2 " ,
"layout" : " batch:x,memory_length:y,embd:y " ,
"activation_function" : " gelu " ,
"recompute_grad" : true ,
"gradient_clipping" : 1.0 ,
"tokens_per_mb_per_replica" : 2048
}
python3 main.py --model <your_config_name> --steps_per_checkpoint <n> --tpu <tpu-name>
tpu
: Nome da TPU a ser usada.steps_per_checkpoint
: a frequência em etapas para salvar os pontos de verificação.--auto_layout
e --auto_layout_and_mesh_shape
(opcional): desative o treinamento e, em vez disso, gere automaticamente um layout
com eficiência de memória (e mesh_shape
)gpu_ids
: se estiver treinando usando GPUs, omita o sinalizador tpu
e passe os ids do seu gpus. No exemplo abaixo, treinamos em 3 GPUs, especificando seus IDs de dispositivos delimitados por espaços: python3 main.py --model <your_config_name> --steps_per_checkpoint <n> --gpu_ids <device:GPU:0 device:GPU:1>
Temos vários tamanhos de modelos disponíveis, mas algumas de nossas configurações exigem TPUs grandes e precisarão de ajustes para rodar em máquinas menores ou GPUs. Abaixo está um breve guia para cada modelo no diretório configs:
PENDÊNCIA
Sacred ajuda a rastrear experimentos e é muito mais agradável de trabalhar do que o tensorboard.
Para configurar:
Instale o Docker e o Docker-compose
Execute docker-compose up
Para usar:
Certifique-se de que model_dir não contenha nenhum log métrico (ele aciona o material métrico do tensorboard, o que pressupõe que é uma continuação da execução existente). Você pode usar gsutil rm -r ...
para excluir o diretório do modelo
Execute python3 run_experiment.py --tpu sometpuhere --model someconfig.json
As opções são iguais a main.py
.
Você pode acessar http://server_ip_goes_here:8081/ para ver a visão geral do Omniboard. Se você preferir ver um tensorboard, o script também ativa um e atribui uma porta a ele automaticamente. O script deve imprimir a porta do tensorboard próximo ao topo do log.
Se você ficar confuso com o conjunto de dados de um arquivo de configuração específico, poderá verificar facilmente os IDs de token mínimo e máximo com um único comando. Isso é útil para garantir que o tamanho do vocabulário do modelo seja pelo menos tão grande quanto o ID máximo do token. O Tensorflow não cometerá erros se você tentar reunir em uma matriz com índices fora dos limites, portanto, você precisa ter certeza de que o tamanho do seu vocabulário é suficientemente grande.
python main --model {config_name} --check_dataset
Além de poder treinar grandes GPT's, este repositório também permite fazer facilmente modelagem de linguagem mascarada (BERT, RoBERTa). Para fazer isso, você deve seguir duas etapas adicionais.
Ao tokenizar seu conjunto de dados, você deve reservar um ID especial para o token [mask]
.
Nas configurações, você terá que definir dois campos adicionais
"mlm_training" : true , # must be set to true
"mlm_mask_id" : < mask id > # the mask id that you reserved from above
Isso é tudo que você precisa para treinar um modelo com o objetivo MLM, bom para qualquer tipo de dado que você tenha codificado corretamente. Se você quiser ajustar os outros hiperparâmetros relacionados, continue lendo.
"mlm_cls_token_id" : < cls token id > , # auto append specified CLS token id on the left
"mlm_mask_prob" : 0.15 , # the probability of masking a token, defaults to 15%
"mlm_same_token_prob" : 0.10 , # probability of keeping the token the same, defaults to 10%
"mlm_random_token_prob" : 0.10 , # probability of tokens that are replaced with random tokens, 10% was recommended by the BERT paper
"mlm_mask_ignore_ids" : [ < cls token > , < sep token > ] # ignore masking other special tokens, if any
Escolha uma configuração válida em /configs
e ajuste os parâmetros conforme necessário:
n_heads
: o número de cabeças de atenção.n_embd
: Tamanho das camadas ocultas, deve ser divisível por n_heads
.n_vocab
: Tamanho do vocabulário.embed_dropout
, res_dropout
, attn_dropout
: Probabilidade de abandono para incorporação/resíduos/atenção de palavraslr
: Taxa de aprendizagemwarmup_steps
: Número de etapas antes que a taxa de aprendizagem total seja atingida (rampa linear de 0
a lr
).lr_decay
: cosine
ou linear
.opt_name
: adam
ou adafactor
.beta1
, beta2
e epsilon
: parâmetros do otimizador adam
.beta1
, ada_epsilon1
e ada_epsilon2
: parâmetros do otimizador adafactor
.weight_decay
: parâmetro de redução de peso, se não estiver presente, nenhuma redução de peso será usada (a correção de redução de peso para Adam é usada) (padrão: 0,01) (opcional).train_batch_size
: tamanho do lote durante o treinamento.train_steps
: Número de etapas de treinamento (lotes), definido para aproximadamente ~1 época por enquanto (número total de tokens em seu conjunto de dados/número de tokens por lote (= train_batch_size
/ n_ctx
)).eval_steps
: Número de etapas a serem executadas para cada avaliação. Defina como 0
para nenhuma avaliação. ou seja, após cada ponto de verificação, o modelo é testado para eval_steps
iterations
: o número de etapas enfileiradas na TPU deve ser menor que steps_per_checkpoint
. (padrão: 500)datasets
: lista de conjuntos de dados tfrecords a serem usados. Cada conjunto de dados é uma lista com os seguintes parâmetros: [train glob , eval glob, stitch, sampling_mode, weight]
. Assim, por exemplo, para um único conjunto de dados (observe a lista dupla): [["bundestag_*.tfrecords", "", 10, "random_sample", 1.0]]
dataset_id
: o nome de um arquivo de configuração do conjunto de dados em ./configs/dataset_configs
stitch
: se sampling_mode
random_sample
for usado, o pipeline de entrada amostrará essa quantidade de textos em um para amostrar. Você deve selecionar o ponto para que stitch * minimum_document_length >= n_ctx
sampling_mode
: chunks
(tfrecords são pré-processados no comprimento correto e lidos sequencialmente) documents_random
(a quantidade de stitch
de documentos é concatenada e então um pedaço n_ctx
é subamostrado aleatoriamente)weights
: quanto peso relativo este conjunto de dados deve ter em comparação com outrosmodel
: Qual modelo treinar. Atualmente, apenas GPT
é suportado e o padrão é este se não estiver presente.model_path
: localização do bucket de armazenamento do Google (ou caminho local, se estiver usando GPUs) para salvar pontos de verificação e registros do modelo.n_ctx
: Tamanho da janela de contexto. O padrão é 2048n_layer
: Número de camadas (blocos) no modelo.scale_by_depth
: Se verdadeiro, a inicialização do peso das camadas é dimensionada por sua profundidade, como no artigo GPT2.scale_by_in
: se verdadeiro, a inicialização do peso das camadas é dimensionada pelo número de entradas, como no artigo GPT2.mesh_shape
: Uma malha é uma matriz n-dimensional de processadores com dimensões nomeadas usadas para paralelismo na biblioteca mesh-tensorflow. Cada Tensor é dividido uniformemente nas dimensões da malha de acordo com o layout (veja abaixo). O 'mesh_shape' é o formato deste array e deve ser igual ao número de processadores. por exemplo, para uma TPU v3-128 "mesh_shape": “x:16,y:8”.layout
: um Tensor é disposto em sua malha com uma fatia em cada processador. Um "layout" de tensor é um mapa parcial injetivo que especifica quais dimensões do tensor são (igualmente) divididas em quais dimensões da malha. Nenhuma dimensão de um tensor pode ser dividida em duas dimensões de sua malha e nenhuma dimensão de um tensor pode ser dividida na mesma dimensão de sua malha. O usuário define um conjunto global de regras de layout na forma de pares (nome da dimensão do tensor, nome da dimensão da malha). Uma dimensão de um tensor é dividida em uma dimensão de sua malha se houver uma regra de correspondência, por exemplo (para o exemplo acima mesh_shape: "layout":"batch:x,heads:y"activation_function
: selu
(auto-normalização) ou gelu
(usado pelo OA), função de ativação usada em passagens de feed-forward. (padrão: gelu)attention_types
: o tipo de atenção para cada camada em uma lista do seguinte formato [[["attention_type"], n_layers]]. por exemplo, para uma rede de 12 camadas [[["global"], 12]] ou [[["local"], 10], [["global"], 2]].linear
, global
, local
ou none
. Descobrimos que uma combinação 50/50 de global
e linear
funciona bem. none
permite criar camadas somente feed-forward para modelos PAR Transformer mais eficientes.precision
: float32
ou bfloat16
.tokens_per_mb_per_replica
: se não for Nenhum, dividirá o lote em microlotes menores contendo tokens tokens_per_mb_per_replica
para evitar OOMs. Os gradientes são acumulados localmente e reduzidos uma vez. IMPORTANTE: mb refere-se a minibatch e não a megabyte aqui.Mistura de especialistas
moe_layers
: Uma lista de números de camadas para anexar uma mistura de camadas de especialistas. EX.: [2,4,6,8,10,12]
. Descobrimos experimentalmente que uma camada moe para cada duas camadas de autoatenção funciona bem.moe_params
: um dicionário de kwargs adicionais para passar para a camada moe. Por exemplo, {"moe_dropout_rate": 0.0 }
Recursos experimentais
axial_pos_emb_
: se verdadeiro, usa [incorporação posicional axial](https://arxiv.org/abs/1912.12180.mlp_glu
: Se verdadeiro, usa uma variante de unidade linear fechada de camadas feed forward.scalenorm
: se verdadeiro, usa scalenorm em vez de layernorm.rezero
: se verdadeiro, usa rezero em vez de layernorm.num_mem_kv
: adiciona valores de memória/chave do papel de toda atenção. Param é um int com o número de valores mem/chave desejados.macaron
: se verdadeiro - usa um transformador macaron para cada bloco de camada. Se você achou o GPT-Neo útil em seu trabalho, você pode citar este repositório como
@software{gpt-neo,
author = {Black, Sid and
Gao, Leo and
Wang, Phil and
Leahy, Connor and
Biderman, Stella},
title = {{GPT-Neo: Large Scale Autoregressive Language
Modeling with Mesh-Tensorflow}},
month = mar,
year = 2021,
note = {{If you use this software, please cite it using
these metadata.}},
publisher = {Zenodo},
version = {1.0},
doi = {10.5281/zenodo.5297715},
url = {https://doi.org/10.5281/zenodo.5297715}
}
O número da versão deve ser substituído pelo número da versão que você está usando e o ano corresponde ao lançamento do código aberto do projeto.
Se você estiver especificamente interessado em citar os modelos GPT-Neo treinados na Pile, gostaríamos de citar também
@article{gao2020pile,
title={The Pile: An 800GB Dataset of Diverse Text for Language Modeling},
author={Gao, Leo and Biderman, Stella and Black, Sid and Golding, Laurence and Hoppe, Travis and Foster, Charles and Phang, Jason and He, Horace and Thite, Anish and Nabeshima, Noa and others},
journal={arXiv preprint arXiv:2101.00027},
year={2020}
}