GPT-2: generazione automatica di testi con Python

Generare del contenuto testuale è un lavoro impegnativo che richiede tempo e risorse. Con l'intelligenza artificiale, ad oggi, è possibile generare del contenuto semplicemente partendo da poche parole. Le tecnologie sviluppate da OpenAI, tra cui GPT-2, hanno aperto nuove frontiere di applicazione legate al Natural Language Generation. Scopriamo come generare automaticamente dei brevi testi mediante poche linee di codice Python.

Share

Reading time: 7 minutes

L’intelligenza artificiale ha compiuto enormi passi avanti negli ultimi anni. Con essa si possono analizzare grandi moli di dati al fine di generare modelli capaci di svolgere anche compiti molto complessi. Un ramo dell’intelligenza artificiale che affascina moltissimo è la capacità di generare del testo a partire da poche parole di input: Natural Language Generation.

In questo articolo vedremo come è possibile generare degli articoli su Elastisearch le cui caratteristiche abbiamo già discusso negli articoli ELK Stack: cos’è e a cosa serve, A cosa serve Kibana?, Kibana: esploriamo i dati, e Python partendo da una semplice domanda e poche linee di codice Python. Useremo, in particolare, il modello GPT-2 Large Pre-trained e i Transformers di HuggingFace. Iniziamo però a dare due informazioni di massima sulle tecnologie che useremo.

GPT-2

Annunciato nel 2019 da OpenAI, GPT-2 è il successore di GPT, ed è stato teorizzato nell’articolo Language Models are Unsupervised Multitask Learners. Questo modello linguistico è composto da transformers con 1,5 miliardi di parametri ed addestrato su un dataset di 8 milioni di pagine web. L’obiettivo dell’addestramento di GPT-2 è molto semplice: prevedere la parola successiva conoscendo tutte le parole precedenti all’interno di un testo. L’eterogeneità del dataset di training implica che il modello generato si possa adattare a diversi domini applicativi. Rispetto al suo predecessore, GPT-2 è uno scale-up diretto con più di 10 volte i parametri e addestrato su un dataset 10 volte maggiore.

Sono stati rilasciati comunque diversi modelli di GPT2 come mostrato in figura. Questi differiscono a seconda della dimensione: small (124M parametri), medium (355M parametri), large (774M parametri) ed extra large (1.5BM parametri, ossia l’implementazione completa).

Nel Maggio 2020, OpenAI ha annunciato GPT-3. Diversamente dai suoi predecessori, questo modello può essere utilizzato solo mediante API a pagamento il che lo rende meno utilizzabile come base di partenza per la creazione di nuovi modelli.

Se volete avere più informazioni potete leggere un interessante articolo direttamente dal sito di OpenAI.

Transformers HuggingFace

HuggingFace Transformers (precedentemente noto come PyTorch-transformers e PyTorch-pretrained-bert) fornisce architetture general-purpose (BERT, GPT-2, RoBERTa, XLM, DistilBert, XLNet…) per la comprensione del linguaggio naturale (NLU) e la generazione del linguaggio naturale (NLG) con oltre 32 modelli pre-addestrati in più di 100 lingue e profonda interoperabilità tra TensorFlow 2.0 e PyTorch.

Fondamentalmente Hugging Face Transformers è un pacchetto python che ha alcune funzioni, pipeline e modelli pre-definiti o pre-addestrati che possiamo usare per i nostri compiti di elaborazione del linguaggio naturale.

GPT-2 Tokenizer e modelli sono anche inclusi in HuggingFace Transformers.

Per avere più informazioni sui Transformers disponibili e il loro utilizzo vi rimandiamo alla documentazione ufficiale.

Ambiente di sviluppo

Per questo tutorial introduttivo alla generazione di testi con GPT utilizzeremo un notebook Jupyter. Come abbiamo visto nell’articolo Jupyter Notebook: guida al suo utilizzo è possibile installarlo semplicemente mediante Anaconda.

Per sfruttare però i transformer di HuggingFace è necessario installare, oltre ad essi, Pytorch. Per farlo è sufficiente recarsi sul si to di Anaconda e cercare i pacchetti che ci interessano. Per ogni pacchetto è indicata l’architettura per cui è rilasciato. Ad esempio, se avete un Mac con chip M1 dovrete guardare tutti i pacchetti compatibili con la piattaforma osx-arm64.

Cliccando sul pacchetto ci verranno fornite le istruzioni per l’installazione, come potete vedere qui sotto.

