Spaces:
Sleeping
Sleeping
File size: 6,302 Bytes
348749a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# app.py
import gradio as gr
import torch
from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
import pandas as pd
# --- 1. Modelle laden ---
# Wir laden die Modelle einmal beim Start der Anwendung, um die Ladezeit bei jeder Anfrage zu vermeiden.
# Modell 1: German GPT-2 für Text-Vervollständigung
# Wir laden hier Tokenizer und Modell manuell, da wir die Logits für das nächste Wort brauchen,
# was die Standard-Pipeline nicht direkt so ausgibt.
gpt2_model_name = "dbmdz/german-gpt2"
gpt2_tokenizer = AutoTokenizer.from_pretrained(gpt2_model_name)
# AutoModelWithLMHead ist veraltet, wir benutzen stattdessen AutoModelForCausalLM
gpt2_model = AutoModelForCausalLM.from_pretrained(gpt2_model_name)
# Modell 2: BERT für Masken-Füllung
# Hier können wir die Pipeline direkt nutzen, da sie genau das tut, was wir wollen.
unmasker = pipeline('fill-mask', model='bert-base-multilingual-uncased', top_k=5)
# --- 2. Logik-Funktionen für die Modelle ---
def predict_next_word(text):
"""
Diese Funktion nimmt einen Text entgegen, tokenisiert ihn, gibt ihn an das GPT-2 Modell
und berechnet die Wahrscheinlichkeitsverteilung für das *unmittelbar* folgende Wort.
"""
if not text or not text.strip():
return {}
# Text in Token-IDs umwandeln
inputs = gpt2_tokenizer(text, return_tensors='pt')
# Modell-Vorhersage ohne Gradientenberechnung (schneller)
with torch.no_grad():
logits = gpt2_model(**inputs).logits
# Wir interessieren uns nur für die Logits des letzten Tokens im Input
# Shape: [batch_size, sequence_length, vocab_size] -> wir nehmen das letzte Token
last_token_logits = logits[0, -1, :]
# Wende Softmax an, um Wahrscheinlichkeiten zu erhalten
probabilities = torch.nn.functional.softmax(last_token_logits, dim=-1)
# Finde die Top 5 wahrscheinlichsten Token-IDs und ihre Wahrscheinlichkeiten
top_k_probs, top_k_indices = torch.topk(probabilities, 5)
# Konvertiere die Token-IDs zurück in lesbare Tokens (Wörter)
top_k_tokens = gpt2_tokenizer.convert_ids_to_tokens(top_k_indices)
# Bereinige die Tokens (z.B. 'Ġ' entfernen, das für ein Leerzeichen steht)
cleaned_tokens = [token.replace('Ġ', '') for token in top_k_tokens]
# Erstelle ein Dictionary für die Ausgabe in Gradio
result_dict = {token: prob.item() for token, prob in zip(cleaned_tokens, top_k_probs)}
return result_dict
def fill_the_mask(text):
"""
Diese Funktion nutzt die fill-mask Pipeline, um die wahrscheinlichsten Wörter für
das [MASK]-Token im Text zu finden.
"""
# Überprüfen, ob das Masken-Token vorhanden ist
mask_token = unmasker.tokenizer.mask_token
if mask_token not in text:
# Einen Fehler in der Gradio-UI anzeigen
raise gr.Error(f"Die Eingabe muss das Masken-Token '{mask_token}' enthalten.")
# Pipeline aufrufen
predictions = unmasker(text)
# Die Ausgabe der Pipeline in ein Dictionary für Gradio umwandeln
# Die Pipeline liefert eine Liste von Dictionaries, wir formatieren sie um.
result_dict = {pred['token_str']: pred['score'] for pred in predictions}
return result_dict
# --- 3. Gradio Interface erstellen ---
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown(
"""
# Funktionalität von Language Models demonstrieren
Diese Anwendung zeigt die Kernfähigkeiten von zwei verschiedenen Arten von Transformer-Modellen:
1. **Causal Language Models (z.B. GPT-2):** Diese Modelle sind darauf trainiert, das nächste Wort in einer Sequenz vorherzusagen. Sie sind ideal für die Textgenerierung.
2. **Masked Language Models (z.B. BERT):** Diese Modelle lernen, fehlende Wörter in einem Satz zu ergänzen. Sie verstehen den Kontext in beide Richtungen (bidirektional) und sind stark in Klassifikations- oder Extraktionsaufgaben.
"""
)
with gr.Tabs():
# --- Tab 1: Causal LM (GPT-2) ---
with gr.TabItem("1. Causal LM (Text-Vervollständigung)"):
gr.Markdown(
"""
## German GPT-2 (`dbmdz/german-gpt2`)
Dieses Modell sagt das wahrscheinlichste *nächste* Wort voraus.
### Anleitung
Gib einen deutschen Satzanfang in das Textfeld ein und klicke auf "Nächstes Wort vorhersagen".
"""
)
with gr.Row():
text_input_gpt = gr.Textbox(
label="Dein Satzanfang",
placeholder="Tippe hier...",
value="Der Sinn des Lebens ist",
lines=3
)
predict_button_gpt = gr.Button("Nächstes Wort vorhersagen")
gr.Markdown("### Wahrscheinlichste Folgewörter")
output_label_gpt = gr.Label(num_top_classes=5)
# --- Tab 2: Masked LM (BERT) ---
with gr.TabItem("2. Masked LM (Masken-Füllung)"):
gr.Markdown(
f"""
## Multilingual BERT (`bert-base-multilingual-uncased`)
Dieses Modell füllt die Lücke, die durch ein sogenanntes "Masken-Token" (`{unmasker.tokenizer.mask_token}`) markiert ist.
### Anleitung
Gib einen Satz mit dem Masken-Token `{unmasker.tokenizer.mask_token}` ein und klicke auf "Maske füllen".
"""
)
with gr.Row():
text_input_bert = gr.Textbox(
label="Satz mit Maske",
placeholder="Tippe hier...",
value=f"Berlin ist die Hauptstadt von {unmasker.tokenizer.mask_token}.",
lines=3
)
fill_mask_button_bert = gr.Button("Maske füllen")
gr.Markdown("### Wahrscheinlichste Füllwörter")
output_label_bert = gr.Label(num_top_classes=5)
# --- 4. Events verknüpfen ---
predict_button_gpt.click(
fn=predict_next_word,
inputs=text_input_gpt,
outputs=output_label_gpt,
api_name="predict_next_word"
)
fill_mask_button_bert.click(
fn=fill_the_mask,
inputs=text_input_bert,
outputs=output_label_bert,
api_name="fill_mask"
)
# Anwendung starten
demo.launch() |