Few-shot NER: Extracción de entidades sin anotación y entrenamiento basado en GPT

Los modelos de extracción de entidades preentrenados basados en spaCy o NLTK dan grandes resultados, pero requieren un tedioso proceso de anotación y entrenamiento para detectar entidades no nativas como títulos de trabajo, números de IVA, medicamentos, etc. Gracias a los grandes modelos lingüísticos como GPT-3, GPT-J y GPT-NeoX, ahora es posible extraer cualquier tipo de entidades gracias al aprendizaje en pocos pasos, sin necesidad de anotación y entrenamiento. En este artículo, mostramos cómo hacerlo.

NER (extracción de entidades) consiste básicamente en extraer información estructurada de un texto no estructurado. Si eres nuevo en NER, puedes leer primero nuestra breve introducción: introducción a la RNC.

NER con spaCy y NLTK: la forma tradicional

SpaCy se ha convertido en la norma de facto para las RNC estos últimos años (ver el sitio web de spaCy). SpaCy es un marco de trabajo muy atractivo porque es fácil de usar, y su velocidad lo hace muy adecuado para su uso en producción.

SpaCy es un marco de procesamiento del lenguaje natural en Python que propone muchos modelos preentrenados en múltiples idiomas, por lo que es fácil extraer varios tipos de entidades (empresas, ciudades, direcciones, fechas, etc.) en su propio idioma sin tener que entrenar su propio modelo.

NLTK también es una opción interesante para la extracción de entidades con Python, pero propone menos entidades por defecto, y en general NLTK no se recomienda para la producción (es más bien un marco educativo y de investigación).

Sin embargo, estos marcos tienen un límite: el número de entidades soportadas de forma nativa es limitado. La mayoría de las empresas quieren aprovechar el NER para extraer información empresarial específica, como información sobre personas, datos financieros, tratamientos médicos, etc. Por supuesto, estas entidades no son soportadas por defecto por los modelos preentrenados de spaCy, por lo que para conseguirlo hay que crear un conjunto de datos propio y entrenar un modelo propio a partir de él.

Entrenar tu propio modelo spaCy es un proceso de anotación largo y tedioso: es necesario que una o varias personas colaboren para crear un enorme conjunto de buenos ejemplos y anotarlos. Se necesita un gran volumen de ejemplos para que el modelo aprenda correctamente. Existen buenas herramientas de anotación (como Prodigy, de spaCy), pero sigue siendo una tarea penosa que hace abortar muchos proyectos de PNL.

Ilustración de la anotación

Buenas noticias: con la aparición de grandes modelos lingüísticos como GPT-3, GPT-J y GPT-NeoX, ahora es posible extraer cualquier entidad sin necesidad de anotar y entrenar un nuevo modelo.

Generación de textos con GPT-3, GPT-J y GPT-NeoX

Los grandes modelos lingüísticos para la generación de textos han empezado a aparecer recientemente con GPT-3 (ver más sobre GPT-3 en el sitio web de OpenAI). Cuando OpenAI lanzó su modelo GPT-3, compuesto por 175.000 millones de parámetros, supuso una revolución porque allanó el camino para muchas aplicaciones de IA de vanguardia basadas en el procesamiento del lenguaje natural sin requerir ninguna formación adicional.

El objetivo inicial de los modelos GPT, como GPT-3, es generar texto: basta con dar una entrada al modelo y dejar que éste genere el resto por usted. Sobre la base de la generación de texto, se puede lograr prácticamente cualquier caso de uso del procesamiento del lenguaje natural: clasificación, resumen, IA conversacional, paráfrasis... y, por supuesto, extracción de entidades.

Dado que GPT-3 no es un modelo de código abierto, la comunidad de código abierto ha trabajado en alternativas a GPT-3 y ahora tenemos 2 grandes equivalentes de código abierto: GPT-J y GPT-NeoX. Todavía no son tan grandes como GPT-3, pero no cabe duda de que es sólo cuestión de tiempo que la comunidad de código abierto se ponga al día con OpenAI.

Aprovechar adecuadamente estos modelos requiere una nueva técnica llamada "aprendizaje de pocos disparos".