Per installare i pacchetti che ci servono, Pytorch e transformers, potete usare i seguenti comandi.

conda install -c pytorch
conda install -c conda-forge transformers 

Una volta terminate le installazioni potete lanciare Anaconda e successivamente un Notebook Jupyter o lo Jupyterlab.

Generazione di un testo su Elastisearch

Per prima cosa, importiamo GPT2LMHeadModel per la generazione del testo e GPT2Tokenizer per la tokenizzazione del testo.

from transformers import GPT2LMHeadModel , GPT2Tokenizer 

Ora carichiamo il modello nel notebook Jupyter.

tokenizer = GPT2Tokenizer.from_pretrained('gpt2-large') 
model = GPT2LMHeadModel.from_pretrained('gpt2-large' , 
pad_token_id = tokenizer.eos_token_id)
 

Dal momento che usiamo il modello large, ci vorrà un pò di tempo prima che venga scaricato. Assicuratevi di avere più di 3GB liberi prima di eseguire questo comando. Diversamente potete usare le versioni più piccole dei modelli GTP-2.

Per la generazione del testo, dobbiamo fornire del testo iniziale al nostro modello. Affinché il testo in input venga riconosciuto correttamente dal modello, è necessario preprocessarlo. Definiamo quindi il testo da cui partire come riportato di seguito.

sentence = 'What is Elasticsearch?' 

A questo punto dobbiamo trasformarlo nei tensori di PyTorch.

input_ids = tokenizer.encode(sentence, return_tensors='pt') 

Le parole vengono convertite in un indice numerico che è possibile visualizzarlo anche mediante la funzione decode.

input_ids = tokenizer.encode(sentence, return_tensors='pt')
# tensor([[ 2061,   318, 48567, 12947,    30]]) 

Infine, generiamo il testo usando la funzione generate da GPT2LMHeadModel.

output = model.generate(input_ids, 
max_length = 1000, 
num_beams = 5,
no_repeat_ngram_size = 2,
early_stopping = True) 

Prima di mostrarvi il risultato analizziamo nel dettaglio i vari parametri usati per generare il testo.

  • max_length: Numero massimo di parole nel testo generato.
  • num_beams: La ricerca a beams riduce il rischio di perdere sequenze di parole nascoste ad alta probabilità mantenendo il numero più probabile di ipotesi ad ogni passo temporale e scegliendo alla fine l’ipotesi che ha la probabilità complessiva più alta. La ricerca a beam troverà sempre una sequenza di output con una probabilità più alta della ricerca greedy, anche se non è garantito di trovare l’output più probabile.
  • no_repeat_ngram_size: Mentre il risultato è probabilmente più fluente, l’output include ancora ripetizioni delle stesse sequenze di parole. Un semplice rimedio è quello di introdurre penalità di n-grammi (ovvero sequenze di n parole) come introdotto da Paulus et al. (2017)   e Klein et al. (2017). Impostando la penalità a 0, si assicura che nessun n-gramma appaia due volte.
  • early_stopping: impostando al valore True, la generazione terminerà quando tutte le ipotesi di beam hanno raggiunto il token EOS.

Maggiori dettagli sugli argomenti della funzione di generazione li trovate nella documentazione ufficiale.

La funzione di generazione restituirà gli id dei tokens del nostro nuovo testo. Semplicemente decondificando il risultato possiamo stampare il nostro articolo. Il tempo di generazione del testo varia in base ai parametri, tra cui la lunghezza del testo da generare, e la potenza della vostra macchina.

print (tokenizer.decode(output[0], skip_special_tokens=True )) 

Ecco il risultato finale.

