Cómo entrenar un modelo BERT desde cero

Nodo de origen: 1013329

Cómo entrenar un modelo BERT desde cero

Conoce al primo italiano de BERT, FiliBERTo.


By james briggs, Científico de datos



BERT, pero en Italia - imagen del autor

 

Muchos de mis artículos se han centrado en BERT, el modelo que surgió y dominó el mundo del procesamiento del lenguaje natural (PNL) y marcó una nueva era para los modelos del lenguaje.

Para aquellos de ustedes que no hayan usado modelos de transformadores (por ejemplo, qué es BERT) antes, el proceso se parece un poco a esto:

  • pip install transformers
  • Inicializar un modelo de transformadores previamente entrenado - from_pretrained.
  • Pruébelo con algunos datos.
  • Tal vez afinar el modelo (entrenarlo un poco más).

Ahora, este es un gran enfoque, pero si solo hacemos esto, carecemos de la comprensión detrás de la creación de nuestros propios modelos de transformadores.

Y, si no podemos crear nuestros propios modelos de transformadores, debemos confiar en que haya un modelo previamente entrenado que se adapte a nuestro problema, este no siempre es el caso:



Algunos comentarios sobre modelos BERT que no están en inglés

 

Entonces, en este artículo, exploraremos los pasos que debemos seguir para construir nuestro propio modelo de transformador, específicamente una versión más desarrollada de BERT, llamada RoBERTa.

LECTURA EN VOZ ALTA Y DEBATE

 
 
Hay algunos pasos en el proceso, así que antes de sumergirnos, resumamos primero lo que debemos hacer. En total, hay cuatro partes clave:

  • Obteniendo los datos
  • Construyendo un tokenizador
  • Crear una canalización de entrada
  • Entrenando al modelo

Una vez que hayamos trabajado en cada una de estas secciones, tomaremos el tokenizador y el modelo que hemos construido, y los guardaremos para que podamos usarlos de la misma manera que lo haríamos normalmente con from_pretrained.

Obteniendo los datos

 
 
Como ocurre con cualquier proyecto de aprendizaje automático, necesitamos datos. En términos de datos para entrenar un modelo de transformador, realmente tenemos muchas opciones: podemos usar casi cualquier dato de texto.



Video guía para descargar el conjunto de datos de OSCAR usando la biblioteca de conjuntos de datos de HuggingFace

 

Y, si hay algo que tenemos en abundancia en Internet, son datos de texto no estructurados.

Uno de los conjuntos de datos más grandes en el dominio del texto extraído de Internet es el conjunto de datos OSCAR.

El conjunto de datos de OSCAR cuenta con una gran cantidad de idiomas diferentes, y uno de los casos de uso más claros para la capacitación desde cero es que podemos aplicar BERT a algunos idiomas de uso menos común, como el telugu o el navajo.

Desafortunadamente, el único idioma que puedo hablar con algún grado de competencia es el inglés, pero mi novia es italiana, por lo que ella, Laura, evaluará los resultados de nuestro modelo BERT de habla italiana, FiliBERTo.

Entonces, para descargar el segmento italiano del conjunto de datos de OSCAR usaremos HuggingFace's datasets biblioteca - que podemos instalar con pip install datasets. Luego descargamos OSCAR_IT con:

Echemos un vistazo a la dataset objeto.

Genial, ahora almacenemos nuestros datos en un formato que podamos usar al construir nuestro tokenizador. Necesitamos crear un conjunto de archivos de texto sin formato que contengan solo el text característica de nuestro conjunto de datos, y dividiremos cada muestra usando una nueva línea n.

En nuestro data/text/oscar_it directorio encontraremos:


Una captura de pantalla que muestra una ventana del explorador de Windows llena de archivos .txt, que representan los datos OSCAR de texto sin formato
El directorio que contiene nuestros archivos OSCAR de texto sin formato

 

Construyendo un Tokenizer

 
 
¡El siguiente es el tokenizador! Cuando usamos transformadores, normalmente cargamos un tokenizador, junto con su respectivo modelo de transformador: el tokenizador es un componente clave en el proceso.