Aprendizaje de pocos disparos

Estos grandes modelos de GPT son tan grandes que pueden aprender muy rápidamente de ti.

Digamos que quiere que GPT-3 genere una breve descripción del producto para usted. Aquí hay un ejemplo sin aprendizaje de pocos disparos:

Generate a product description containing these specific keywords: t-shirt, men, $50

La respuesta que obtendrá será inútil. Podría ser algo así, por ejemplo:

Generate a product description containing these specific keywords: t-shirt, men, $50 and short.

The product description needs to be a few words long. Don’t use plurals, use the keywords in the order they are

Buenas noticias: ¡puedes conseguir resultados mucho mejores simplemente dando un par de ejemplos al modelo!

Generate a product description containing specific keywords.

Keywords: shoes, women, $59
Result: Beautiful shoes for women at the price of $59.
###
Keywords: trousers, men, $69
Result: Modern trousers for men, for $69 only.
###
Keywords: gloves, winter, $19
Result: Amazingly hot gloves for cold winters, at $19.
###
Keywords: gpu, gaming, $1499
Result:

El resultado será algo así:

Generate a product description containing specific keywords.

Keywords: shoes, women, $59
Result: Beautiful shoes for women at the price of $59.
###
Keywords: trousers, men, $69
Result: Modern trousers for men, for $69 only.
###
Keywords: gloves, winter, $19
Result: Amazingly hot gloves for cold winters, at $19.
###
Keywords: gpu, gaming, $1,499
Result: The best gaming GPU on the market, at the price of $1,499 only.

Como puede ver, la respuesta del modelo es ahora perfectamente a propósito, gracias a los 3 ejemplos que le dimos al principio. Sin embargo, este modelo nunca fue entrenado en este tipo de tarea de generación de descripciones de productos. En esto consiste la técnica del "aprendizaje de pocos disparos": se realiza un "aprendizaje de transferencia" sobre la marcha con un par de ejemplos solamente. Para conseguir este tipo de resultados, normalmente se espera entrenar un modelo de procesamiento del lenguaje natural con toneladas de ejemplos, pero no en este caso.

Extracción de entidades con aprendizaje de pocos disparos

Ahora realizaremos la extracción de entidades gracias al aprendizaje de pocos disparos.

Supongamos que quiere extraer los títulos de los puestos de trabajo de los sitios web. Simplemente dé un par de ejemplos de extracción de títulos de trabajo antes de hacer su solicitud real:

Extract job titles from the following sentences.

Sentence: John Doe has been working for Microsoft for 20 years as a Linux Engineer.
Job title: Linux Engineer
###
Sentence: John Doe has been working for Microsoft for 20 years and he loved it.
Job title: none
###
Sentence: Marc Simoncini | Director | Meetic
Job title: Director
###
Sentence: Franck Riboud was born on 7 November 1955 in Lyon. He is the son of Antoine Riboud, who transformed the former European glassmaker BSN Group into a leading player in the food industry. He is the CEO at Danone.
Job title: CEO
###
Sentence: Damien is the CTO of Platform.sh, he was previously the CTO of Commerce Guys, a leading ecommerce provider.
Job title:

El resultado será el siguiente:

Extract job titles from the following sentences.

Sentence: John Doe has been working for Microsoft for 20 years as a Linux Engineer.
Job title: Linux Engineer
###
Sentence: John Doe has been working for Microsoft for 20 years and he loved it.
Job title: none
###
Sentence: Marc Simoncini | Director | Meetic
Job title: Director
###
Sentence: Franck Riboud was born on 7 November 1955 in Lyon. He is the son of Antoine Riboud, who transformed the former European glassmaker BSN Group into a leading player in the food industry. He is the CEO at Danone.
Job title: CEO
###
Sentence: Damien is the CTO of Platform.sh, he was previously the CTO of Commerce Guys, a leading ecommerce provider.
Job title: CTO

