Tutorial on how to use fastai v2 over Hugging Face's Transformers and Tokenizers libraries to fine-tune an English pre-trained transformer-based language model (GPT-2) to any language other than English
In this tutorial, instead of training from scratch, we will see how to fine-tune in just over a day, on one GPU and with a little more than 1GB of training data an English pre-trained transformer-based language model to any another language.
As a practical case, we fine-tune to Portuguese the English pre-trained GPT-2 by wrapping the Transformers and Tokenizers libraries of Hugging Face into fastai v2. We thus create a new language model: GPorTuguese-2, a language model for Portuguese text generation (and more NLP tasks...).
This tutorial was made possible thanks to the computing power of the AI Lab (University of Brasilia) to which I am attached as an Associate Researcher in NLP and the participation of its directors in the definition of the NLP strategy, Professors Fabricio Ataides Braz and Nilton Correia da Silva. Thank you so much!
And special thanks to Sylvain Gugger for his tutorial on Transformers and fastai v2 which is the basis of this tutorial.
The main code of the tutorial is published in this post (Faster than training from scratch - Fine-tuning the English GPT-2 in any language with Hugging Face and fastai v2 (practical case with Portuguese)), organized by paragraph.
The complete code is in this notebook. However, as this notebook is very detailed, you can use this fast notebook finetuning-English-GPT2-any-language-Portuguese-HuggingFace-fastaiv2_FAST.ipynb (nbviewer version) if you just want to execute the code without explanation.
In addition, our GPorTuguese-2 (Portuguese GPT-2 small) , a language model for Portuguese text generation (and more NLP tasks...), is testable online in the Hugging face model hub with all usage information at this address: https://huggingface.co/pierreguillou/gpt2-small-portuguese
In a little more than a day (we only used one GPU NVIDIA V100 32GB; through a Distributed Data Parallel (DDP) training mode, we could have divided by three this time to 10 hours, just with 2 GPUs), we got a loss of 3.17, an accuracy of 37.99% and a perplexity of 23.76 (see the validation results table below and explications about perplexity at the end of the paragraph). Happy!
+------------+------+----------+------------+----------+-----------+
| after | loss | accuracy | perplexity | time | cumulative|
| ... epochs | | (%) | | by epoch | time |
+------------+------+----------+------------+----------+-----------+
| 0 | 9.95 | 9.90 | 20950.94 | 00:00:00 | 00:00:00 |
| 1 | 3.64 | 32.52 | 38.12 | 5:48:31 | 5:48:31 |
| 2 | 3.30 | 36.29 | 27.16 | 5:38:18 | 11:26:49 |
| 3 | 3.21 | 37.46 | 24.71 | 6:20:51 | 17:47:40 |
| 4 | 3.19 | 37.74 | 24.21 | 6:06:29 | 23:54:09 |
| 5 | 3.17 | 37.99 | 23.76 | 6:16:22 | 30:10:31 |
+------------+------+----------+------------+----------+-----------+
Fine-tuning of GPT-2 into Portuguese
Table of training and validation results
After a huge gain at the end of the first epoch (see validation results graph below), the validation accuracy continues to improve until the end of training but less (it goes to nearly 40%, that is considered a good performance for a language model - check these notebooks nn-vietnamese.ipynb and nn-turkish.ipynb from Jeremy Howard of fastai).
To read more about these results, read the post "Faster than training from scratch - Fine-tuning the English GPT-2 in any language with Hugging Face and fastai v2 (practical case with Portuguese)".
Even if English is today the most spoken language in the world, the world is multilingual. It is therefore necessary to have natural language models trained in all existing languages, and not just in English, since these models constitute the essential basis for the training of models capable of performing a particular task in linguistics (classification, Q&A, synthesis, entity searches, etc.).
However, if it is extremely simple and free to download a language model trained in English via in particular the Transformers library of Hugging Face, it is often much more difficult to find online a model trained in another language.
The easiest way to get theses language-specific language models would be to use a pipeline of existing pre-trained transformer-based models like the following one:
For example, to obtain a Portuguese GPT-2, we could download from the Transformers library of Hugging Face the OpenAI GPT-2 pre-trained in English and the MarianMT translator (we could also use BART or T5 for the translation) in order to create the following pipeline:
(input) Portuguese to English (MarianMT)
>> English pre-trained language model (GPT-2)
>> (output) English to Portuguese (MarianMT)
So, for free and with only a few lines of code, we can get any language model in any language, and even any task-oriented NLP model (classification, Q&A, synthesis, entity searches, etc.) using the same pipeline. Not bad!
We will find the code of this pipeline and examples of use for text generation in the post "Fast pipeline to localize any transformer-based model to any language".
However, the problem with this simple solution is that we depend on the quality of training of 2 pre-trained NLP models, which greatly increases the risk of losing the linguistic singularities and nuances of the desired language.
Therefore, it often becomes necessary to have to train its own language model.
Nevertheless, training from scratch a powerful language model like GPT-2 or GPT-3 of OpenAI, BART of Facebook or T5 of Google requires tens or even hundreds of GB of text, which is impossible or difficult to find or requires power gigantic computing that only a few companies in the world have. For example,
Thus, as it is easy to download a few GB of texts from an online language corpus (Wikipedia, OSCAR, Common Crawl for example) and rent a NVIDIA V100 GPU for $1.24 an hour (GCP, AWS, Azur for example), it is more realistic for the majority of people and organizations wishing to use a language model other than English to fine-tune on few GB of texts a model already pre-trained in English (i.e. fine-tuning a model obtained by Transfer Learning) using Deep Learning frameworks such as TensorFlow+Keras or PyTorch+fastai.
This tutorial show how to implement this second option and you will find examples of use for text generation in the paragraph Text Generation by our Portuguese GPT-2 at the end of this tutorial.
The Tokenizers and Transformers library from Hugging Face are today the most up-to-date NLP libraries (Natural Language Processing) used all over the world.
Let's copy and paste the most important information from the Transformers documentation:
Transformers (formerly known as pytorch-transformers and pytorch-pretrained-bert) provides general-purpose architectures (BERT, GPT-2, RoBERTa, XLM, DistilBert, XLNet...) for Natural Language Understanding (NLU) and Natural Language Generation (NLG) with over 32+ pretrained models in 100+ languages and deep interoperability between TensorFlow 2.0 and PyTorch".
The library was designed with two strong goals in mind:
- be as easy and fast to use as possible
- provide state-of-the-art models with performances as close as possible to the original models
The library is build around three types of classes for each model:
- model classes like
BertModel
which are 20+ PyTorch models (torch.nn.Modules
) that work with the pretrained weights provided in the library. In TF2, these aretf.keras.Model
.- configuration classes which store all the parameters required to build a model, like
BertConfig
. You don’t always need to instantiate these your-self. In particular, if you are using a pretrained model without any modification, creating the model will automatically take care of instantiating the configuration (which is part of the model).- tokenizer classes which store the vocabulary for each model and provide methods for encoding/decoding strings in a list of token embeddings indices to be fed to a model, like
BertTokenizer
.
All these classes can be instantiated from pretrained instances:
from_pretrained()
let you instantiate a model/configuration/tokenizer from a pretrained version either provided by the library itself or stored locally (or on a server) by the user.
However, as written in the Philosophy paragraph of the Quickstart page:
the Transformers library is NOT a modular toolbox of building blocks for neural nets. If you want to extend/build-upon the library, just use regular Python/PyTorch modules and inherit from the base classes of the library to reuse functionalities like model loading/saving.
Therefore, despite of the running py files published by Hugging Face (for example, the run_language_modeling.py for fine-tuning the library models for language modeling on a text file (GPT, GPT-2, BERT, RoBERTa)), when it comes necessary to fine-tune a pre-trained model to another language and/or to another task, we need to use regular Python/PyTorch modules in order to apply Transfer Learning and fine-tuning modern techniques, in particular if we do not have a huge new training dataset.
Here is a non-exhaustive list of these fine-tuning techniques based on Transfer Learning:
Since fastai v2 provides all of these powerful fine-tuning techniques, this is a primary candidate library for training transformer-based language models pre-trained with the Tokenizers and Transformers libraries of Hugging Face.
In order to demonstrate the feasibility of fine-tuning Hugging Face models via fastai v2, we had to choose an emblematic model of the Transformer revolution in the NLP since 2017.
Thus, between the GPT-2 and BERT models, we chose the GPT-2 model because it has strongly influenced minds beyond the circle of Deep Learning specialists in early 2019 by writing texts of a quality level close to that of humans. Today "exceeded" in number of parameters and performance by more recent models like BART, T5 and of course GPT-3 (175 billion parameters!), it remains a reference and a model used in research and applications. For those you want to understand better how GPT-2 works, read the following posts:
About the version of GPT-2
There are 3 versions of the GPT-2 model (look at the transformers documentation for more details). Here, we use the small version, the one with the smallest number of weights (124 millions, not 117 as written in the original paper) but you can change the model used by changing the content of pretrained_weights
(if it's not a GPT2 model, you'll need to change the classes used for the model and the tokenizer of course).
More about GPT-2
OpenAI GPT-2 model was proposed in Language Models are Unsupervised Multitask Learners by Alec Radford, Jeffrey Wu, Rewon Child, David Luan, Dario Amodei** and Ilya Sutskever**. It’s a causal (unidirectional) transformer pre-trained using language modeling on a very large corpus of ~40 GB of text data.
The abstract from the paper is the following: GPT-2 is a large transformer-based language model with 1.5 billion parameters, trained on a dataset[1] of 8 million web pages. GPT-2 is trained with a simple objective: predict the next word, given all of the previous words within some text. The diversity of the dataset causes this simple goal to contain naturally occurring demonstrations of many tasks across diverse domains. GPT-2 is a direct scale-up of GPT, with more than 10X the parameters and trained on more than 10X the amount of data.
Tips:
- GPT-2 is a model with absolute position embeddings so it’s usually advised to pad the inputs on the right rather than the left.
- GPT-2 was trained with a causal language modeling (CLM) objective and is therefore powerful at predicting the next token in a sequence. Leveraging this feature allows GPT-2 to generate syntactically coherent text as it can be observed in the run_generation.py example script.
- The PyTorch models can take the past as input, which is the previously computed key/value attention pairs. Using this past value prevents the model from re-computing pre-computed values in the context of text generation. See reusing the past in generative models for more information on the usage of this argument.
Write With Transformer is a webapp created and hosted by Hugging Face showcasing the generative capabilities of several models. GPT-2 is one of them and is available in five different sizes: small, medium, large, xl and a distilled version of the small checkpoint: distilgpt-2.
The original code can be found here.
The 6 main steps detailed below can be summarized in 3 main ones:
from fastai2.text.all import *
from nlputils_fastai2 import *
%reload_ext autoreload
%autoreload 2
%matplotlib inline
gpu = 0
torch.cuda.set_device(gpu)
print(f'cuda device: {torch.cuda.current_device()}')
# print(f'cuda device name: {torch.cuda.get_device_name(gpu)}')
cuda device: 0
# Get config of paths
config = Config()
config.d
{'archive_path': '/storage/archive/', 'data_path': '/storage/data/', 'model_path': '/storage/models/', 'storage_path': '/storage/data/', 'version': 2}
This will create a {lang}wiki
folder, containing a {lang}wiki
text file with the wikipedia contents. (For other languages, replace {lang}
with the appropriate code from the list of wikipedias.)
lang = 'pt'
# setup new path_data and create the corresponding folder
name = f'{lang}wiki'
data_path = config['data_path']
path_data = data_path/name
path_data.mkdir(exist_ok=True, parents=True)
Note: all the following methods come from the file nlputils_fastai2.py.
Path.cwd(), path_data
(Path('/mnt/home/pierre/course-v4/nbs'), Path('/mnt/home/pierre/.fastai/data/ptwiki'))
get_wiki(path_data,lang)
/mnt/home/pierre/.fastai/data/ptwiki/ptwiki already exists; not downloading
If get_wiki(path_data,lang)
breaks, fix the download manually no terminal:
And re-run get_wiki(path_data,lang)
once the download is successful.
!head -n4 {path_data}/{name}
<doc id="220" url="https://pt.wikipedia.org/wiki?curid=220" title="Astronomia"> Astronomia Astronomia é uma ciência natural que estuda corpos celestes (como estrelas, planetas, cometas, nebulosas, aglomerados de estrelas, galáxias) e fenômenos que se originam fora da atmosfera da Terra (como a radiação cósmica de fundo em micro-ondas). Preocupada com a evolução, a física, a química e o movimento de objetos celestes, bem como a formação e o desenvolvimento do universo.
dest = split_wiki(path_data,lang)
/mnt/home/pierre/.fastai/data/ptwiki/docs already exists; not splitting
dest = path_data/'docs'
for file in dest.ls()[:5]:
print(file)
/mnt/home/pierre/.fastai/data/ptwiki/docs/Fotografia.txt /mnt/home/pierre/.fastai/data/ptwiki/docs/Espadanedo (Macedo de Cavaleiros).txt /mnt/home/pierre/.fastai/data/ptwiki/docs/Jacques-Germain Soufflot.txt /mnt/home/pierre/.fastai/data/ptwiki/docs/Faculdade de Medicina da Universidade de São Paulo.txt /mnt/home/pierre/.fastai/data/ptwiki/docs/Escola do Teatro Bolshoi no Brasil.txt
%%time
# Size of downloaded data in the docs folder
num_files, num_tokens = get_num_tokens(dest)
print(f'{num_files} files - {num_tokens} tokens')
203205 files - 193686269 tokens CPU times: user 1min, sys: 20.8 s, total: 1min 21s Wall time: 11min 16s
nlp is a lightweight and extensible library from Hugging Face to easily share and access datasets and evaluation metrics for Natural Language Processing (NLP).
[ WARNING ] We did try to use it in order to download Wikipedia in Portuguese but without success. However, to help people solving this issue, we decided to leave our code in this notebook.
# source: https://huggingface.co/nlp/viewer/?dataset=wikipedia&config=20200501.pt
# !pip install nlp
# Issues
# source: https://github.com/huggingface/nlp/issues/227
# !pip instal apache_beam
# !pip install dill==0.3.1.1
# !pip install apache-beam[interactive]
# !pip install mwparserfromhell
# source: https://github.com/huggingface/nlp
import nlp
from nlp import load_dataset
Error and Warning messages when running load_dataset() with wikipedia
MissingBeamOptions: Trying to generate a dataset using Apache Beam, yet no Beam Runner or PipelineOptions() has been provided in load_dataset
or in the builder arguments. For big datasets it has to run on large-scale data processing tools like Dataflow, Spark, etc. More information about Apache Beam runners at https://beam.apache.org/documentation/runners/capability-matrix/
If you really want to run it locally because you feel like the Dataset is small enough, you can use the local beam runner called DirectRunner
(you may run out of memory).
Example of usage:
load_dataset('wikipedia', '20200501.pt', beam_runner='DirectRunner')
WARNING:apache_beam.options.pipeline_options:Discarding unparseable args: ['-f', '/mnt/home/pierre/.local/share/jupyter/runtime/kernel-bc2a44af-2ceb-4b4c-ae03-ca85e5598616.json']
WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: pip install apache-beam[interactive]
to install necessary dependencies to enable all data visualization features.
# Print all the available datasets
datasets = nlp.list_datasets()
print([dataset.id for dataset in datasets])
['aeslc', 'ai2_arc', 'allocine', 'anli', 'arcd', 'art', 'billsum', 'blended_skill_talk', 'blimp', 'blog_authorship_corpus', 'bookcorpus', 'boolq', 'break_data', 'c4', 'cfq', 'civil_comments', 'cmrc2018', 'cnn_dailymail', 'coarse_discourse', 'com_qa', 'commonsense_qa', 'compguesswhat', 'coqa', 'cornell_movie_dialog', 'cos_e', 'cosmos_qa', 'crime_and_punish', 'csv', 'definite_pronoun_resolution', 'discofuse', 'drop', 'eli5', 'empathetic_dialogues', 'eraser_multi_rc', 'esnli', 'event2Mind', 'flores', 'fquad', 'gap', 'germeval_14', 'gigaword', 'glue', 'hansards', 'hellaswag', 'imdb', 'jeopardy', 'json', 'k-halid/ar', 'kor_nli', 'lc_quad', 'lhoestq/c4', 'librispeech_lm', 'lm1b', 'math_dataset', 'math_qa', 'mlqa', 'movie_rationales', 'multi_news', 'multi_nli', 'multi_nli_mismatch', 'natural_questions', 'newsroom', 'openbookqa', 'opinosis', 'para_crawl', 'piaf', 'qa4mre', 'qangaroo', 'qanta', 'qasc', 'quarel', 'quartz', 'quoref', 'race', 'reclor', 'reddit', 'reddit_tifu', 'rotten_tomatoes', 'scan', 'scicite', 'scientific_papers', 'scifact', 'sciq', 'scitail', 'sentiment140', 'snli', 'social_i_qa', 'squad', 'squad_es', 'squad_it', 'squad_v1_pt', 'squad_v2', 'super_glue', 'ted_hrlr', 'ted_multi', 'tiny_shakespeare', 'trivia_qa', 'tydiqa', 'ubuntu_dialogs_corpus', 'webis/tl_dr', 'wiki40b', 'wiki_qa', 'wiki_snippets', 'wiki_split', 'wikihow', 'wikipedia', 'wikisql', 'wikitext', 'winogrande', 'wiqa', 'wmt14', 'wmt15', 'wmt16', 'wmt17', 'wmt18', 'wmt19', 'wmt_t2t', 'wnut_17', 'x_stance', 'xcopa', 'xnli', 'xquad', 'xsum', 'xtreme', 'yelp_polarity']
# List all the available metrics
print([metric.id for metric in nlp.list_metrics()])
['bertscore', 'bleu', 'coval', 'gleu', 'glue', 'rouge', 'sacrebleu', 'seqeval', 'squad', 'squad_v2', 'xnli']
# You can read a few attributes of the datasets before loading them (they are python dataclasses)
from dataclasses import asdict
for key, value in asdict(datasets[6]).items():
print('👉 ' + key + ': ' + str(value))
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-15-b8ace6c227a2> in <module> 2 from dataclasses import asdict 3 ----> 4 for key, value in asdict(datasets[6]).items(): 5 print('👉 ' + key + ': ' + str(value)) ~/.conda/envs/fastai2/lib/python3.7/dataclasses.py in asdict(obj, dict_factory) 1061 """ 1062 if not _is_dataclass_instance(obj): -> 1063 raise TypeError("asdict() should be called on dataclass instances") 1064 return _asdict_inner(obj, dict_factory) 1065 TypeError: asdict() should be called on dataclass instances
# source: https://huggingface.co/nlp/viewer/?dataset=wikipedia&config=20200501.pt
# !pip install nlp
# Issues
# source: https://github.com/huggingface/nlp/issues/227
# !pip instal apache_beam
# !pip install dill==0.3.1.1
# !pip install apache-beam[interactive]
# !pip install mwparserfromhell
%%time
#dataset = load_dataset('wikipedia', '20200501.pt', beam_runner='DirectRunner')
dataset = load_dataset('wikipedia', '20200501.pt')
Downloading and preparing dataset wikipedia/20200501.pt (download: Unknown size, generated: Unknown size, total: Unknown size) to /mnt/home/pierre/.cache/huggingface/datasets/wikipedia/20200501.pt/1.0.0...
# Informations on the dataset (description, citation, size, splits, format...)
# are provided in `dataset.info` (as a python dataclass)
for key, value in asdict(dataset.info).items():
print('👉 ' + key + ': ' + str(value))
print(dataset)
from pprint import pprint
print(f"👉Dataset len(dataset): {len(dataset)}")
print("\n👉First item 'dataset[0]':")
pprint(dataset[0])
# Print the first examples in the training set
print(dataset['train'][0])
# Load a metric
metric = nlp.load_metric('wikipedia')
dest = path_data/'docs'
%%time
get_one_clean_file(dest,lang)
%%time
get_one_clean_csv_file(dest,lang)
fname = f'all_texts_{lang}wiki.csv'
df = pd.read_csv(dest.parent/fname)
df.head()
# csv file
dest.parent/fname
We are following 3 steps in order to get a GPT-2 tokenizer with the vocab in Portuguese:
Firstly, will need to install the transformers library.
# ! pip install transformers
!pip freeze | grep transformers
transformers==3.0.0
As we will fine-tune the GPT2 pretrained model on wikipedia in Portuguese, we need:
GPT2Tokenizer
or GPT2TokenizerFast
) to prepare the dataGPT2LMHeadModel
) (since we want the GPT2 language model).from transformers import GPT2TokenizerFast, GPT2LMHeadModel
We can use several versions of this GPT2 model, look at the transformers documentation for more details. Here we will use the basic version (ie, the one with the smallest number of weights) but you can change the model used by changing the content of pretrained_weights
(if it's not a GPT2 model, you'll need to change the classes used for the model and the tokenizer of course):
add_prefix_space
flag set to True
. Otherwise, this tokenizer encode and decode method will not conserve the absence of a space at the beginning of a string.%%time
# The GPT2 Model transformer with a language modeling head on top
# (linear layer with weights tied to the input embeddings)
# GPT2Tokenizer: https://huggingface.co/transformers/model_doc/gpt2.html#gpt2tokenizer
# GPT2TokenizerFast: https://huggingface.co/transformers/model_doc/gpt2.html#gpt2tokenizerfast
# GPT2LMHeadModel: https://huggingface.co/transformers/model_doc/gpt2.html#transformers.GPT2LMHeadModel
pretrained_weights = 'gpt2'
tokenizer_en = GPT2TokenizerFast.from_pretrained(pretrained_weights)
model_en = GPT2LMHeadModel.from_pretrained(pretrained_weights)
Some weights of GPT2LMHeadModel were not initialized from the model checkpoint at gpt2 and are newly initialized: ['h.0.attn.masked_bias', 'h.1.attn.masked_bias', 'h.2.attn.masked_bias', 'h.3.attn.masked_bias', 'h.4.attn.masked_bias', 'h.5.attn.masked_bias', 'h.6.attn.masked_bias', 'h.7.attn.masked_bias', 'h.8.attn.masked_bias', 'h.9.attn.masked_bias', 'h.10.attn.masked_bias', 'h.11.attn.masked_bias', 'lm_head.weight'] You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
CPU times: user 13 s, sys: 922 ms, total: 13.9 s Wall time: 7.48 s
# To correct the warning about token_pad (GPT2TokenizerFast), run the following code
# source: https://github.com/huggingface/transformers/issues/2648#issuecomment-616177044
tokenizer_en.pad_token = tokenizer_en.eos_token
model_en.config
GPT2Config { "activation_function": "gelu_new", "architectures": [ "GPT2LMHeadModel" ], "attn_pdrop": 0.1, "bos_token_id": 50256, "embd_pdrop": 0.1, "eos_token_id": 50256, "initializer_range": 0.02, "layer_norm_epsilon": 1e-05, "model_type": "gpt2", "n_ctx": 1024, "n_embd": 768, "n_head": 12, "n_layer": 12, "n_positions": 1024, "resid_pdrop": 0.1, "summary_activation": null, "summary_first_dropout": 0.1, "summary_proj_to_labels": true, "summary_type": "cls_index", "summary_use_proj": true, "task_specific_params": { "text-generation": { "do_sample": true, "max_length": 50 } }, "vocab_size": 50257 }
# source: https://huggingface.co/transformers/_modules/transformers/tokenization_utils_fast.html
# print('short-cut-names:',tokenizer_en.short-cut-names)
# print()
print('max_model_input_sizes')
for k,v in tokenizer_en.max_model_input_sizes.items():
print('- ',k,v)
print()
print('model_max_length:',tokenizer_en.model_max_length)
print()
for k,v in tokenizer_en.pretrained_init_configuration.items():
print(k,v)
print('padding_side:',tokenizer_en.padding_side)
print()
print('model_input_names:',tokenizer_en.model_input_names)
print()
print('bos_token & bos_token_id:',tokenizer_en.bos_token,tokenizer_en.bos_token_id)
print()
print('eos_token & eos_token_id:',tokenizer_en.eos_token,tokenizer_en.eos_token_id)
print()
print('unk_token & unk_token_id:',tokenizer_en.unk_token,tokenizer_en.unk_token_id)
print()
print('sep_token:',tokenizer_en.sep_token)
print()
print('pad_token, pad_token_id & pad_token_type_id:',tokenizer_en.pad_token,tokenizer_en.pad_token_id,tokenizer_en.pad_token_type_id)
print()
print('cls_token:',tokenizer_en.cls_token)
print()
print('mask_token:',tokenizer_en.mask_token)
print()
print('additional_special_tokens:',tokenizer_en.additional_special_tokens)
print()
print('all_special_tokens & all_special_ids:',tokenizer_en.all_special_tokens,tokenizer_en.all_special_ids)
print()
print('---------- vocab ----------')
print()
print('vocab_files_names:',tokenizer_en.vocab_files_names)
print()
for k,v in tokenizer_en.pretrained_vocab_files_map.items():
print(k)
for kk,vv in v.items():
print('- ',kk,':',vv)
print()
print('vocab_size:',tokenizer_en.vocab_size)
print()
#print(tokenizer_en.get_vocab())
num = 20
print(f'First {num} items of the vocab: {dict(itertools.islice(tokenizer_en.get_vocab().items(), 20))}')
Using sep_token, but it is not set yet. Using cls_token, but it is not set yet. Using mask_token, but it is not set yet.
max_model_input_sizes - gpt2 1024 - gpt2-medium 1024 - gpt2-large 1024 - gpt2-xl 1024 - distilgpt2 1024 model_max_length: 1024 padding_side: right model_input_names: ['token_type_ids', 'attention_mask'] bos_token & bos_token_id: <|endoftext|> 50256 eos_token & eos_token_id: <|endoftext|> 50256 unk_token & unk_token_id: <|endoftext|> 50256 sep_token: None pad_token, pad_token_id & pad_token_type_id: <|endoftext|> 50256 0 cls_token: None mask_token: None additional_special_tokens: [] all_special_tokens & all_special_ids: ['<|endoftext|>'] [50256] ---------- vocab ---------- vocab_files_names: {'vocab_file': 'vocab.json', 'merges_file': 'merges.txt'} vocab_file - gpt2 : https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-vocab.json - gpt2-medium : https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-medium-vocab.json - gpt2-large : https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-large-vocab.json - gpt2-xl : https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-xl-vocab.json - distilgpt2 : https://s3.amazonaws.com/models.huggingface.co/bert/distilgpt2-vocab.json merges_file - gpt2 : https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-merges.txt - gpt2-medium : https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-medium-merges.txt - gpt2-large : https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-large-merges.txt - gpt2-xl : https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-xl-merges.txt - distilgpt2 : https://s3.amazonaws.com/models.huggingface.co/bert/distilgpt2-merges.txt vocab_size: 50257 First 20 items of the vocab: {'Ġeuph': 40381, 'DeliveryDate': 39749, 'ĠFighting': 19098, 'Ġmandated': 28853, 'Ġcalls': 3848, 'ibly': 3193, 'Pain': 38490, 'Ġremind': 7101, 'odynamics': 44124, 'Ġelectoral': 13901, '989': 42520, 'Emb': 31567, 'pure': 37424, 'Ġ404': 32320, 'ĠFridays': 45011, 'ĠWick': 36029, 'Ġaggression': 15569, 'Ġapprehended': 41979, 'ĠGenetic': 42295, 'ĠHB': 25997}
We'll use the Tokenizers library from Hugging Face in order to train a Byte Level BPE (BBPE) Tokenizer on the Portuguese Wikipedia with the objective to get the vocab files vocab.json
, which is a list of the most frequent tokens ranked by frequency, and the merges.txt
which is a list of merges.
# !pip install tokenizers
!pip freeze | grep tokenizers
tokenizers==0.8.0
Neural Machine Translation with Byte-Level Subwords (Facebook AI, 12/05/2019)
[Abstract] Almost all existing machine translation models are built on top of character-based vocabularies: characters, subwords orwords. Rare characters from noisy text or character-rich languages such as Japanese and Chinese however can unnecessarily take up vocabulary slots and limit its compactness. Representing text at the level of bytes andusing the 256 byte set as vocabulary is a potential solution to this issue. High computational cost has however prevented it from being widely deployed or used in practice. In this paper, we investigate byte-level subwords, specifically byte-level BPE (BBPE), which is compacter than character vocabulary and has no out-of-vocabulary tokens, but is more efficient than using pure bytes only is. We claim that contextualizing BBPE embeddings is necessary, which can be implemented by a convolutional or recurrent layer. Our experiments show that BBPE has comparable performance to BPE while its size is only 1/8 of that for BPE. In the multilingual setting, BBPE maximizes vocabulary sharing across many languages and achieves better translation quality. Moreover, we show that BBPE enables transferring models between languages with non-overlapping character sets.
[Conclusion] We proposed BBPE which builds a byte-level subword vocabulary for machine translation. It results in a much more compact vocabulary than character-based ones do without the loss of performance. In multilingual settings, the former often outperforms the latter. BBPE does not have any out-of-vocabulary tokens, allowing us to transfer a model using BBPE between languages with non-overlapping vocabularies. This transfer learning paradigm is actually very generic and can be applied to any languages and datasets for performance gain or training acceleration. With the same vocabulary size, BBPE segments sentences into shorter sequences than character-based methods do, leading to faster trainingand inference. Our future work includes: eliminating source-target sentence length imbalance; evaluating BBPE in one-to-many and many-to-many translation settings; exploring better segmentation algorithms for byte-level subwords.
# Get GPT2 tokenizer_en vocab size
ByteLevelBPE_tokenizer_pt_vocab_size = tokenizer_en.vocab_size
ByteLevelBPE_tokenizer_pt_vocab_size
50257
%%time
# ByteLevelBPETokenizer Represents a Byte-level BPE as introduced by OpenAI with their GPT-2 model
from tokenizers import ByteLevelBPETokenizer
ByteLevelBPE_tokenizer_pt = ByteLevelBPETokenizer()
# Get list of paths to corpus files
paths = [str(path_data/'all_texts_ptwiki.txt')]
# Customize training with <|endoftext|> special GPT2 token
ByteLevelBPE_tokenizer_pt.train(files=paths,
vocab_size=ByteLevelBPE_tokenizer_pt_vocab_size,
min_frequency=2,
special_tokens=["<|endoftext|>"])
# Get sequence length max of 1024
ByteLevelBPE_tokenizer_pt.enable_truncation(max_length=1024)
# save tokenizer
ByteLevelBPE_tokenizer_pt_rep = 'ByteLevelBPE_tokenizer_pt'
path_to_ByteLevelBPE_tokenizer_pt_rep = path_data/ByteLevelBPE_tokenizer_pt_rep
if not (path_to_ByteLevelBPE_tokenizer_pt_rep).exists():
path_to_ByteLevelBPE_tokenizer_pt_rep.mkdir(exist_ok=True, parents=True)
ByteLevelBPE_tokenizer_pt.save_model(str(path_to_ByteLevelBPE_tokenizer_pt_rep))
CPU times: user 5h 47min 23s, sys: 43min 12s, total: 6h 30min 35s Wall time: 10min 52s
['/mnt/home/pierre/.fastai/data/ptwiki/ByteLevelBPE_tokenizer_pt/vocab.json', '/mnt/home/pierre/.fastai/data/ptwiki/ByteLevelBPE_tokenizer_pt/merges.txt']
We now have both a vocab.json, which is a list of the most frequent tokens ranked by frequency, and a merges.txt list of merges.
# Load the tokenizer ByteLevelBPE_tokenizer_pt
from tokenizers import ByteLevelBPETokenizer
# Get the path to ByteLevelBPE_tokenizer_pt config files
ByteLevelBPE_tokenizer_pt_rep = 'ByteLevelBPE_tokenizer_pt'
path_to_ByteLevelBPE_tokenizer_pt_rep = path_data/ByteLevelBPE_tokenizer_pt_rep
ByteLevelBPE_tokenizer_pt = ByteLevelBPETokenizer(
vocab_file=f'{path_to_ByteLevelBPE_tokenizer_pt_rep}/vocab.json',
merges_file=f'{path_to_ByteLevelBPE_tokenizer_pt_rep}/merges.txt'
)
# Get sequence length max of 1024
ByteLevelBPE_tokenizer_pt.enable_truncation(max_length=1024)
# Get vocab as a list
ByteLevelBPE_tokenizer_pt_vocab = ByteLevelBPE_tokenizer_pt.get_vocab()
ByteLevelBPE_tokenizer_pt_vocab_ls = [k for k, v in sorted(ByteLevelBPE_tokenizer_pt_vocab.items(), key=lambda item: item[1])]
len(ByteLevelBPE_tokenizer_pt_vocab_ls),ByteLevelBPE_tokenizer_pt_vocab_ls[:5]
(50257, ['<|endoftext|>', '!', '"', '#', '$'])
text = "Gosto do queijo e vinho."
output = ByteLevelBPE_tokenizer_pt.encode(text)
output.ids,output.tokens,output.offsets
([39, 1119, 298, 22317, 258, 11041, 14], ['G', 'osto', 'Ġdo', 'Ġqueijo', 'Ġe', 'Ġvinho', '.'], [(0, 1), (1, 5), (5, 8), (8, 15), (15, 17), (17, 23), (23, 24)])
back_to_text = ByteLevelBPE_tokenizer_pt.decode(ByteLevelBPE_tokenizer_pt.encode(text).ids)
print('input text:', text)
print('tokens ids:', output.ids)
print('back to text:', back_to_text)
input text: Gosto do queijo e vinho. tokens ids: [39, 1119, 298, 22317, 258, 11041, 14] back to text: Gosto do queijo e vinho.
# Get the path to ByteLevelBPE_tokenizer_pt config files
ByteLevelBPE_tokenizer_pt_rep = 'ByteLevelBPE_tokenizer_pt'
path_to_ByteLevelBPE_tokenizer_pt_rep = path_data/ByteLevelBPE_tokenizer_pt_rep
# import the pre-trained GPT2TokenizerFast tokenizer with the tokenizer_pt config files
tokenizer_pt = GPT2TokenizerFast.from_pretrained(
str(path_to_ByteLevelBPE_tokenizer_pt_rep),
pad_token='<|endoftext|>')
# Get sequence length max of 1024
tokenizer_pt.model_max_length = 1024
# Check
text = "Gosto do queijo e vinho."
tokens_ids = tokenizer_pt.encode(text)
back_to_text = tokenizer_pt.decode(tokenizer_pt.encode(text))
print('input text:', text)
print('tokens ids:', tokens_ids)
print('back to text:', back_to_text)
input text: Gosto do queijo e vinho. tokens ids: [39, 1119, 298, 22317, 258, 11041, 14] back to text: Gosto do queijo e vinho.
Now let's see how we can use fastai v2 to fine-tune this model on Wikipedia in Portuguese, using all the fastai v2 training utilities.
We will follow these 2 following steps:
First, we import all the text utilities:
from fastai2.text.all import *
(text from Sylvain Gugger Transformers Tutorial) To process this data to train a model, we need to build a Transform
that will be applied lazily. In a fastai Transform
you can define:
encodes
method that is applied when you call the transform (a bit like the forward
method in a nn.Module
)decodes
method that is applied when you call the decode method of the transform, if you need to decode anything for showing purposes (like converting ids to a text here)setups
method that sets some inner state of the Transform
(not needed here)class TransformersTokenizer(Transform):
def __init__(self, tokenizer): self.tokenizer = tokenizer
def encodes(self, x):
toks = self.tokenizer.tokenize(x)
return tensor(self.tokenizer.convert_tokens_to_ids(toks))
def decodes(self, x): return TitledStr(self.tokenizer.decode(x.cpu().numpy()))
Two comments on the code above:
encodes
we don't use the tokenizer.encode method since it does some additional preprocessing for the model after tokenizing and numericalizing (the aprt throwing a warning before). Here we don't need any post-processing so it's fine to skip it and we use the tokenizer.tokenize method followed by the tokenizer.convert_tokens_to_ids one.decodes
we return a TitledStr
object and not just a plain string. That's a fastai class that adds a show
method to the string, which will allow us to use all the fastai show methods.%%time
# Load the GPT2 tokenizer in English
from transformers import GPT2TokenizerFast, GPT2LMHeadModel
pretrained_weights = 'gpt2'
tokenizer_en = GPT2TokenizerFast.from_pretrained(pretrained_weights)
model_en = GPT2LMHeadModel.from_pretrained(pretrained_weights)
# To correct the warning about token_pad (GPT2TokenizerFast), run the following code
# source: https://github.com/huggingface/transformers/issues/2648#issuecomment-616177044
tokenizer_en.pad_token = tokenizer_en.eos_token
Some weights of GPT2LMHeadModel were not initialized from the model checkpoint at gpt2 and are newly initialized: ['h.0.attn.masked_bias', 'h.1.attn.masked_bias', 'h.2.attn.masked_bias', 'h.3.attn.masked_bias', 'h.4.attn.masked_bias', 'h.5.attn.masked_bias', 'h.6.attn.masked_bias', 'h.7.attn.masked_bias', 'h.8.attn.masked_bias', 'h.9.attn.masked_bias', 'h.10.attn.masked_bias', 'h.11.attn.masked_bias', 'lm_head.weight'] You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
CPU times: user 16.3 s, sys: 831 ms, total: 17.1 s Wall time: 6.94 s
# Get the path to ByteLevelBPE_tokenizer_pt config files
ByteLevelBPE_tokenizer_pt_rep = 'ByteLevelBPE_tokenizer_pt'
path_to_ByteLevelBPE_tokenizer_pt_rep = path_data/ByteLevelBPE_tokenizer_pt_rep
# import the pre-trained GPT2TokenizerFast tokenizer with the tokenizer_pt config files
tokenizer_pt = GPT2TokenizerFast.from_pretrained(
str(path_to_ByteLevelBPE_tokenizer_pt_rep),
pad_token='<|endoftext|>')
# Get sequence length max of 1024
tokenizer_pt.model_max_length = 1024
# Test of the class TransformersTokenizer of fastai with tokenizer_en
tokenizer_fastai_en = TransformersTokenizer(tokenizer_en)
text = "Maybe, you're right"
tokens_ids = tokenizer_fastai_en.encodes(text)
tokens = tokenizer_fastai_en.tokenizer.convert_ids_to_tokens(tokens_ids)
print('input text:',TitledStr(text))
print('text tokens:',TitledStr(tokens))
print('text tokens_ids:',TitledStr(tokens_ids))
print('output text:',TitledStr(tokenizer_fastai_en.decodes(tokens_ids)))
input text: Maybe, you're right text tokens: ['Maybe', ',', 'Ġyou', "'re", 'Ġright'] text tokens_ids: tensor([13300, 11, 345, 821, 826]) output text: Maybe, you're right
# Test of the class TransformersTokenizer of fastai with tokenizer_pt
tokenizer_fastai_pt = TransformersTokenizer(tokenizer_pt)
text = "Maybe, you're right"
tokens_ids = tokenizer_fastai_pt.encodes(text)
tokens = tokenizer_fastai_pt.tokenizer.convert_ids_to_tokens(tokens_ids)
print('input text:',TitledStr(text))
print('text tokens:',TitledStr(tokens))
print('text tokens_ids:',TitledStr(tokens_ids))
print('output text:',TitledStr(tokenizer_fastai_pt.decodes(tokens_ids)))
input text: Maybe, you're right text tokens: ['May', 'be', ',', 'Ġyou', "'re", 'Ġrig', 'ht'] text tokens_ids: tensor([24656, 609, 12, 17793, 25842, 8341, 2084]) output text: Maybe, you're right
# import model if needed
# from transformers import GPT2LMHeadModel
# pretrained_weights = 'gpt2'
# model_en = GPT2LMHeadModel.from_pretrained(pretrained_weights)
tokenizer_fastai_en = TransformersTokenizer(tokenizer_en)
old_vocab_size = tokenizer_fastai_en.tokenizer.vocab_size
tokenizer_fastai_pt = TransformersTokenizer(tokenizer_pt)
new_vocab_size = tokenizer_fastai_pt.tokenizer.vocab_size
old_vocab_size,new_vocab_size,old_vocab_size-new_vocab_size
(50257, 50257, 0)
tokenizer_fastai_vocab_en = tokenizer_fastai_en.tokenizer.get_vocab()
tokenizer_fastai_vocab_ls_en = [k for k, v in sorted(tokenizer_fastai_vocab_en.items(), key=lambda item: item[1])]
len(tokenizer_fastai_vocab_ls_en),tokenizer_fastai_vocab_ls_en[:10]
(50257, ['!', '"', '#', '$', '%', '&', "'", '(', ')', '*'])
tokenizer_fastai_vocab_pt = tokenizer_fastai_pt.tokenizer.get_vocab()
tokenizer_fastai_vocab_ls_pt = [k for k, v in sorted(tokenizer_fastai_vocab_pt.items(), key=lambda item: item[1])]
len(tokenizer_fastai_vocab_ls_pt),tokenizer_fastai_vocab_ls_pt[:10]
(50257, ['<|endoftext|>', '!', '"', '#', '$', '%', '&', "'", '(', ')'])
# Check atual weight of wte and lm_head and if wte = lm_head
tens_a = model_en.transformer.wte.weight
tens_b = model_en.lm_head.weight
model_en.transformer.wte.weight,model_en.lm_head.weight,torch.all(tens_a.eq(tens_b))
(Parameter containing: tensor([[-0.1101, -0.0393, 0.0331, ..., -0.1364, 0.0151, 0.0453], [ 0.0403, -0.0486, 0.0462, ..., 0.0861, 0.0025, 0.0432], [-0.1275, 0.0479, 0.1841, ..., 0.0899, -0.1297, -0.0879], ..., [-0.0445, -0.0548, 0.0123, ..., 0.1044, 0.0978, -0.0695], [ 0.1860, 0.0167, 0.0461, ..., -0.0963, 0.0785, -0.0225], [ 0.0514, -0.0277, 0.0499, ..., 0.0070, 0.1552, 0.1207]], requires_grad=True), Parameter containing: tensor([[-0.1101, -0.0393, 0.0331, ..., -0.1364, 0.0151, 0.0453], [ 0.0403, -0.0486, 0.0462, ..., 0.0861, 0.0025, 0.0432], [-0.1275, 0.0479, 0.1841, ..., 0.0899, -0.1297, -0.0879], ..., [-0.0445, -0.0548, 0.0123, ..., 0.1044, 0.0978, -0.0695], [ 0.1860, 0.0167, 0.0461, ..., -0.0963, 0.0785, -0.0225], [ 0.0514, -0.0277, 0.0499, ..., 0.0070, 0.1552, 0.1207]], requires_grad=True), tensor(True))
# Get weights of the old wte
old_wgts = model_en.transformer.get_input_embeddings().weight.clone().detach()
# Get the mean embedding vetor of the old wte
wgts_m = old_wgts.mean(0)
# Initialize vocab size and weights of the new wte
new_vocab_size = tokenizer_fastai_pt.tokenizer.vocab_size
new_wgts = old_wgts.new_zeros(new_vocab_size,old_wgts.size(1))
Save
# Get the new wte keeping the embeddings vetors of tokens in common in the 2 vocabs
# A token present in the new vocab but not in the old one gets the mean embedding vetor of the old wte
old_vocab = tokenizer_fastai_en.tokenizer.get_vocab()
new_vocab = tokenizer_fastai_pt.tokenizer.get_vocab()
same_tokens_list = list()
different_tokens_list = list()
for w,idx_new in new_vocab.items():
idx_old = old_vocab.get(w, -1)
if idx_old>=0:
new_wgts[idx_new] = old_wgts[idx_old]
same_tokens_list.append((w,idx_new))
else:
new_wgts[idx_new] = wgts_m
different_tokens_list.append((w,idx_new))
# setup in model the new wte
new_wte = nn.Embedding(new_vocab_size,old_wgts.size(1))
#new_wte.weight.data.normal_(mean=0.0, std=model.config.initializer_range)
new_wte.weight.data = new_wgts
model_en.transformer.set_input_embeddings(new_wte)
print(f'Portuguese wte matrix setup done!\n\nWe kept {len(same_tokens_list)} embeddings vectors from the English one.\nWe did not kept {len(different_tokens_list)} embeddings vectors from the English one (instead, we used the old wte mean vector).\n')
# Check identical tokens between the 2 vocabs
num = 15
print(f'{num} first tokens IN common between the 2 vocabs:\n{same_tokens_list[:num]}\n')
print(f'{num} first tokens NOT in common between the 2 vocabs:\n{different_tokens_list[:num]}')
# save new_wgts
torch.save(new_wgts, path_data/'new_wte_wgts.pt')
# save same_tokens_list and different_tokens_list
torch.save(same_tokens_list, path_data/'same_tokens_list.pt')
torch.save(different_tokens_list, path_data/'different_tokens_list.pt')
Portuguese wte matrix setup done! We kept 12948 embeddings vetors from the English one. We did not kept 37309 embeddings vetors from the English one (we used the old wte mean vetor). 15 first tokens IN common between the 2 vocabs: [('ĠQuit', 40195), ('Smith', 32470), ('Ġomit', 39040), ('oc', 574), ('ym', 18252), ('Ġactual', 9443), ('ck', 911), ('ĠPremier', 16558), ('Ġeste', 987), ('ĠInd', 3438), ('Ġbol', 4203), ('phen', 35836), ('ĠParticip', 36689), ('ĠZeus', 19316), ('Ġnan', 39770)] 15 first tokens NOT in common between the 2 vocabs: [('PSDB', 23151), ('Ġenvio', 19270), ('Ġocupação', 5938), ('Ġdocumentada', 30011), ('Ġduros', 36706), ('visto', 44422), ('ĠSiro', 43061), ('Ġdestacavam', 47397), ('Ġarqui', 49060), ('ĠArte', 5977), ('ĠValor', 29721), ('Ġalinhados', 38446), ('Ġnúmeros', 4626), ('Ġpênis', 31686), ('cisa', 29710)]
Load
# load new_wgts
new_wgts = torch.load(path_data/'new_wte_wgts.pt')
# load same_tokens_list and different_tokens_list
same_tokens_list = torch.load(path_data/'same_tokens_list.pt')
different_tokens_list = torch.load(path_data/'different_tokens_list.pt')
# setup in model the new wte
new_wte = nn.Embedding(new_vocab_size,old_wgts.size(1))
new_wte.weight.data = new_wgts
model_en.transformer.set_input_embeddings(new_wte)
print(f'Portuguese wte matrix setup done!\n\nWe kept {len(same_tokens_list)} embeddings vectors from the English one.\nWe did not kept {len(different_tokens_list)} embeddings vectors from the English one (instead, we used the old wte mean vector).\n')
# Check identical tokens between the 2 vocabs
num = 15
print(f'{num} first tokens IN common between the 2 vocabs:\n{same_tokens_list[:num]}\n')
print(f'{num} first tokens NOT in common between the 2 vocabs:\n{different_tokens_list[:num]}')
Portuguese wte matrix setup done! We kept 12948 embeddings vetors from the English one. We did not kept 37309 embeddings vetors from the English one (we used the old wte mean vetor). 15 first tokens IN common between the 2 vocabs: [('ĠQuit', 40195), ('Smith', 32470), ('Ġomit', 39040), ('oc', 574), ('ym', 18252), ('Ġactual', 9443), ('ck', 911), ('ĠPremier', 16558), ('Ġeste', 987), ('ĠInd', 3438), ('Ġbol', 4203), ('phen', 35836), ('ĠParticip', 36689), ('ĠZeus', 19316), ('Ġnan', 39770)] 15 first tokens NOT in common between the 2 vocabs: [('PSDB', 23151), ('Ġenvio', 19270), ('Ġocupação', 5938), ('Ġdocumentada', 30011), ('Ġduros', 36706), ('visto', 44422), ('ĠSiro', 43061), ('Ġdestacavam', 47397), ('Ġarqui', 49060), ('ĠArte', 5977), ('ĠValor', 29721), ('Ġalinhados', 38446), ('Ġnúmeros', 4626), ('Ġpênis', 31686), ('cisa', 29710)]
%%time
# Check that the embeddings vetors of the common tokens are the ones from the old wte matrix
old_vocab = tokenizer_fastai_en.tokenizer.get_vocab()
#new_vocab = tokenizer_fastai_pt.tokenizer.get_vocab()
count = 0
for (tok,idx) in same_tokens_list:
w = tokenizer_fastai_pt.tokenizer.convert_ids_to_tokens(idx)
tens_a = new_wgts[idx]
idx_old = old_vocab.get(w, -1)
if idx_old >= 0:
tens_b = old_wgts[idx_old]
else:
tens_b = wgts_m
if ( torch.all(tens_a.eq(tens_b)) == False) or (w != tok):
print('idx,tok:',idx,tok)
print('idx,w:',idx,w)
print('idx_old:',idx_old)
print('identical?',torch.all(tens_a.eq(tens_b)))
count += 1
if count == 0:
print(f'Great! All the embeddings vetors of the {len(same_tokens_list)} common tokens are the ones of the old wte matrix :-)\n')
Great! All the embeddings vetors of the 12948 common tokens are the ones of the old wte matrix :-) CPU times: user 351 ms, sys: 3.98 ms, total: 355 ms Wall time: 353 ms
%%time
# Check that the embeddings vetors of the NOT common tokens are the old wte mean vetor
count = 0
for (tok,idx) in different_tokens_list:
w = tokenizer_fastai_pt.tokenizer.convert_ids_to_tokens(idx)
tens_a = new_wgts[idx]
idx_old = old_vocab.get(w, -1)
if idx_old >= 0:
tens_b = old_wgts[idx_old]
else:
tens_b = wgts_m
if ( torch.all(tens_a.eq(tens_b)) == False) or (w != tok):
print('idx,tok:',idx,tok)
print('idx,w:',idx,w)
print('idx_old:',idx_old)
print('identical?',torch.all(tens_a.eq(tens_b)))
count += 1
if count == 0:
print(f'Great! All the embeddings vetors of the {len(different_tokens_list)} NOT common tokens are the old wte mean vetor :-)\n')
Great! All the embeddings vetors of the 37309 NOT common tokens are the old wte mean vetor :-) CPU times: user 1.24 s, sys: 635 µs, total: 1.24 s Wall time: 1.23 s
model_en.lm_head.weight = model_en.transformer.wte.weight
model_en.lm_head
Linear(in_features=768, out_features=50257, bias=False)
# Check atual weight of wte and lm_head and if wte = lm_head
tens_a = model_en.transformer.wte.weight
tens_b = model_en.lm_head.weight
model_en.transformer.wte.weight,model_en.lm_head.weight,torch.all(tens_a.eq(tens_b))
(Parameter containing: tensor([[ 0.0514, -0.0277, 0.0499, ..., 0.0070, 0.1552, 0.1207], [-0.1101, -0.0393, 0.0331, ..., -0.1364, 0.0151, 0.0453], [ 0.0403, -0.0486, 0.0462, ..., 0.0861, 0.0025, 0.0432], ..., [-0.0025, -0.0585, 0.1174, ..., 0.0236, 0.0039, 0.0344], [ 0.1554, -0.1325, 0.3294, ..., -0.0977, 0.0863, -0.1514], [-0.0025, -0.0585, 0.1174, ..., 0.0236, 0.0039, 0.0344]], requires_grad=True), Parameter containing: tensor([[ 0.0514, -0.0277, 0.0499, ..., 0.0070, 0.1552, 0.1207], [-0.1101, -0.0393, 0.0331, ..., -0.1364, 0.0151, 0.0453], [ 0.0403, -0.0486, 0.0462, ..., 0.0861, 0.0025, 0.0432], ..., [-0.0025, -0.0585, 0.1174, ..., 0.0236, 0.0039, 0.0344], [ 0.1554, -0.1325, 0.3294, ..., -0.0977, 0.0863, -0.1514], [-0.0025, -0.0585, 0.1174, ..., 0.0236, 0.0039, 0.0344]], requires_grad=True), tensor(True))
(text from Sylvain Gugger Transformers Tutorial) You can then group your data with this Transform
using a TfmdLists
. It has an s in its name because it contains the training and validation datasets.
We indicate the indices of the training dataset and the validation dataset with splits
(here, 80% of the indices randomly chosen, then all the remaining indices).
lang = 'pt'
fname = f'all_texts_{lang}wiki.csv'
df = pd.read_csv(path_data/fname)
len(df)
203205
df.head()
text | |
---|---|
0 | Fotografia (do grego φως ["fós"] ("luz"), e γραφις ["grafis"] ("estilo", "pincel") ou γραφη "grafê", e significa "desenhar com luz e contraste"), por definição, é essencialmente a "técnica de criação" de imagens por meio de exposição luminosa, fixando-as em uma superfície sensível. A primeira fotografia reconhecida remonta ao ano de 1826 e é atribuída ao francês Joseph Nicéphore Niépce. Contudo, a invenção da fotografia não é obra de um só autor, mas um processo de acúmulo de avanços por parte de muitas pessoas, trabalhando, juntas ou em paralelo, ao longo de muitos anos. Se por um lado os... |
1 | Espadanedo é uma antiga freguesia portuguesa do concelho de Macedo de Cavaleiros, com 17,90 km² de área e 188 habitantes (2011). A sua densidade populacional era 10,5 hab/km².\nFoi extinta (agregada) pela reorganização administrativa de 2012/2013, sendo o seu território integrado na União de Freguesias de Espadanedo, Edroso, Murçós e Soutelo Mourisco.\n\nA antiga freguesia de S. Miguel de Espadanedo e Valongo pertenceu ao antigo concelho de Torre D. Chama, extinto a 24 de Outubro de 1855, em 1839 aparece agregada à comarca de Bragança e em 1852 à de Mirandela. Passa a pertencer definitivam... |
2 | Jacques-Germain Soufflot (Irancy, 22 de julho de 1713 — Paris, 29 de agosto de 1780) foi um arquitecto francês, iniciador do estilo arquitectónico do Neoclassicismo. O seu trabalho mais conhecido é, sem dúvida, o Panthéon (Panteão) de Paris, construído a partir de 1755, inicialmente uma igreja dedicada a Santa Genoveva.\n\nSoufflot nasceu em Irancy, perto de Auxerre, na França. Com 18 anos, entrou para a Academia Francesa de Roma, onde os jovens estudantes da década de 1750 se tornariam na primeira geração de criativos pleanamente neoclássicos. Ficará na Itália de 1731 a 1738. Quando volto... |
3 | A Faculdade de Medicina da Universidade de São Paulo (FMUSP) é uma escola médica da Universidade de São Paulo. Foi fundada em 1912 com o nome de "Faculdade de Medicina e Cirurgia de São Paulo" por Arnaldo Vieira de Carvalho (1867-1920), médico formado em 1888 pela Faculdade de Medicina do Rio de Janeiro. Em homenagem ao ilustre fundador, a Faculdade é, ainda hoje, chamada de a "Casa de Arnaldo" por seus alunos e ex-alunos. Em 1925 teve seu nome alterado para "Faculdade de Medicina de São Paulo" e em 1934, foi incorporada à recém-criada Universidade de São Paulo, passando a ter a atual desi... |
4 | A Escola do Teatro Bolshoi no Brasil é uma tradicional escola de balé existente na cidade de Joinville, no estado de Santa Catarina. Fundada em 2000, é a única filial do Teatro Bolshoi de Moscou e possui alunos de vários estados brasileiros. Tem como missão formar artistas cidadãos, promover e difundir a arte-educação.\n\nA instituição foi fundada em 15 de março de 2000, é a única filial do Teatro Bolshoi. \n\nUm orgulho para o Brasil e para Joinville, cidade sede. A Escola do Teatro Bolshoi no Brasil, com professores russos e brasileiros, forma bailarinos com a mesma precisão, técnica e q... |
df_sample = df[:1000]
num = int(0.8*len(df_sample))
idxs = np.random.randint(0, len(df_sample), len(df_sample))
idxs_train = idxs[:num]
idxs_val = idxs[num:]
We gather all texts in one numpy array (since it will be easier to use this way with fastai):
%%time
all_texts = np.concatenate([df_sample.iloc[idxs_train].text.values, df_sample.iloc[idxs_val].text.values])
CPU times: user 1.46 ms, sys: 218 µs, total: 1.68 ms Wall time: 1.61 ms
%%time
splits = [list(idxs_train), list(idxs_val)]
tls = TfmdLists(all_texts, TransformersTokenizer(tokenizer_pt), splits=splits, dl_type=LMDataLoader)
CPU times: user 322 ms, sys: 43.1 ms, total: 365 ms Wall time: 33.3 ms
We specify dl_type=LMDataLoader
for when we will convert this TfmdLists
to DataLoaders
: we will use an LMDataLoader
since we have a language modeling problem, not the usual fastai TfmdDL
.
# num = int(0.8*len(df))
# idxs = np.random.randint(0, len(df), len(df))
# idxs_train = idxs[:num]
# idxs_val = idxs[num:]
# save idxs train and valid
# torch.save(idxs_train, path_data/'idxs_train.pt')
# torch.save(idxs_val, path_data/'idxs_val.pt')
# load idxs train and valid
idxs_train = torch.load(path_data/'idxs_train.pt')
idxs_val = torch.load(path_data/'idxs_val.pt')
We gather all texts in one numpy array (since it will be easier to use this way with fastai):
%%time
all_texts = np.concatenate([df.iloc[idxs_train].text.values, df.iloc[idxs_val].text.values])
CPU times: user 42.6 ms, sys: 3.79 ms, total: 46.4 ms Wall time: 44.6 ms
%%time
splits = [list(idxs_train), list(idxs_val)]
tls = TfmdLists(all_texts, TransformersTokenizer(tokenizer_pt), splits=splits, dl_type=LMDataLoader)
CPU times: user 340 ms, sys: 31.9 ms, total: 372 ms Wall time: 151 ms
We specify dl_type=LMDataLoader
for when we will convert this TfmdLists
to DataLoaders
: we will use an LMDataLoader
since we have a language modeling problem, not the usual fastai TfmdDL
.
In a TfmdLists
you can access to the elements of the training or validation set quite easily:
tls.train[0],tls.valid[0]
(tensor([19715, 305, 12866, ..., 21725, 14, 199]), tensor([ 47, 3004, 261, 6913, 7358, 12, 372, 342, 3046, 261, 3478, 2535, 13, 29617, 12, 3998, 347, 5926, 4067, 305, 787, 14, 199, 199, 47, 1326, 712, 1912, 303, 1486, 275, 3004, 621, 342, 23590, 307, 1162, 303, 13286, 33431, 261, 4266, 3925, 298, 6431, 723, 4202, 11772, 12, 47284, 324, 341, 3007, 1361, 475, 1055, 1938, 298, 1568, 261, 3699, 4384, 12, 300, 13988, 14, 315, 3182, 379, 7618, 1224, 305, 2582, 4060, 643, 12, 10247, 475, 5306, 14, 199, 199, 2704, 10553, 544, 7095, 315, 12240, 7941, 12, 3837, 305, 4624, 261, 29549, 305, 1668, 10052, 14, 937, 10130, 323, 443, 1569, 349, 5615, 300, 307, 377, 21016, 303, 10388, 818, 347, 32881, 12, 443, 6339, 298, 6042, 15992, 489, 1622, 2341, 305, 1223, 12, 391, 5760, 258, 2806, 14, 384, 1845, 621, 25092, 258, 18822, 4166, 12, 576, 379, 10553, 297, 342, 11641, 325, 3928, 12, 300, 307, 21016, 258, 5437, 1188, 447, 24901, 307, 377, 16987, 14, 14194, 788, 750, 12, 1188, 38843, 430, 375, 21697, 341, 259, 1868, 261, 48357, 14, 29591, 307, 5724, 9573, 375, 21697, 7297, 275, 6744, 261, 810, 604, 341, 5105, 14, 315, 3219, 621, 3124, 6913, 7358, 275, 2043, 2823, 298, 1568, 300, 1796, 710, 14, 199, 199, 3062, 377, 2862, 4426, 298, 1279, 3129, 12, 259, 4900, 305, 4607, 303, 5741, 391, 2074, 261, 5773, 305, 8368, 1326, 12, 297, 660, 17316, 12, 35051, 258, 18433, 12, 1361, 712, 375, 2247, 303, 12790, 341, 23511, 12, 6315, 261, 1876, 258, 305, 1172, 14, 2284, 48800, 12, 259, 4823, 5594, 373, 5278, 341, 275, 346, 3433, 569, 363, 401, 868, 258, 22825, 5661, 1367, 818, 12, 32711, 49209, 12, 1674, 2935, 261, 21346, 1106, 9792, 615, 608, 199, 199, 47, 5252, 3648, 363, 445, 1223, 1351, 1286, 762, 9, 621, 914, 31729, 661, 6139, 13, 393, 13, 46944, 14, 6329, 12, 259, 2794, 7624, 2424, 341, 16041, 9519, 12, 7583, 290, 414, 1569, 49532, 322, 31366, 12, 1205, 5365, 38605, 330, 266, 1278, 595, 551, 2358, 621, 3009, 307, 377, 19054, 4795, 22399, 10627, 7189, 12, 297, 3406, 77, 10122, 258, 7004, 282, 4394, 14, 199, 199, 33, 1646, 6860, 258, 375, 16021, 468, 9433, 793, 1125, 4297, 14, 1309, 307, 1173, 10470, 300, 2551, 15359, 298, 2043, 258, 450, 5147, 7608, 375, 32985, 261, 4453, 489, 39323, 33204, 14, 2044, 1705, 12, 347, 1430, 2768, 1173, 1188, 6654, 7050, 305, 4623, 12, 307, 12, 358, 2390, 261, 342, 2374, 18423, 12, 4296, 47253, 13, 1276, 12, 9782, 330, 86, 8949, 824, 551, 199, 199, 33, 1583, 261, 2750, 372, 9245, 534, 1868, 261, 7580, 28818, 25399, 12, 4037, 549, 2319, 579, 49568, 12, 4117, 1361, 259, 2611, 5592, 261, 13621, 14, 199, 199, 1220, 604, 4127, 32122, 259, 36930, 298, 3004, 14, 315, 17856, 2721, 18633, 261, 6913, 7358, 6526, 300, 867, 33193, 7016, 14, 384, 3396, 33957, 324, 305, 1646, 347, 787, 10103, 300, 349, 1430, 2768, 9347, 29455, 14, 7267, 623, 375, 604, 300, 307, 259, 8368, 23832, 660, 13027, 297, 275, 3004, 12, 12603, 2613, 341, 2611, 2310, 447, 9251, 305, 787, 12, 391, 259, 27928, 19106, 14, 199, 199, 3062, 375, 604, 307, 303, 4171, 12, 275, 3004, 379, 23111, 7032, 1768, 3958, 305, 787, 14, 778, 1368, 3376, 13111, 1396, 420, 25006, 14, 47557, 1139, 1370, 267, 12, 13567, 358, 36628, 1739, 258, 4915, 25459, 258, 2775, 4718, 261, 23268, 45599, 409, 275, 467, 4007, 258, 4275, 1979, 1179, 3883, 443, 4786, 298, 20445, 661, 604, 4251, 14, 199, 199, 598, 2791, 12, 6710, 349, 7744, 2978, 12, 259, 7336, 2589, 275, 3343, 261, 27374, 298, 3004, 14, 11073, 377, 3735, 307, 30954, 3826, 1473, 259, 7693, 420, 452, 1368, 3376, 489, 5437, 27, 259, 6509, 261, 14577, 261, 3349, 12, 307, 40320, 13076, 259, 23268, 27, 258, 259, 8237, 261, 5437, 258, 22524, 14, 199, 199, 21101, 1430, 261, 12770, 258, 4084, 76, 310, 305, 787, 14, 21514, 27281, 300, 13491, 14, 199, 199, 6658, 2123, 391, 12943, 12150, 23287, 14, 27050, 1056, 375, 18948, 12, 297, 1472, 261, 961, 708, 34943, 4482, 14, 199, 199, 47, 762, 258, 447, 32339, 5199, 3901, 261, 3699, 4384, 14, 199, 199, 598, 2265, 5576, 21352, 423, 14, 12937, 1496, 347, 1583, 261, 3188, 14, 199, 199, 2557, 342, 2424, 47930, 1397, 261, 31301, 2022, 199, 199, 18000, 261, 19220, 307, 8816, 325, 6016, 305, 2659, 7813, 261, 6032, 261, 3699, 4384, 12, 300, 2265, 20092, 13, 7448, 12478, 12, 261, 2440, 341, 275, 18538, 4067, 14, 199, 199, 36610, 300, 342, 4968, 10330, 6016, 261, 5565, 10569, 13, 71, 8189, 12, 261, 8300, 3752, 14, 199, 199, 598, 2265, 20092, 13, 39, 7622, 258, 20092, 13, 7448, 12478, 14, 21514, 37162, 300, 10415, 14, 199, 199, 49222, 261, 762, 2168, 261, 1821, 259, 787, 14, 199, 30330, 9447, 261, 6913, 7358, 14, 28923, 358, 712, 2121, 1461, 275, 3093, 258, 4208, 261, 1815, 9312, 341, 259, 1868, 305, 1055, 1938, 14, 199, 199, 49163, 347, 6608, 305, 8330, 12, 325, 6016, 305, 2659, 3265, 12005, 12, 300, 2265, 20092, 13, 7448, 12478, 14, 199]))
They are not the same. We can see the shape are differents:
tls.tfms(tls.train.items[0]).shape, tls.tfms(tls.valid.items[0]).shape
(torch.Size([1327]), torch.Size([849]))
And we can have a look at both decodes using show_at
:
show_at(tls.train, 0)
Francisco da Silveira Pinto da Fonseca Teixeira (Canelas (Peso da Régua), 1 de Setembro de 1763 — Vila Real, 27 de Maio de 1821), 1.º conde de Amarante, mais conhecido por General Silveira, foi um oficial general do Exército Português e político, que se destacou durante a Guerra Peninsular. O general Silveira (como é mais conhecido em numerosas obras) era filho de Manuel da Silveira Pinto da Fonseca e de D. Antónia da Silveira, teve um irmão, António da Silveira Pinto da Fonseca, que foi o 1º Visconde de Canelas. Casou em 16 de Abril de 1781 com D. Maria Emília Teixeira de Magalhães e Lacerda e deste matrimónio teve três filhos: Manuel da Silveira Pinto da Fonseca Teixeira, 1º Marquês de Chaves, Miguel da Silveira Pinto da Fonseca e D. Mariana da Silveira Pinto da Fonseca. Assentou praça, como Cadete, no Regimento de Cavalaria de Almeida (mais tarde Cavalaria 11) a 25 de Abril de 1780. Ali foi promovido a Alferes em 22 de Abril de 1790 e a Tenente, no Regimento de Cavalaria 6, em 17 de Dezembro de 1792. No dia 17 de Dezembro de 1799 foi promovido a Capitão e nomeado Ajudante-de-Ordens do Governador das Armas da província da Beira. Em 1801, por decreto de 6 de Março, Francisco da Silveira foi promovido ao posto de sargento-mor. Nesse mesmo ano, quando teve início a chamada Guerra das Laranjas, juntamente com outras pessoas importantes de Trás-os-Montes, participou no levantamento de um corpo de voluntários, tendo sido nomeado a 19 de Maio Comandante-Chefe das Companhias Francas de Trás-os-Montes. Em 14 de Março de 1803 foi promovido ao posto de tenente-coronel, no Regimento de Cavalaria 6. Em Dezembro de 1807, no início da Primeira Invasão Francesa encontrava-se em Aveiro. Junot tinha dado ordem para desmobilizar a maior parte do Exército Português e formar, com as melhores unidades, um corpo de tropas que foi designado Legião Lusitana (ou Legião Portuguesa). Silveira foi chamado a Coimbra para testemunhar a desmobilização dos Regimentos de Cavalaria 6, 9, 11 e 12. Pediu a sua demissão que foi aceite pelo governo de Junot e partiu para o Porto com o objectivo de chegar a bordo da esquadra britânica que se encontrava ao largo e, dessa forma, fugir para o Brasil. Não lhe sendo possível executar este plano foi para Vila Real. Quando a insurreição que tinha nascido em Espanha chegou a Portugal, foi criada no Porto a Junta Provisional do Supremo Governo do Reino, presidida pelo bispo do Porto. A revolta rapidamente se estendeu a todo o Reino, primeiro em Trás-os-Montes, onde Francisco da Silveira teve um papel preponderante na aclamação do governo legítimo de Portugal. O papel que então desempenhou mereceu o reconhecimento da Junta do Supremo Governo do Reino que decretou, a 21 de Julho, a sua promoção a coronel do regimento de Cavalaria 6. Ainda em 1808, participou na força sob comando do general Bernardim Freire de Andrade que se dirigiu para Sul ao encontro das tropas britânicas desembarcadas em Lavos. Exercia então as funções de comandante da guarda avançada deste corpo de tropas. Depois de as tropas francesas terem saído de Portugal, Silveira regressou ao Norte para participar na reorganização do Exército. Foi promovido a Brigadeiro e nomeado Governador Militar de Trás-os-Montes por carta régia de 15 de Fevereiro de 1809. Entretanto teve início a Segunda Invasão Francesa. Perante a superioridade dos franceses, Silveira foi obrigado a abandonar a praça de Chaves, tendo-se dirigido para a região de Vila Real. Quando as tropas francesas continuaram o seu avanço em direcção a Braga, deixando uma pequena guarnição em Chaves, Silveira regressou com as suas tropas, colocou cerco aquela praça que acabou por se render pouco tempo depois. Soult ocupou o Porto em finais de Março de 1809 e Silveira, com as suas tropas mal treinadas, mal equipadas, muitos deles sem armas de fogo, desenvolveu uma actividade notável na defesa da linha do Tâmega. Desta acção, o episódio mais marcante foi a defesa da ponte de Amarante. Obrigado a retirar após catorze dias de resistência, não se deixou abater e, em breve, as suas tropas, obrigavam o corpo de tropas francesas, sob comando de Loison, a retirar para Guimarães. Na ordem do dia de 21 de Maio de 1809, o brigadeiro Francisco da Silveira era promovido a Marechal de Campo em recompensa pela forma como se bateu contra os invasores franceses. A Terceira Invasão Francesa colocou-o novamente em actividade operacional em que o seu prestígio se consolidou. Das acções em que participou destaca-se o ataque ao reduto em Puebla de Sanábria (1 a 10 de Agosto de 1810) na província de Zamora junto à fronteira no norte de Portugal, nos combates em Valverde (14 de Novembro de 1810), defesa de Pinhel (31 de Dezembro de 1810) e defesa Vila da Ponte (11 de Janeiro de 1811). A portaria de 5 de Fevereiro de 1812 veio confirmar a sua promoção a Tenente-general com antiguidade reportada a 1 de Janeiro desse ano. O seu valor foi reconhecido tanto pelo marechal Beresford, comandante em chefe do Exército Português, como por Wellesley que comandava o Exército Aliado na luta contra os franceses. É assim que o encontramos a comandar uma divisão de infantaria portuguesa no exército de Wellesley na Batalha de Vitoria e outras acções na fase final da guerra. Após a Guerra Peninsular, que termina em 1814, Silveira voltou ao lugar de Governador das Armas da Província de Trás-os-Montes. Em 1820, quando a 24 de Agosto rebentou a revolução Liberal, foi convidado a aderir ao partido da Junta Provisória do Porto mas recusou e reuniu em Chaves as tropas da província de Trás-os-Montes com o objectivo contrário, de combater a revolução. Não foi bem sucedido nesta empresa pois essas tropas acabaram por se colocar do lado da Junta do Porto. Depois deste episódio, Silveira retirou-se para Vila Real onde veio a falecer no ano seguinte. Foi sepultado no jazigo da família, na capela do Espírito Santo em Canelas. A 13 de Maio de 1809, o Príncipe Regente agraciou-o com o título de Conde de Amarante. A sua acção durante a Segunda Invasão Francesa mereceu-lhe o maior respeito em todo o Reino. Além desta honra, o 1º Conde de Amarante foi condecorado com a medalha de sete campanhas da Guerra Peninsular, com as medalhas britânica e espanhola por acções e batalhas nesta guerra, com os graus de grã-cruz da Ordem Militar de Cristo e de comendador honorário da Ordem Militar da Torre e Espada.
(text from Sylvain Gugger Transformers Tutorial) The fastai v2 library expects the data to be assembled in a DataLoaders
object (something that has a training and validation dataloader). We can get one by using the dataloaders
method. We just have to specify a batch size and a sequence length.
Since the GPT-2 model was trained with sequences of size 1024, we use this sequence length (it's a stateless model, so it will change the perplexity if we use less).
%%time
bs,sl = 8,1024
dls = tls.dataloaders(bs=bs, seq_len=sl)
CPU times: user 6h 43min 14s, sys: 59min 46s, total: 7h 43min Wall time: 31min 27s
%%time
# IMPOSSIBLE TO SAVE Dataloaders at the date of 07/01/2020
# source: https://forums.fast.ai/t/how-to-save-dataloaders/73828/6
# save
# fname = 'dls_ptwiki_tokenizerGPT2.pkl'
# torch.save(dls, path_data/fname)
# load
# dls = torch.load(path_data/fname)
CPU times: user 4 µs, sys: 1e+03 ns, total: 5 µs Wall time: 11 µs
Note that you may have to reduce the batch size depending on your GPU RAM.
In fastai v2, as soo as we have a DataLoaders
, we can use show_batch
to have a look at the data (here texts for inputs, and the same text shifted by one token to the right for validation).
dls.show_batch(max_n=5)
text | text_ | |
---|---|---|
0 | Leandro da Silva Nogueira, ou Buscapé, como também é conhecido (São Paulo, 11 de novembro de 1985) é um lutador brasileiro de MMA. Atualmente integra o elenco UFC na categoria peso-leve (até 70,3 kg). \n\nLeandro Silva fez sua estreia no MMA profissional no Beach Fight Festival contra o lutador Viscardi Andrade e ganhou por decisão unânime.\n\nBuscapé lutou nas eliminatórias do TUF contra o lutador David Vieira mas perdeu por decisão majoritária. \n\nLeandro foi contratado para enfrentar o Ildemar Marajó no, mas Leandro perdeu por decisão unânime. Após a derrota ele foi liberado do UFC.\n\nApós ser demitido do UFC, Leandro lutou em alguns eventos no Brasil e também no Pancrase do Japão, vencendo todas as cinco lutas que fez.\n\nLeandro retornou ao UFC em 14 de Setembro de 2014 no substituindo o mexicano Efrain Escudero e enfrentou seu conterrâneo Francisco Trinaldo. Ele foi derrotado por decisão unânime em uma luta muito equilibrada.\n\nLeandro | andro da Silva Nogueira, ou Buscapé, como também é conhecido (São Paulo, 11 de novembro de 1985) é um lutador brasileiro de MMA. Atualmente integra o elenco UFC na categoria peso-leve (até 70,3 kg). \n\nLeandro Silva fez sua estreia no MMA profissional no Beach Fight Festival contra o lutador Viscardi Andrade e ganhou por decisão unânime.\n\nBuscapé lutou nas eliminatórias do TUF contra o lutador David Vieira mas perdeu por decisão majoritária. \n\nLeandro foi contratado para enfrentar o Ildemar Marajó no, mas Leandro perdeu por decisão unânime. Após a derrota ele foi liberado do UFC.\n\nApós ser demitido do UFC, Leandro lutou em alguns eventos no Brasil e também no Pancrase do Japão, vencendo todas as cinco lutas que fez.\n\nLeandro retornou ao UFC em 14 de Setembro de 2014 no substituindo o mexicano Efrain Escudero e enfrentou seu conterrâneo Francisco Trinaldo. Ele foi derrotado por decisão unânime em uma luta muito equilibrada.\n\nLeandro |
1 | em idades mais precoces. Carleton criticou ainda mais a decisão de diminuir a votação, citando as preocupações americanas com a juventude em geral, a dependência exagerada do ensino superior e equiparando a inteligência tecnológica com a responsabilidade e a inteligência. Ele denunciou também o argumento do serviço militar, chamando-o de "clichê". Considerando as idades dos soldados na Guerra Civil Americana, Ele afirmou que alfabetização e educação não eram motivo para limitar o voto; Em vez disso, o senso comum e a capacidade de compreender o sistema político fundamentaram as restrições de idade para votar.\n\nJames J. Kilpatrick, Um colunista político, afirmou que os estados foram "extorquidos para ratificar a Vigésima Sexta Emenda". Em seu artigo, ele alega que ao passar a extensão de 1970 à Lei de Direitos de Voto, o Congresso efetivamente forçou os Estados a ratificar a emenda para que eles não sejam forçados a lidar financeiramente e burocraticamente | idades mais precoces. Carleton criticou ainda mais a decisão de diminuir a votação, citando as preocupações americanas com a juventude em geral, a dependência exagerada do ensino superior e equiparando a inteligência tecnológica com a responsabilidade e a inteligência. Ele denunciou também o argumento do serviço militar, chamando-o de "clichê". Considerando as idades dos soldados na Guerra Civil Americana, Ele afirmou que alfabetização e educação não eram motivo para limitar o voto; Em vez disso, o senso comum e a capacidade de compreender o sistema político fundamentaram as restrições de idade para votar.\n\nJames J. Kilpatrick, Um colunista político, afirmou que os estados foram "extorquidos para ratificar a Vigésima Sexta Emenda". Em seu artigo, ele alega que ao passar a extensão de 1970 à Lei de Direitos de Voto, o Congresso efetivamente forçou os Estados a ratificar a emenda para que eles não sejam forçados a lidar financeiramente e burocraticamente com |
2 | registra o primeiro voo intercontinental sobre o Atlântico norte com um avião de dois motores, Boeing 767 - Montreal/Tel Aviv.\n\nA EL AL opera o voo direto mais longo da sua história: Los Angeles-Tel Aviv: 11.265,408 quilômetros em 13 horas e 41 minutos.\n\nVoo histórico para Moscou.\n\nUm Boeing 747 da EL AL leva um recorde de 1087 passageiros - judeus etíopes voando de Addis Ababa para Israel, parte da Operação Salomão.\n\nO primeiro voo para Aman.\n\nO primeiro voo do Boeing 777 da EL AL\n\nAbertura de capital - Como parte do processo de privatização da companhia de aviação, esta e o Estado de Israel publicaram um prospecto, em 30 de maio de 2003, colocando a venda as ações e as opções de ações da empresa. No início de junho de 2003 a empresa abriu o seu capital e as suas ações são registradas para negociações na Bolsa de Valores de Tel Aviv.\n\nA companhia | o primeiro voo intercontinental sobre o Atlântico norte com um avião de dois motores, Boeing 767 - Montreal/Tel Aviv.\n\nA EL AL opera o voo direto mais longo da sua história: Los Angeles-Tel Aviv: 11.265,408 quilômetros em 13 horas e 41 minutos.\n\nVoo histórico para Moscou.\n\nUm Boeing 747 da EL AL leva um recorde de 1087 passageiros - judeus etíopes voando de Addis Ababa para Israel, parte da Operação Salomão.\n\nO primeiro voo para Aman.\n\nO primeiro voo do Boeing 777 da EL AL\n\nAbertura de capital - Como parte do processo de privatização da companhia de aviação, esta e o Estado de Israel publicaram um prospecto, em 30 de maio de 2003, colocando a venda as ações e as opções de ações da empresa. No início de junho de 2003 a empresa abriu o seu capital e as suas ações são registradas para negociações na Bolsa de Valores de Tel Aviv.\n\nA companhia de |
3 | . Em 1857, foi nomeado Director do Hospital de Febre Amarela instalado no Convento do Desterro.\n\nAssistiu, em 1867, como Delegado do Governo Português, ao Congresso Internacional de Oftalmologia, que se reuniu em Paris, França, e onde apresentou valiosos trabalhos sobre a Oftalmologia em Portugal. José Cândido Loureiro teve que defender os seus trabalhos em controvérsias com vários Professores, nomeadamente com o Especialista Francês Carcassonne.\n\nDe novo em Portugal, dedicou-se activamente ao estudo da doenças dos olhos e pugnou, com extraordinária energia, pelo estabelecimento duma Enfermaria para Oftálmicos, no Hospital Real de São José.\n\nFoi, ainda, Subdelegado de Saúde em Lisboa.\n\nTendo adoecido e, sendo dum carácter profundamente impressionável, julgou-se perdido e atirou-se da janela do seu quarto, situado no terceiro pavimento do Hospital Real de São José.\n\nColaborou no "Jornal da Sociedade de Ciências Médicas" e escreveu:\nCartão Verde é um telejornal esportivo produzido e exibido pela TV Cultura. Idealizado por Michel Laurence, é exibido | Em 1857, foi nomeado Director do Hospital de Febre Amarela instalado no Convento do Desterro.\n\nAssistiu, em 1867, como Delegado do Governo Português, ao Congresso Internacional de Oftalmologia, que se reuniu em Paris, França, e onde apresentou valiosos trabalhos sobre a Oftalmologia em Portugal. José Cândido Loureiro teve que defender os seus trabalhos em controvérsias com vários Professores, nomeadamente com o Especialista Francês Carcassonne.\n\nDe novo em Portugal, dedicou-se activamente ao estudo da doenças dos olhos e pugnou, com extraordinária energia, pelo estabelecimento duma Enfermaria para Oftálmicos, no Hospital Real de São José.\n\nFoi, ainda, Subdelegado de Saúde em Lisboa.\n\nTendo adoecido e, sendo dum carácter profundamente impressionável, julgou-se perdido e atirou-se da janela do seu quarto, situado no terceiro pavimento do Hospital Real de São José.\n\nColaborou no "Jornal da Sociedade de Ciências Médicas" e escreveu:\nCartão Verde é um telejornal esportivo produzido e exibido pela TV Cultura. Idealizado por Michel Laurence, é exibido |
4 | outros suprimentos, enquanto lealistas saqueavam assentamentos civis, especialmente em Nova Iorque, Kentucky e na Pensilvânia. Forças-tarefa de Iroqueses e lealistas lançaram-se em batalhas bem-sucedidas, como no vale de Wyoming e no vale de Cherry em 1778, provocando George Washington a ordenar uma expedição punitiva sob comando do general John Sullivan a oeste de Nova Iorque, no verão de 1779. Houve pouca luta, com os americanos incendiando terras indígenas e saqueando mantimentos, forçando os índios a fugir até Quebec ou para a região das Cataratas do Niágara.\n\nNo norte das regiões de Ohio e Illinois, o general americano George Rogers Clark tentou neutralizar a influência britânica nas tribos próximas a Ohio ao capturar as importantes cidades de Kaskaskia, Cahokia e Vincennes no verão de 1778. Ele foi bem-sucedido. Quando o general Henry Hamilton, comandante da guarnição britânica em Detroit, retomou Vincennes, Clark retornou com uma marcha surpresa em janeiro de 1779 | suprimentos, enquanto lealistas saqueavam assentamentos civis, especialmente em Nova Iorque, Kentucky e na Pensilvânia. Forças-tarefa de Iroqueses e lealistas lançaram-se em batalhas bem-sucedidas, como no vale de Wyoming e no vale de Cherry em 1778, provocando George Washington a ordenar uma expedição punitiva sob comando do general John Sullivan a oeste de Nova Iorque, no verão de 1779. Houve pouca luta, com os americanos incendiando terras indígenas e saqueando mantimentos, forçando os índios a fugir até Quebec ou para a região das Cataratas do Niágara.\n\nNo norte das regiões de Ohio e Illinois, o general americano George Rogers Clark tentou neutralizar a influência britânica nas tribos próximas a Ohio ao capturar as importantes cidades de Kaskaskia, Cahokia e Vincennes no verão de 1778. Ele foi bem-sucedido. Quando o general Henry Hamilton, comandante da guarnição britânica em Detroit, retomou Vincennes, Clark retornou com uma marcha surpresa em janeiro de 1779 e |
Another way to gather the data is to preprocess the texts once and for all and only use the transform to decode the tensors to texts:
%%time
def tokenize(text):
toks = tokenizer.tokenize(text)
return tensor(tokenizer.convert_tokens_to_ids(toks))
#tokenized = [tokenize(t) for t in progress_bar(all_texts)]
CPU times: user 5 µs, sys: 1e+03 ns, total: 6 µs Wall time: 11.4 µs
#save tokenized
# torch.save(tokenized, path_data/'tokenized_gpt2.pt')
%%time
# load tokenized
tokenized_pt = torch.load(path_data/'tokenized_gpt2.pt')
Now we change the previous Tokenizer
like this:
class TransformersTokenizer(Transform):
def __init__(self, tokenizer): self.tokenizer = tokenizer
def encodes(self, x):
return x if isinstance(x, Tensor) else tokenize(x)
def decodes(self, x): return TitledStr(self.tokenizer.decode(x.cpu().numpy()))
In the encodes
method, we still account for the case where we get something that's not already tokenized, just in case we were to build a dataset with new texts using this transform.
%%time
tls2 = TfmdLists(tokenized_pt, TransformersTokenizer(tokenizer_pt), splits=splits, dl_type=LMDataLoader)
dls2 = tls.dataloaders(bs=bs, seq_len=sl)
And we can check it still works properly for showing purposes:
dls2.show_batch(max_n=5)
text | text_ | |
---|---|---|
0 | O GAP (Projeto de Proteção dos Grandes Primatas) é um movimento internacional com o objetivo de garantir direitos básicos aos Grandes Primatas: Chimpanzés, Gorilas, Orangotangos e Bonobos.\n\nO conceito de Direitos Animais proíbe o uso de animais não-humanos como meios para fins humanos (alimentação, roupa, companhia, entretenimento, estudo, pesquisa médica...), reconhecendo-os como fins em si. A abrangência desta idéia é uma discussão à parte: De acordo com Tom Regan devemos estendê-la a todos os animais que sejam "sujeitos-de-uma-vida", ou seja, que existem e sabem que existem, possuem uma vida e são sencientes. Mesmo assim, é de concordância geral que se os direitos devem ser aplicados em etapas, o primeiro e decisivo passo seria incluir os grandes primatas, uma vez que eles além de serem os nossos parentes evolutivos compartilham conosco 98,6% do DNA.\n\nDe acordo com essa filosofia os animais, bem como os humanos sem a capacidade do raciocínio (Argumento dos Casos | GAP (Projeto de Proteção dos Grandes Primatas) é um movimento internacional com o objetivo de garantir direitos básicos aos Grandes Primatas: Chimpanzés, Gorilas, Orangotangos e Bonobos.\n\nO conceito de Direitos Animais proíbe o uso de animais não-humanos como meios para fins humanos (alimentação, roupa, companhia, entretenimento, estudo, pesquisa médica...), reconhecendo-os como fins em si. A abrangência desta idéia é uma discussão à parte: De acordo com Tom Regan devemos estendê-la a todos os animais que sejam "sujeitos-de-uma-vida", ou seja, que existem e sabem que existem, possuem uma vida e são sencientes. Mesmo assim, é de concordância geral que se os direitos devem ser aplicados em etapas, o primeiro e decisivo passo seria incluir os grandes primatas, uma vez que eles além de serem os nossos parentes evolutivos compartilham conosco 98,6% do DNA.\n\nDe acordo com essa filosofia os animais, bem como os humanos sem a capacidade do raciocínio (Argumento dos Casos |
1 | e televisão americano.\n\nVencedor de 5 prêmios Globo de Ouro e 7 Emmy é mais conhecido por criar e escrever as séries Nip/Tuck (com Dylan Walsh e Julian McMahon) e a comédia-drama musical Glee. É também conhecido pela série "Popular". Suas mais recentes séries são "9-1-1", "Pose" e "The Politician". É também o realizador de "Eat Pray Love". Ryan é abertamente "gay", o que é um dos assuntos mais comuns em suas séries.\n\nEm 13 de fevereiro de 2018, foi anunciado que Ryan assinou um contrato milionário de 5 anos com a Netflix para produzir conteúdos originais para seu catálogo.\n\nMurphy começou como um jornalista trabalhando para "The Miami Herald", "Los Angeles Times", "New York Daily News", "Knoxville News Sentinel" e "Entertainment Weekly". Ele começou a escrever roteiros no fim de 1990, quando Steven Spielberg comprou seu roteiro "Why Can't I Be Audrey Hepburn?".\n\nMurphy começou sua carreira na televisão em 1999 com | televisão americano.\n\nVencedor de 5 prêmios Globo de Ouro e 7 Emmy é mais conhecido por criar e escrever as séries Nip/Tuck (com Dylan Walsh e Julian McMahon) e a comédia-drama musical Glee. É também conhecido pela série "Popular". Suas mais recentes séries são "9-1-1", "Pose" e "The Politician". É também o realizador de "Eat Pray Love". Ryan é abertamente "gay", o que é um dos assuntos mais comuns em suas séries.\n\nEm 13 de fevereiro de 2018, foi anunciado que Ryan assinou um contrato milionário de 5 anos com a Netflix para produzir conteúdos originais para seu catálogo.\n\nMurphy começou como um jornalista trabalhando para "The Miami Herald", "Los Angeles Times", "New York Daily News", "Knoxville News Sentinel" e "Entertainment Weekly". Ele começou a escrever roteiros no fim de 1990, quando Steven Spielberg comprou seu roteiro "Why Can't I Be Audrey Hepburn?".\n\nMurphy começou sua carreira na televisão em 1999 com a |
2 | ando de um símbolo já costumeiro.\n\nEm 14 de março de 1933, logo após o compromisso de Hitler como Chanceler da Alemanha, a bandeira do NSDAP foi içada ao lado das cores nacionais da Alemanha. Foi adotada como bandeira nacional exclusiva no dia 15 de setembro de 1935.\n\nA suástica foi usada nos distintivos e bandeiras ao longo de toda a era nazista, especialmente pelo governo e pelo exército, mas também foi usada por organizações "populares", como o "Reichsbund Deutsche Jägerschaft".\n\nVariantes do uso da suástica pelos nazistas:\n\nA suástica, usada por Hitler e pelo Partido Nazista, ainda é, na atualidade, utilizada por grupos neonazistas. Mas, para a maioria das pessoas do Ocidente, a suástica, sendo um símbolo associado às ideias e atos de nazistas, tornou-se um tabu em muitos países ocidentais.\n\nNa Alemanha de pós-guerra, por exemplo, o Código Penal ("Strafgesetzbuch") tornou criminosa a exibição de símbolos nazistas, tais como a suástica - exceto | de um símbolo já costumeiro.\n\nEm 14 de março de 1933, logo após o compromisso de Hitler como Chanceler da Alemanha, a bandeira do NSDAP foi içada ao lado das cores nacionais da Alemanha. Foi adotada como bandeira nacional exclusiva no dia 15 de setembro de 1935.\n\nA suástica foi usada nos distintivos e bandeiras ao longo de toda a era nazista, especialmente pelo governo e pelo exército, mas também foi usada por organizações "populares", como o "Reichsbund Deutsche Jägerschaft".\n\nVariantes do uso da suástica pelos nazistas:\n\nA suástica, usada por Hitler e pelo Partido Nazista, ainda é, na atualidade, utilizada por grupos neonazistas. Mas, para a maioria das pessoas do Ocidente, a suástica, sendo um símbolo associado às ideias e atos de nazistas, tornou-se um tabu em muitos países ocidentais.\n\nNa Alemanha de pós-guerra, por exemplo, o Código Penal ("Strafgesetzbuch") tornou criminosa a exibição de símbolos nazistas, tais como a suástica - exceto |
3 | \nteoria da aprendizagem computacional, um cálculo é considerado viável se\nele pode ser feito em um tempo polinomial. Existe dois tipos de resultados \nde complexibilidade de tempo:\nOs resultados negativos muitas vezes dependem se geralmente se acredita, mas ainda a hipóteses não comprovadas, tais como:\n\nHá várias abordagens diferentes da teoria de aprendizagem computacional. \nEstas diferenças são baseadas em fazer suposições sobre a\nInferência princípios usados para generalizar a partir de dados limitados.\nIsto inclui diferentes definições Probabilidade (veja\nProbabilidade de frequência, Probabilidade epistemológica) e premissas diferentes sobre a geração de amostras.\n\n\nLimitações de criptografia na aprendizagem fórmulas boolean e autômatos finitos. Em Proceedings of the 21st Annual ACM Symposium sobre Teoria da Computação, páginas 433-444, de Nova York. ACM.\nWilliam "Bill" Warren Bradley (nascido em 28 de julho de 1943) é um político americano e ex-jogador de basquete profissional. Ele serviu três mandatos como senador democrata de Nova Jersey. Ele concorreu sem sucesso pela nomeação do Partido | teoria da aprendizagem computacional, um cálculo é considerado viável se\nele pode ser feito em um tempo polinomial. Existe dois tipos de resultados \nde complexibilidade de tempo:\nOs resultados negativos muitas vezes dependem se geralmente se acredita, mas ainda a hipóteses não comprovadas, tais como:\n\nHá várias abordagens diferentes da teoria de aprendizagem computacional. \nEstas diferenças são baseadas em fazer suposições sobre a\nInferência princípios usados para generalizar a partir de dados limitados.\nIsto inclui diferentes definições Probabilidade (veja\nProbabilidade de frequência, Probabilidade epistemológica) e premissas diferentes sobre a geração de amostras.\n\n\nLimitações de criptografia na aprendizagem fórmulas boolean e autômatos finitos. Em Proceedings of the 21st Annual ACM Symposium sobre Teoria da Computação, páginas 433-444, de Nova York. ACM.\nWilliam "Bill" Warren Bradley (nascido em 28 de julho de 1943) é um político americano e ex-jogador de basquete profissional. Ele serviu três mandatos como senador democrata de Nova Jersey. Ele concorreu sem sucesso pela nomeação do Partido |
4 | do culto público, um ofício, uma missa especial e uma leitura própria no Breviário (atual Liturgia das Horas). O Papa Leão XIII aprovou o uso do famoso "Cordão de Santa Filomena", assim como eregiu a Arquiconfraria de Santa Filomena na França. Por sua vez São Pio X estendeu a Arquiconfraria de Santa Filomena para o mundo inteiro. Assim, a popularidade dela logo se espalhou, sendo seus mais memoráveis devotos João Maria Batista Vianney, Madalena Sofia Barat, Pedro Eymard, e Pedro Chanel, todos eles santos da Igreja Católica Apostólica Romana. \n\nJá em 1904, uma publicação feita pelo arqueólogo Orazio Marucchi () ("Osservazioni archeologiche sulla Iscrizione di S. Filomena dans Miscellanea di Storia Ecclesiastica, Vol. 2, 1904, pp. 365–386") colocou em dúvida a existência histórica de Santa Filomena. Ele defendia fundamentalmente quatro postulados:\n\n1. As placas deveriam estar em ordem direta e não indireta (como estavam) o que constituía um indício de que | culto público, um ofício, uma missa especial e uma leitura própria no Breviário (atual Liturgia das Horas). O Papa Leão XIII aprovou o uso do famoso "Cordão de Santa Filomena", assim como eregiu a Arquiconfraria de Santa Filomena na França. Por sua vez São Pio X estendeu a Arquiconfraria de Santa Filomena para o mundo inteiro. Assim, a popularidade dela logo se espalhou, sendo seus mais memoráveis devotos João Maria Batista Vianney, Madalena Sofia Barat, Pedro Eymard, e Pedro Chanel, todos eles santos da Igreja Católica Apostólica Romana. \n\nJá em 1904, uma publicação feita pelo arqueólogo Orazio Marucchi () ("Osservazioni archeologiche sulla Iscrizione di S. Filomena dans Miscellanea di Storia Ecclesiastica, Vol. 2, 1904, pp. 365–386") colocou em dúvida a existência histórica de Santa Filomena. Ele defendia fundamentalmente quatro postulados:\n\n1. As placas deveriam estar em ordem direta e não indireta (como estavam) o que constituía um indício de que haviam |
(text from Sylvain Gugger Transformers Tutorial) The Hugging Face model will return a tuple in outputs, with the actual predictions and some additional activations (should we want to use them is some regularization scheme). To work inside the fastai training loop, we will need to drop those using a Callback
: we use those to alter the behavior of the training loop.
Here we need to write the event after_pred
and replace self.learn.pred
(which contains the predictions that will be passed to the loss function) by just its first element. In callbacks, there is a shortcut that lets you access any of the underlying Learner
attribute so we can write self.pred[0]
instead of self.learn.pred[0]
. That shorcut only works for read access, not write, so we have to write self.learn.pred
on the right side (otherwise we would set a pred
attribute in the Callback
).
class DropOutput(Callback):
def after_pred(self): self.learn.pred = self.pred[0]
Of course we could make this a bit more complex and add some penalty to the loss using the other part of the tuple of predictions, like the RNNRegularizer
.
The model has 2 main layers groups: transformer
and lm_head
. As we can read in The illustrated GPT2, the lm_head
is a copy of the embeddings matrix wte
. Therefore, we need to split only the transformer
layers group to get all layers.
transformer
lm_head
Note: the last layer is a copy of the embeddings matrix wte in order to get after the softmax probability of each token in the vocab.
Now, we can create our layers groups that will allow us to use fastai v2 fine-tuning techniques:
We decided to follow the fine-tuning method showed in the notebook 10_nlp.ipynb by creating 4 layers groups: 3 layers groups of 4 decoder blocks and one embeddings groups with the wte and wpe matrices.
#model_en = model_en.train().to('cuda')
model_en
GPT2LMHeadModel( (transformer): GPT2Model( (wte): Embedding(50257, 768) (wpe): Embedding(1024, 768) (drop): Dropout(p=0.1, inplace=False) (h): ModuleList( (0): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (1): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (2): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (3): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (4): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (5): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (6): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (7): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (8): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (9): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (10): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) (11): Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) ) ) (ln_f): LayerNorm((768,), eps=1e-05, elementwise_affine=True) ) (lm_head): Linear(in_features=768, out_features=50257, bias=False) )
# Example of a decoder block (attention head)
model_en.transformer.h[0]
Block( (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (attn): Attention( (c_attn): Conv1D() (c_proj): Conv1D() (attn_dropout): Dropout(p=0.1, inplace=False) (resid_dropout): Dropout(p=0.1, inplace=False) ) (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) (mlp): MLP( (c_fc): Conv1D() (c_proj): Conv1D() (dropout): Dropout(p=0.1, inplace=False) ) )
def splitter(model):
"Split a GPT2 `model` in 3 groups for differential learning rates."
# First layers group : decoder blocks from 0 to 3
modules = []
for i in range(4): modules.append(model.transformer.h[i])
groups = [nn.Sequential(*modules)]
# Second layers group : decoder blocks from 4 to 7
modules = []
for i in range(4,8,1): modules.append(model.transformer.h[i])
groups = L(groups + [nn.Sequential(*modules)])
# Third layers group : decoder blocks from 8 to 11
modules = []
for i in range(8,12,1): modules.append(model.transformer.h[i])
groups = L(groups + [nn.Sequential(*modules)])
# Fourth layers group : embeddings matrices wte and wpe + LayerNorm at the model output
groups = L(groups + [nn.Sequential(model.transformer.wte,model.transformer.wpe,model.transformer.ln_f)])
return groups.map(params)
(text from Sylvain Gugger Transformers Tutorial) Now, we are ready to create our Learner
, which is a fastai object grouping data, model and loss function and handles model training or inference. Since we are in a language model setting, we pass accuracy and perplexity as metrics, and we need to use the callback we just defined. Lastly, we use mixed precision to save every bit of memory we can (and if you have a modern GPU, it will also make training faster).
# Learner: basic class for handling the training loop
# source: https://dev.fast.ai/learner#Learner
learn = Learner(dls, model_en, loss_func=CrossEntropyLossFlat(),
splitter = splitter,
cbs=[DropOutput],
metrics=[accuracy, Perplexity()]).to_fp16()
# Check the number of parameters groups and the hyperparameters values
learn.create_opt()
print(f'number of parameters groups: {len(learn.opt.param_groups)}')
# ... and the list of Learning Rates (before its atualization by the Optimizer of the function fit_one_cycle())
for i,h in enumerate(learn.opt.hypers):
print(i,h)
number of parameters groups: 4 0 {'wd': 0.01, 'sqr_mom': 0.99, 'lr': 0.001, 'mom': 0.9, 'eps': 1e-05} 1 {'wd': 0.01, 'sqr_mom': 0.99, 'lr': 0.001, 'mom': 0.9, 'eps': 1e-05} 2 {'wd': 0.01, 'sqr_mom': 0.99, 'lr': 0.001, 'mom': 0.9, 'eps': 1e-05} 3 {'wd': 0.01, 'sqr_mom': 0.99, 'lr': 0.001, 'mom': 0.9, 'eps': 1e-05}
We can check how good the model is without any fine-tuning step.
%%time
# loss, accuracy, Perplexity() of validation dataset
learn.validate()
CPU times: user 4h 45min 53s, sys: 1h 1min 36s, total: 5h 47min 30s Wall time: 53min 2s
(#3) [9.949938774108887,0.09898579120635986,20950.939453125]
Now that we have a Learner
, we will use during training all the fine-tuning techniques seen for classification model training (see the notebook 10_nlp.ipynb about "NLP Deep Dive: RNNs") to take advantage of the Transfer Learning of the GPT-2 pre-trained embeddings and model from Hugging Face Transformers:
splitter
: the embedding one and the 3 groups of 4 decoder blocks each)lr_max/div
to lr_max
then lr_max/div_final
(pass an array to lr_max
if you want to use differential learning rates) and the momentum with cosine annealing according to the values in moms
. The first phase takes pct_start
of the training. You can optionally pass additional cbs
and reset_opt
.)wte
, wpe
embeddings matrices and last LayerNorm
)¶learn.freeze()
learn.summary()
GPT2LMHeadModel (Input shape: ['8 x 1024']) ================================================================ Layer (type) Output Shape Param # Trainable ================================================================ Embedding 8 x 1024 x 768 38,597,376 True ________________________________________________________________ Embedding 8 x 1024 x 768 786,432 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Linear 8 x 1024 x 50257 38,597,376 True ________________________________________________________________ Total params: 163,037,184 Total trainable params: 77,982,720 Total non-trainable params: 85,054,464 Optimizer used: <function Adam at 0x7fce2f8dae60> Loss function: FlattenedLoss of CrossEntropyLoss() Model frozen up to parameter group number 3 Callbacks: - DropOutput - ModelToHalf - TrainEvalCallback - Recorder - ProgressCallback - MixedPrecision
The learn.summary ()
method gives almost the right numbers. In fact, it counts twice the weights of the wte matrix (vocab embeddings) because they are duplicated in the weights of the output linear layer.
The real numbers are:
%%time
learn.lr_find()
CPU times: user 4min 21s, sys: 58.9 s, total: 5min 20s Wall time: 1min 5s
SuggestedLRs(lr_min=0.005754399299621582, lr_steep=2.2908675418875646e-06)
The learning rate finder curve suggests picking a lr min of 6e-3. Let's use 2e-3.
learn.fit_one_cycle(1, 2e-3)
epoch | train_loss | valid_loss | accuracy | perplexity | time |
---|---|---|---|---|---|
0 | 3.803344 | 3.640777 | 0.325177 | 38.121441 | 5:48:31 |
IOPub message rate exceeded. The notebook server will temporarily stop sending output to the client in order to avoid crashing it. To change this limit, set the config variable `--NotebookApp.iopub_msg_rate_limit`. Current values: NotebookApp.iopub_msg_rate_limit=1000.0 (msgs/sec) NotebookApp.rate_limit_window=3.0 (secs)
#hide
learn.recorder.plot_loss()
In just one epoch, our model passed
Not too bad!
Now, We can pass -2
to freeze_to
to freeze all except the last two parameter groups.
learn.save(path_data/'GPT2_pt_1epoch_lr2e-3')
learn = learn.load(path_data/'GPT2_pt_1epoch_lr2e-3')
# model size
!du -hs {path_data}/'GPT2_pt_1epoch_lr2e-3.pth'
788M /mnt/home/pierre/.fastai/data/ptwiki/GPT2_pt_1epoch_lr2e-3.pth
learn.freeze_to(-2)
learn.summary()
GPT2LMHeadModel (Input shape: ['8 x 1024']) ================================================================ Layer (type) Output Shape Param # Trainable ================================================================ Embedding 8 x 1024 x 768 38,597,376 True ________________________________________________________________ Embedding 8 x 1024 x 768 786,432 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Linear 8 x 1024 x 50257 38,597,376 True ________________________________________________________________ Total params: 163,037,184 Total trainable params: 106,334,208 Total non-trainable params: 56,702,976 Optimizer used: <function Adam at 0x7fb385bf8e60> Loss function: FlattenedLoss of CrossEntropyLoss() Model frozen up to parameter group number 2 Callbacks: - DropOutput - ModelToHalf - TrainEvalCallback - Recorder - ProgressCallback - MixedPrecision
The learn.summary ()
method gives almost the right numbers. In fact, it counts twice the weights of the wte matrix (vocab embeddings) because they are duplicated in the weights of the output linear layer.
The real numbers are:
learn.fit_one_cycle(1, slice(1e-3/(2.6**4),1e-3))
epoch | train_loss | valid_loss | accuracy | perplexity | time |
---|---|---|---|---|---|
0 | 3.453913 | 3.301886 | 0.362879 | 27.163816 | 5:38:18 |
#hide
learn.recorder.plot_loss()
learn.save(path_data/'GPT2_pt_2epoch_lr1e-3')
learn = learn.load(path_data/'GPT2_pt_2epoch_lr1e-3')
# model size
!du -hs {path_data}/'GPT2_pt_2epoch_lr1e-3.pth'
1004M /mnt/home/pierre/.fastai/data/ptwiki/GPT2_pt_2epoch_lr1e-3.pth
learn.freeze_to(-3)
learn.summary()
GPT2LMHeadModel (Input shape: ['8 x 1024']) ================================================================ Layer (type) Output Shape Param # Trainable ================================================================ Embedding 8 x 1024 x 768 38,597,376 True ________________________________________________________________ Embedding 8 x 1024 x 768 786,432 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 False ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 False ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 False ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 False ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Linear 8 x 1024 x 50257 38,597,376 True ________________________________________________________________ Total params: 163,037,184 Total trainable params: 134,685,696 Total non-trainable params: 28,351,488 Optimizer used: <function Adam at 0x7fb385bf8e60> Loss function: FlattenedLoss of CrossEntropyLoss() Model frozen up to parameter group number 1 Callbacks: - DropOutput - ModelToHalf - TrainEvalCallback - Recorder - ProgressCallback - MixedPrecision
The learn.summary ()
method gives almost the right numbers. In fact, it counts twice the weights of the wte matrix (vocab embeddings) because they are duplicated in the weights of the output linear layer.
The real numbers are:
learn.fit_one_cycle(1, slice(5e-4/(2.6**4),5e-4))
epoch | train_loss | valid_loss | accuracy | perplexity | time |
---|---|---|---|---|---|
0 | 3.333389 | 3.207390 | 0.374579 | 24.714487 | 6:20:51 |
#hide
learn.recorder.plot_loss()
learn.save(path_data/'GPT2_pt_3epoch_lr5e-4')
learn = learn.load(path_data/'GPT2_pt_3epoch_lr5e-4')
# model size
!du -hs {path_data}/'GPT2_pt_3epoch_lr5e-4.pth'
1.2G /mnt/home/pierre/.fastai/data/ptwiki/GPT2_pt_3epoch_lr5e-4.pth
learn.unfreeze()
learn.summary()
GPT2LMHeadModel (Input shape: ['8 x 1024']) ================================================================ Layer (type) Output Shape Param # Trainable ================================================================ Embedding 8 x 1024 x 768 38,597,376 True ________________________________________________________________ Embedding 8 x 1024 x 768 786,432 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 2304 1,771,776 True ________________________________________________________________ Conv1D 8 x 1024 x 768 590,592 True ________________________________________________________________ Dropout 8 x 12 x 1024 x 102 0 False ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Conv1D 8 x 1024 x 3072 2,362,368 True ________________________________________________________________ Conv1D 8 x 1024 x 768 2,360,064 True ________________________________________________________________ Dropout 8 x 1024 x 768 0 False ________________________________________________________________ LayerNorm 8 x 1024 x 768 1,536 True ________________________________________________________________ Linear 8 x 1024 x 50257 38,597,376 True ________________________________________________________________ Total params: 163,037,184 Total trainable params: 163,037,184 Total non-trainable params: 0 Optimizer used: <function Adam at 0x7f10d796ae60> Loss function: FlattenedLoss of CrossEntropyLoss() Model unfrozen Callbacks: - DropOutput - ModelToHalf - TrainEvalCallback - Recorder - ProgressCallback - MixedPrecision
The learn.summary ()
method gives almost the right numbers. In fact, it counts twice the weights of the wte matrix (vocab embeddings) because they are duplicated in the weights of the output linear layer.
The real numbers are:
learn.fit_one_cycle(2, slice(1e-4/(2.6**4),1e-4))
epoch | train_loss | valid_loss | accuracy | perplexity | time |
---|---|---|---|---|---|
0 | 3.288433 | 3.186721 | 0.377380 | 24.208906 | 6:06:29 |
1 | 3.232569 | 3.167864 | 0.379885 | 23.756687 | 6:16:22 |
#hide
learn.recorder.plot_loss()
learn.save(path_data/'GPT2_pt_5epoch_lr1e-4_v2')
learn = learn.load(path_data/'GPT2_pt_5epoch_lr1e-4_v2')
# model size
!du -hs {path_data}/'GPT2_pt_5epoch_lr1e-4_v2.pth'
1.5G /mnt/home/pierre/.fastai/data/ptwiki/GPT2_pt_5epoch_lr1e-4_v2.pth
Let’s see now how we can share our Portuguese GPT-2 on the Hugging Face model hub (source: Model sharing and uploading).
# directory with the name you want your model to have on the model hub
lang = 'pt'
name = f'{lang}wiki'
path_to_awesome_name_you_picked = data_path/name/'gpt2-small-portuguese'
path_to_awesome_name_you_picked.mkdir(exist_ok=True, parents=True)
# fastai v2 learner with the fine-tuned Portuguese GPT-2 model
learn = Learner(dls, model_en, loss_func=CrossEntropyLossFlat(),
splitter = splitter,
cbs=[DropOutput],
metrics=[accuracy, Perplexity()]).to_fp16()
learn = learn.load(path_data/'GPT2_pt_5epoch_lr1e-4_v2')
# get the model (we already have the tokenizer in tokenizer_pt)
model_pt = learn.model
# save tokenizer and model
model_pt.save_pretrained(f"{str(path_to_awesome_name_you_picked)}")
tokenizer_pt.save_pretrained(f"{str(path_to_awesome_name_you_picked)}")
('/storage/data/ptwiki/gpt2-small-portuguese/vocab.json', '/storage/data/ptwiki/gpt2-small-portuguese/merges.txt', '/storage/data/ptwiki/gpt2-small-portuguese/special_tokens_map.json', '/storage/data/ptwiki/gpt2-small-portuguese/added_tokens.json')
As we trained our model in PyTorch, we have to create a TensorFlow version with the following code:
# !pip install --upgrade tensorflow
First, check that our model class exists in the other framework, that is try to import the same model by either adding or removing TF:
# source: https://huggingface.co/transformers/model_doc/gpt2.html#tfgpt2lmheadmodel
from transformers import TFGPT2LMHeadModel
import tensorflow as tf
# save TensorFlow model
tf_model = TFGPT2LMHeadModel.from_pretrained(f"{str(path_to_awesome_name_you_picked)}", from_pt=True)
tf_model.save_pretrained(f"{str(path_to_awesome_name_you_picked)}")
All PyTorch model weights were used when initializing TFGPT2LMHeadModel. Some weights or buffers of the PyTorch model TFGPT2LMHeadModel were not initialized from the TF 2.0 model and are newly initialized: ['transformer.h.7.attn.bias', 'transformer.h.2.attn.masked_bias', 'transformer.h.8.attn.masked_bias', 'transformer.h.1.attn.masked_bias', 'transformer.h.0.attn.bias', 'transformer.h.9.attn.masked_bias', 'transformer.h.5.attn.masked_bias', 'transformer.h.3.attn.masked_bias', 'lm_head.weight', 'transformer.h.6.attn.masked_bias', 'transformer.h.10.attn.masked_bias', 'transformer.h.8.attn.bias', 'transformer.h.1.attn.bias', 'transformer.h.6.attn.bias', 'transformer.h.10.attn.bias', 'transformer.h.11.attn.masked_bias', 'transformer.h.5.attn.bias', 'transformer.h.4.attn.bias', 'transformer.h.2.attn.bias', 'transformer.h.7.attn.masked_bias', 'transformer.h.11.attn.bias', 'transformer.h.3.attn.bias', 'transformer.h.9.attn.bias', 'transformer.h.4.attn.masked_bias', 'transformer.h.0.attn.masked_bias'] You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
config.json
file, which saves the configuration of your model ;pytorch_model.bin
file, which is the PyTorch checkpoint (unless you can’t have it for some reason) ;tf_model.h5
file, which is the TensorFlow checkpoint (unless you can’t have it for some reason) ;special_tokens_map.json
, which is part of your tokenizer save;tokenizer_config.json
, which is part of your tokenizer save;vocab.txt
, which is the vocabulary of your tokenizer, part of your tokenizer save;added_tokens.json
, which is part of your tokenizer save.for fn in path_to_awesome_name_you_picked.ls():
print(fn)
/storage/data/ptwiki/gpt2-small-portuguese/tf_model.h5 /storage/data/ptwiki/gpt2-small-portuguese/config.json /storage/data/ptwiki/gpt2-small-portuguese/vocab.json /storage/data/ptwiki/gpt2-small-portuguese/pytorch_model.bin /storage/data/ptwiki/gpt2-small-portuguese/tokenizer_config.json /storage/data/ptwiki/gpt2-small-portuguese/special_tokens_map.json /storage/data/ptwiki/gpt2-small-portuguese/merges.txt
!du -ah
475M ./tf_model.h5 4.0K ./config.json 832K ./vocab.json 487M ./pytorch_model.bin 4.0K ./tokenizer_config.json 4.0K ./special_tokens_map.json 500K ./merges.txt 963M .
Now go in a terminal and run the following command. It should be in the virtual enviromnent where you installed 🤗 Transformers, since that command transformers-cli comes from the library.
transformers-cli login
Then log in using the same credentials as on huggingface.co. To upload your model, just type
cd storage/data/ptwiki transformers-cli upload '/storage/data/ptwiki/gpt2-small-portuguese'
This uploads the model to our personal account.
About to upload file /storage/data/ptwiki/gpt2-small-portuguese/tf_model.h5 to S3 under filename gpt2-small-portuguese/tf_model.h5 and namespace pierreguillou
About to upload file /storage/data/ptwiki/gpt2-small-portuguese/config.json to S3 under filename gpt2-small-portuguese/config.json and namespace pierreguillou
About to upload file /storage/data/ptwiki/gpt2-small-portuguese/vocab.json to S3 under filename gpt2-small-portuguese/vocab.json and namespace pierreguillou
About to upload file /storage/data/ptwiki/gpt2-small-portuguese/pytorch_model.bin to S3 under filename gpt2-small-portuguese/pytorch_model.bin and namespace pierreguillou
About to upload file /storage/data/ptwiki/gpt2-small-portuguese/tokenizer_config.json to S3 under filename gpt2-small-portuguese/tokenizer_config.json and namespace pierreguillou
About to upload file /storage/data/ptwiki/gpt2-small-portuguese/special_tokens_map.json to S3 under filename gpt2-small-portuguese/special_tokens_map.json and namespace pierreguillou
About to upload file /storage/data/ptwiki/gpt2-small-portuguese/merges.txt to S3 under filename gpt2-small-portuguese/merges.txt and namespace pierreguillou
Proceed? [Y/n] Y
Uploading... This might take a while if files are large
Your file now lives at:
https://s3.amazonaws.com/models.huggingface.co/bert/pierreguillou/gpt2-small-portuguese/tf_model.h5
Your file now lives at:
https://s3.amazonaws.com/models.huggingface.co/bert/pierreguillou/gpt2-small-portuguese/config.json
Your file now lives at:
https://s3.amazonaws.com/models.huggingface.co/bert/pierreguillou/gpt2-small-portuguese/vocab.json
Your file now lives at:
https://s3.amazonaws.com/models.huggingface.co/bert/pierreguillou/gpt2-small-portuguese/pytorch_model.bin
Your file now lives at:
https://s3.amazonaws.com/models.huggingface.co/bert/pierreguillou/gpt2-small-portuguese/tokenizer_config.json
Your file now lives at:
https://s3.amazonaws.com/models.huggingface.co/bert/pierreguillou/gpt2-small-portuguese/special_tokens_map.json
Your file now lives at:
https://s3.amazonaws.com/models.huggingface.co/bert/pierreguillou/gpt2-small-portuguese/merges.txt
Our model will then be accessible through its identifier, which is, as we saw above, pierreguillou/gpt2-small-portuguese
.
Just click on the “Create a model card on GitHub” button on the model page, it will get you directly to the right location.
Your model now has a page on huggingface.co/models 🔥
Anyone can load it from code:
tokenizer = AutoTokenizer.from_pretrained("namespace/awesome-name-you-picked")
model = AutoModel.from_pretrained("namespace/awesome-name-you-picked")
In our case, the code is:
from transformers import AutoTokenizer, AutoModelWithLMHead
tokenizer = AutoTokenizer.from_pretrained("pierreguillou/gpt2-small-portuguese")
model = AutoModelWithLMHead.from_pretrained("pierreguillou/gpt2-small-portuguese")
Check our Hugging face model page to get more information.
Now that we have a GPT-2 in Portuguese, we can use it for different tasks in NLP (Text Generation, Reading Comprehension, Translation, Summary) as showed in the post "GPT-2 use cases: beyond Text Generation".
For now, let's use it to generate new texts, which allows us to check that it works properly and also have a little fun.
At each stage of text generation, GPT-2 provides a vector of 50.257 probabilities (each corresponds to a possible token of the vocabulary whose size is 50.257). To decide how to choose the output token from these probabilities, there are at least 5 methods: Greedy, Beam Search, Sampling with temperature, Top-k sampling and Top-p (nucleus) sampling.
In this tutorial, we will test only 2 of these text generation methods: Top-k sampling and Top-p (nucleus) sampling.
Note: to get more information on text generation techniques for transformer-based language model, read the article "How to generate text: using different decoding methods for language generation with Transformers" from Patrick von Platen (Hugging Face, 03/18/2020).
Our use case 1 follows the same method used by OpenAI in page 20 of the paper Language Models are Unsupervised Multitask Learners by choosing Top-k sampling text generation technique with a value of 40.
This text generation method is implemented in the model.generate()
function of a Transformers model thanks to the following arguments:
top_k
(int): the number of highest probability vocabulary tokens to keep for top-k-filtering. Between 1 and infinity. Default to 50.Our use case 2 follows the top-p (nucleus) sampling method with Top-p sampling (top_p = 0.95), top-k sampling (top_k = 50), temperature (temperature = 0.7) and repetition penalty (repetition_penalty = 1.2).
This text generation method is implemented in the model.generate()
function of a Transformers model thanks to the following arguments:
top_p
(float): the cumulative probability of parameter highest probability vocabulary tokens to keep for nucleus sampling. Must be between 0 and 1. Default to 1.top_k
(int): the number of highest probability vocabulary tokens to keep for top-k-filtering. Between 1 and infinity. Default to 50.temperature
(float): the value used to module the next token probabilities. Must be strictly positive. Default to 1.0.repetition_penalty
(float): the parameter for repetition penalty. Between 1.0 and infinity. 1.0 means no penalty. Default to 1.0.At the time of publication of GPT-2 in the article "Better Language Models and Their Implications" (02/14/2019), the media retained from its different possibilities in NLP that of text generation because of the now famous text generated on unicorns from this small paragraph:
In a shocking finding, scientist discovered a herd of unicorns living in a remote, previously unexplored valley, in the Andes Mountains. Even more surprising to the researchers was the fact that the unicorns spoke perfect English.
From this text, GPT-2 wrote the following sample out of 10 tries:
openai_generated_text_en = "In a shocking finding, scientist discovered a herd of unicorns living in a remote, previously unexplored valley, in the Andes Mountains. Even more surprising to the researchers was the fact that the unicorns spoke perfect English. \
\n\nThe scientist named the population, after their distinctive horn, Ovid's Unicorn. These four-horned, silver-white unicorns were previously unknown to science. \
\n\nNow, after almost two centuries, the mystery of what sparked this odd phenomenon is finally solved. \
\n\nDr. Jorge Pérez, an evolutionary biologist from the University of La Paz, and several companions, were exploring the Andes Mountains when they found a small valley, with no other animals or humans. Pérez noticed that the valley had what appeared to be a natural fountain, surrounded by two peaks of rock and silver snow. \
\n\nPérez and the others then ventured further into the valley. “By the time we reached the top of one peak, the water looked blue, with some crystals on top,” said Pérez. \
\n\nPérez and his friends were astonished to see the unicorn herd. These creatures could be seen from the air without having to move too much to see them – they were so close they could touch their horns. \
\n\nWhile examining these bizarre creatures the scientists discovered that the creatures also spoke some fairly regular English. Pérez stated, “We can see, for example, that they have a common ‘language,’ something like a dialect or dialectic.” \
\n\nDr. Pérez believes that the unicorns may have originated in Argentina, where the animals were believed to be descendants of a lost race of people who lived there before the arrival of humans in those parts of South America. \
\n\nWhile their origins are still unclear, some believe that perhaps the creatures were created when a human and a unicorn met each other in a time before human civilization. According to Pérez, “In South America, such incidents seem to be quite common.” \
\n\nHowever, Pérez also pointed out that it is likely that the only way of knowing for sure if unicorns are indeed the descendants of a lost alien race is through DNA. “But they seem to be able to communicate in English quite well, which I believe is a sign of evolution, or at least a change in social organization,” said the scientist."
print(openai_generated_text_en)
In a shocking finding, scientist discovered a herd of unicorns living in a remote, previously unexplored valley, in the Andes Mountains. Even more surprising to the researchers was the fact that the unicorns spoke perfect English. The scientist named the population, after their distinctive horn, Ovid's Unicorn. These four-horned, silver-white unicorns were previously unknown to science. Now, after almost two centuries, the mystery of what sparked this odd phenomenon is finally solved. Dr. Jorge Pérez, an evolutionary biologist from the University of La Paz, and several companions, were exploring the Andes Mountains when they found a small valley, with no other animals or humans. Pérez noticed that the valley had what appeared to be a natural fountain, surrounded by two peaks of rock and silver snow. Pérez and the others then ventured further into the valley. “By the time we reached the top of one peak, the water looked blue, with some crystals on top,” said Pérez. Pérez and his friends were astonished to see the unicorn herd. These creatures could be seen from the air without having to move too much to see them – they were so close they could touch their horns. While examining these bizarre creatures the scientists discovered that the creatures also spoke some fairly regular English. Pérez stated, “We can see, for example, that they have a common ‘language,’ something like a dialect or dialectic.” Dr. Pérez believes that the unicorns may have originated in Argentina, where the animals were believed to be descendants of a lost race of people who lived there before the arrival of humans in those parts of South America. While their origins are still unclear, some believe that perhaps the creatures were created when a human and a unicorn met each other in a time before human civilization. According to Pérez, “In South America, such incidents seem to be quite common.” However, Pérez also pointed out that it is likely that the only way of knowing for sure if unicorns are indeed the descendants of a lost alien race is through DNA. “But they seem to be able to communicate in English quite well, which I believe is a sign of evolution, or at least a change in social organization,” said the scientist.
%%time
from transformers import GPT2TokenizerFast, GPT2LMHeadModel
pretrained_weights = 'gpt2'
tokenizer_en = GPT2TokenizerFast.from_pretrained(pretrained_weights)
model_en = GPT2LMHeadModel.from_pretrained(pretrained_weights)
Some weights of GPT2LMHeadModel were not initialized from the model checkpoint at gpt2 and are newly initialized: ['h.0.attn.masked_bias', 'h.1.attn.masked_bias', 'h.2.attn.masked_bias', 'h.3.attn.masked_bias', 'h.4.attn.masked_bias', 'h.5.attn.masked_bias', 'h.6.attn.masked_bias', 'h.7.attn.masked_bias', 'h.8.attn.masked_bias', 'h.9.attn.masked_bias', 'h.10.attn.masked_bias', 'h.11.attn.masked_bias', 'lm_head.weight'] You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
CPU times: user 14.4 s, sys: 1.8 s, total: 16.2 s Wall time: 7.72 s
from transformers import GPT2TokenizerFast
# Get the path to ByteLevelBPE_tokenizer_pt config files
ByteLevelBPE_tokenizer_pt_rep = 'ByteLevelBPE_tokenizer_pt'
path_to_ByteLevelBPE_tokenizer_pt_rep = path_data/ByteLevelBPE_tokenizer_pt_rep
# import the pre-trained GPT2TokenizerFast tokenizer with the tokenizer_pt config files
tokenizer_pt = GPT2TokenizerFast.from_pretrained(
str(path_to_ByteLevelBPE_tokenizer_pt_rep),
pad_token='<|endoftext|>')
# Get sequence length max of 1024
tokenizer_pt.model_max_length = 1024
class TransformersTokenizer(Transform):
def __init__(self, tokenizer): self.tokenizer = tokenizer
def encodes(self, x):
toks = self.tokenizer.tokenize(x)
return tensor(self.tokenizer.convert_tokens_to_ids(toks))
def decodes(self, x): return TitledStr(self.tokenizer.decode(x.cpu().numpy()))
# get data
lang = 'pt'
fname = f'all_texts_{lang}wiki.csv'
df = pd.read_csv(path_data/fname)
# load idxs train and valid
idxs_train = torch.load(path_data/'idxs_train.pt')
idxs_val = torch.load(path_data/'idxs_val.pt')
all_texts = np.concatenate([df.iloc[idxs_train].text.values, df.iloc[idxs_val].text.values])
splits = [list(idxs_train), list(idxs_val)]
tls = TfmdLists(all_texts, TransformersTokenizer(tokenizer_pt), splits=splits, dl_type=LMDataLoader)
%%time
bs,sl = 8,1024
dls = tls.dataloaders(bs=bs, seq_len=sl)
CPU times: user 27min 56s, sys: 3min 20s, total: 31min 16s Wall time: 25min 8s
class DropOutput(Callback):
def after_pred(self): self.learn.pred = self.pred[0]
def splitter(model):
"Split a GPT2 `model` in 3 groups for differential learning rates."
# First layers group : decoder blocks from 0 to 3
modules = []
for i in range(4): modules.append(model.transformer.h[i])
groups = [nn.Sequential(*modules)]
# Second layers group : decoder blocks from 4 to 7
modules = []
for i in range(4,8,1): modules.append(model.transformer.h[i])
groups = L(groups + [nn.Sequential(*modules)])
# Third layers group : decoder blocks from 8 to 11
modules = []
for i in range(8,12,1): modules.append(model.transformer.h[i])
groups = L(groups + [nn.Sequential(*modules)])
# Fourth layers group : embeddings matrices wte and wpe + LayerNorm at the model output
groups = L(groups + [nn.Sequential(model.transformer.wte,model.transformer.wpe,model.transformer.ln_f)])
return groups.map(params)
# Learner: basic class for handling the training loop
# source: https://dev.fast.ai/learner#Learner
learn = Learner(dls, model_en, loss_func=CrossEntropyLossFlat(),
splitter = splitter,
cbs=[DropOutput],
metrics=[accuracy, Perplexity()]).to_fp16()
learn = learn.load(path_data/'GPT2_pt_5epoch_lr1e-4_v2')
# model
model_pt = learn.model
# put model into eval mode and on GPU
model_pt.eval();
model_pt.to('cuda');
from transformers import MarianMTModel, MarianTokenizer
# MarianMT Translator
model_name = 'Helsinki-NLP/opus-mt-en-ROMANCE'
tokenizer_en_pt = MarianTokenizer.from_pretrained(model_name)
print(tokenizer_en_pt.supported_language_codes)
model_en_pt = MarianMTModel.from_pretrained(model_name)
['>>fr<<', '>>es<<', '>>it<<', '>>pt<<', '>>pt_br<<', '>>ro<<', '>>ca<<', '>>gl<<', '>>pt_BR<<', '>>la<<', '>>wa<<', '>>fur<<', '>>oc<<', '>>fr_CA<<', '>>sc<<', '>>es_ES<<', '>>es_MX<<', '>>es_AR<<', '>>es_PR<<', '>>es_UY<<', '>>es_CL<<', '>>es_CO<<', '>>es_CR<<', '>>es_GT<<', '>>es_HN<<', '>>es_NI<<', '>>es_PA<<', '>>es_PE<<', '>>es_VE<<', '>>es_DO<<', '>>es_EC<<', '>>es_SV<<', '>>an<<', '>>pt_PT<<', '>>frp<<', '>>lad<<', '>>vec<<', '>>fr_FR<<', '>>co<<', '>>it_IT<<', '>>lld<<', '>>lij<<', '>>lmo<<', '>>nap<<', '>>rm<<', '>>scn<<', '>>mwl<<']
src_text = [
'>>pt_BR<< In a shocking finding, scientist discovered a herd of unicorns living in a remote, previously unexplored valley, in the Andes Mountains. Even more surprising to the researchers was the fact that the unicorns spoke perfect English.',
]
print(src_text)
['>>pt_BR<< In a shocking finding, scientist discovered a herd of unicorns living in a remote, previously unexplored valley, in the Andes Mountains. Even more surprising to the researchers was the fact that the unicorns spoke perfect English.']
translated = model_en_pt.generate(**tokenizer_en_pt.prepare_translation_batch(src_text))
tgt_text = [tokenizer_en_pt.decode(t, skip_special_tokens=True) for t in translated]
prompt = tgt_text[0]
prompt
'Num achado chocante, o cientista descobriu uma manada de unicórnios vivendo num vale remoto, anteriormente inexplorado, nas Montanhas dos Andes. Ainda mais surpreendente para os pesquisadores foi o fato de que os unicórnios falavam inglês perfeito.'
# Get the number of tokens of the OpenAI English generated text
openai_generated_text_en = "In a shocking finding, scientist discovered a herd of unicorns living in a remote, previously unexplored valley, in the Andes Mountains. Even more surprising to the researchers was the fact that the unicorns spoke perfect English. \
\n\nThe scientist named the population, after their distinctive horn, Ovid's Unicorn. These four-horned, silver-white unicorns were previously unknown to science. \
\n\nNow, after almost two centuries, the mystery of what sparked this odd phenomenon is finally solved. \
\n\nDr. Jorge Pérez, an evolutionary biologist from the University of La Paz, and several companions, were exploring the Andes Mountains when they found a small valley, with no other animals or humans. Pérez noticed that the valley had what appeared to be a natural fountain, surrounded by two peaks of rock and silver snow. \
\n\nPérez and the others then ventured further into the valley. “By the time we reached the top of one peak, the water looked blue, with some crystals on top,” said Pérez. \
\n\nPérez and his friends were astonished to see the unicorn herd. These creatures could be seen from the air without having to move too much to see them – they were so close they could touch their horns. \
\n\nWhile examining these bizarre creatures the scientists discovered that the creatures also spoke some fairly regular English. Pérez stated, “We can see, for example, that they have a common ‘language,’ something like a dialect or dialectic.” \
\n\nDr. Pérez believes that the unicorns may have originated in Argentina, where the animals were believed to be descendants of a lost race of people who lived there before the arrival of humans in those parts of South America. \
\n\nWhile their origins are still unclear, some believe that perhaps the creatures were created when a human and a unicorn met each other in a time before human civilization. According to Pérez, “In South America, such incidents seem to be quite common.” \
\n\nHowever, Pérez also pointed out that it is likely that the only way of knowing for sure if unicorns are indeed the descendants of a lost alien race is through DNA. “But they seem to be able to communicate in English quite well, which I believe is a sign of evolution, or at least a change in social organization,” said the scientist."
openai_generated_text_en_ids = tokenizer_en.encode(openai_generated_text_en, return_tensors='pt').to('cuda')
max_length = openai_generated_text_en_ids.shape[1]
print(max_length)
504
# encode
input_ids = tokenizer_pt.encode(prompt, return_tensors='pt').to('cuda')
%%time
#set top_k = 40 and num_return_sequences = 3
sample_outputs = model_pt.generate(input_ids, pad_token_id=50256,
do_sample=True,
max_length=max_length,
min_length=max_length,
top_k=40,
num_return_sequences=3)
for i, sample_output in enumerate(sample_outputs):
print(">> Generated text {}\n\n{}".format(i+1, tokenizer_pt.decode(sample_output.tolist())))
print('\n---')
>> Generated text 1 Num achado chocante, o cientista descobriu uma manada de unicórnios vivendo num vale remoto, anteriormente inexplorado, nas Montanhas dos Andes. Ainda mais surpreendente para os pesquisadores foi o fato de que os unicórnios falavam inglês perfeito. Um deles, um escocês chamado Thomas (um anatomista irlandês) que havia trabalhado com o britânico em seu trabalho como assistente do diretor experimental da universidade, John Holley, foi chamado de por eles para um encontro sobre os dois conceitos, que não tinham encontrado muito trabalho até o momento. Eles foram palestrantes, mas ficaram impressionados que Thomas (como todos os outros cientistas da época) não sabia falar Inglês. Quando Thomas fez isso com os unicórnios por engano, Holley a escreveu e enviou um telegrama à BBC perguntando: ""Tão, o que é tal dizer se você quer saber de nenhum outro, eu não sei como ele fala inglês?"" Eles disseram a ele: "Não, mas é um idiota." Então, uma semana depois, no mesmo dia, Holley o enviou, uma carta com um questionário para os membros do elenco de ""Doctor Who"". Thomas, como qualquer um dos cientistas mencionados, não se lembra muito bem dos eventos que aconteceram em Londres. Depois do segundo episódio, o editor-produtor Michael Gambon deu o que ele achou que valia, então disse: "Vamos fazer um comentário, para o elenco e equipe deDoctor Who." Como resultado, eles deram permissão para que eles assistissem outro episódio. Isto foi o suficiente para que "The Magician" aparecesse para o cânone da BBC. Na segunda temporada, "The Magician" teve um episódio chamado "The End of the World", e o ator John Huston, que interpreta John Watson, era o mais conhecido ator inglês do programa. "The End of the World" foi ao ar em 13 de outubro de 2000. A BBC anunciou que "The Magician" seria exibida ao vivo em janeiro de 2003 da HBO em 15 de janeiro de 2003. Ele também foi transmitido na televisão em 16 de janeiro de 2004 da BBC One, em uma transmissão que também marcou o cancelamento de um episódio. A série é uma produção da BBC-NBC Television Limited. Ela foi produzida por Paul Rudd, John Swarns e Jonathan Seagal e foi criada por David Tennant, Graham Hill, Colin Smith, Tom Baker, Jack Davies e Paul Thompson. O primeiro episódio foi exibido em 17 de outubro de --- >> Generated text 2 Num achado chocante, o cientista descobriu uma manada de unicórnios vivendo num vale remoto, anteriormente inexplorado, nas Montanhas dos Andes. Ainda mais surpreendente para os pesquisadores foi o fato de que os unicórnios falavam inglês perfeito. "Não é mais estranho que a nossa forma tivesse o inglês com dois de suas asas como se o macho fosse inglês — o que é interessante. Mas a sua natureza inata seria estranha para o inglês", acredita eles. Em 2015, cientistas realizaram uma nova análise sobre as formas dos unicórnios. De acordo com especialistas na área, os membros superiores do grupo foram provavelmente derivados de outra espécie de escorpião — uma espécie com características semelhantes. Uma nova equipe de cientistas calculou que uma fêmea unicornada da Eurásia seria originalmente uma humana. "Isto significa que o ancestral do unicórnio, um híbrido de um esquilo e um escorpião macho não nasceu. Um estudo recente estimou que cerca de 12% do corpo humano é composto por membros de qualquer um dos grupos mais diverso de animais extintos, incluindo o ser humano e o unicórnio-do-sul. "A análise dos dados mostra que a maioria dos membros do gênero é composta por um exito e um exito macho que compartilham uma única espécie de corpo. Em alguns casos, estes membros compartilham um mesmo conjunto (a linhagem) de partes em dois espécimes." O estudo indica que os membros de "P. rubi" são semelhantes em aparência e morfologia aos membros humanos modernos, como as fêmeas modernas e machos robustos. "Como é evidente com os membros de "P. rubi", os ancestrais e o ancestral eram similares na forma e na composição das semelhanças em um organismo." O DNA do "P. rubi," chamado por sua forma em inglês de "sonoroplasto", revela que o "sonoroplasto" inclui três genes de alto nível e quatro genes relativamente reduzidos (e ausentes) e um gene de baixo nível (e ausentes) com uma concentração de cloroplasto em cada núcleo. A "sonoroplasto" se assemelha à "P. rubi" em características morfológicas e comportamentais, embora as diferenças na morfologia sejam menores. "A espécie "P. rubi" apresenta cinco pares de cromossomos separados (com 6 pares se aproximando e 8 pares se afastando) e um "sonoroplasto de base" (com 12 pares se aproximando e 15 pares se afastando), sugerindo que o membro tenha uma composição semelhante ao ancestral "P. rubi --- >> Generated text 3 Num achado chocante, o cientista descobriu uma manada de unicórnios vivendo num vale remoto, anteriormente inexplorado, nas Montanhas dos Andes. Ainda mais surpreendente para os pesquisadores foi o fato de que os unicórnios falavam inglês perfeito. O jogo de corrida da FIAT foi introduzido no Salão Internacional de FIAT (em 1989) em um evento que teve como principal objetivo fornecer uma oportunidade a todos que competirem em corridas de carros nacionais, como as categorias de base e pilotos. Esse evento trouxe o título de "National Le Mans Series" (1973), além de um terceiro título que o vencedor da competição ganharia. O primeiro campeonato foi disputado entre 1983 e 1985, e foi vencido pelo piloto estadunidense Dennis Young. O Campeonato de Le Mans foi criado por uma equipa formada em 1983 na rua General Motors, em Long Beach, Califórnia, e patrocinado pela "Frampton Racing", criada pelo empresário de corridas do Reino Unido Derek J. Cox, e é atualmente patrocinado pela equipe da equipe de Fórmula 1 da Ferrari, Lotus e McLaren, "Lusa Motorsports" e pela equipe de corrida britânica Team Lotus. "Lusa" foi fundada como uma "casa", mas a companhia não conseguiu competir em corridas por cinco anos devido à falta de patrocinador, e os pilotos que competiram em Lusa foram proibidos de pilotar a equipe McLaren em 1997. A equipe mudou seu nome para Lusa Motorsports em 1999. As corridas de Fórmula 1 só foram retomadas duas vezes por falta de patrocinadores, no começo de 2000, e novamente em 2003 por "franqueza". Em 2003, a Williams-Renault obteve o seu primeiro título da temporada, uma corrida de Le Mans de estilo "Grand Prix", em que os carros eram todos monopostos, mas com carros "primo", mais do que os carros de Fórmula 1. A temporada de 2003 teve muitas modificações em termos de desempenho, como novos pneus e mudanças na configuração dos carros, e foi a sexta temporada do campeonato do campeonato com mais pontos no campeonato na temporada de 2004, com cinco vitórias no campeonato, três na temporada de 2008 e cinco na de 2009. Em 2005, a Toyota assinou um contrato exclusivo para a produção de veículos para a Temporada de Le Mans e o primeiro ano em que a equipe Toyota foi a primeira equipe a ser a primeira a dar uma vitória ao correr "Le Mans Series", uma prova de Fórmula 1, na qual a equipe Toyota produziu dois carros da temporada. Apesar de ter vencido a prova, foi a --- CPU times: user 7.77 s, sys: 372 ms, total: 8.15 s Wall time: 8.16 s
%%time
#set top_p = 0.95, top_k = 50, temperature = 0.7, repetition_penalty = 1.2 and num_return_sequences = 3
sample_outputs = model_pt.generate(input_ids, pad_token_id=50256,
do_sample=True,
max_length=max_length,
min_length=max_length,
repetition_penalty=1.2,
temperature=0.7,
top_k=50,
top_p=0.95,
num_return_sequences=3)
for i, sample_output in enumerate(sample_outputs):
print(">> Generated text {}\n\n{}".format(i+1, tokenizer_pt.decode(sample_output.tolist())))
print('\n---')
>> Generated text 1 Num achado chocante, o cientista descobriu uma manada de unicórnios vivendo num vale remoto, anteriormente inexplorado, nas Montanhas dos Andes. Ainda mais surpreendente para os pesquisadores foi o fato de que os unicórnios falavam inglês perfeito. Eles não sabiam onde exatamente eram falantes nativos do idioma, e acreditaram que eles simplesmente migraram das terras altas da região de Mendoza ao norte como consequência do declínio populacional que ocorreu na Cordilheira das Cobras. Em 2004, o Departamento de Antropologia da Universidade do Colorado anunciou que havia encontrado uma fêmea no vale do rio Orinoco na Bolívia, mas essa fêmea foi morta durante a investigação. No entanto, no início de 2006, as autoridades locais anunciaram que havia identificado uma fêmea encontrada em uma área próxima à Cordilheira dos Andes, no Vale do Cauca. A equipe de pesquisadores relatou que esta fêmea era chamada de "El Maria" ou "El Maria". O estudo revelou que o grupo de unicórnios habitava um ecossistema bastante diverso, com espécies endêmicas incluindo espécies como as tiláceas gigantescas (que são encontradas principalmente nos países subdesenvolvidos) e as quelupus ("Erica azoricae"). Um dos principais objetivos do estudo da espécie é determinar se os europeus teriam colonizado a região entre a década de 1940 e 1960 e se estes últimos grupos étnicos sobreviveram até hoje. Os cientistas acreditam que as populações desses grupos poderiam ter sido muito maiores antes disso; por exemplo, a teoria sugere que a população europeia provavelmente teria introduzido os humanos primitivos na América Central depois que os espanhóis invadiram a região, embora isso seja controverso. O gênero "El Maria" tem um ancestral comum, os "Looney-do-the-Bone", um pequeno grupo de "Looney-da-Daíndia" encontrados apenas no leste dos Estados Unidos, Canadá e México. O gênero possui parentesco próximo ao gênero "Lontrapyrus", também conhecido como lontras negras. Acredita-se que esses indivíduos tenham migrado para o leste dos Andes, atravessando regiões montanhosas do sul de América Central e América Central. Os membros desta família são geralmente confundidos com os lontras brancos. As fêmeas têm cerca de seis centímetros de comprimento, pesando de 9 quilogramas e medindo 11 cm de largura. A cabeça é branca, com manchas escuras pretas escuras sobre seus flancos. As patas posteriores podem ser amarelas, enquanto sua cauda pode estar preta ou branca, dependendo da cor utilizada na identificação. As costas apresentam quatro dedos dorsais bem desenvolvidas --- >> Generated text 2 Num achado chocante, o cientista descobriu uma manada de unicórnios vivendo num vale remoto, anteriormente inexplorado, nas Montanhas dos Andes. Ainda mais surpreendente para os pesquisadores foi o fato de que os unicórnios falavam inglês perfeito. O fóssil é encontrado no Vale de La Guaira, na região de San Juan, com cerca de 1 metro (1,8 m) de comprimento e cerca de 4 metros (2 pés) de largura, em Wyoming. A cabeça possui cinco dedos no pé direito e duas garras direita. No topo do crânio há quatro placas pretas-escuros. O cérebro tem um formato triangular, a base apresenta apenas uma pequena porção da metade anterior e três partes do pescoço são pretos-claro; a face tem um tom vermelho escuro-escuro. A mandíbula também contém oito pares de maxilas bem desenvolvidas. A região de San Juan foi descoberta por volta de 14 mil anos atrás. Foi escavado durante a Guerra dos Sete Anos e tem aproximadamente 6 metros quadrados de espessura. O local era habitado pelo povo de Tacuareña, que vivia entre o final do e o início do e tinha uma cultura diferente das outras regiões próximas ao território de El Berriol. Os indígenas não eram caçadores conhecidos pelos nativos e como "carijós". O fóssil foi descoberto em 2002 e depois enviado para uma equipe de arqueólogos liderada pela Universidade de Wyoming. A equipe encontrou os restos humanos e o chamou de "caçadores" ou "coletores", pois eles tinham sido mortos pelas expedições anteriores ao assentamento. O arqueólogo Brian C. Fanning, da Universidade de Wyoming, fez várias entrevistas com os esqueletos humanos e descobriram os crânios de dois ou três homens que foram enterrados em um túmulo localizado abaixo do túmulo de um antigo homem chamado Huehue, que estava enterrado por volta de 10500 anos atrás. O homem que estava enterrado é o membro de um grupo étnico conhecido como "Huehue". A equipe de pesquisadores da equipe de Fanning incluiu a presença humana no local onde o homem enterrado, incluindo um cemitério indígena que está próximo à entrada do cemitério. Eles encontraram evidências ósseas humanas enterradas perto dos ossos do homem e outros artefatos encontrados dentro de um depósito de ossos de um homem chamado "Creator". Os pesquisadores acharam vários ossos humanos semelhantes aos ossos de Huehue, mas sem as marcas físicas. Eles notaram semelhanças anatômicas entre esses membros de um grupo étnico chamado "Caçadores", possivelmente porque ambos viviam no Vale de --- >> Generated text 3 Num achado chocante, o cientista descobriu uma manada de unicórnios vivendo num vale remoto, anteriormente inexplorado, nas Montanhas dos Andes. Ainda mais surpreendente para os pesquisadores foi o fato de que os unicórnios falavam inglês perfeito. Os arqueólogos descobriram um conjunto de moedas cunhadas por indígenas e outros achados arqueológicos encontrados no local durante as escavações foram feitos ao longo da década de 1960 em um esforço de resgate arqueológica e reconhecimento pela população indígena. O achado arqueológico é o único relato sobre a cultura do gênero "Saccharus", que se refere às culturas terrestres primitivas não relacionadas com o "Homo sapiens". A pesquisa envolveu cerca de 60 anos de escavação, incluindo levantamento topográfico efetuado entre 1972 e 1977. Em 1988, o arqueólogo americano John Deere, que pesquisou as ruínas do complexo arqueológico do Monte dos Andes, observou que a cultura deste gênero estava fortemente relacionada com outras civilizações mesoamericanas, como o olmeca e a olmeca. O arqueólogo franco-americano John Deere observou que a cultura desses gêneros era bem próxima à civilização olmeca e "a cultura dos astecas" foi muito similar àquelas encontradas na América Central em seus sítios prévios. Em 1991, o arqueólogo americano John Deere publicou uma extensa monografia descrevendo a cultura dos Andes. Ele escreveu: Muitos estudiosos têm alegado que a cultura dos Andes pode ter sido transmitida através de migrações humanas do continente americano. Contudo, estudos recentes, baseados nos dados históricos obtidos em diferentes lugares dos Andes sugerem que tais migrações ocorreram antes ou imediatamente após as primeiras invasões americanas de europeus. Pesquisas iniciais demonstraram que esta migração ocorreu provavelmente entre o final do século XVIII e meados do século XIX, quando sociedades modernas dominavam o solo chileno, Peru, Bolívia e Colômbia. As tribos inca e xamãs também estavam envolvidas nesta atividade. A história das Américas começou em torno de um grupo de caçadores sulamericanos pertencentes aos Andes liderados pelo índio A. Iruña, que estabeleceu sua capital no atual assentamento chamado "San Juan del Sur". Acreditava-se que ele teria fundado um assentamento que seria conhecido por sua fama de ser capaz de caçar com seus guerreiros e construir suas casas com o passar do tempo. Durante o século XVIII, as terras baixas eram propícias para o crescimento populacional e, consequentemente, o desenvolvimento econômico das novas cidades situadas em torno delas. Os primeiros exploradores espanhóis chegaram ao Novo Mundo em 1692 e estabeleceram assentamentos permanentes nesses territórios até a década de 1830. As tentativas espanholas --- CPU times: user 35.3 s, sys: 1.85 s, total: 37.2 s Wall time: 37.2 s
# source (uol, 07/13/2020): https://www.uol.com.br/vivabem/noticias/redacao/2020/07/13/russia-vacina-conclui-testes-distribuicao-em-agosto.htm
prompt = "A Rússia está mais perto de se tornar o primeiro país a iniciar a distribuição de uma vacina contra o coronavírus para a população. O país anunciou hoje que concluiu parte dos testes clínicos necessários para comprovar a eficácia da imunização desenvolvida por iniciativa do governo russo. A expectativa é de que a distribuição comece já em agosto."
print(prompt)
A Rússia está mais perto de se tornar o primeiro país a iniciar a distribuição de uma vacina contra o coronavírus para a população. O país anunciou hoje que concluiu parte dos testes clínicos necessários para comprovar a eficácia da imunização desenvolvida por iniciativa do governo russo. A expectativa é de que a distribuição comece já em agosto.
# encode
input_ids = tokenizer_pt.encode(prompt, return_tensors='pt').to('cuda')
%%time
#set top_k = 40 and num_return_sequences = 3
sample_outputs = model_pt.generate(input_ids, pad_token_id=50256,
do_sample=True,
max_length=max_length,
min_length=max_length,
top_k=40,
num_return_sequences=3)
for i, sample_output in enumerate(sample_outputs):
print(">> Generated text {}\n\n{}".format(i+1, tokenizer_pt.decode(sample_output.tolist())))
print('\n---')
>> Generated text 1 A Rússia está mais perto de se tornar o primeiro país a iniciar a distribuição de uma vacina contra o coronavírus para a população. O país anunciou hoje que concluiu parte dos testes clínicos necessários para comprovar a eficácia da imunização desenvolvida por iniciativa do governo russo. A expectativa é de que a distribuição comece já em agosto. Entre os primeiros casos confirmados de COVID-19 na Rússia estava um homem russo com idade entre 50 e 49 anos, segundo o jornal " Moscow" e o primeiro caso em 28 de fevereiro, a primeira no Hospital Pulkai. No entanto, os primeiros casos foram mais sérios devido sua "maturidade sem gravidade" e a falta de uma pessoa estar disponível para testes de suas condições de vida. Entre os pacientes que foram considerados estão funcionários de um hospital ou enfermeiros na cidade de Moscou (ver abaixo) ou médicos. Depois de serem testados negativos após um teste positivo, o paciente se recupera completamente. Os russos também anunciaram que serão realizados testes de coronavírus de outros países, como a França, que inicialmente acreditava que os vírus da gripe tinham sido transmitido pela Europa (a expectativa é de 20 a 50 casos por dia). A situação foi resolvida em 24 de fevereiro, quando o Ministério da Saúde confirmou sua conclusão de que a COVID-19 é transmitida de via aérea. Até ao dia do seu primeiro caso, a Rússia tinha o menor número de funcionários e médicos com doença grave antes de o vírus ter se tornado um vírus no país. Os números de funcionários com doença grave não chegaram a ser confirmados, segundo o Ministério da Saúde, devido a sua falta de apoio. O vírus que está em curso no país é transmitido pela primeira vez nos Estados Unidos, onde foi isolado em 14 de fevereiro. Em Portugal o Ministério dos Negócios Estrangeiros declarou oficialmente em 11 de fevereiro que a COVID-19 está presente no país, mas não anunciou nenhum impacto na prática. No entanto, o Ministério do Trabalho declarou no dia seguinte que o coronavírus existe "em todo os países que não têm regulamentação" e que nenhum "aedes", que era identificado em 11 de fevereiro, tinha entrado na corrente sanguínea. Em 9 de março, autoridades russas confirmaram que o paciente não está hospitalizado e que está em quarentena no Hospital Pulkai. Mais dois casos de COVID-19 foram anunciados em 9 de março, mas foram considerados casos de "propaganda" e não de risco. Em 9 de maio, autoridades russas confirmaram os confirmados em todo país. Em 10 de maio, --- >> Generated text 2 A Rússia está mais perto de se tornar o primeiro país a iniciar a distribuição de uma vacina contra o coronavírus para a população. O país anunciou hoje que concluiu parte dos testes clínicos necessários para comprovar a eficácia da imunização desenvolvida por iniciativa do governo russo. A expectativa é de que a distribuição comece já em agosto. As populações de Wuhan, Wuhan, Qinghai, Shenzhen na costa oeste do China e no norte de Xangai, na província de Hubei, e os subúrbios da cidade de Tvershend em Hong Kong já estão de acordo com o número de casos confirmados. Uma nova equipe de infecologistas para ajudar a determinar os possíveis efeitos da pandemia já está em Xangai. Em 14 de março, a Rússia também tem a oportunidade de testar novas vacinas virais e testar novas versões para garantir a propagação de maisvírus na China através da transmissão de novos coronavírus. As autoridades russas e autoridades de saúde chinesas têm se preparado para assumir essa atitude de emergência com base nos dados coletados pela máscaras, máscaras de voo e máscaras faciais. Um relatório de uma empresa francesa informou que mais de 30 pessoas morreram na área de transmissão ao longo do mês de março, em relação aos dois primeiros casos. Em 21 de março, mais de 2,3 milhões de pessoas foram afetadas em áreas urbanas. Segundo o Conselho de Saúde, cerca de 10% dos habitantes são da China continental e quase metade do Distrito de Pequim, incluindo as regiões Norte e Noroeste. A doença foi descrita pela primeira vez em uma carta enviada às autoridades sanitárias no dia 15 de março. Três dias depois, um estudo genético para o vírus causou grande preocupação aos especialistas em transmissão, que acreditavam que a doença se espalhava através de duas regiões do país. A China continental relatou que apenas 8 pessoas foram diagnosticadas no país. Os vírus estão propagando-se por todo o continente europeu, do Ásia e de diversas partes do globo. De acordo com análises recentes do Centro de Controle e Prevenção da Doenças, em 14 de março, havia um total de 785 casos confirmados confirmados em todo o mundo. O surto da doença chegou aos Estados Unidos, com o surto de gripe na cidade de Wuhan, China, sendo o quarto maior já registrado em um período desde a epidemia de surtos no ano de 1994. Além disso, os casos das novas epidemias trazidas pela epidemia das SARS de 2013 no Haiti em 2020 tornaram-se os maiores problemas para a saúde da China. Em 14 de março, cerca de 4,85 milhão de pessoas estavam infectadas e cerca de 8% --- >> Generated text 3 A Rússia está mais perto de se tornar o primeiro país a iniciar a distribuição de uma vacina contra o coronavírus para a população. O país anunciou hoje que concluiu parte dos testes clínicos necessários para comprovar a eficácia da imunização desenvolvida por iniciativa do governo russo. A expectativa é de que a distribuição comece já em agosto. O Papa Francisco pediu ao povo russo que confirme a data da chegada da vacina. O Papa também pediu aos cidadãos russos que realizem uma conferência de imprensa oficial para o anúncio. Em 7 de dezembro de 2016, quando se iniciou o trabalho de tradução para mais idiomas, mais de 300 pessoas no mundo tiveram acesso aos benefícios da vacina. A primeira vacina para o coronavírus foi testada no Japão em 9 de março de 2020. Em 6 de fevereiro, um estudo realizado em Taiwan revelou que a epidemia do SARS é mais provável devido ao aumento do hábito. Por causa do aumento nas visitas dos cidadãos a hospitais para verificar que a vacina é eficaz, a saúde do país começou a declinar. O ministro da Saúde japonês, Toshihiko Hayashi disse que a crise da saúde era uma consequência da melhora das medidas de prevenção e contra o coronavírus em relação ao início do período de alta infecção. A Rússia começou a distribuir a vacina no início de outubro, após a confirmação por funcionários da saúde pública de uma nova coronavírus. Foi lançada no mesmo dia em todas as regiões ocidentais do país. O total de pessoas hospitalizadas pelo vírus foi de aproximadamente 431 em Taiwan. Além disso, entre 15 e 17 de outubro, uma pessoa foi internada no Hospital Universitário de Pequim, nos arredores de Pequim, devido a um surto viral de SARS. Os sintomas de pneumonia, febre, prurido e pneumonia permaneceram altas durante toda a primeira quinzena de outubro. Os outros dois dias depois, no Hospital Universitário de Moscou, a doença causou mais mortes confirmadas do que não provocado anteriormente, com cerca de 211. O número de passageiros do Hospital Universitário de Moscou caiu 297 pessoas. A agência russa "DPS" declarou como uma das principais preocupações sobre a doença a saúde pública na República Popular da China. Em janeiro de 2020, o governo chinês lançou três programas de vacinação oral nos distritos urbanos em resposta à melhora global e a pandemia no Vale do Silício. O programa nacional de vacinação, chamado de "Omgao", consiste num conjunto de 36 cidades com um total de 1.429 municípios (em regiões mais remotas do país). A aplicação do programa foi feita em 27 --- CPU times: user 7.56 s, sys: 242 ms, total: 7.81 s Wall time: 7.8 s
%%time
#set top_p = 0.95, top_k = 50, temperature = 0.7, repetition_penalty = 1.2 and num_return_sequences = 3
sample_outputs = model_pt.generate(input_ids, pad_token_id=50256,
do_sample=True,
max_length=max_length,
min_length=max_length,
repetition_penalty=1.2,
temperature=0.7,
top_k=50,
top_p=0.95,
num_return_sequences=3)
for i, sample_output in enumerate(sample_outputs):
print(">> Generated text {}\n\n{}".format(i+1, tokenizer_pt.decode(sample_output.tolist())))
print('\n---')
>> Generated text 1 A Rússia está mais perto de se tornar o primeiro país a iniciar a distribuição de uma vacina contra o coronavírus para a população. O país anunciou hoje que concluiu parte dos testes clínicos necessários para comprovar a eficácia da imunização desenvolvida por iniciativa do governo russo. A expectativa é de que a distribuição comece já em agosto. A Rússia tem um mercado interno bruto (PIB) estimado entre US$ 1,2 bilhões e US$ 7 bilhões. O PIB "per capita" em 2007 foi de US $ 4,348. A maior parte do crescimento econômico anual ocorreu na agricultura. Em 2003, a taxa média anual era de 22%. Em 2004, cerca de 3 milhões de pessoas foram infectadas pelo coronavírus. Cerca de 17 mil casos foram identificados entre 2001 e 2002, incluindo aproximadamente 2,8% das crianças e adolescentes com idade inferior a seis anos; 5,1 milhão deles eram endêmicas ou sem cuidados médicos; 8,711 mortes ocorreram nos três primeiros meses de vida após o contato com o vírus; 13,6 mil haviam retornado à Rússia; e 14,4% estavam doentes devido aos sintomas causados pela doença durante seus últimos dias no exterior, principalmente idosos e recém-nascidos infectados. Cerca de 6 milhões de russos estão vivendo em países fora da União Europeia, sendo eles os Estados Unidos, China, Índia, Itália, Japão, Reino Unido, Austrália, Nova Zelândia, Países Baixos, Rússia, Turquia, Espanha, Suécia e África do Sul. Em novembro de 2008, estimava-se que 20 milhões de russos estariam potencialmente infetados naquele ano. A Organização Mundial da Saúde divulgou dados detalhados sobre as medidas antivirais prescritas por cada país segundo os padrões estabelecidos. O número total de infeção por coronavírus foi inicialmente estimado em 12.000 em 2005. Em janeiro de 2006, estimava-se que 924.300 pessoas tinham sido contaminadas. No mesmo mês, o Ministério da Saúde confirmou que havia aumentado o número de casos confirmados desde o início da pandemia. O número de mortes atribuídas ao coronavírus caiu de 50 para 54 em janeiro de 2006, enquanto novos surtos começaram em março de 2006. Os números de casos suspeitos aumentaram ainda mais após o início da epidemia em janeiro. A Organização Mundial da Saúde divulgou estatísticas oficiais em fevereiro de 2006 mostrando que todos os indivíduos que tenham sido contestados como tendo casos não apresentaram qualquer sintoma claro ou grave risco. Desde o início da pandemia, um grande número de pessoas têm sido afetadas por COVID-19. Mais tarde, --- >> Generated text 2 A Rússia está mais perto de se tornar o primeiro país a iniciar a distribuição de uma vacina contra o coronavírus para a população. O país anunciou hoje que concluiu parte dos testes clínicos necessários para comprovar a eficácia da imunização desenvolvida por iniciativa do governo russo. A expectativa é de que a distribuição comece já em agosto. Em junho, a Organização Mundial da Saúde divulgou um relatório sobre o surto e previu que os casos confirmados pela Rússia naquele ano ultrapassariam 10 milhões de pessoas. Em julho, foi relatado que o vírus havia matado 50% das crianças entre 15 e 21 anos. Em agosto, o Ministério da Saúde confirmou que as mortes foram estimadas no total devido à infecção causada pelo vírus "S". Em setembro, uma nova pesquisa revelou que 90% dos infectados haviam sido mortos antes mesmo da chegada da vacina. O governo soviético aprovou em dezembro de 2008, como forma de comemorar o centenário do nascimento da primeira vacina contra o coronavírus (CVD), dois novos centros comerciais russos estão sendo construídos na cidade de Moscou. No entanto, apenas três deles são permanentes: um na Rússia central; outro na fronteira leste com a Ucrânia; e outro nos subúrbios de Vyacheslavsky-Kaliningrado. Em 29 de janeiro de 2009, o governo anunciou planos futuros para construir estações comerciais em todas as regiões afetadas pelos surtos. Até maio de 2013, todos os postos de saúde oficiais estabelecidos no país estavam fechados desde então. Em 1º de março de 2014, a Rússia fechou seus aeroportos, deixando suas fronteiras fechadas para os voos domésticos e internacionais. Desde abril de 2015, cerca de 318 mil imigrantes estrangeiros vêm anualmente da Rússia, principalmente alemães étnicos russos residentes na Alemanha Oriental e eslavos orientais radicados lá. A entrada desses migrantes trouxe também grandes quantidades de problemas econômicos ao país. Os últimos emigrantes vindos ilegalmente vieram sobretudo após a Segunda Guerra Mundial. No final de 2019, muitos milhares de trabalhadores europeus emigraram para o leste da Europa para escapar da guerra civil russa. A maioria destes emigrantes veio da Rússia depois da invasão alemã de 1941. De acordo com a Organização Mundial da Saúde, a taxa de mortalidade infantil na Rússia diminuiu substancialmente desde o início do século XX, mas o número caiu em grande medida entre 1990 e 2001, quando o número aumentou novamente, alcançando a cifra de 7,5% entre 1995 e 2000. No entanto, esse número permaneceu estável até 2007, quando passou de 4,1%, e subiu novamente para 5,9%. As taxas gerais de mortalidade diminuíram consideravelmente durante este --- >> Generated text 3 A Rússia está mais perto de se tornar o primeiro país a iniciar a distribuição de uma vacina contra o coronavírus para a população. O país anunciou hoje que concluiu parte dos testes clínicos necessários para comprovar a eficácia da imunização desenvolvida por iniciativa do governo russo. A expectativa é de que a distribuição comece já em agosto. A Organização Mundial de Saúde (OMS) estima que, no final de dezembro de 2015, havia pelo menos 50 milhões de pessoas infectadas com o vírus na Rússia e Ucrânia. Estimativas semelhantes foram feitas pela OMS sobre os casos registrados desde a década passada. Em março de 2018, o Ministério da Saúde confirmou a descoberta de um novo coronavírus e recomendou aos cidadãos russos manter a disposição para evitar viagens ao exterior após o início das aulas médicas ou exames médicos. Em novembro de 2016, o Ministro da Saúde russo confirmou que todos os indivíduos infectados poderiam ser testados em março; assim como seus familiares e amigos, eles podem fazer teste clínico em uma unidade cirúrgica do hospital da cidade em que são colocados, caso necessário. Também foi anunciado no mesmo dia que o Ministério do Trabalho revelou que as autoridades russas estão trabalhando em conjunto visando reduzir o número de mortes causadas pelas epidemias. A agência informou que a Agência Nacional de Vigilância Sanitária Russa (Anvisa) começou a monitorar a pandemia através de máscaras faciais nos hospitais. Em abril de 2019, o Ministério da Saúde divulgou que 582 mil pessoas haviam sido infetadas com o vírus no país entre janeiro de 2019 e maio de 2020. Cerca de 370 mil desses pacientes estariam diretamente relacionados à doença. A Rússia também tem planos promissores para produzir vacinas que sejam eficazes contra o coronavírus, incluindo a vacina anti-SIDA e antivirais (ver Lista Vermelha da OMS). Em 1º de julho de 2017, a Organização Mundial de Saúde lançou uma nota oficial alertando que "um grande aumento pode vir da necessidade de medidas preventivas necessárias" antes do início das aulas médicas em escolas públicas nas cidades ucranianas. Em outubro de 2017, a Secretaria Municipal de Saúde ucraniana publicou uma nota oficial informando que os profissionais responsáveis pela coordenação da vacinação deveriam estar preparados, bem como suas famílias e amigos durante a realização de exames adicionais para determinar sua saúde mental. Em 30 de junho de 2019, o Ministério da Saúde lançou um comunicado afirmando que três grupos escolares teriam dificuldades de administrar adequadamente o vacina contra o coronavírus na Rússia: A primeira ministra russa, Valentina Tereshinakova, disse em entrevista coletiva que não haverá --- CPU times: user 37.9 s, sys: 1.78 s, total: 39.7 s Wall time: 39.6 s
We are the first, fortunately surprised by the efficiency of fine-tuning in Portuguese an English pre-trained transformer-based language model like GPT-2 small.
In about 1 day using 1 GPU and a little over 1 GB of Portuguese texts, we managed to obtain a GPorTuguese-2 capable of generating contextual Portuguese texts of a level comparable to that of the GPT-2 used by OpenAI in 2019.
Happy.
The next step would be to apply our fine-tuning method to most recent NLP models like GPT-3, BART, T5 or Reformer. Let’s do it?