Artikel

  • Hugging Face Transfomers: Q&A Modell

    In den letzten Monaten haben KIs durch den Erfolg von Large Language Models (z.B. ChatGPT) viel Aufmerksamkeit erhalten. Dabei gibt es schon seit längerer Zeit mit Hugging Face eine Community, die verschiedene KI Modelle als Open Source bereitstellt. Hugging Face verfügt außerdem mit der Transformers über eine Bibliothek, die es erlaubt diese Modelle sehr einfach einzusetzen. Dieser Artikel zeigt am Beispiel eines deutschen Question & Answer Modells, wie einfach ein Python Skript zum Durchsuchen einer Webseite mit natürlicher Sprache geschrieben werden kann. Das entsprechende Skript liegt außerdem auf GitHub als Quellcode vor.

    Schritt 1: Installation von Python, Transformers und PyTorch

    Die Installation von Python wird im Folgenden nicht beschrieben. Alle Beispiele sind jedoch getestet mit Python 3.10.9 und Windows 11.

    Transformers lässt sich sehr einfach über pip installieren:

    pip install transfomers
    

    Zusätzlich benötigt Transformers entweder TensorFlow oder Pytorch. Über dieses Kommando wird PyTorch mit Cuda 11.7 installiert:

    pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
    

    Weitere Installationsmöglichkeiten finden sich auf der PyTorch Homepage.

    Schritt 2: Das Skript schreiben

    Im Folgenden erkläre ich die einzelnen Schritte zum Schreiben des Skripts. Das vollständige Skript ist auch auf GitHub zu finden.

    Zunächst importieren wir alle notwendigen Abhängigkeiten:

    from transformers import pipeline
    import requests
    from bs4 import BeautifulSoup
    import sys
    

    Requests und BeautifulSoup nutzen wir, um die Webseite zu laden und den Text zu extrahieren. Als nächstes lesen wir die URL und die zu stellende Frage aus den Kommandozeilenparametern:

    url = sys.argv[1]
    question = sys.argv[2]
    

    Die URL nutzen wir gleich, um die Webseite abzufragen und den Text der Webseite zu extrahieren:

    response = requests.get(url)
    html = response.content
    soup = BeautifulSoup(html, 'html.parser')
    text = soup.get_text()
    

    Nun nutzen wir die pipeline Funktion aus der Tranformers Bibliothek, um das entsprechende Modell zu laden:

    model_name = 'deepset/gelectra-base-germanquad'
    nlp = pipeline('question-answering', model=model_name, tokenizer=model_name)
    

    Wir nutzen hier das Modell deepset/gelectra-base-germanquad, das speziell zum Durchsuchen von deutschen Texten trainiert wurde und unter MIT Lizenz zur Verfügung gestellt wird. Der erste Parameter der Funktion besagt außerdem, dass wir das Modell für “question-answering” nutzen möchten.

    Nun können wir dieses Modell nutzen, um eine Anfrage zu stellen:

    input = { 'question': question, 'context': text}
    result = nlp(input)
    print(f"{ result['answer'] } (Score: {result['score']})")
    

    Die beiden Parameter sind jeweils die Frage aus dem Kommandozeilen-Parameter und der aus der Webseite extrahierte Text. Das result ist ein Dictionary. Aus diesem Dictionary nutzen wir answer für die Antwort und score um zu erfahren, wie wahrscheinlich es sich bei der Antwort um die richtige Antwort handelt (wie “sicher” sich das Modell ist).

    Schritt 3: Ausführen

    Nun lässt sich das Skript einfach folgendermaßen ausführen (hier wird davon ausgegangen, dass das Skript “german-qa.py” heißt):

    > python german-qa.py https://de.wikipedia.org/wiki/Fu%C3%9Fball-Bundesliga "Wer ist deutscher Rekordmeister?"
    > FC Bayern München (Score: 0.7162473201751709)
    

    Wird die Frage hingegen auf einer Seite gestellt, auf der die Antwort nicht zu finden ist, sieht das Ergebnis so aus:

    > python german-qa.py https://de.wikipedia.org/wiki/Fu%C3%9Fball "Wer ist deutscher Rekordmeister?"
    > Konrad Koch (Score: 0.07024901360273361)
    

    Fazit

    Ich hoffe, ich konnte mit diesem Artikel zeigen, wie einfach die Anwendung von KI Modellen heutzutage geworden ist. In der Hugging Face Transformers Dokumentation gibt es noch viele weitere Beispiele für Anwendungsfälle.

    Der Quellcode zu diesem Artikel steht auf GitHub bereit.

  • Consumer Driven Contracts - Erfahrungsbericht, Teil 2

    In den letzten Monaten haben wir bei meinem aktuellen Projekt Consumer Driven Contracts eingeführt. Dabei habe ich einiges über diese Technik gelernt. Meine Erkenntnisse schreibe ich in einer zweiteiligen Artikelserie nieder. Dieser Artikel ist der zweite Teil und befasst sich mit Pact als Implementierung von Consumer-Driven Contracts.

  • Consumer Driven Contracts - Erfahrungsbericht, Teil 1

    In den letzten Monaten haben wir bei meinem aktuellen Projekt Consumer Driven Contracts eingeführt. Dabei habe ich einiges über diese Technik gelernt. Meine Erkenntnisse schreibe ich in einer zweiteiligen Artikelserie nieder. Dieser Artikel ist der erste Teil und befasst sich mit der Theorie, ohne auf Vor- und Nachteile einer speziellen Implementierung einzugehen.

  • Komponenten in Angular unkompliziert mocken

    Beim Schreiben von Tests für Komponenten in Angular empfiehlt es sich Abhängigkeiten zu mocken, um unerwünschte Nebeneffekte zu vermeiden. Um im Template eingebundene Komponenten zu mocken, gibt es mehrere Möglichkeiten.

  • Einfache Tools mit Node.js schreiben

    Mit Node.js lassen sich nicht nur Webanwendungen schreiben, sondern auch kleine Tools, die den Projektalltag erleichtern. Dieser Ansatz ist besonders für Projekte geeignet, bei denen Node.js ohnehin schon im Einsatz ist. Dieser Artikel zeigt, wie ein solches Projekt aufgesetzt werden kann und welche Abhängigkeiten den Start erleichtern.

    Im Weiteren wird vorausgesetzt, dass Node.js bereits installiert ist. Die Beispiele verwenden Node.js 16.16.0. Außerdem wird für eine verbesserte Typsicherheit TypeScript eingesetzt.

    1. Ein neues Projekt anlegen: npm init
    2. TypeScript hinzufügen: npm install --save-dev typescript
    3. Types für Node.js: npm install --save-dev @types/node
    4. Linting: npm install --save-dev tslint
    5. Initialisieren von TypeScript: npx tsc --init
    6. Initialisieren von tslint: npx tslint --init

    Anschließend ist das Projekt theoretisch einsatzbereit. Um eine TypeScript Datei direkt ausführen zu können, empfiehlt sich aber noch der Einsatz von ts-node: npm install --save-dev ts-node.

    Dadurch lässt sich ein Script wie folgt ausführen: npx ts-node src/mein-script.ts

    Weitere nützliche Abhängigkeiten:

    • commander: Hilft bei der Implementierung einer CLI für das Skript.
    • typed-rest-client: Einfacher typisierter REST Client
  • Retry implementieren mit Spring Retry

    Die meisten Clients bieten bereits die Möglichkeit einen Retry zu konfigurieren, falls die Anfrage fehl schlägt. Dennoch kann es vorkommen, dass Retry nicht als Feature angeboten wird. In Spring-Projekten bietet sich als Alternative zur Eigenimplementierung die Bibliothek Spring Retry an.

  • Docker for Windows: Pakete in einem Bridge Netzwerk umleiten

    Kürzlich hatte ich das Problem, dass ein Prozess in einem Docker Container Pakete an eine falsche IP-Adresse schickt: Statt an den Host gingen die Pakete an das Standard Gateway des Bridge Netzwerks. Leider ließ sich die IP-Adresse im Prozess wegen eines Bugs nicht anpassen. Unter Windows funktioniert zudem das Host Netzwerk von Docker nicht richtig. Die einzige Wahl war daher die Umleitung der Pakete an die richtige IP-Adresse.

  • CSV einfach nach JSON konvertieren

    NPM ist eine riesige Sammlung an Bibliotheken. Einige dieser Bibliotheken lassen sich auch über die Kommandozeile als Tools ausführen. Möglich wird das über das Tool npx. Damit ist es auch möglich, auf einfachem Weg CSV nach JSON zu konvertieren.

  • Responsive Webdesign mit SASS

    Mithilfe von SASS lässt sich das Responsive Webdesign deutlich vereinfachen. Als Beispiel wird die maximale Breite des dargestellten Seiteninhalts für drei Größen definiert. Das Beispiel ist dabei natürlich konstruiert und in der Praxis gäbe es einfacherer Methoden, das gewünschte Ergebnis zu erreichen. Hier soll vorallem das zu Grunde liegende Prinzip verdeutlicht werden.

  • REST in der Praxis - Teil 2: Datenaufbereitung

    In der Artikelreihe “REST in der Praxis” stelle ich verschiedene Themen aus dem Umfeld von REST Schnittstellen vor. Teil 1 der Reihe habe ich dem Maturity Model gewidmet. Dieses Mal beschäftige ich mich mit der Datenaufbereitung für REST Schnittstellen.

  • Nützliche Links - Teil 1: Webentwicklung

    Über die Jahre habe ich mir eine Sammlung nützlicher Links aufgebaut, die ich an dieser Stelle teilen möchte. Da es relativ viele Links sind, werde ich sie nach und nach veröffentlichen. Dieses Mal geht es um Links aus der Webentwicklung.

  • Persönliche Docker Toolbox erstellen

    Mit Hilfe von Docker lässt sich einfach eine persönliche Toolbox erstellen, die es erlaubt typische Linux Tools auch unter Windows zu verwenden. In meinem Artikel zeige ich, wie das Dockerfile auszusehen hat und wie der Aufruf über Batch Skripte einfach von der Hand geht.

  • REST in der Praxis - Teil 1: Maturity Model

    In der Artikelreihe “REST in der Praxis” stelle ich verschiedene Themen aus dem Umfeld von REST Schnittstellen vor. Ich beginne mit dem Maturity Model von Leonard Richardson, ein Versuch den Reifegrad einer REST Schnittstelle formal zu beschreiben.

  • Arbeitsverzeichnis in Shell-Skripten referenzieren

    In Shell-Skripten muss von Zeit zu Zeit das aktuelle Arbeitsverzeichnis referenziert werden. Hierzu gibt es sowohl unter Windows als auch unter Linux zwei kurze Statements.

  • Docker Compose Werkzeugkasten für Entwickler

    Docker hat die Arbeit von uns Entwicklern revolutioniert. Mussten früher Anwendungen wie z.B. eine Datenbank aufwändig installiert werden, geht das heute mit einem einzigen Befehl. Einer der größten Nachteile bei Docker ist meiner Meinung nach allerdings das vergleichsweise komplexe CLI. Hier setzt Docker Compose an. Um die Arbeit noch weiter zu erleichtern, habe ich mit der Sammlung typischer Docker Compose Konfigurationen begonnen.

  • Spring Boot Server nach gegebener Zeit herunterfahren

    Manchmal soll ein Spring Boot Server nach einer gegebenen Zeit oder dem Eintreten einer Bedingung heruntergefahren werden. Eine Demoanwendung soll beispielsweise zunächst einige Kommandos ausführen und sich danach automatisch beenden. In diesem Artikel zeige ich einen Weg, wie das zu bewerkstelligen ist.

  • Git Repository ohne Versionsinformationen kopieren

    Von Zeit zu Zeit möchte man ein Git Repository ohne Versionsinformationen kopieren. Wie das mit zwei simplen Befehlen geht, beschreibe ich in diesem Artikel.

  • Nützliche IntelliJ Plugins

    In diesem Artikel liste ich IntelliJ Plugins auf, die ich in der Vergangenheit eingesetzt habe und die sich bewährt haben.

  • Neustart des Spring Kontexts in Tests erzwingen

    Beim Arbeiten mit Integrationstests im Spring Umfeld kann es passieren, dass ein Neustart des Spring Kontexts erforderlich ist. Hier schafft die @DirtiesContext Annotation Abhilfe.

  • Oracle Sequences in Spring Data JDBC 2.0

    Ich beschreibe eine Möglichkeit Oracle Sequences in Spring Data JDBC zu integrieren. Zum Einsatz kommt dabei Spring Data JDBC 2.0. Von Haus aus unterstützt diese Version keine Sequences.

  • Custom Progress Bar für Wizards

    Kürzlich stand ich vor der Herausforderung einen Wizard mit Fortschrittsbalken ohne Komponentenframework zu erstellen. Für den Fortschrittsbalken verwendete ich daher ausschließlich HTML und CSS.

  • Hallo Welt

    Das hier ist mein erster Artikel in diesem neuen Blog. Und wie es sich für einen Blog Rund um Software Entwicklung gehört, beginnt er natürlich mit Hallo Welt.

subscribe via RSS