Como ya has notado, tenemos que ser inteligentes a la hora de crear nuestros ejemplos de pocos puestos. Puede ocurrir que no se encuentre ningún puesto de trabajo, por lo que hemos creado un ejemplo que devuelve "ninguno" (así se evitan los falsos positivos). ¿Quizás quiera extraer varios títulos de trabajo al mismo tiempo? En ese caso, es importante crear ejemplos que devuelvan varios títulos de trabajo también (títulos de trabajo separados por comas, por ejemplo).

Obtendrá resultados aún mejores si añade más ejemplos. Y es importante que tus ejemplos sean lo más parecidos posible a tu petición final real. Por ejemplo, si sabes que vas a analizar párrafos enteros en lugar de meras frases, lo mejor es que crees también ejemplos con párrafos.

Si no tiene acceso a un modelo GPT, puede simplemente utilizar la API de NLP Cloud. Hay varios clientes disponibles (Python, Go, Node.js, Ruby, PHP...). Vamos a mostrar un ejemplo aquí usando GPT-J con el cliente Python:

import nlpcloud

client = nlpcloud.Client("gpt-j", "your API token", gpu=True)
client.generation("""Extract job titles from the following sentences.

    Sentence: John Doe has been working for Microsoft for 20 years as a Linux Engineer.
    Job title: Linux Engineer
    ###
    Sentence: John Doe has been working for Microsoft for 20 years and he loved it.
    Job title: none
    ###
    Sentence: Marc Simoncini | Director | Meetic
    Job title: Director
    ###
    Sentence: Franck Riboud was born on 7 November 1955 in Lyon. He is the son of Antoine Riboud, who transformed the former European glassmaker BSN Group into a leading player in the food industry. He is the CEO at Danone.
    Job title: CEO
    ###
    Sentence: Damien is the CTO of Platform.sh, he was previously the CTO of Commerce Guys, a leading ecommerce provider.
    Job title:""",
top_p=0.1,
length_no_input=True,
remove_input=True,
end_sequence="###",
remove_end_sequence=True
)

El resultado será: CTO

Permítame darle una explicación rápida sobre los parámetros de generación de texto que acabamos de utilizar.

Establecemos un valor p superior muy bajo porque no queremos que GPT-J cree resultados demasiado originales: sólo queremos que se ciña a lo que vio en su solicitud.

"length_no_input" significa que el valor de la longitud máxima no debe tener en cuenta el texto de entrada.

"remove_input" significa que el texto de entrada debe ser eliminado del resultado.

"end_sequence" significa que cuando el modelo se encuentra con este carácter, debe dejar de generar texto. Como en nuestros ejemplos de pocos disparos añadimos "###" al final de cada respuesta, el modelo generará automáticamente "###" después de generar la respuesta y se detendrá ahí.

"remove_end_sequence" significa que queremos eliminar "###" de la respuesta.

Puede ver más detalles en la documentación de NLP Cloud: véalo aquí.

Consideraciones sobre el rendimiento

Realizar la extracción de entidades con un modelo GPT da mucha libertad, ya que se puede extraer cualquier entidad nueva sobre la marcha, aunque el modelo no haya sido entrenado para ello.

Sin embargo, tiene un coste: estos grandes modelos lingüísticos son enormes y relativamente lentos.

Por ejemplo, si quieres usar GPT-J o GPT-NeoX necesitarás una GPU enorme con mucha VRAM como una NVIDIA RTX A6000 o A40. Y habrá cierta latencia (extraer una entidad tarda unos 500ms). Por el contrario, spaCy o NLTK serán mucho más rápidos y menos costosos desde el punto de vista de la infraestructura.

Conclusión

En 2022, será posible realizar un NER avanzado de forma muy sencilla sin necesidad de anotación ni formación. Esto ayudará en gran medida a las empresas a entregar sus proyectos de extracción de entidades con mayor rapidez, y también permite realizar más aplicaciones de vanguardia basadas en el procesamiento del lenguaje natural.

Sin embargo, los modelos lingüísticos de gran tamaño, como GPT-3, GPT-J y GPT-NeoX, son costosos, por lo que no hay que subestimar los costes de infraestructura que conllevan.

Espero que este artículo le ayude a ahorrar tiempo y dinero.

Julien Salinas
CTO en NLP Cloud