Wir zeigen, welche Daten große Sprachmodelle verwenden und wie man eigene Textdaten aufbereiten kann.
Um ein großes Sprachmodell zu trainieren, wird ein großer Datensatz verwendet. Die meisten großen Sprachmodelle haben gemeinsam, dass diese zum Großteil auf Website-Daten trainiert werden. Wir schauen uns den Datensatz des zurzeit bekanntesten Sprachmodells LLaMA von Meta/Facebook, genauer an.LLaMA Paper
Die wichtigsten Fakten über den für das LLaMA-Training verwendeten Datensatz sind:
Zusammenfassend lässt sich sagen, dass der LLaMA-Trainingsdatensatz verschiedene Datensätze umfasst und diese aufwendige Aufbereitungsschritte durchlaufen, um einen qualitativ hochwertigen Datensatz zu erzeugen. Generell hat das Modell eine Kenntnis über verschiedenste Sprachen, wenn auch nur sehr begrenzt.
Die einzelnen Bestandteile des Datensatzes für das LLaMA-Training sind zwar frei verfügbar, der Datensatz selber nach der Aufbereitung jedoch nicht. Möchte man sich einen eigenen Datensatz zusammenstellen, folgen hier die Links zu den einzelnen Bestandteilen:
Wir werden hier immer wieder den Begriff Huggingface lesen: Huggingface ist ein Unternehmen, das sich auf die Entwicklung von Werkzeugen und Bibliotheken für Natural Language Processing (NLP) spezialisiert hat. Ihre bekannteste Bibliothek, Transformers, ermöglicht die Implementierung von State-of-the-Art-NLP-Modellen. Darüber hinaus stellen sie auch eine Austauschplattform zur Verfügung, auf der vortrainierte Modelle und Datensätze von der Community geteilt werden können.
| Datensatz | Links |
|---|---|
| CommonCrawl | CommonCrawl GitHub |
| C4 | GitHub - Huggingface - Washington Post Analyse |
| GitHub | Google BigQuery - Info Google Codelabs |
| Wikipedia | Wikipedia Dumps - Huggingface |
| Books | Huggingface Pile Books3 - Gutenberg - PG19 |
| arXiv | arxiv |
| StackExchange | archive - Huggingface |
Es gibt verschiedene Projekte, die einen vergleichbaren Datensatz zu dem des LLaMA-Netzes aufgebaut haben:
RedPajama Datensatz auf Huggingface
Hier ist der Nachteil, dass ebenfalls wieder hauptsächlich englische Texte verwendet wurden. Lediglich die Wikipedia-Artikel hatten unterschiedliche Sprachen.
Darüber hinaus wurde ein vergleichbares Sprachmodell zu den LLaMA-Modellen trainiert namens Falcon, der Datensatz hierzu wurde ebenfalls veröffentlicht: Huggingface
Der Vorteil gegenüber den oben vorgestellten Datensätzen ist, dass bei der großen Variante des Netzes ein weiterer (leider nicht veröffentlichter) Datensatz verwendet wurde, bei dem europäische Sprachen mit 7 % Anteil verwendet wurden. Hiervon sind 26 % der Daten Deutsch. Was einem Gesamtanteil von 1,82 % entspricht. Dies entspricht immerhin einem Gesamtanteil von 1,82 % was aber natürlich immer noch eher gering ist.
Die Web-Datensätze werden durch Webscraping über Crawling erzeugt. Hierbei werden große Mengen an Internetseiten heruntergeladen und der Text extrahiert. In Europa gibt es ebenfalls ein Projekt namens OSCAR (Open Super-large Crawled Aggregated coRpus), welcher einen großen Open Source Datensatz erzeugt.Oscar Datensatz
Generell muss das Scraping bedacht angegangen werden und aktuell gibt es noch rechtliche Bedenken. Bei StableDiffusion zum Beispiel (eine KI zur Bilderzeugung) wurde erst vor kurzem ein mögliches opt out Verfahren eingeführt, damit die Bilder nicht für das Training verwendet werden.MIT Technology Review Außerdem zeigt sich, dass Scraping von den Websitebetreibern kritisch angesehen wird und die Zugriffe nicht mehr kostenfrei erfolgen sollen.Heise Artikel über StackExchanget3n Artikel über Reddit Möchte man ein eigenes Webscraping aufbauen, kann dies mit bereits vorhandenen Tools wie Scrapy, StormCrawler o.ä. aufgebaut werden.
Wie können wir nun eigene Dokumente in die großen Sprachmodelle bringen? Generell gibt es unterschiedliche Herangehensweisen. Entweder können diese Texte in das Sprachmodell eintrainiert werden, oder man verwendet ein allgemeines Sprachmodell und nutzt Text-Embedding. Dabei werden ähnliche Textbausteine zu der Anfrage in vorhandenen Dokumenten gesucht und dem Sprachmodell zugeführt. Im ersten Schritt zeigen wir, wie man die Daten in das Sprachmodell eintrainieren kann.
import requests
from bs4 import BeautifulSoup
URL = "https://www.gutenberg.org/files/2229/2229-h/2229-h.htm"
# Herunterladen der .html Website
r = requests.get(URL)
soup = BeautifulSoup(r.content, "html.parser")
# Entfernen des Inhaltsverzeichnisses, der Überschriften, ...
text = soup.find_all("p")
text = [p.text for p in text]
# Entfernen der Einleitung am Anfang
text = text[5:]
print(" ".join(text[:1]))DIREKTOR. Ihr beiden, die ihr mir so oft, In Not und Trübsal, beigestanden, Sagt, was ihr wohl in deutschen Landen Von unsrer Unternehmung hofft? [...]
Anschließende Datenaufbereitung:
# Filtern des Textes, damit nur die Konversationen und keine weiteren Einleitungen o.ä. verwendet wird:
final_text = []
for raw_text in text:
split_txt = raw_text.lstrip().split("\r\n", 1)
if split_txt[0].replace(".", "").isupper():
final_text.append("\n".join(split_txt))
final_text[:2]['DIREKTOR.\nIhr beiden, die ihr mir so oft,\r\n [...]', 'DICHTER.\nIhr fühlet nicht, wie schlecht ein solches Handwerk sei!\r\n [...]']
import requests
import ebooklib
from ebooklib import epub
from bs4 import BeautifulSoup
URL = "https://www.gutenberg.org/ebooks/2229.epub.noimages"
r = requests.get(URL)
with open('Faust.epub', 'wb') as f:
f.write(r.content)
book = epub.read_epub("Faust.epub")
items = list(book.get_items_of_type(ebooklib.ITEM_DOCUMENT))
# Ab hier vergleichbar zu html-Dateien
final_text = []
for item in items:
soup = BeautifulSoup(item.get_body_content().decode('utf-8'), "html.parser")
# Entfernen des Inhaltsverzeichnisses, der Überschriften, ..., u.ä.
text = soup.find_all("p")
text = [p.text for p in text]
# Filtern des Textes, damit nur die Konversationen und keine weiteren Einleitungen o.ä. verwendet wird:
for raw_text in text:
split_txt = raw_text.lstrip().split("\n", 1)
if split_txt[0].isupper():
final_text.append("\n".join(split_txt))
final_text[:2]['DIREKTOR.\nIhr beiden, die ihr mir so oft,\nIn Not und Trübsal, beigestanden,\n [...]', 'DICHTER.\nIhr fühlet nicht, wie schlecht ein solches Handwerk sei!\n [...]']
Für die PDF verwenden wir einen PDF-Ausdruck der bereits verwendeten Website. Hier wurde der Text nur relativ einfach extrahiert und manche Abschnitte zur Vereinfachung verworfen. Der Aufwand, PDF-Dateien aufzubereiten, ist deutlich größer, insbesondere wenn der Text nicht eingebettet ist. Hierbei müsste dann in einem ersten Schritt noch eine OCR-Umwandlung erfolgen.
def get_sprecher(text_list:list)->list:
"""Gibt die einzelnen Sprecher zurück. Der Anfang wird verworfen!"""
sprecher_list = []
for i, text in enumerate(text_list):
if text.isupper():
sprecher_list.append(i)
merged_sprecher = []
for sprecher, _ in enumerate(sprecher_list):
try:
merged_sprecher.append("\n".join(text_list[sprecher_list[sprecher]: sprecher_list[sprecher+1]]))
except IndexError:
merged_sprecher.append("\n".join(text_list[sprecher_list[sprecher]:]))
return merged_sprecher
import fitz
doc = fitz.open("Faust.pdf")
alle_konversationen = []
for page in range(3, 130):
text = doc[page].get_text()
text = text.split("/139")[1].lstrip().split("\n")
alle_konversationen.extend(get_sprecher(text))
alle_konversationen[:2]['DIREKTOR.\nIhr beiden, die ihr mir so oft,\nIn Not und Trübsal, beigestanden,\n [...]', 'DICHTER.\nIhr fühlet nicht, wie schlecht ein solches Handwerk sei!\n [...]']
In unserem nächsten Blogbeitrag zeigen wir, wie die aufbereiteten Daten verwendet werden können um ein großes Sprachmodell an Faust anzupassen.