Woche 7 - mkappus1/DatenmanagementMTHS24 GitHub Wiki

Woche 7: Vorverarbeitung paralleler Korpora für das Training neuronaler Maschinenübersetzungssysteme.

1. Einleitung

In dieser Woche werden wir uns mit den verschiedenen Schritten der Korpusvorverarbeitung für das Training von statistischen und neuronalen maschinellen Übersetzungssystemen beschäftigen. Obwohl der Schwerpunkt des Seminars auf neuronaler maschineller Übersetzung liegt, gibt es einige Vorverarbeitungsschritte, die für beide Arten von Systemen gleich sind. Ein wichtiger Aspekt, den Sie beachten sollten, ist, dass die Vorverarbeitung nicht einheitlich ist und dass man aus einer Vielzahl von Optionen wählen kann, indem man einige der Schritte nach eigenen Bedürfnissen anpasst und ausführt. In den Materialien dieser Woche gibt es einen theoretischen Teil (Abschnitt 3) mit einigen Beispielen, den Sie sorgfältig lesen und befolgen sollten, um den praktischen Teil zu verstehen.

Hinweis: In diesem Block gibt es weniger praktische Übungen und Aufgaben, dafür etwas mehr zu lesen.

2. Empfohlene Lektüre

Bitte lesen Sie aus dem Buch Machine translation for everyone: Empowering users in the age of artificial intelligence (herausgegeben von Dorothy Kenny) den Abschnitt 4 Customization in practice aus dem Kapitel Custom machine translation (von Gema Ramírez-Sánchez)

Im Kurs der UOC wird folgende (etwas technischere) die Lektüre von Sentencepiece empfohlen, einem der am weitesten verbreiteten Algorithmen zur Korpusvorverarbeitung für das Training neuronaler Maschinenübersetzungssysteme. Kudo, T., & Richardson, J. (2018). SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing. In Proceedings of the 2018 Conference on Empirical Methods in Natural Language Processing: System Demonstrations (S. 66-71).

3. Allgemeine Vorverarbeitungsschritte

Hier im Abschnitt 3 werden typische Vorverarbeitungsschritte für parallele Korpora im Hinblick auf das Training neuronaler Maschinenübersetzungssysteme vorgestellt (die meisten Konzepte werden auch im ober erwähnten Abschnitt "Customization in practice" erläutert, es lohnt sich auch diese Darstellung zu lesen). Diese Schritte werden einzeln erklärt und teilweise anhand kleiner Beispieldateien veranschaulicht. Die eigentliche Korpusvorbereitung an einem grösseren Korpus werden dann im Abschnitt 4 durchgeführt. Versuchen Sie die kleinen Übungen hier nachzuspielen, die resultierenden Dateien werden aber später nicht gebraucht.

3.1 Tokenisierung

Die Tokenisierung besteht darin, den Eingabetext in lexikalische Einheiten zu zerlegen.

Eine Einführung zum Thema Tokenisierung finden Sie im Exkurs zur Tokenisieung

Das MTUOC-Projekt bietet Tokenisierer für mehrere Sprachen an:

  • Aragonesisch (arg)
  • Asturisch (ast)
  • Katalanisch (cat)
  • Deutsch (deu)
  • Englisch (eng)
  • Französisch (fra)
  • Galicisch (gal)
  • Kroatisch (hrv)
  • Italienisch (ita)
  • Portugiesisch (por)
  • Russisch (rus)
  • Sardisch (srd)
  • Spanisch (spa)

Es gibt auch einen generischen Tokenisierer (gen), der für andere Sprachen verwendet werden kann, bis ein spezifischer Tokenisierer entwickelt wird. Ausserdem bietet es einen Pseudo-Tokenisierer für Chinesisch (zho-pseudo), der einfach alle Zeichen in der Datei durch Leerzeichen trennt.

Die Tokenisierer des MTUOC-Projekts können unter https://github.com/mtuoc/MTUOC-tokenizers heruntergeladen werden. Oder direkt von folgenden Links:

Obwohl Tokenisierer normalerweise in Bash-Skripten verwendet werden, können sie auch direkt im Terminal benutzt werden. Sie können einen Satz tokenisieren, indem Sie folgendes eingeben:

echo "They're the teacher's best students." | python3 MTUOC_tokenizer_eng.py

und Sie erhalten dann:

They 're the teacher 's best students .

Sie können eine auch ganze Datei tokenisieren und sie an eine andere Datei senden, indem Sie den folgenden Befehl verwenden. python3 MTUOC_tokenizer_eng.py < input.txt > output.txt (für einen englischsprachige Datei)

Hier finden Sie Beispieldateien für Englisch, Deutsch und Italienisch:

  • wget https://raw.githubusercontent.com/mkappus1/DatenmanagementMTHS24/refs/heads/main/Woche%207/Tokenisierung-en.txt
  • wget https://raw.githubusercontent.com/mkappus1/DatenmanagementMTHS24/refs/heads/main/Woche%207/Tokenisierung-de.txt
  • wget https://raw.githubusercontent.com/mkappus1/DatenmanagementMTHS24/refs/heads/main/Woche%207/Tokenisierung-it.txt

Aufgabe 1: Führen Sie Tokenisierung der Beispieldateien auf Englisch und Deutsch oder Italienisch durch. Wie gehen die Tokenizer mit Anführungszeichen, Apostrophen, Bindestrichen und Satzzeichen um? Speichern Sie die entstandenen Dateien und Ihre Antwort auf die Frage.

Die Umkehrung von tokenize wird detokenize genannt:

echo "They 're the teacher 's best students ." | python3 MTUOC_tokenizer_eng.py detokenize

Das Ergebnis ist: They're the teacher's best students.

Sie können diese Operation auch für eine ganze Datei durchführen:

python3 MTUOC_tokenizer_eng.py detokenize < input.txt > output.txt (wieder für eine englishcsprachige Datei)

Aufgabe 2: Führen Sie die Detokenisierung an den Dateien mit den Ergebnissen der Tokenisierung durch. Wurden die Sätze wieder korrekt zusammengeführt? Laden Sie Ihre Ergebnisse und die aus Aufgabe 1 unter Aufgabe 1 & 2 auf Moodle hoch.

⚠️ ⚠️ ⚠️ Muss nicht bearbeitet werden

In der aktuellen Version sind verschiedene Tokenize- und Detokenize-Modi verfügbar:

  • tokenize / detokenize: normale Tokenisierung und Detokenisierung, wie in den Beispielen oben dargestellt.
  • tokenize_j / detokenize_j: Tokenisierung mit sogenannten Joiner-Flags und die entsprechende Detokenisierung.
echo "They're the teacher's best students." | python3 MTUOC_tokenizer_eng.py tokenize_j
They ■'re the teacher ■'s best students ■.
echo "They ■'re the teacher ■'s best students ■." | python3 MTUOC_tokenizer_eng.py detokenize_j
They're the teacher's best students.

Diese Tokenisierungsmarkierung erleichtert die anschliessende Detokenisierung. tokenize_jn / detokenize_jn: Tokenisierung mit „Joiner“-Marken und die Trennung der Ziffern von numerischen Ausdrücken und die entsprechende Detokenisierung:

echo „L'àvia ha guanyat 145.765 euros a la Loteria.“ | python3 MTUOC_tokenizer_cat.py tokenize_jn

L'■ àvia ha guanyat 1■ 4■ 5 ■.■ 7■ 6■ 5 euros a la Loteria ■.

echo „L'■ àvia ha guanyat 1■ 4■ 5 ■.■ 7■ 6■ 5 euros a la Loteria ■.“ | python3 MTUOC_tokenizer_cat.py detokenize_jn

L'àvia ha guanyat 145.765 euros a la Loteria.

tokenize_s/detokenizer_s/tokenize_sn/detokenize_sn: verwendet „Splitter“-Flags:

echo „L'àvia ha guanyat 145.756 euros a la Loteria.“ | python3 MTUOC_tokenizer_cat.py tokenize_sn L' àvia ▁ha ▁guanyat ▁1 4 5 . 7 5 6 ▁euros ▁a ▁la ▁Loteria .

⚠️ ⚠️ ⚠️

Aufgabe 😄 : Was bedeutet der Satz "L'àvia ha guanyat 145.765 euros a la Loteria."

3.2 Truecasing

⚠️ In diesem Abschnitt gibt es keine praktischen Beispiele und Übungen. ⚠️

Beim Truecasing werden jedem Token die Gross- und Kleinbuchstaben zugewiesen, die ihm entsprechen, unabhängig von der Position im Satz oder der Grossschreibung des Satzes. Um diese Operation durchzuführen, brauchen Sie zunächst ein Truecasing-Modell, das anhand von Wörterbüchern mit Wortformen und den Korpora selbst trainiert wird. Es ist wichtig, daran zu denken, dass die Gross- und Kleinschreibung nur für Sprachen sinnvoll ist, die Gross- und Kleinbuchstaben haben. Nur Sprachen, die die folgenden Alphabete verwenden, haben Gross- und Kleinbuchstaben:

  • Armenisch
  • Kyrillisch
  • Griechisch
  • Latein

Daher wird bei den folgenden Sprachen NICHT zwischen Gross- und Kleinschreibung unterschieden (Liste übersetzt von https://www.quora.com/Which-languages-have-no-capitalized-letter):

  • Amharisch
  • Arabisch
  • Assamisch
  • Aserbaidschanisch
  • Brahui
  • Balinesisch
  • Baluchi
  • Batak (Toba)
  • Baybayin
  • Bengalisch
  • Bolen
  • Birmanisch
  • Chinesisch
  • Georgisch
  • Gujarati
  • Gurmuji
  • Hebräisch
  • Hindi
  • Japanisch
  • Kannada oder Kannada
  • Kashmiri
  • Khmer
  • Koreanisch
  • Kurdisch
  • Laotisch
  • Lontara
  • Malayalam
  • Mittleres Brahmi
  • Hass
  • Paschtu
  • Persisch
  • Punjabi
  • Sindhi
  • Singhalesisch
  • Sundanisch
  • sylheti
  • Tamilisch
  • Telugu
  • Thailändisch
  • Tibetisch
  • tigré
  • Tigrinya
  • tirhuta
  • Urdu
  • Uyghurisch
  • Jiddisch

Der Truecasing-Prozess wird normalerweise in zwei Schritten durchgeführt: das Training eines Truecasing-Modells und das Truecasing des Korpus oder Satzes. Das MTUOC-Projekt stellt Programme sowohl für das Training des Modells als auch für das Truecasing zur Verfügung. Wir werden diese Programme später in den Skripten zur Vorverarbeitung des Korpus verwenden. Wenn wir zum Beispiel eine Überschrift haben wie:

Once again, Spring will arrive in Barcelona this year (wobei aus stilistischen Gründen der erste Buchstabe gross geschrieben wurde).

Der entsprechende Satz mit richtiger Grossschreibung lautet: Once again, spring will arrive in Barcelona this year

Das Gegenteil davon ist die Detruecasing, bei der in der Regel nur das erste Wort des Satzes grossgeschrieben wird (wenn die orthotypografischen Regeln der betreffenden Sprache dies erfordern). Es ist jedoch sehr wichtig zu beachten, dass die Regeln für die Grossschreibung von der jeweiligen Sprache abhängen. Im Deutschen werden zum Beispiel alle Substantive mit dem ersten Buchstaben grossgeschrieben, während dies in vielen anderen Sprachen nur bei Eigennamen der Fall ist.

Das Verfahren des Truecasing ist beim Training statistischer Systeme sehr verbreitet. Bei neuronalen Systemen, die den Algorithmus SentencePiece verwenden (einen Algorithmus, auf den wir später noch eingehen werden), ist die Gross-/Kleinschreibung (das Truecasing) optional, da der SentencePiece-Algorithmus selbst in der Lage ist, viele Gross- und Kleinbuchstaben zu verarbeiten. Es ist wichtig, dass wir die Gross- und Kleinschreibung sowohl auf den Trainingskorpus anwenden, bevor wir das System trainieren, als auch, wenn das trainierte System läuft, um den Eingabesatz für das System zu korrigieren und den übersetzten Ausgabesatz zu entzerren.

3.3 Behandlung von numerischen Ausdrücken

⚠️ In diesem Abschnitt gibt es keine praktischen Beispiele und Übungen. ⚠️

Numerische Ausdrücke müssen sowohl in statistischen als auch in neuronalen Systemen besonders behandelt werden. Es ist zu bedenken, dass es eine unendliche Anzahl verschiedener numerischer Ausdrücke gibt, so dass es unmöglich wäre, die Übersetzung jedes einzelnen zu lernen. Die Strategie für die Verarbeitung numerischer Ausdrücke ist für statistische und neuronale Systeme unterschiedlich:

  • Statistische Systeme: Numerische Ausdrücke werden in den Trainingskorpora und in den vom System zu übersetzenden Sätzen durch einen Code (@NUM@) ersetzt und in den übersetzten Sätzen wiederhergestellt.
  • Neuronale Systeme: Die Ziffern in numerischen Ausdrücken werden im Trainingskorpus und in den zu übersetzenden Sätzen durch Leerzeichen getrennt. Nach Erhalt einer Übersetzung werden die Leerzeichen zwischen den Ziffern entfernt. 2010 ▶️ 2■0■1■0 ▶️ 2010

3.4. Verarbeitung von E-Mails und URLs

Diese beiden Elemente, E-Mails und URLs, sind in der Regel nicht übersetzbar und erfordern eine besondere Behandlung. Sie werden normalerweise sowohl im Trainingskorpus als auch im zu übersetzenden Satz durch Codes ersetzt und nach der Übersetzung des Satzes durch die entsprechenden Originale wiederhergestellt:

  • Ersetzen von E-Mails durch einen Code (standardmässig @EMAIL@).
  • Ersetzen von URLs durch einen Code (standardmässig @URL@).

Aufgabe 3: Laden Sie das Skript emailUrlsErstzen.py mit dem Befehl wget https://github.com/mkappus1/DatenmanagementMTHS24/raw/refs/heads/main/Woche%207/emailUrlsErstzen.py herunter. Testen Sie es an den Dateien:

Die Syntax lautet python3 emailUrlsErstzen.py eingabedatei.txt ausgabedatei.txt Wurden die richtigen E-Mail-Adressen und URLS ersetzte? Fallen Ihnen andere mögliche Problemfälle ein? Laden Sie die resultierende Datei und Ihre Überlegungen unter Aufgabe 3 auf Moodle hoch..

⚠️ Ähnliche Strategien lassen sich auch auf andere nicht zu übersetzende Elemente anwenden.

3.5. Unterwörter

3.5.a. Einführung

Die ersten neuronalen Systeme hatten ein grosses Problem mit der Erweiterung des Vokabulars, das heisst, mit der Anzahl unterschiedlicher Wörter (genauer gesagt mit Formen, also flektierten oder deklinierten Wörtern), die sie übersetzen konnten. Da jedes Wort (genauer gesagt jede Form) in einen Vektor umgewandelt wird und das System mit diesen Vektoren arbeitet, war die Anzahl der Wörter begrenzt. Wenn die mögliche Anzahl an Wörtern sehr gross war, benötigte das System viel Speicher, um zu arbeiten, und wenn sie klein war, war die Anzahl der unbekannten Wörter zu gross.

Mit diesen Systemen kam es häufig vor, dass ein Satz wie „I spent my holidays in Spain“ in einem System, das „Spain“ nicht in seinem Wörterbuch hatte, dafür aber z.B. das Wort. „France“, so übersetzt wurde: „He pasado mis vacaciones en Francia“. Eine Strategie, die angewendet wurde, bestand darin, unbekannte Wörter durch eine Markierung wie <unk> zu ersetzen. Der Ausgangssatz wurde also zu „I spent my holidays in “, und die Übersetzung lautete dann „He pasado mis vacaciones en “. Nachdem die Übersetzung erstellt wurde, wurde das ursprüngliche unbekannte Wort in der Übersetzung wiederhergestellt, entweder direkt, sodass der Satz „He pasado mis vacaciones en Spain.“ lautete, oder durch eine Abfrage in einem Wörterbuch. Wenn das Wörterbuch z. B. die Übersetzung „Spain–España“ enthielt, ergab sich die korrekte Übersetzung: „He pasado mis vacaciones en España.“

Seit einigen Jahren ist die am weitesten verbreitete Strategie zur Lösung des Vokabularproblems die Arbeit mit Unterwörtern (Subwords), also mit Wortfragmenten. Auf diese Weise werden häufig verwendete Wörter (genauer gesagt Formen) vollständig verwendet, während weniger häufige Wörter in häufigere Fragmente zerlegt werden. So können alle Wörter dargestellt werden, sei es in vollständiger Form oder in Fragmenten. Das System übersetzt Wörter und Unterwörter, was zu einer Übersetzung mit vollständigen Wörtern und Unterwörtern führt. Am Ende des Prozesses werden die Fragmente der übersetzten Unterwörter zusammengefügt.


Hier ein kleines Beispiel:

Angenommen, Sie haben einen Satz in einem Trainingskorpus für maschinelle Übersetzung:

Englisch: "I am enjoying the unpredictability of this novel."

Deutsch: "Ich geniesse die Unvorhersehbarkeit dieses Romans."

Das Problem ist, dass Wörter wie unpredictability oder Unvorhersehbarkeit selten vorkommen und möglicherweise nicht im Vokabular des Modells enthalten sind. Das führt zu schlechten Übersetzungsergebnissen, weil das Modell sie als unbekannt (<unk>) markiert oder falsch verarbeitet.

Schritt 1: Subword-Segmentierung Mit einem Algorithmus wie Byte Pair Encoding (BPE) oder SentencePiece wird das Vokabular in kleinere, häufig vorkommende Wortbestandteile (Subwords) zerlegt. Dabei werden häufige Wortteile erkannt und separat behandelt.

Beispiel mit Byte Pair Encoding:

  1. Englischer Satz:

    • Original: "unpredictability"
    • Zerlegt: un + predict + able + ity
  2. Deutscher Satz:

    • Original: "Unvorhersehbarkeit"
    • Zerlegt: Un + vor + her + seh + bar + keit

Das Ergebnis:

  • Wörter werden in Subwords zerlegt, die auch in anderen Wörtern häufig vorkommen, z. B. predict in predictable, keit in Möglichkeit.

Schritt 2: Training mit Subwords

Das maschinelle Übersetzungsmodell wird jetzt nicht mehr auf ganzen Wörtern trainiert, sondern auf den Subwords. Dadurch:

  • Kann das Modell seltener Wörter besser verstehen, weil es deren Bestandteile kennt.
  • Wird das Vokabular kleiner, weil viele Subwords wiederverwendet werden können.

** Training-Daten nach Subword-Segmentierung:**

Englisch:
I am enjoy ing the un predict able ity of this novel .
Deutsch:
Ich geniess e die Un vor her seh bar keit dieses Romans .

Schritt 3: Übersetzung mit Subwords

Wenn das Modell später einen neuen Satz wie:

"She admired the unpredictability of life."

übersetzen soll, und "unpredictability" nicht im Wörterbuch steht, wird es trotzdem richtig segmentiert:

  • Zerlegt: un + predict + able + ity

Das Modell erkennt die Bestandteile und generiert eine Übersetzung:

"Sie bewunderte die Unvorhersehbarkeit des Lebens."

Schritt 4: Rekonstruktion des Satzes

Am Ende des Übersetzungsprozesses werden die Subwords wieder zusammengefügt, um lesbare Sätze zu erhalten.

  • Zwischenzustand (Subwords):
    Sie bewunderte die _Un vor her seh bar keit des Lebens_ .

  • Finaler Satz:
    Sie bewunderte die Unvorhersehbarkeit des Lebens.

Das Subword-Verfahren ist besonders nützlich für Sprachen mit komplexen Wortformen wie Deutsch oder Türkisch, da es flexibel auf Wortbestandteile wie Präfixe, Stämme und Suffixe eingehen kann.

Diejenigen, die ausprobieren wollen, wie Subword-Segementierung aussieht können diese freiwillige Übung zur Subword-Segmentierung machen.


Aufgabe 4: Gegeben ist der folgende Satz:

  • Englisch: unpredictable outcomes are unexpected.
  • Deutsch: Unvorhersehbare Ergebnisse sind überraschend.
  • Italienisch: Risultati imprevedibili sono sorprendenti.

Zerlegen Sie die Wörter in häufige Subwords (manuell oder mit Regeln). Orientieren Sie sich dich an folgenden Beispielen: * Zerlegen Sie Präfixe wie "un-", "vor-", "un-" "im-" (negierende Präfixe). * Zerlegen Sie häufige Suffixe wie "-able", "-keit", "-lich", "-ibili", "-ati".... * Erhalten Sie den Hauptstamm des Wortes. Geben Sie ihre ergebnisse in einem geeigneten formatunter Aufgabe 4 auf Moodle ab.

In den folgenden Abschnitten werden wir zwei Algorithmen betrachten, die zur Berechnung und Verwendung von Unterwörtern eingesetzt werden: subword-nmt und sentencepiece. Wie wir etwas später sehen werden, geht sentencepiece über die Berechnung und Verwendung von Unterwörtern hinaus und strebt an, ein universeller, unbeaufsichtigter Tokenizer und Detokenizer zu sein.

Die Schritte und Befehle in den Abschnitten 3.5.b und 3.5.c müssen Sie nicht selbst ausführen. es is wichtiger nachzuvollziehen, was mit den jeweiligen Algorithmen erreicht werden soll.

#####3.5.b. subword-nmt

Alle Details zu diesem Algorithmus finden Sie auf Github: https://github.com/rsennrich/subword-nmt

Es könnte auch interessant sein, den Artikel zu lesen: Sennrich, R., Haddow, B., & Birke, A. (2015). Neuronale maschinelle Übersetzung von seltenen Wörtern mit Teilworteinheiten. arXiv preprint arXiv:1508.07909.

Um subword-nmt zu verwenden, müssen Sie es zuerst installieren:

sudo pip3 install subword-nmt

Dann können Sie es benutzen, indem wir zuerst das trainierte Modell trainieren und dann anwenden (das müssen Sie hier nicht ausführen da wir es im praktischen Teil mit Skripten machen werden. subword-nmt learn-bpe -s {num_operations} < {train_file} > {codes_file} subword-nmt apply-bpe -c {codes_file} < {test_file} > {out_file}

Zum Beispiel für den Satz Turkey is discriminating against EU pharmaceuticals producers by forcing them to move production there .

Angenommen discriminating ist ein seltenes Wort im Korpus, dann würde der Algorithmus folgendes ergeben:

Turkey is discrimin@@ ating against EU pharmaceuticals producers by forcing them to move production there .

Wie wir sehen, wurden die weniger häufigen Wörter mit Hilfe des @@-Symbols aufgeteilt. Die ursprüngliche Segmentierung kann mit einer einfachen Ersetzung wiederhergestellt werden:

sed -r 's/(@@ )|(@@ ?$)//g'

Wenn wir also folgendes eingeben: echo "Turkey is discrimin@@ ating against EU pharmaceuticals producers by forcing them to move production there ." | sed -r 's/(@@ )|(@@ ?$)//g' Dann erhalten wir: Turkey is discriminating against EU pharmaceuticals producers by forcing them to move production there .

Wer dazu mehr wissen will sollte den Abschnitt „BEST PRACTICE ADVICE FOR BYTE PAIR ENCODING IN NMT“ im Github des Projekts lesen. Hier noch eine Faustregel wie Unterworteinheiten berechnet werden sollten:

  • für Sprachen, die dasselbe Alphabet verwenden: gleichzeitig (d. h. durch Verkettung der Korpora) für die Ausgangs- und die Zielsprache.
  • für Sprachen, die nicht dasselbe Alphabet verwenden: für jede Sprache separat.

Wichtig ist auch, dass bei der Verwendung von subword-nmt die Korpora tokenisiert und truecased werden müssen.

3.5.c. sentencepiece

Alle Details zu sentencepiece finden Sie auf Github: https://github.com/google/sentencepiece Um sentencepiece auf Ihrem Computer zu installieren, müssen Sie die folgenden Schritte ausführen:

sudo apt-get install cmake build-essential pkg-config libgoogle-perftools-dev
git clone https://github.com/google/sentencepiece.git
cd sentencepiece
mkdir build
cd build
cmake ..
make -j $(nproc)
sudo make install
sudo ldconfig -v
sudo pip3 install sentencepiece

Wichtig zu wissen ist, dass sentencepiece ein unüberwachter Tokenisierer und Detokenisierer ist und sowohl als Algorithmus zur Berechnung und Anwendung von Teilwörtern (subwords) als auch als einzelner Korpusprozessor verwendet werden kann, der weder Tokenisierung noch Truecasing benötigt. Wie die Autoren sagen: "SentencePiece ermöglicht es uns, ein reines End-to-End-System zu entwickeln, das nicht von sprachspezifischen Vor- und Nachbearbeitungen abhängig ist. * Es liegt also in unserem Ermessen wie weiter vorgegangen werden soll:

  • Tokenisierung und Truecasing vor der Anwendung von SentencePiece.
  • Nur sentencepiece verwenden.

Obwohl es keine allgemeingültige Regel gibt, um sich für die eine oder andere Option zu entscheiden, hier ein paar Tipps:

  • Wenn die zu übersetzenden Texte sehr frei in der Verwendung von grossgeschriebenen Sätzen sind (z. B. in Literatur, in der Kapitelüberschriften grossgeschrieben werden können), ist es besser, sich für Tokenisierung, Truecase und Sentencing zu entscheiden.
  • In Fällen, in denen die Verwendung von grossgeschriebenen Wörtern oder Sätzen auf einige wenige, sich wiederholende Fälle beschränkt ist (z. B. in offiziellen Zeitungstexten der Regierung), ist es besser, nur sentencepiece zu verwenden.

Um_sentencepiece_ auf den tokenisierten und True-Case-Korpus anzuwenden, würden sie folgende Befehle verwenden (⚠️ Sie brauchen diese Befehle nicht auszuführen): spm_train --input=corpus.true.en --model_prefix=spmodel-de --vocab_size=32000 --character_coverage=1.0 --model_type=bpe spm_encode --model=spmodel-en.model --output_format=piece <corpus100K.true.en> corpus.sp.en

Und die Ergebnisse würden ungefähr so aussehen: ▁the ▁us ▁liebt ▁ly n ch ings ▁, ▁besonders ▁von ▁the ▁air ▁, ▁wissend ▁dass ▁sie ▁sind ▁more ▁powerful ▁powerful ▁than ▁principles ▁.

Sie können das Verfahren auch ohne Vorverarbeitung auf das Korpus anwenden, und zwar mit den folgenden Befehlen (⚠️ Sie brauchen auch diese Befehle nicht auszuführen): ´´´ spm_train --input=corpus100K.en --model_prefix=spmodel-en --vocab_size=32000 --character_coverage=1.0 --model_type=bpe spm_encode --model=spmodel-en.model --output_format=piece < corpus100K.en> corpus100K.SP.en ▁The ▁US ▁loves ▁l yn ch ings , ▁especially ▁from ▁the ▁air , ▁knowing ▁that ▁they ▁are ▁more ▁powerful ▁than ▁principles . ´´´

Um einen Satz zu entschlüsseln, geben Sie folgendes ein: echo „The ▁US ▁loves ▁l yn ch ings , ▁especially ▁from ▁the ▁air , ▁knowing ▁that ▁they ▁are ▁are ▁more ▁powerful ▁powerful ▁than ▁principles .“ | spm_decode --model spmodel-de.model --input_format=piece und wir erhalten: The US loves lynchings, especially from the air, knowing that they are more powerful than principles.

In sentencepiece wird das gleiche Kriterium normalerweise auf die Verkettung der Korpora von Ausgangs- und Zielsprache angewendet. Es ist zu beachten, dass in der Praxis Teilworteinheiten berechnet werden:

  • für Sprachen, die dasselbe Alphabet verwenden: gleichzeitig (d. h. durch Verkettung der Korpora) für die Ausgangs- und die Zielsprache.
  • für Sprachen, die nicht das gleiche Alphabet verwenden: für jede Sprache separat.

3.6 Aufteilung des Korpus in train, val und eval

Das parallele Trainingskorpus wird in drei Fragmente unterteilt:

  • train: wird das Fragment sein, das zum Trainieren des Systems verwendet wird.
  • val: Das ist das Fragment, das in jeder Iteration von train verwendet wird.
  • eval: wird das Fragment sein, das verwendet wird, um das System nach dem Training zu bewerten.

Wie wir später sehen werden, kann diese Trennung mit dem Preprocessing-Skript vorgenommen werden. Es ist sehr wichtig, dass es in diesen drei Sub-Korpora keine gemeinsamen Segmente gibt. Daher ist es sehr ratsam, die sich wiederholenden Segmente aus unserem Korpus zu entfernen (wie wir es in den vergangenen Wochen gelernt haben), bevor wir die Vorverarbeitungsschritte durchführen.

4. MTUOC-Korpus-Vorverarbeitung

Die Vorverarbeitung des Korpus wird mit MTUOC-corpus-preprocessing durchgeführt: wget https://github.com/mtuoc/MTUOC-corpus-preprocessing.

Die Bedienung ist sehr einfach, denn wie Sie sehen werden, handelt es sich um ein Programm, das über eine YAML-Datei konfiguriert wird. Doch bevor Sie das Programm nutzen könnent, müssen Sie unbedingt die Voraussetzungen installieren, denen wir weiter unten einen Unterabschnitt widmen.

4.1. Voraussetzungen

Zusätzlich zu den Voraussetzungen von MTUOC-corpus-preprocessing.py, die wir etwas später sehen werden, benötigt das Programm eine ganze Reihe von Hilfsprogrammen, die sich in einem Verzeichnis auf Ihrem Computer befinden müssen. Sie können sich in einem beliebigen Verzeichnis befinden, aber wenn Sie unter Linux arbeiten, empfehle ich Ihnen, sie direkt im Stammverzeichnis des Systems abzulegen, und zwar in einem Verzeichnis namens MTUOC (d.h. in /MTUOC).

Alle diese Hilfsprogramme finden Sie im Repository https://github.com/mtuoc/MTUOC. Die Programme, die in diesem Repository enthalten sind, haben Anforderungen in der Datei requierements.txt. Um dieses Verzeichnis in das Stammverzeichnis (/) zu verschieben, können Sie -- wenn Sie Linux verwendeen , folgende Befehle verwenden:

git clone https://github.com/mtuoc/MTUOC.git sudo mv /MTUOC /

Wenn Sie auf einem Mac arbeiten, kopieren Sie vorher alle Dateien aus dem MacOs-Verzeichnis in das obere Verzeichnis, um die Linux-Binärdateien durch die Mac-Binärdateien zu ersetzen. Es ist ausserdem wichtig, dass Sie eine vollständige SentencePiece-Installation durchführen, wie unter https://github.com/google/sentencepiece beschrieben:

Das Python-Modul SentencePiece bietet einen Python-Wrapper, der sowohl das Training als auch die Segmentierung von SentencePiece unterstützt. Sie können das Python-Binärpaket von SentencePiece installieren mit.

  • pip install sentencepiece Für weitere Details siehe Python-Modul

Andere Optionen sind folgende, diese sollten Sie aber nicht benötigen: Erstellen und installieren Sie die SentencePiece Kommandozeilen-Tools aus dem C++-Quellcode Die folgenden Tools und Bibliotheken > werden benötigt, um SentencePiece zu erstellen:

  • cmake C++11-Compiler gperftools-Bibliothek (optional, 10-40% Leistungsverbesserung kann erreicht werden) Unter Ubuntu können die Build-Tools mit apt-get installiert werden:
  • % sudo apt-get install cmake build-essential pkg-config libgoogle-perftools-dev Dann kannst du die Kommandozeilentools wie folgt bauen und installieren.
  • % git clone https://github.com/google/sentencepiece.git % cd sentencepiece % mkdir build % cd build % cmake ... % make -j $(nproc) * % sudo make install % sudo ldconfig -v Unter OSX/macOS ersetze den letzten Befehl durch sudo update_dyld_shared_cache

4.2 Vorverarbeitung des Korpus

⚠️ Sie müssen diese Schritte nicht durchführen, können es aber natürlich gerne testen. ⚠️ Die Korpusvorverarbeitung wird mit dem Programm _MTUOC-corpus-preprocessing.py _durchgeführt. Dieses Programm wird mit der Datei config-corpus-preprocessing.yaml konfiguriert. YAML-Dateien sind Textdateien. Öffnen Sie sie mit einem guten Texteditor und bearbeiten Sie die notwendigen Felder.

grafik

Wenn Sie die Schritte an einem Korpus durchführen wollen, können Sie die folgenden Korpora benutzen.

  • med-en-de.txt
  • med-en-it.txt

Beide sind als ZIP dateien auf Moodle verfügbar. Es handelt sich dabei jeweils um die Verkettung des EMEA-Korpus mit dem alignierten BAG Korpus.

Nachfolgend zeige ich die Konfigurationsdatei und schreibe fett, was bearbeitet werden musst, und kursiv eine Erklärung zu jedem Feld MTUOC: /MTUOC Hier muss nicht geändert werden, WENN Sie die Hilfskomponenten in diesem Verzeichnis abgelegt haben, wenn nicht, geben Sie das Verzeichnis an. preprocess_type: sentencepiece

#eines von smt sentencepiece sentencepiece subwordnmt

Wir werden sentencepiece behalten

VERBOSE: True

LOG_FILE: process.log

DELETE_TEMP: True

corpus: corpus-medicine-eng-spa.txt Name unseres Korpus

from_train_val: False

train_corpus: train-eng-deu.txt

val_corpus: val-eng-deu.txt

valsize: 5000

evalsize: 5000

SLcode3: eng

SLcode2: en

TLcode3: deu

TLcode2: de

SL_DICT: /MTUOC/eng.dict

TL_DICT: /MTUOC/deu.dict

#state None oder null.dict wenn kein Wortformwörterbuch für diese Sprachen verfügbar ist

SL_TOKENIZER: MTUOC_tokenizer_eng.py

TOKENIZE_SL: False

TL_TOKENIZER: MTUOC_tokenizer_deu.py

TOKENIZE_TL: False

###PREPARATION

REPLACE_EMAILS: True

EMAIL_CODE: „@EMAIL@“

REPLACE_URLS: True

URL_CODE: „@URL@“

TRAIN_SL_TRUECASER: True

TRAIN_SL_TRUECASER_MAXLINES: 10000000

#-1 kein Limit

TRUECASE_SL: False

SL_TC_MODEL: auto

#if auto wird der Name tc.+SLcode2 sein

TRAIN_TL_TRUECASER: True

TRAIN_TL_TRUECASER_MAXLINES: 10000000

#-1 keine Begrenzung

TRUECASE_TL: False

TL_TC_MODEL: auto

#wenn auto wird der Name tc.+TLcode2 sein

CLEAN: False

MIN_TOK: 1

MAX_TOK: 80

MIN_CHAR: 1

MAX_CHAR: 1000

#SENTENCE PIECE und SUBWORD NMT

bos:

#oder Keine

eos:

#oder Keine

JOIN_LANGUAGES: True

WICHTIG: Wir setzen join_languages auf True, weil wir es in diesem Beispiel mit zwei Sprachen zu tun haben, die das gleiche Alphabet verwenden.

SPLIT_DIGITS: true

VOCABULARY_THRESHOLD: 50

#SMT

REPLACE_NUM: False

NUM_CODE: „@NUM@“

#SENTENCE PIECE CONTROL_SYMBOLS: ""

USER_DEFINED_SYMBOLS: "@EMAIL@,@URL@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,," SP_MODEL_PREFIX: spmodel

MODEL_TYPE: bpe

#eines von unigram, bpe, char, word

VOCAB_SIZE: 32000

CHARACTER_COVERAGE: 1.0

CHARACTER_COVERAGE_SL: 1.0

CHARACTER_COVERAGE_TL: 1.0

INPUT_SENTENCE_SIZE: 5000000

#SUBWORD NMT

LEARN_BPE: Wahr

JOINER: „@@“

#verwende eines von ■ oder @@

NUM_OPERATIONS: 85000

APPLY_BPE: Wahr

BPE_DROPOUT: Wahr

BPE_DROPOUT_P: 0.1

Es gibt viele Parameter, die wir hier nicht geändert haben, weil der Standardwert für uns in Ordnung war. Aber bei anderen Sprachpaaren müssen Sie aufpassen, dass Sie die richtigen Parameter auswählen.

Aufgabe 5: Laden Sie eine Kopie der Datei config-corpus-preprocessing.yaml herunter und öffnen Sie sie in einem geeigneten Texteditor. Passen Sie sie so an, dass ein Korpus mit dem Namen Korpus-Gross.txt vearbeitet wird.

  • Das Korpus, das verarbeitet werden soll enthält Segmente auf Englisch und Deutsch bzw. Englisch und Italienisch.
  • E-Mail-Adressen sollen nicht ersetzt werden
  • URL sollen mit dem Ausdruck ((URL)) ersetzt werden. Geben Sie die angepasste Datei unter Aufgabe 5 auf Moodle ab.

Nachdem wir unsere Konfigurationsdatei bearbeitet haben, geben wir zum Starten des Preprocessings einfach python3 MTUOC-corpus-preprocessing.py

5. Guided Alignment ⚠️ (kurzer) Input dazu nächste Woche

5.1. Einleitung

Eine neuronale (und statistische) maschinelle Übersetzungsmaschine muss in der Lage sein, uns nicht nur eine qualitativ hochwertige Übersetzung zu liefern, sondern auch einige zusätzliche Informationen. In diesem Abschnitt werden wir darüber sprechen, wie wichtig es ist, dass das MÜ-System uns Informationen über das Alignment auf Wort- (oder Unterwort-) Ebene liefern kann. Das heisst, die Beziehung zwischen den Wörtern im Originalsatz und im übersetzten Satz. Wenn unser Original zum Beispiel lautet: This is a simple example . Und die automatische Übersetzung lautet: Dies ist ein einfaches Beispiel .

oder Questo è un esempio semplice .

(beachte, dass es tokenisiert ist, da der Punkt abgetrennt wird).

Wir möchten auch, dass das System uns das Alignment auf Wortebene mitteilt, und zwar 0-0 1-1 2-2 3-3 4-4 5-5 (für Deutsch, wo die Wortstellung gleich ist wie im Englischen)

bzw: 0-0 1-1 2-2 3-4 4-3 5-5 (für Italiensich, wobei Reihenfolge von Adeltiv und Nomen hier anders ist als im englischen).

Dies hat mehrere Vorteile, z. B. die Möglichkeit, XML-Tags abzurufen, die der Text enthalten kann. Zum Beispiel, wenn der Ausgangstext Tags enthält: Dies ist ein einfaches Beispiel.

In der Regel wird das System angewiesen, das Segment ohne die Tags zu übersetzen und dann mit den Alignment-Informationen die Tags in die maschinelle Übersetzung einzufügen. Der Algorithmus sieht, dass in Wort 3 des Originals ein Anfangstag vor und ein Schlusstag nach der Übersetzung steht. Wenn er sich das Alignment auf Wortebene ansieht, erkennt er, dass das italienische Wort 4 dem englischen Wort 3 entspricht, und platziert die Tags zwischen diesen Wörtern: Questo è un esempio semplice .

Beachte, dass statistische Systeme, wie z. B. Moses, in der Lage sind, genaue Alignment-Informationen zu liefern. Von den neuronalen Maschinen sind s2s ebenfalls in der Lage, diese Informationen genau zu liefern, aber die neuronalen Maschinen vom Typ Transformator sind es nicht. Bei neuronalen Maschinen vom Typ Transformator wird eine Schicht des Modells so trainiert, dass es die Ausrichtung genau wiedergeben kann. Diese Technik wird als geführte Ausrichtung bezeichnet. Um diese Schicht zu trainieren, benötigen wir jedoch die wortgenaue Ausrichtung des Trainingskorpus (und optional auch des Validierungskorpus). In diesem Abschnitt erfahren wir, wie wir das Alignment auf Wortebene (eigentlich auf Unterwortebene, da wir sentencepiece verwenden) des Trainingskorpus erstellen.

5.2. fast_align

Es gibt mehrere Algorithmen, um Korpora auf Wortebene zu alignieren. Nicht zu verwechseln mit dem Alignment von Parallelkorpora, das wir in den letzten Wochen kennengelernt haben, bei dem es darum geht, übersetzungsäquivalente Segmentpaare in zwei Sprachen zu erhalten. Jetzt wollen wir diese Segmente auf Wortebene (oder Unterwortebene) alignieren, d.h. jedes Wort in Sprache 1 mit dem entsprechenden Wort in Sprache 2 in Beziehung setzen. Zu den am häufigsten verwendeten Algorithmen in der MÜ gehören u.a:

In dieser Übung werden wir lernen, wie man fast_align benutzt. Du kannst es selbst kompilieren, wie im Repository erklärt, oder direkt die Version verwenden, die mit den MTUOC-Hilfsskripten verteilt wird, die du wahrscheinlich schon in den vergangenen Wochen heruntergeladen hast. Ich habe das Programm auch in das Archiv dieser Woche gestellt: https://github.com/mtuoc/seminario_online_TAN/tree/main/semana_7.

5.2.1 Schritt 1: Konvertieren der Korpora zum Alignieren

Die beiden Korpora, die aligniert werden sollen (das Korpora der Sprache 1 und das Korpora der Sprache 2), müssen in eine einzige Datei in einem bestimmten Format konvertiert werden: L1_segment ||| L2_segment ||. Dies kann auf zwei Arten geschehen. Direkt im Linux Terminal: paste train.sp.en train.sp.es | sed 's/\t/ ||| /' > train.toalign

Oder über das Python-Skript mergefiles.py, das in den Archiven dieser Woche enthalten ist: python3 mergefiles.py train.sp.en train.sp.en > train.toalign Jetzt können wir das Alignment in beide Richtungen durchführen (vorwärts, d.h. L1-L2; und rückwärts, d.h. L2-L1):

  • ./fast_align -i train.toalign -d -v -o -p fwd_params >train.sp.en.en.es.align 2>fwd_err
  • ./fast_align -i train.toalign -r -d -v -o -p rev_params >train.sp.en.en.align 2>rev_err Die Alignments müssen in train.sp.en.en.align (die eng-spa-Adresse) und in train.sp.en.en.align (die spa-eng-Adresse) stehen. In fwd_params und rev_params werden die Parameter des Alignments gespeichert. Wir werden sie in diesem Seminar nicht verwenden, aber sie können genutzt werden, um kleinere Korpora (aus denen nicht so viele Statistiken gewonnen werden können) anhand der Parameter eines früheren Alignments eines grösseren Korpus zu alignieren. Für das Training der Engines können wir die obigen Befehle vereinfachen, indem Sie folgendes eingeben:
  • ./fast_align -i train.toalign -d -v -o >train.sp.en.es.align
  • ./fast_align -i train.toalign -r -d -v -o >train.sp.en.en.en.align Es ist wichtig zu überprüfen, dass alle train.sp-Dateien die gleichen Zeilen haben:
wc -l *.sp.*
  1145905 zug.sp.en
  1145905 train.sp.en.en.en.align
  1145905 zug.sp.en.es
  1145905 zug.sp.en.es.en.align
  4583620 total

Sie können das Ergebnis des Alignments in der Datei alineacion.zip herunterladen.

⚠️ **GitHub.com Fallback** ⚠️