Addestrare GPT-2 nella propria lingua

Addestrare GPT-2 nella propria lingua

Una guida passo passo per addestrare da zero il proprio modello GPT-2 per la generazione di testo in una lingua a scelta

Photo by Jr Korpa on Unsplash

Sappiamo tutti che la moderna elaborazione del linguaggio naturale (NLP) ha fatto passi da gigante negli ultimi due anni grazie allo sviluppo delle reti di attenzione e dei trasformatori. Ciò ha aperto la strada a una pletora di nuovi algoritmi che hanno raggiunto lo stato dell’arte (SOTA) per i diversi compiti dell’NLP.

OpenAI è stato uno dei leader nel fornire il proprio modello linguistico (ora rilasciato GPT-3), addestrato su un enorme corpus di dati internet. Dato che il GPT-3 è un fenomeno recente, al momento in lingua inglese, ed è accessibile solo tramite le API fornite da OpenAI, ci concentreremo sulla versione precedente, cioè il GPT-2. Per conoscere i dettagli interni di GPT-2, vi suggerisco di consultare questo link. Per approfondire il tema dell’attenzione e dei trasformatori, ecco alcuni link eccellenti:

– Il trasformatore illustrato di Jay Alammar

– Il Trasformatore commentato di Harvard NLP

Il GPT-2 è stato rilasciato anche per l’inglese, il che rende difficile per chi cerca di generare testo in una lingua diversa.

Allora perché non addestrare il proprio modello GPT-2 sulla propria lingua preferita per la generazione di testi? Questo è esattamente ciò che faremo. Quindi, senza ulteriori indugi, iniziamo.

Per la dimostrazione, ho preso in considerazione una scrittura con alfabeto non latino (il bengalese), perché no! Per il modello ho utilizzato l’implementazione di Huggingface.

  1. Raccolta dei dati.

La raccolta di dati di buona qualità è una delle fasi più importanti, come concordano tutti i Data Scientist. Pertanto, si presuppone che si disponga già di una cartella contenente file .txt con tutti i dati puliti e memorizzati. Per semplicità, si possono usare i dati degli articoli di Wikipedia, che sono disponibili e possono essere scaricati con il seguente codice.

python wikipedia_download.py –lang bn

In questo modo verrà creata una cartella contenente tutti i file di Wikipedia dall’aspetto simile:

screenshot of file list

Nota: a causa della scarsità di risorse e poiché è a scopo dimostrativo, ho addestrato il modello su un piccolo sottoinsieme di libri di Satyajit Ray, in particolare la serie del detective Feluda.

  1. Tokenizzazione

Il secondo passo è la tokenizzazione dei dati. A tale scopo, utilizziamo la seguente classe.

Alcune note sulla tokenizzazione:

– Utilizziamo la codifica BPE (Byte Pair Encoding), che è una codifica di sottoparole, che in genere si preoccupa di non trattare forme diverse di parole come diverse. (Ad esempio, greatest sarà trattato come due token: ‘great’ ed ‘est’, il che è vantaggioso perché mantiene la somiglianza tra great e greatest, mentre ‘greatest’ ha un altro token aggiunto ‘est’ che lo rende diverso). Inoltre, non è un livello così basso come la codifica a livello di carattere, che non conserva alcun valore di una particolare parola.

– Un altro punto piccolo ma sottile è NFKC (Normalization Form Compatibility Composition) nella riga 13 del codice. Si tratta di una delle forme di compatibilità standard di Unicode. Non avrebbe molta importanza se la lingua fosse l’inglese, ma dato che stiamo usando il bengalese, che contiene una forma diversa di carattere, usiamo questa specifica. Per saperne di più, consultare questo link

Quindi, quello che facciamo è tokenizzare i nostri dati e salvarli in una cartella. Verranno creati due file (merges.txt e vocab.json) in una directory specificata. Per eseguire il file, utilizzare il seguente codice:

