Traducción automática multilingüe con Spark NLP

📜 Fondo

MarianMT es un marco de trabajo de traducción automática neuronal eficiente y gratuito escrito en C++ puro con dependencias mínimas. Fue desarrollado por el equipo de Microsoft Translator y muchos académicos (sobre todo la Universidad de Edimburgo y en el pasado la Universidad Adam Mickiewicz en Poznań) y colaboradores comerciales ayudaron con su desarrollo.

El modelo se basa en una arquitectura de transformadores codificadores-decodificadores y logró excelentes resultados. Sigue siendo el núcleo de la herramienta Traductor de Microsoft. En Spark NLP, el modelo es implementado por el MarianTransformer annotator y hay más de trescientos modelos preentrenados disponibles en NLP Models Hub.

Actualmente, los modelos pueden realizar traducciones entre el inglés y más de 150 otros idiomas y dialectos. El inglés se utiliza como puente entre idiomas porque es el idioma con más recursos para entrenar modelos, y también el más confiable. Mediante el uso de estos modelos en tuberías, podemos obtener traducciones para la mayoría de las aplicaciones.

¡Veamos cómo usarlos!

También te puede interesar“Susurro: liberando el potencial de la PNL para empoderar a los lectores”

⚒️ Bibliotecas de configuración e importación

Primero, importemos los anotadores y las clases necesarios e iniciemos la sesión de Spark.

import sparknlp
from sparknlp.base import LightPipeline, Pipeline, DocumentAssembler
from sparknlp.annotator import SentenceDetectorDLModel, MarianTransformer
from pyspark.sql import functions as F

# Start the spark session
spark = sparknlp.start()

LightPipeline y Pipeline crear canalizaciones de procesamiento para ejecutar los anotadores en alguna secuencia. DocumentAssembler transforma textos en bruto en DOCUMENT anotaciones, SentenceDetectorDLModel divide los documentos en oraciones y el MarianTransformer traduce las oraciones.

El anotador del traductor tiene algunos parámetros que vale la pena explicar:

También te puede interesarCómo aprender SQL en 2023: una guía completa para principiantes
  • langId: el código de idioma (p. ej., «en», «fr», «pt», «tr», etc.) para el idioma de entrada de los modelos multilingües que aceptan muchos idiomas como entrada. (Por defecto: «»)
  • maxInputLength: controla la longitud máxima de la secuencia de entrada tokenizada (SentencePieces del idioma de origen), por defecto 40.
  • maxOutputLength: Controla la longitud máxima de la secuencia de salida (textos en el idioma de destino), por defecto 40. Si este parámetro es menor que maxInputLengthentonces maxInputLength se usará en su lugar, lo que significa que la longitud máxima de salida será el valor máximo entre maxInputLength y maxOutputLength parámetros

El modelo predeterminado es "opus_mt_en_fr"el idioma predeterminado es «xx» (lo que significa que es multilingüe), si no se proporcionan valores, y cualquier parámetro se puede establecer mediante el correspondiente set método en CamelCase. Por ejemplo, podemos establecer la longitud máxima de entrada del idioma en 100:

marian_model = MarianTransformer.pretrained().setMaxInputLength(100)

Ahora vamos a ejecutar algún modelo en oraciones de ejemplo. Primero, traduciremos del inglés al francés utilizando el modelo predeterminado.

documentAssembler = DocumentAssembler().setInputCol("text").setOutputCol("document")

sentence = (
SentenceDetectorDLModel.pretrained("sentence_detector_dl", "xx")
.setInputCols("document")
.setOutputCol("sentence")
)

marian = (
MarianTransformer.pretrained()
.setInputCols("sentence")
.setOutputCol("translation")
.setMaxInputLength(30)
.setMaxOutputLength(30)
)

También te puede interesar¡Lo último en IA: AutoGPT, Wonder Dynamics y más!

pipeline = Pipeline().setStages([documentAssembler, sentence, marian])

data = spark.createDataFrame(
[["What is the capital of France? We should know this in french."]]
).toDF("text")

result = pipeline.fit(data).transform(data)
result.selectExpr("explode(translation.result) as translation").show(truncate=False)
+-------------------------------------+
|translation |
+-------------------------------------+
|Quelle est la capitale de la France ?|
|On devrait le savoir en français. |
+-------------------------------------+

Podemos ver que las oraciones fueron divididas por el SentenceDetectorDLModel y ambos hemos traducido al francés. Ahora, veamos cómo usar un modelo multilenguaje para traducir una oración de ejemplo del turco al inglés. Usaremos el opus_mt_mul_en modelo (xx significa multilenguaje):

marian = (
MarianTransformer.pretrained("opus_mt_mul_en", "xx")
.setInputCols("document")
.setOutputCol("translation")
.setLangId("tr")
)

pipeline = Pipeline().setStages([documentAssembler, sentence, marian])

También te puede interesarCree un ChatGPT con sus datos privados usando LlamaIndex y MongoDB

Enviemos una oración de ejemplo a un marco de datos de chispa para usar el modelo en él:

data = spark.createDataFrame(
[["Bu adam 50 yaşında ve çok çalışkan"]]
).toDF("text")

result = pipeline.fit(data).transform(data)
result.selectExpr("explode(translation.result) as translation").show(truncate=False)

Obtención de la traducción:

+-----------------------------------------------+
|translation |
+-----------------------------------------------+
|This guy is 50 years old and working very hard.|
+-----------------------------------------------+

Uso con LightPipeline

  • Canalización de luz es una clase de Pipeline específica de Spark NLP equivalente a Spark ML Pipeline. La diferencia con la ejecución no se basa en los principios de Spark, sino que calcula todo localmente (pero en paralelo) para lograr una inferencia más rápida cuando se trata de cantidades menores de datos. Esto significa que no tenemos un marco de datos de Spark, sino una cadena o una matriz de cadenas para anotar. Para crear LightPipelines, debe ingresar un Spark ML Pipeline ya entrenado (ajustado).
  • Es transform() el escenario se convierte en annotate() o fullAnnotate() en cambio.

Vamos a crear una canalización con MarianTransformery ejecutarlo con LightPipeline y ver los resultados con un texto de ejemplo. Esta vez, usaremos un modelo para traducir del italiano al inglés.

text = """La Gioconda è un dipinto ad olio del XVI secolo creato da Leonardo. Si tiene al Louvre di Parigi."""
marian = (
MarianTransformer.pretrained("opus_mt_it_en", "xx")
.setInputCols(["sentences"])
.setOutputCol("translation")
)
nlp_pipeline = Pipeline(stages=[documentAssembler, sentencerDL, marian])

empty_df = spark.createDataFrame([['']]).toDF('text')
pipeline_model = nlp_pipeline.fit(empty_df)

lmodel = LightPipeline(pipeline_model)

Primero usamos el .fullAnnotate() método para obtener las traducciones y mantener los objetos de anotación. La inferencia se realiza directamente en la cadena, sin necesidad de crear un marco de datos de chispa. El formato de salida es una lista de diccionarios que contienen las anotaciones.

res = lmodel.fullAnnotate(text)
for i, sentence in enumerate(res[0]['translation']):
print(f"Translation of sentence {i}:")
print (f"\t{sentence.result}")
print("Metadata:\n")
print(f"\t{sentence. Metadata}")
Translation of sentence 0:
La Gioconda is an oil painting of the sixteenth century created by Leonardo.
Metadata:

{'sentence': '0'}
Translation of sentence 1:
It's held at the Louvre in Paris.
Metadata:

{'sentence': '1'}

Si los metadatos presentes en los objetos de anotación no son relevantes para su aplicación, entonces puede usar el .annotate() método para obtener la .result parte de las anotaciones solamente:

res = lmodel.annotate(text)
print('Translated:\n')
for sentence in res['translation']:
print(sentence)
Original: La Gioconda è un dipinto ad olio del XVI secolo creato da Leonardo. Si tiene al Louvre di Parigi. 

Translated:

La Gioconda is an oil painting of the sixteenth century created by Leonardo.
It's held at the Louvre in Paris.

Nota 1: usamos el SentenceDetectorDL anotador para dividir los textos en oraciones. Esto es opcional ya que el modelo también puede traducir textos completos (recuerde configurar el maxInputLength respectivamente).

Nota 2: En algunos casos, puede estar interesado en detectar primero el idioma de entrada para luego aplicar el traductor asociado a ese idioma. Para este escenario, es posible usar otro anotador llamado LanguageDetectorDL que se basa en una arquitectura de aprendizaje profundo para identificar más de doscientos idiomas.

Conclusión

presentamos el MarianTransformer anotador en Spark NLP y mostró cómo realizar tareas de traducción automática neuronal en el ecosistema de chispa que podría escalarse fácilmente. El MarianMT El modelo logra excelentes resultados en la traducción entre muchos idiomas, y con la cantidad de modelos preentrenados, la mayoría de las aplicaciones NMT se pueden implementar en Spark NLP.

🔗 Referencias:

Scroll al inicio