Video guía para construir nuestro tokenizador personalizado

 

Al construir nuestro tokenizador, lo alimentaremos con todos nuestros datos OSCAR, especificaremos el tamaño de nuestro vocabulario (número de tokens en el tokenizador) y cualquier token especial.

Ahora, los tokens especiales de RoBERTa se ven así:

Por lo tanto, nos aseguramos de incluirlos en el special_tokens parámetro de nuestro tokenizador train llamada al método.

Nuestro tokenizador ya está listo y podemos guardarlo para su uso posterior:

Ahora tenemos dos archivos que definen nuestro nuevo FiliBERTO tokenizador:

  • combina.txt - realiza el mapeo inicial de texto a tokens
  • vocabulario.json - asigna los tokens a los ID de token

Y con ellos, podemos pasar a inicializar nuestro tokenizador para que podamos usarlo como usaríamos cualquier otro from_pretrained tokenizador.

Inicializando el Tokenizer

 
 
Primero inicializamos el tokenizador usando los dos archivos que construimos antes, usando un simple from_pretrained:

Ahora que nuestro tokenizador está listo, podemos intentar codificar algo de texto con él. Al codificar usamos los mismos dos métodos que usamos normalmente, encode y encode_batch.

Desde el objeto de codificaciones tokens estaremos extrayendo el input_ids y attention_mask tensores para usar con FiliBERTo.

Crear la canalización de entrada

 
 
La canalización de entrada de nuestro proceso de formación es la parte más compleja de todo el proceso. Consiste en que tomamos nuestros datos de entrenamiento OSCAR sin procesar, los transformamos y los cargamos en un DataLoader listo para entrenar.



Video guía de la canalización de entrada de MLM

 

Preparando los datos

 
 
Comenzaremos con una sola muestra y trabajaremos a través de la lógica de preparación.

Primero, necesitamos abrir nuestro archivo, los mismos archivos que guardamos como .TXT archivos anteriores. Dividimos cada uno en función de los caracteres de nueva línea n ya que esto indica las muestras individuales.

Luego codificamos nuestros datos usando el tokenizer - asegurándose de incluir parámetros clave como max_lengthpaddingtruncation.

Y ahora podemos pasar a la creación de nuestros tensores: entrenaremos nuestro modelo a través del modelado de lenguaje enmascarado (MLM). Entonces, necesitamos tres tensores:

  • id_entrada - nuestro identificadores_token con ~ 15% de tokens enmascarados usando el token de máscara <mask>.
  • máscara_atención - un tensor de 1s y 0s, marcando la posición de los tokens 'reales' / tokens de relleno - usados ​​en los cálculos de atención.
  • etiquetas - nuestro identificadores_token   no enmascaramiento.

Si no está familiarizado con MLM, lo he explicado esta página.

Nuestra attention_mask y labels tensores simplemente se extraen de nuestro batchinput_ids Sin embargo, los tensores requieren más atención, para este tensor enmascaramos ~ 15% de los tokens, asignándoles el ID del token 3.

En la salida final, podemos ver parte de un código input_ids tensor. El primer ID de token es 1 - El [CLS] simbólico. Salpicado alrededor del tensor tenemos varios 3 ID de token: estos son nuestros nuevos [MASK] tokens.

Construyendo el DataLoader

 
 
A continuación, definimos nuestro Dataset class - que usamos para inicializar nuestros tres tensores codificados como PyTorch torch.utils.data.Dataset objetos.

Por último, nuestra dataset se carga en una PyTorch DataLoader objeto, que usamos para cargar nuestros datos en nuestro modelo durante el entrenamiento.

Entrenando el modelo

 
 
Necesitamos dos cosas para entrenar, nuestro DataLoader y un modelo. los DataLoader tenemos - pero no modelo.



Inicializando el modelo

 
 
Para el entrenamiento, necesitamos un crudo (no pre-entrenado) BERTLMHeadModel. Para crear eso, primero necesitamos crear un objeto de configuración RoBERTa para describir los parámetros con los que nos gustaría inicializar FiliBERTo.

Luego, importamos e inicializamos nuestro modelo RoBERTa con un cabezal de modelado de lenguaje (LM).

Preparación de entrenamiento

 
 
Antes de pasar a nuestro ciclo de entrenamiento, debemos configurar algunas cosas. Primero, configuramos el uso de GPU / CPU. Luego activamos el modo de entrenamiento de nuestro modelo y, finalmente, inicializamos nuestro optimizador.

Formación

 
 
Finalmente, ¡tiempo de entrenamiento! Entrenamos como lo haríamos normalmente cuando entrenamos a través de PyTorch.

Si nos dirigimos a Tensorboard, encontraremos nuestra pérdida con el tiempo, parece prometedor.



Pérdida / tiempo: en este cuadro se han agrupado varias sesiones de entrenamiento.

 

La verdadera prueba

 
 
Ahora es el momento de la prueba real. Creamos una canalización de MLM y le pedimos a Laura que evalúe los resultados. Puede ver la revisión del video a las 22:44 aquí:



Primero inicializamos un pipeline objeto, usando el 'fill-mask' argumento. Entonces comience a probar nuestro modelo así:

"Ciao cómo ¿Virginia?" es la respuesta correcta! Eso es lo más avanzado que se vuelve mi italiano, así que entreguémoslo a Laura.

Comenzamos con "Buongiorno, ¿ven va?" - o "¿Buenos días cómo estás?":

La primera respuesta, "buongiorno, chi va?" significa "buen día, ¿quién está ahí?" - por ejemplo, absurdo. ¡Pero nuestra segunda respuesta es correcta!

A continuación, una frase un poco más difícil, "Ciao, dove ci incontriamo oggi pomeriggio?" - o "Hola, ¿dónde nos vamos a encontrar esta tarde?":

Y devolvemos algunos resultados más positivos:

✅ "hi, where do we see each other this afternoon?"
✅ "hi, where do we meet this afternoon?"
❌ "hi, where here we are this afternoon?"
✅ "hi, where are we meeting this afternoon?"
✅ "hi, where do we meet this afternoon?"

Finalmente, una oración más, más dura, "Cosa sarebbe successo se avessimo scelto un altro giorno?" - o "¿qué hubiera pasado si hubiéramos elegido otro día?":

También devolvemos algunas buenas respuestas más buenas aquí:

✅ "what would have happened if we had chosen another day?"
✅ "what would have happened if I had chosen another day?"
✅ "what would have happened if they had chosen another day?"
✅ "what would have happened if you had chosen another day?"
❌ "what would have happened if another day was chosen?"

En general, parece que nuestro modelo pasó las pruebas de Laura, ¡y ahora tenemos un modelo competente en italiano llamado FiliBERTo!

¡Eso es todo por este tutorial para entrenar un modelo BERT desde cero!

Hemos cubierto mucho terreno, desde obtener y formatear nuestros datos, hasta usar el modelado de lenguaje para entrenar nuestro modelo BERT sin procesar.

¡Espero que hayas disfrutado de este artículo! Si tiene alguna pregunta, hágamelo saber a través de Twitter o en los comentarios a continuación. Si desea más contenido como este, publico en YouTube 

¡Gracias por leer!

 

¡70% de descuento! Procesamiento del lenguaje natural: PNL con transformadores en Python

Los modelos de transformadores son el estándar de facto en la PNL moderna. Han demostrado ser los más expresivos ...
 

* Todas las imágenes son del autor, salvo que se indique lo contrario.

 
Bio: james briggs es un científico de datos que se especializa en el procesamiento del lenguaje natural y trabaja en el sector financiero, con sede en Londres, Reino Unido. También es mentor, escritor y creador de contenido independiente. Puede comunicarse con el autor por correo electrónico (jamescalam94@gmail.com).

Original. Publicado de nuevo con permiso.

Relacionado:

Fuente: https://www.kdnuggets.com/2021/08/train-bert-model-scratch.html

Sello de tiempo:

Mas de nuggets