from tokenise import BPE_token
from pathlib import Path
import os# the folder ‘text’ contains all the files
paths = [str(x) for x in Path(“./text/”).glob(“**/*.txt”)]tokenizer = BPE_token()# train the tokenizer model
tokenizer.bpe_train(paths)# saving the tokenized data in our specified folder
save_path = ‘tokenized_data’
tokenizer.save_tokenizer(save_path)

  1. Inizializzazione del modello

Prima di iniziare la vera magia, dobbiamo assicurarci che le artiglierie siano pronte. Cominciamo con alcune inizializzazioni.

 

import tensorflow as tf
from transformers import GPT2Config, TFGPT2LMHeadModel, GPT2Tokenizer# loading tokenizer from the saved model path
tokenizer = GPT2Tokenizer.from_pretrained(save_path)tokenizer.add_special_tokens({
  “eos_token”: “</s>”,
  “bos_token”: “<s>”,
  “unk_token”: “<unk>”,
  “pad_token”: “<pad>”,
  “mask_token”: “<mask>”
})# creating the configurations from which the model can be made
config = GPT2Config(
  vocab_size=tokenizer.vocab_size,
  bos_token_id=tokenizer.bos_token_id,
  eos_token_id=tokenizer.eos_token_id
)# creating the model
model = TFGPT2LMHeadModel(config)

Inoltre, creiamo una singola stringa da tutti i nostri documenti e la tokenizziamo.

single_string = ”
for filename in paths:
  with open(filename, “r”, encoding=’utf-8′) as f:
   x = f.read()  single_string += x + tokenizer.eos_tokenstring_tokenized = tokenizer.encode(single_string)

Dopo aver codificato l’intera stringa, passiamo a creare un set di dati TensorFlow, suddividendo i dati in intervalli uguali, in modo che il nostro modello possa imparare. In questo caso utilizziamo una dimensione di blocco di 100 (lunghezza del token in ciascun esempio) e una dimensione di batch di 16. Questa dimensione è stata mantenuta bassa per poterla eseguire con facilità su una GPU RTX 2060.

examples = []
block_size = 100
BATCH_SIZE = 12
BUFFER_SIZE = 1000for i in range(0, len(string_tokenized) – block_size + 1, block_size):
  examples.append(string_tokenized[i:i + block_size])
inputs, labels = [], []for ex in examples:
  inputs.append(ex[:-1])
  labels.append(ex[1:])dataset = tf.data.Dataset.from_tensor_slices((inputs, labels))
dataset = dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True)

 

  1. Formazione del modello

Ora arriva la parte che stavamo aspettando: la creazione del modello e l’addestramento. Definiamo quindi il nostro ottimizzatore, le funzioni di perdita e le metriche e iniziamo l’addestramento.

 

# defining our optimizer
optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0)# definining our loss function
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)# defining our metric which we want to observe
metric = tf.keras.metrics.SparseCategoricalAccuracy(‘accuracy’)# compiling the model
model.compile(optimizer=optimizer, loss=[loss, *[None] * model.config.n_layer], metrics=[metric])

Ora, addestriamo il modello

num_epoch = 10
history = model.fit(dataset, epochs=num_epoch)

 

  1. Predizione

Per predire, è sufficiente codificare il testo in ingresso e passarlo al modello

 

text = “লালমোহনবাবু “# encoding the input text
input_ids = tokenizer.encode(text, return_tensors=’tf’)# getting out output
beam_output = model.generate(
  input_ids,
  max_length = 50,
  num_beams = 5,
  temperature = 0.7,
  no_repeat_ngram_size=2,
  num_return_sequences=5
)

screenshot of the output

Ora, se siete bengalesi, potete far notare che l’output, sebbene la frase sia sintatticamente corretta, non sembra coeso. È vero, ma per questa dimostrazione l’ho ridotta al minimo.

  1. Salvare il modello

Dopo un lungo periodo di addestramento, a cosa servirebbe se chiudessimo la sessione e tutto il modello addestrato andasse perso e dovessimo addestrarlo di nuovo da zero. Quindi, salviamo il modello e il tokenizer in modo da poter riallenare da dove abbiamo lasciato

from transformers import WEIGHTS_NAME, CONFIG_NAME
import osoutput_dir = ‘./model_bn_custom/’# creating directory if it is not present
if not os.path.exists(output_dir):
  os.mkdir(output_dir)model_to_save = model.module if hasattr(model, ‘module’) else model
output_model_file = os.path.join(output_dir, WEIGHTS_NAME)
output_config_file = os.path.join(output_dir, CONFIG_NAME)# save model and model configs
model.save_pretrained(output_dir)
model_to_save.config.to_json_file(output_config_file)# save tokenizer
tokenizer.save_pretrained(output_dir)

Bonus

Abbiamo già fatto tutto il lavoro duro, quindi per caricare il modello salvato e il tokenizer, dobbiamo eseguire solo due righe di codice e siamo a posto.

 

tokenizer = GPT2Tokenizer.from_pretrained(output_dir)
model = TFGPT2LMHeadModel.from_pretrained(output_dir)

Voila! Ora potete addestrare il vostro modello nella vostra lingua. E creare contenuti in grado di competere con alcune delle migliori opere letterarie in qualsiasi lingua.

Share:

Contenuti

Leggi anche

Tutorials correlati

Transformers

O, come mi piace chiamarla, “attenzione sotto steroidi”.. 💉💊 Photo by Arseny Togulev on Unsplash No, questo articolo non riguarda la serie americana di film d’azione fantascientifici –

Che cos’è il Question Answering?

Question answering: definizione   Il question answering è una particolare specificazione di un problema molto più grande: ossia la capacità di comprendere il linguaggio naturale.

Che cos’è un motore di ricerca?

La complessità  Sembra una domanda banale ma sottende molte complicazioni tecniche. Il problema principale è sempre la formalizzazione della semantica, molto difficile da poter rappresentare

Usa il codice 𝗕𝗟𝗔𝗖𝗞𝗙𝗥𝗜𝗗𝗔𝗬𝟲𝟬 e approfitta del 60% di sconto su tutti i corsi singoli 😉
dai un lancio alla tua carriera con i corsi di dli 🚀