# Wolfram Neural Net Repository

Immediate Computable Access to Neural Net Models

Generate text in English and represent text as a sequence of vectors

Released in 2019, this model improves and scales up its predecessor model. It has a richer vocabulary and uses BPE tokenization on UTF-8 byte sequences and additional normalization at the end of all of the transformer blocks.

Number of models: 3

- Preliminary version of the OpenWebText dataset, consisting of 40 GB of text scraped from webpages that have been curated by humans.

Accuracy of the models for various datasets:

Bits-per-character of the models for various datasets:

Perplexity of the models for various datasets:

Get the pre-trained net:

In[1]:= |

Out[1]= |

This model consists of a family of individual nets, each identified by a specific parameter combination. Inspect the available parameters:

In[2]:= |

Out[2]= |

Pick a non-default net by specifying the parameters:

In[3]:= |

Out[3]= |

Pick a non-default uninitialized net:

In[4]:= |

Out[4]= |

Given a piece of text, the GPT-2 net produces a sequence of feature vectors of size 768, which corresponds to the sequence of input words or subwords:

In[5]:= |

Obtain dimensions of the embeddings:

In[6]:= |

Out[6]= |

Visualize the embeddings:

In[7]:= |

Out[7]= |

The input string is first normalized and then tokenized, or split into words or subwords. This two-step process is accomplished using the NetEncoder "Function":

In[8]:= |

Out[9]= |

The tokenization step is performed using the NetEncoder "BPESubwordTokens" and can be extracted using the following steps:

In[10]:= |

Out[11]= |

The encoder produces an integer index for each subword token that corresponds to the position in the vocabulary:

In[12]:= |

Out[12]= |

Each subword token is also assigned a positional index:

In[13]:= |

Out[13]= |

A lookup is done to map these indices to numeric vectors of size 768:

In[14]:= |

Out[15]= |

For each subword token, these two embeddings are combined by summing elements with ThreadingLayer:

In[16]:= |

Out[16]= |

The transformer architecture then processes the vectors using 12 structurally identical self-attention blocks stacked in a chain:

In[17]:= |

Out[17]= |

The key part of these blocks is the attention module comprising of 12 parallel self-attention transformations, also called “attention heads”:

In[18]:= |

Out[18]= |

Attention is done with causal masking, which means that the embedding of a given subword token depends on the previous subword tokens and not on the next ones. This is a prerequisite to be able to generate text with the language model. The following figures compare causal attention to other forms of connectivity between input tokens:

Retrieve the language model by specifying the "Task" parameter:

In[19]:= |

Out[19]= |

Predict the next word in a given sequence:

In[20]:= |

Out[20]= |

Obtain the top 15 probabilities:

In[21]:= |

Out[21]= |

Plot the top 15 probabilities:

In[22]:= |

Out[22]= |

Define a function to predict the next token:

In[23]:= |

Generate the next 20 tokens by using it on a piece of text:

In[24]:= |

Out[24]= |

The third optional argument is a “temperature” parameter that scales the input to the final softmax. A high temperature flattens the distribution from which tokens are sampled, increasing the probability of extracting less likely tokens:

In[25]:= |

Out[25]= |

Decreasing the temperature sharpens the peaks of the sampling distribution, further decreasing the probability of extracting less likely tokens:

In[26]:= |

Out[26]= |

Very high temperature settings are equivalent to random sampling:

In[27]:= |

Out[27]= |

Very low temperature settings are equivalent to always picking the character with maximum probability. It is typical for sampling to “get stuck in a loop”:

In[28]:= |

Out[28]= |

The text generation example in the previous section wastes computational resources because every time a new token is produced, the language model reads the entire generated string from the beginning. This means that generating new tokens is more and more costly as text generation progresses. This can be avoided by using NetUnfold:

In[29]:= |

Write a function to efficiently generate text using the unfolded net:

In[30]:= |

Generate the next 20 tokens efficiently by using it on a piece of text:

In[31]:= |

Out[31]= |

Compute the timings of the two methods for an increasing number of tokens:

In[32]:= |

Observe that the inefficient method grows quadratically with the number of tokens, while the efficient one is linear:

In[33]:= |

Out[33]= |

Define a sentence embedding that consists of the last subword embedding of GPT-2 (this choice is justified by the fact that GPT-2 is a forward causal model):

In[34]:= |

Out[34]= |

Define some sentences in two broad categories for comparison:

In[35]:= |

Precompute the embeddings for a list of sentences:

In[36]:= |

Visualize the similarity between the sentences using the net as a feature extractor:

In[37]:= |

Out[37]= |

Get a text-processing dataset:

In[38]:= |

View a random sample of the dataset:

In[39]:= |

Out[39]= |

Define a sentence embedding that consists of the last subword embedding of GPT-2 (this choice is justified by the fact that GPT-2 is a forward causal model):

In[40]:= |

Out[40]= |

Precompute the GPT-2 vectors for the training and the validation datasets (if available, GPU is recommended), using the last embedded vector as a representation of the entire text:

In[41]:= |

Define a simple network for classification:

In[42]:= |

Out[42]= |

Train the network on the precomputed GPT-2 vectors:

In[43]:= |

Out[43]= |

Check the classification error rate on the validation data:

In[44]:= |

Out[44]= |

Compare the results with the performance of a classifier trained on context-independent word embeddings. Precompute the GloVe vectors for the training and the validation datasets (if available, GPU is recommended):

In[45]:= |

In[46]:= |

Define a simple network for classification using a max-pooling strategy:

In[47]:= |

Out[47]= |

Train the classifier on the precomputed GloVe vectors:

In[48]:= |

Out[48]= |

Compare the results obtained with GPT-2 and with GloVe:

In[49]:= |

Out[49]= |

Inspect the number of parameters of all arrays in the net:

In[50]:= |

Out[50]= |

Obtain the total number of parameters:

In[51]:= |

Out[51]= |

Obtain the layer type counts:

In[52]:= |

Out[52]= |

Display the summary graphic:

In[53]:= |

Out[53]= |

Wolfram Language 12.1 (March 2020) or above

- A. Radford, J. Wu, R. Child, D. Luan, D. Amodei, I. Sutskever, "Language Models Are Unsupervised Multitask Learners" (2019)
- Available from: https://github.com/openai/gpt-2
- Rights: MIT License