Контекст
Я использую MarianMT von Huggingface через Python для перевода текста из источника на целевой язык.
Ожидаемое поведение
Я ввожу последовательность в модель MarianMT и получаю обратно эту последовательность. Для этого я использую соответствующую языковую модель и токенизатор. Все предложения, которые я ввожу, также возвращаются. Предложения рассматриваются как последовательность.
Текущее поведение
В зависимости от языковой модели модель не переводит все, а возвращает только части. В этом примере отсутствует последнее предложение:
Оригинал (немецкий): Ein Nilpferd Lief im Dschungel rum und musste aufs WC. Da traf es einen Kakadu und fragte nach dem Weg. Der sagte wenn du Kaka musst, dann pass mal ganz kurz auf. Ich sag dir wo du hanghen musst, ich kenn mich hier gut aus.
Результат (на английском языке): Бегемот бегал по джунглям и должен был сходить в туалет. Там был какаду и спросил дорогу. Он сказал, что если вам нужно Кака, то поосторожней минутку. Я скажу вам, куда вам нужно идти, я знаю дорогу здесь.
Результат (голландский): Een nijlpaard liep rond in de Jungle en moest naar het Toilet... en een kaketoe vroeg naar de weg... die zei dat als je Kaka moest, ik even moest oppassen.
Текущий код
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
def translate_text(input, source, target):
# Prepare output
output = ""
model = AutoModelForSeq2SeqLM.from_pretrained("Helsinki-NLP/opus-mt-" + source + "-" + target)
tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-" + source + "-" + target)
inputs = tokenizer.encode(input[:512], return_tensors = "pt", padding='longest')
outputs = model.generate(inputs, max_length=4000, num_beams=4, early_stopping=True)
for t in [tokenizer.convert_ids_to_tokens(s) for s in outputs.tolist()[0]]:
output = output + t.replace("▁", " ").replace("</s>", "")
output.replace("<pad>", "")
return output
print(translate_text("Ein Nilpferd lief im Dschungel rum und musste aufs WC. Da traf es einen Kakadu und fragte nach dem Weg. Der sagte wenn du Kaka musst, dann pass mal ganz kurz auf. Ich sag dir wo du hingehen musst, ich kenn mich hier gut aus.", "de", "nl"))
print(translate_text("Ein Nilpferd lief im Dschungel rum und musste aufs WC. Da traf es einen Kakadu und fragte nach dem Weg. Der sagte wenn du Kaka musst, dann pass mal ganz kurz auf. Ich sag dir wo du hingehen musst, ich kenn mich hier gut aus.", "de", "en"))
Нужна помощь
Что мне не хватает? Почему некоторые части последовательности отсутствуют?
Спасибо, что указали на опечатку, которую я исправил выше. Но это не меняет описанного поведения!
Вы знаете, как Opus MT сегментировал обучающие данные? Видела ли модель такие последовательности при обучении?
Насколько я знаю, это приговор-предложение. Это означает, что модель на самом деле не знает о других последовательностях предложений. Но если я разделю предложения до того, как переведу их, я потеряю важный для перевода контекст!
Когда я разделяю предложения, он работает, как и ожидалось. Но я потеряю контекст следующим образом: ['Er liep een nijlpaard rond in de jungle en hij moest naar het Toilet.', 'Toen ontmoette hij een kaketoe en vroeg naar de weg.', 'Hij zei dat als je Kaka moest, je even moet opletten.', 'Ik vertel je waar je heen moet. Ik ken het hier пошел».]
Если модель не была обучена контексту, то она все равно не будет знать, что с ней делать.
В этом случае вы можете перевести его через английский язык:
de_en = translate_text("Ein Nilpferd lief im Dschungel rum und musste aufs WC. Da traf es einen Kakadu und fragte nach dem Weg. Der sagte wenn du Kaka musst, dann pass mal ganz kurz auf. Ich sag dir wo du hingehen musst, ich kenn mich hier gut aus.", "de", "en")
en_nl = translate_text(de_en, "en", "nl")
print(en_nl)
Результат: Een nijlpaard rende rond в джунглях в самом большом туалете. Er was een kaketoe en vroeg om de weg. Hij zei als je moet Kaka, dan uitkijken voor een minuut. Ik zal je vertellen waar je moet gaan, Ik weet mijn weg hier.
Последнее предложение не исчезло, но качество ниже. Вероятно, модели De->En и En->Nl имели в своих обучающих данных гораздо более длинные предложения (мало ли), чем De->Nl, и поэтому последнее предложение не исчезло из перевода. Но в то же время перевод на английский может привести к некоторой потере информации (например, du/Sie -> you).
Учитывая название модели (обученной на корпусе OPUS), насколько большими теоретически могут быть предложения, вы можете посмотреть здесь: http://opus.nlpl.eu/Europarl/v8/de-nl_sample.html или здесь: ️ 🔁 http://opus.nlpl.eu/MultiParaCrawl/v7.1/de-nl_sample.html; или в других образцах de-nl на opus.nlpl.eu
Более подробная информация доступна здесь: https://github.com/Helsinki-NLP/Opus-MT
tl;dr Тот факт, что эти модели переводят несколько склеенных вместе предложений, скорее всего, является просто побочным эффектом, на который не следует полагаться.
Что произойдет, если вы попробуете это с
"Ein Nilpferd ...
вместо"in Nilpferd ...
?