Многоязычный машинный перевод с Spark NLP

Испытайте мощный машинный перевод с помощью Spark NLP и многоязычных возможностей Python.

тл; Д.Р.: В этой статье вы узнаете, как масштабировать модель машинного перевода Marian с помощью Spark NLP в Python. В свободном доступе есть несколько предварительно обученных моделей, которые могут переводиться на многие языки и готовы к добавлению в ваши конвейеры обработки.

Нейронный машинный перевод — это возможность использовать алгоритмы или модели машинного обучения для автоматического перевода текстов с одного языка на другой. В этой статье мы расскажем о модели глубокого обучения Мариан и о том, как ее использовать в экосистеме Spark с библиотекой Spark NLP с открытым исходным кодом на Python.

Автоматический машинный перевод можно использовать во многих сценариях, включая возможность переводить веб-страницы с языков, которыми вы не владеете в совершенстве, на язык, которым вы владеете. Это также может повысить вашу производительность, адаптировав предыдущее содержимое на одном языке к другому и сэкономить время, чтобы написать его с нуля.

В следующих разделах мы расскажем о Spark NLP и о том, как использовать реализованный MarianTransformer для перевода текстов между языками.

Введение в Spark НЛП

Spark NLP — это библиотека с открытым исходным кодом, поддерживаемая John Snow Labs. Он построен на основе Apache Spark и Spark ML и предоставляет простые, эффективные и точные аннотации NLP для конвейеров машинного обучения, которые можно легко масштабировать в распределенной среде.

Чтобы установить Spark NLP, вы можете просто использовать любой менеджер пакетов, например condaили pip. Например, используя pip, вы можете просто запустить pip install spark-nlp. Различные варианты установки смотрите в официальной документации.

Spark NLP обрабатывает данные, используя Pipelines, структуру, которая содержит все шаги, которые необходимо выполнить для входных данных, так же, как это делает Spark ML.

Каждый этап конвейера создается аннотатором, который использует одну или несколько предыдущих данных для создания новой аннотации. Каждый аннотатор может быть двух типов: AnnotatorModel, который можно использовать для прогнозирования на основе предварительно обученных моделей, и AnnotatorApproach, который можно использовать для обучения новых пользовательских моделей. Предварительно обученные модели можно найти в Центре моделей НЛП.

В рамках экосистемы spark перед использованием библиотеки нам необходимо запустить сеанс spark, что можно сделать следующим образом:

import sparknlp


spark = sparknlp.start()

Теперь, когда вы знаете основы Spark NLP, давайте посмотрим, как переводить тексты!

📜 Фон

MarianMT — это эффективная бесплатная платформа нейронного машинного перевода, написанная на чистом C++ с минимальным количеством зависимостей. Он был разработан командой Microsoft Translator, и многие ученые (в первую очередь Эдинбургский университет, а в прошлом — Университет Адама Мицкевича в Познани) и коммерческие участники помогают в его разработке.

Модель основана на архитектуре преобразователей кодер-декодер и достигла отличных результатов. Он по-прежнему является ядром инструмента Microsoft Translate. В Spark NLP модель реализуется аннотатором MarianTransformer, а на NLP Models Hub доступно более трехсот предварительно обученных моделей.

В настоящее время модели могут выполнять переводы между английским и более чем 150 другими языками и диалектами. Английский используется в качестве моста между языками, потому что это язык с наибольшим количеством ресурсов для обучения моделей, а также самый надежный. Используя эти модели в конвейерах, мы можем получить переводы для большинства приложений.

Давайте посмотрим, как их использовать!

⚒️ Настройка и импорт библиотек

Во-первых, давайте импортируем необходимые аннотаторы и классы и запустим сеанс 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 и Pipeline создают конвейеры обработки для выполнения аннотаторов в некоторой последовательности. DocumentAssembler преобразует необработанные тексты в DOCUMENT аннотации, SentenceDetectorDLModel разбивает документы на предложения, а MarianTransformer переводит предложения.

Аннотатор переводчика имеет несколько параметров, которые стоит пояснить:

  • langId: Код языка (например, 'en', 'fr', 'pt', 'tr' и т. д.) для языка ввода многоязычных моделей, которые принимают в качестве ввода множество языков. (По умолчанию: '')
  • maxInputLength: контролирует максимальную длину токенизированной входной последовательности (исходный язык SentencePieces), по умолчанию 40.
  • maxOutputLength: управляет максимальной длиной выходной последовательности (тексты на целевом языке), по умолчанию 40. Если этот параметр меньше maxInputLength, вместо него будет использоваться maxInputLength, то есть максимальная длина вывода будет максимальным значением между maxInputLength и maxOutputLength. параметры.

Модель по умолчанию — "opus_mt_en_fr", язык по умолчанию — «xx» (что означает многоязычность), если значения не указаны, и любой параметр можно установить с помощью соответствующего метода set в CamelCase. Например, мы можем установить максимальную длину ввода языка на 100:

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

Теперь давайте запустим некоторую модель в примерах предложений. Сначала мы переведем английский на французский, используя модель по умолчанию.

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)
)

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.    |
+-------------------------------------+

Мы видим, что предложения были разделены SentenceDetectorDLModel, и мы оба перевели на французский язык. Теперь давайте посмотрим, как использовать многоязычную модель для перевода примерного предложения с турецкого на английский. Мы будем использовать модель opus_mt_mul_en (xx означает мультиязычность):

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

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

Давайте отправим пример предложения во фрейм данных искры, чтобы использовать в нем модель:

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)

Получение перевода:

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

Использование с LightPipeline

  • LightPipeline – это специальный класс Pipeline Spark NLP, эквивалентный Spark ML Pipeline. Разница в выполнении не соответствует принципам Spark, вместо этого он вычисляет все локально (но параллельно), чтобы добиться более быстрого вывода при работе с меньшими объемами данных. Это означает, что нам нужно не фрейм данных Spark, а вместо этого строку или массив строк для аннотирования. Чтобы создать LightPipelines, вам нужно ввести уже обученный (подходящий) Spark ML Pipeline.
  • Этап transform() вместо этого преобразуется в annotate() или fullAnnotate().

Давайте создадим конвейер с MarianTransformer, запустим его с LightPipeline и посмотрим на результаты с примером текста. На этот раз мы будем использовать модель для перевода с итальянского на английский.

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)

Сначала мы используем метод .fullAnnotate() для получения переводов и сохранения объектов аннотаций. Вывод выполняется непосредственно в строке без необходимости создания фрейма данных искры. Выходной формат представляет собой список словарей, содержащих аннотации.

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'}

Если метаданные, присутствующие в объектах аннотаций, не имеют отношения к вашему приложению, вы можете использовать метод .annotate() для получения только .result части аннотаций:

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.

Примечание 1. Мы использовали аннотатор SentenceDetectorDL, чтобы разделить текст на предложения. Это необязательно, так как модель также может переводить полные тексты (не забудьте соответствующим образом установить maxInputLength).

Примечание 2. В некоторых случаях может потребоваться сначала определить язык ввода, а затем применить переводчик, связанный с этим языком. Для этого сценария можно использовать другой аннотатор под названием LanguageDetectorDL, который основан на архитектуре глубокого обучения для идентификации более двухсот языков.

Заключение

Мы представили аннотатор MarianTransformer в Spark NLP и показали, как выполнять задачи нейронного машинного перевода в экосистеме spark, которые можно легко масштабировать. Модель MarianMT обеспечивает отличные результаты при переводе между многими языками, а благодаря количеству предварительно обученных моделей большинство приложений NMT можно реализовать в Spark NLP.

🔗 Ссылки: