#
Transformer-Modelle - wozu sind sie imstande?

In diesem Abschnitt schauen wir uns an, was Transformer-Modelle zu leisten imstande sind. Zudem verwenden wir unser erstes Werkzeug aus der 🤗 Transformers-Bibliothek: die Funktion `pipeline()`.

> 👀 Siehst du rechts oben die Schaltfläche Open in Colab? Klicke darauf, um ein Google Colab Notebook, das alle Codebeispiele dieses Abschnitts enthält, zu öffnen. Diese Schaltfläche ist in jedem Abschnitt, der Codebeispiele enthält, zu finden.

> Wenn du die Beispiele lieber lokal ausführen möchtest, empfehlen wir dir, einen Blick auf das Kapitel Einrichtung zu werfen.

##
Transformer-Modelle sind überall anzutreffen!

Transformer-Modelle werden verwendet, um alle Arten von CL-Aufgaben (engl. Tasks) zu lösen, u. a. die im vorherigen Abschnitt genannten. Hier sind einige der Unternehmen und Organisationen, die Hugging-Face- und Transformer-Modelle verwenden und ihre Modelle mit der Community teilen:

Die 🤗 Transformers-Bibliothek bietet die Funktionalität, um diese geteilten Modelle zu erstellen und zu nutzen. Der Model Hub enthält Tausende von vortrainierten Modellen, die jeder herunterladen und nutzen kann. Auch du kannst dort deine eigenen Modelle hochladen!

> ⚠️ Der Hugging Face Hub ist nicht auf Transformer-Modelle beschränkt. Jede bzw. jeder kann die von ihr bzw. ihm gewünschten Arten von Modellen oder Datensätzen teilen! Erstelle ein Konto auf huggingface.co, um alle verfügbaren Features nutzen zu können!

Bevor wir uns ansehen, wie Transformer-Modelle im Einzelnen funktionieren, widmen wir uns ein paar Beispielen, die veranschaulichen, wie sie zur Lösung interessanter CL-Problemstellungen eingesetzt werden können.

##
Mit Pipelines arbeiten

Das grundlegendste Objekt in der 🤗 Transformers-Bibliothek ist die `pipeline()`-Funktion. Sie verbindet ein Modell mit den notwendigen Vor- und Nachverarbeitungsschritten (engl. Preprocessing/Postprocessing) und ermöglicht es uns, direkt einen beliebigen Text eingeben zu können und eine Antwort zu erhalten, die verständlich ist:

    from transformers import pipeline

    classifier = pipeline("sentiment-analysis")
    classifier("I've been waiting for a HuggingFace course my whole life.")

    [{'label': 'POSITIVE', 'score': 0.9598047137260437}]

Wir können sogar mehrere Sätze auf einmal übergeben!

    classifier(
        ["I've been waiting for a HuggingFace course my whole life.", "I hate this so much!"]
    )

    [{'label': 'POSITIVE', 'score': 0.9598047137260437},
     {'label': 'NEGATIVE', 'score': 0.9994558095932007}]

In der Voreinstellung wählt diese Pipeline ein bestimmtes vortrainiertes Modell aus, das bereits für die Sentiment-Analyse in englischer Sprache feingetunt wurde. Wenn du das `classifier`-Objekt erstellst, wird das Modell heruntergeladen und zwischengespeichert. Wenn du den Befehl erneut ausführst, wird stattdessen das zwischengespeicherte Modell verwendet und das Modell muss nicht erneut heruntergeladen werden.

Wenn du einen Text an eine Pipeline übergibst, gibt es drei wichtige Schritte:

1. Der Text wird im Rahmen der Vorverarbeitung in ein Format überführt, das das Modell verstehen kann.
2. Die vorverarbeiteten Inputs bzw. Eingaben werden an das Modell übergeben.
3. Die Vorhersagen des Modells werden so nachverarbeitet, sodass du sie nutzen kannst.

Einige der derzeit verfügbaren Pipelines sind:

- `feature-extraction` (Vektordarstellung eines Textes erhalten)
- `fill-mask`
- `ner` (Named Entity Recognition)
- `question-answering`
- `sentiment-analysis`
- `summarization`
- `text-generation`
- `translation`
- `zero-shot-classification`

Werfen wir doch gleich mal einen Blick auf ein paar von ihnen!

##
Zero-Shot-Klassifizierung

Beginnen wir mit der recht anspruchsvollen Aufgabe, Texte zu klassifizieren, die noch nicht gelabelt wurden. Dieses Problem tritt häufig in realen Projekten auf, da das Labeln von Texten in der Regel zeitaufwendig ist und Fachwissen erfordert. Für diesen Anwendungsfall ist die Pipeline `zero-shot-classification` sehr vielversprechend: Mit ihr kannst du festlegen, welche Labels für die Klassifizierung verwendet werden sollen, und musst nicht auf die Labels des vortrainierten Modells zurückgreifen. Wie du bereits gesehen hast, kann das Modell einen Satz - entsprechend der beiden Labels - als positiv oder negativ klassifizieren. Es kann den Text aber auch auf der Grundlage einer beliebigen anderen Auswahl an Labels klassifizieren.

    from transformers import pipeline

    classifier = pipeline("zero-shot-classification")
    classifier(
        "This is a course about the Transformers library",
        candidate_labels=["education", "politics", "business"],
    )

    {'sequence': 'This is a course about the Transformers library',
     'labels': ['education', 'business', 'politics'],
     'scores': [0.8445963859558105, 0.111976258456707, 0.043427448719739914]}

Diese Pipeline heißt zero-shot, weil du das Modell nicht erst auf deine Daten feintunen musst, ehe du es verwenden kannst. Sie kann direkt die Wahrscheinlichkeiten für jede beliebige von dir vorgegebene Liste von Labels liefern!

> ✏️ Probiere es aus! Spiel mit deinen eigenen Sequenzen und Labels herum und beobachte, wie sich das Modell verhält.

##
Textgenerierung

Sehen wir uns nun an, wie du eine Pipeline verwenden kannst, wenn du einen Text generieren möchtest. Der Grundgedanke dabei ist, dass du einen bestimmten Input (einen sog. Prompt) vorgibst und das Modell diesen automatisch vervollständigt, indem es den restlichen Text generiert. Das ist ähnlich wie die Textvorhersagefunktion, die auf vielen Handys zu finden ist. Die Textgenerierung erfolgt nach dem Zufallsprinzip - daher ist es normal, wenn du nicht die gleichen Ergebnisse wie die unten gezeigten erhältst.

    from transformers import pipeline

    generator = pipeline("text-generation")
    generator("In this course, we will teach you how to")

    [{'generated_text': 'In this course, we will teach you how to understand and use '
                        'data flow and data interchange when handling user data. We '
                        'will be working with one or more of the most commonly used '
                        'data flows — data flows of various types, as seen by the '
                        'HTTP'}]

Mit dem Argument `num_return_sequences` kannst du steuern, wie viele verschiedene Sequenzen erzeugt werden und mit dem Argument `max_length`, wie lang der Ausgabetext insgesamt sein soll.

> ✏️ Probiere es aus! Wähle die Argumente `num_return_sequences` und `max_length` so, dass zwei Sätze mit jeweils 15 Wörtern erzeugt werden.

##
Verwendung eines beliebigen Modells vom Hub in einer Pipeline

In den vorherigen Beispielen wurde für die jeweilige Aufgabe das voreingestellte Standardmodell verwendet. Du kannst aber auch ein bestimmtes Modell aus dem Hub auswählen und es in einer Pipeline für eine konkrete Aufgabe verwenden - zum Beispiel für die Textgenerierung. Gehe zum Model Hub und klicke auf der linken Seite unter `Tasks` auf das entsprechende Tag, um dir lediglich die für diese Aufgabenstellung unterstützten Modelle anzeigen zu lassen. Du solltest anschließend auf eine Seite wie diese gelangen.

Probieren wir nun das Modell `distilgpt2` aus! So kannst du es mit der gleichen Pipeline wie zuvor laden:

    from transformers import pipeline

    generator = pipeline("text-generation", model="distilgpt2")
    generator(
        "In this course, we will teach you how to",
        max_length=30,
        num_return_sequences=2,
    )

    [{'generated_text': 'In this course, we will teach you how to manipulate the world and '
                        'move your mental and physical capabilities to your advantage.'},
     {'generated_text': 'In this course, we will teach you how to become an expert and '
                        'practice realtime, and with a hands on experience on both real '
                        'time and real'}]

Du kannst deine Suche nach einem Modell verfeinern, indem du auf eines der `Languages`-Tags klickst und ein Modell auswählst, das Text in einer anderen Sprache generiert. Der Model Hub enthält sogar Checkpoints für mehrsprachige Modelle, die mehrere verschiedene Sprachen unterstützen.

Nachdem du auf ein Modell geklickt und es ausgewählt hast, siehst du, dass es ein Widget gibt, mit dem du es direkt online ausprobieren kannst. Dementsprechend kannst du die Fähigkeiten eines Modells erst schnell testen, bevor du dich dazu entschließt, es herunterzuladen.

> ✏️ Probiere es aus! Verwende die Filter, um ein Textgenerierungsmodell für eine andere Sprache zu finden. Experimentiere ruhig ein wenig mit dem Widget und verwende das Modell in einer Pipeline!

###
Die Inference API

Alle Modelle können direkt über deinen Browser getestet werden, indem du die Inference API verwendest, die auf der Webseite von Hugging Face verfügbar ist. Auf dieser Seite kannst du direkt mit dem Modell experimentieren, indem du einen eigenen Text eingibst und beobachtest, wie das Modell die Input-Daten verarbeitet.

Die Inference API, die dem Widget zugrunde liegt, ist auch als kostenpflichtiges Produkt erhältlich, was recht praktisch ist, wenn du sie für deine Workflows benötigst. Weitere Informationen findest du auf der Preisseite.

##
Mask Filling

Die nächste Pipeline, die du ausprobieren wirst, ist `fill-mask`. Bei dieser Aufgabe geht es darum, Lücken in einem vorgegebenen Text zu füllen:

    from transformers import pipeline

    unmasker = pipeline("fill-mask")
    unmasker("This course will teach you all about <mask> models.", top_k=2)

    [{'sequence': 'This course will teach you all about mathematical models.',
      'score': 0.19619831442832947,
      'token': 30412,
      'token_str': ' mathematical'},
     {'sequence': 'This course will teach you all about computational models.',
      'score': 0.04052725434303284,
      'token': 38163,
      'token_str': ' computational'}]

Mit dem Argument `top_k` kannst du bestimmen, wie viele Möglichkeiten dir ausgegeben werden sollen. Beachte, dass das Modell hier das spezielle Wort `<mask>` auffüllt, das oft als Mask-Token bezeichnet wird. Andere Modelle, die dazu dienen, Maskierungen aufzufüllen, können andere Mask Tokens haben. Deshalb ist es immer gut, erst das verwendete Mask Token zu ermitteln, wenn du andere Modelle nutzen möchtest. Eine Möglichkeit, zu überprüfen, welches Mask Token verwendet wird, ist das Widget.

> ✏️ Probiere es aus! Suche im Hub nach dem Modell `bert-base-cased` und finde sein Mask Token im Widget, das auf der Inference API basiert, heraus. Was sagt dieses Modell für den oben in der Pipeline verwendeten Satz vorher?

##
Named Entity Recognition

Bei der Eigennamenerkennung (engl. Named Entity Recognition, NER) handelt es sich um eine Aufgabenstellung, bei der das Modell herausfinden muss, welche Teile des Input-Textes Entitäten wie Personen, Orte oder Organisationen darstellen. Nehmen wir uns ein konkretes Beispiel zur Hand:

    from transformers import pipeline

    ner = pipeline("ner", grouped_entities=True)
    ner("My name is Sylvain and I work at Hugging Face in Brooklyn.")

    [{'entity_group': 'PER', 'score': 0.99816, 'word': 'Sylvain', 'start': 11, 'end': 18},
     {'entity_group': 'ORG', 'score': 0.97960, 'word': 'Hugging Face', 'start': 33, 'end': 45},
     {'entity_group': 'LOC', 'score': 0.99321, 'word': 'Brooklyn', 'start': 49, 'end': 57}
    ]

Hier hat das Modell richtig erkannt, dass Sylvain eine Person (PER), Hugging Face eine Organisation (ORG) und Brooklyn ein Ort (LOC) ist.

In der Funktion zur Erstellung der Pipeline übergeben wir die Option `grouped_entities=True`, um die Pipeline anzuweisen, die Teile des Satzes, die der gleichen Entität entsprechen, zu gruppieren: Hier hat das Modell “Hugging” und “Face” richtigerweise als eine einzelne Organisation gruppiert, auch wenn der Name aus mehreren Wörtern besteht. Wie wir im nächsten Kapitel sehen werden, werden bei der Vorverarbeitung (engl. Preprocessing) sogar einige Wörter in kleinere Teile zerlegt. Zum Beispiel wird `Sylvain` in vier Teile zerlegt: `S`, `##yl`, `##va` und `##in`. Im Nachverarbeitungsschritt (engl. Post-Processing) hat die Pipeline diese Teile erfolgreich neu gruppiert.

> ✏️ Probiere es aus! Suche im Model Hub nach einem Modell, das in der Lage ist, Part-of-Speech-Tagging (in der Regel als POS abgekürzt) im Englischen durchzuführen (Anm.: d. h. Wortarten zuzuordnen). Was sagt dieses Modell für den Satz im obigen Beispiel vorher?

##
Frage-Antwort-Systeme (Question Answering)

Die Pipeline `question-answering` beantwortet Fragen anhand von Informationen, die aus einem bestimmten Kontext stammen:

    from transformers import pipeline

    question_answerer = pipeline("question-answering")
    question_answerer(
        question="Where do I work?",
        context="My name is Sylvain and I work at Hugging Face in Brooklyn",
    )

    {'score': 0.6385916471481323, 'start': 33, 'end': 45, 'answer': 'Hugging Face'}

Beachte, dass diese Pipeline Informationen aus dem gegebenen Kontext extrahiert; sie generiert nicht die Antwort.

##
Automatische Textzusammenfassung

Bei der automatischen Textzusammenfassung (engl. Summarization) geht es darum, einen Text zu kürzen und dabei alle (oder die meisten) wichtigen Aspekte, auf die im Text verwiesen wird, beizubehalten. Hier ist ein Beispiel:

    from transformers import pipeline

    summarizer = pipeline("summarization")
    summarizer(
        """
        America has changed dramatically during recent years. Not only has the number of
        graduates in traditional engineering disciplines such as mechanical, civil,
        electrical, chemical, and aeronautical engineering declined, but in most of
        the premier American universities engineering curricula now concentrate on
        and encourage largely the study of engineering science. As a result, there
        are declining offerings in engineering subjects dealing with infrastructure,
        the environment, and related issues, and greater concentration on high
        technology subjects, largely supporting increasingly complex scientific
        developments. While the latter is important, it should not be at the expense
        of more traditional engineering.

        Rapidly developing economies such as China and India, as well as other
        industrial countries in Europe and Asia, continue to encourage and advance
        the teaching of engineering. Both China and India, respectively, graduate
        six and eight times as many traditional engineers as does the United States.
        Other industrial countries at minimum maintain their output, while America
        suffers an increasingly serious decline in the number of engineering graduates
        and a lack of well-educated engineers.
    """
    )

    [{'summary_text': ' America has changed dramatically during recent years . The '
                      'number of engineering graduates in the U.S. has declined in '
                      'traditional engineering disciplines such as mechanical, civil '
                      ', electrical, chemical, and aeronautical engineering . Rapidly '
                      'developing economies such as China and India, as well as other '
                      'industrial countries in Europe and Asia, continue to encourage '
                      'and advance engineering .'}]

Wie bei der Textgenerierung kannst du eine maximale (`max_length`) oder minimale (`min_length`) Länge für das Ergebnis angeben.

##
Maschinelle Übersetzung

Für die Maschinelle Übersetzung (engl. Translation) kannst du ein vorgegebenes Standardmodell verwenden, indem du ein Sprachpaar im Aufgabennamen angibst (z. B. `"translation_en_to_fr"`). Am einfachsten ist es jedoch, das Modell, das du verwenden möchtest, im Model Hub auszuwählen. Im folgenden Beispiel probieren wir die Übersetzung vom Französischen ins Englische aus:

    from transformers import pipeline

    translator = pipeline("translation", model="Helsinki-NLP/opus-mt-fr-en")
    translator("Ce cours est produit par Hugging Face.")

    [{'translation_text': 'This course is produced by Hugging Face.'}]

Wie bei der Textgenerierung und -zusammenfassung kannst du auch hier `max_length` oder `min_length` als Argumente für das Ergebnis angeben.

> ✏️ Probiere es aus! Suche nach Übersetzungsmodellen in anderen Sprachen und versuche, den vorangegangenen Satz in mehrere verschiedene Sprachen zu übersetzen.

Die bisher gezeigten Pipelines dienen hauptsächlich zu Demonstrationszwecken. Sie wurden für bestimmte Aufgabenstellungen programmiert und sind nicht für Abwandlungen geeignet. Im nächsten Kapitel erfährst du, was sich hinter einer `pipeline()`-Funktion verbirgt und wie du ihr Verhalten anpassen kannst.

Update on GitHub