What is Elasticsearch? Elasticsearch is a full-text search engine that can be used to search and index large amounts of data. It is used by companies like Google, Microsoft, Yahoo, and many others. ElasticSearch is also used in many open source projects, such as Apache Hadoop, Apache Spark, HBase, MongoDB, Cassandra, Redis, Memcached, etc. In this post, we will be looking at how to install and set up a simple elasticsearch cluster on Ubuntu 16.04 LTS (Xenial Xerus) using Docker. We will also be using the Docker Compose tool to automate the installation and configuration of the cluster. This post assumes that you have a basic understanding of Docker and how it works. If you are not familiar with Docker, you can read more about it here: https://docs.docker.com/en/latest/userguide/getting-started/installation-and-configuration-of-docker-compose.html. For the purposes of this tutorial, let's assume you already have Docker installed and running on your system. You can find more information about Docker on the official Docker website: http://docker.io/docs/tutorials/how-to-build-a-containerized-application-on-ubuntu-16-04-lts-with-dockery-1.2.0-beta-2-amd64-linux-x86_64. The following Dockerfile will create a Docker container that will act as the master node of our cluster and will serve as a data store for the data that we are going to index. Note that this is not a production-ready cluster, but it should give you a good idea of how Docker works and what it can do for you. #!/bin/bash export DOCKER_OPTS="-v" docker run -d -p 8080:8080 \ -v /var/lib/docker/data:/data \ --name my-elastic-search-cluster \ my_docker_data_dir /data/my_search_file.txt -it --restart=always --volume-driver=dynamodb \ /usr/share/nginx/html/index.php:8000:9000 \ nginx -t http.server:5000 -c "server { listen 80; listen [::]:80; server_name localhost; location / { try_files $uri @api; fastcgi_split_path_info ^(.+\.php)(/.+)$; } location ~ \.(jpg|jpeg|gif|png|ico|css|js|swf)$ { add_header Cache-Control "public, max-age=0, must-revalidate" ; } }" /etc/init.d/nginx start # Create a container for our index file docker create -f /path/to/your/search.yml.example /dev/null # Start the container docker exec -ti -e "rm -rf /tmp/*" -i /home/ubuntu/dynamic-index-file-name-server.sh /root/node_modules/mysql-5.6.1-0ubuntu1_all.deb # Run the indexing service docker start --net=host --memory-size=512M --volumes-from=my-data-dir --start-stop-daemon --log-level=info --user=root --group=ubuntu --system-type=linux --vhosts=localhost.localdomain --tls-verify=yes --ssl-cert-path=/etc/.ssl/certs.pem docker stop --rm-if-not-found --recursive-service docker rm --ignore-errors --remove-empty-files --force-removal --no-startup-id docker restart --recheck-interval=1s --privileged --service=mysqldd # Check that everything is working docker ps docker inspect --format '{{.}}' --color=auto | grep -E 'index' | awk -F: '{print $1}' > /proc/sys/kernel/random/entropy_avail docker logs --tail -n 1 --pretty=format: "%d" | sort | uniq | head -1 | xargs -I {} \ | sed's/.*\(.*\)$/\1/g' \; docker status # List all the containers that are running docker info # This will show you the name of each container and the number of processes # in each of them. Each process is represented by a number in the range 1-65535 # (e.g. 1 is

Essendo un argomento tecnico sono stati inseriti molti comandi più relativi a Docker che ad Elasticsearch. L’inizio è abbastanza buono, poi però devia troppo dall’argomento iniziale. Infine, il testo non si conclude.

Generazione di un testo su Python

Proviamo adesso a modificare la frase iniziale con la seguente domanda.

sentence = 'What is Python?' 

Ridiciamo il numero di parole massime generate per ridurre sia il tempo di esecuzione che la possibile deriva del testo. Il risultato che otteniamo per un testo di 500 parole massimo è il seguente.

What is Python? Python is a general-purpose programming language that is used to write computer programs. It is also known as the "language of the Internet" because it is the most widely used language in the world. Python is written in C++, a high-level, object-oriented language developed by Sun Microsystems, Inc. (NASDAQ:SUN). Python can be used in a wide variety of applications, including web servers, databases, web browsers, and embedded systems. The language is available for free download at http://www.python.org/download.html.

In questo caso l’argomento è molto ben discusso anche se è un po’ corto. Nessuno potrebbe intuire che è stata una macchina e non un essere umano a scriverlo.

Come abbiamo visto la generazione del testo usando GPT-2 è molto semplice e apre una varietà di impieghi in molti settori tra cui i chatbot, la generazione di contenuti per i siti web e l’impiego nell’industria 4.0.

Letture consigliate

More To Explore

Elasticsearch

Elasticsearch: query compound

Elasticsearch offre uno strumento molto valido per effettuare ricerche semplici ma anche complesse. In questo articolo capiremo come inserire più condizioni nella stessa query e modificare il calcolo dello score in base a funzioni personalizzate e ad i valori dei dati.

Elasticsearch

Elasticsearch: uso delle term query

Elasticsearch offre uno strumento molto valido non solo per le ricerche testuali, ma anche per i dati strutturati. In questo articolo capiremo come interrogare i campi strutturati mediante le query term. Le varie tipologie di query ci permetteranno di raffinare le ricerche per i nostri progetti futuri.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Design with MongoDB

Design with MongoDB!!!

Buy the new book that will help you to use MongoDB correctly for your applications. Available now on Amazon!