Top k
Top k ist ein Sampling-Parameter, der die Textgenerierung auf die k wahrscheinlichsten Tokens beschränkt. Fan et al. (2018) zeigten, dass diese Methode dabei hilft, unwahrscheinliche oder unsinnige Ausgaben zu vermeiden und gleichzeitig kreativere Texte als Beam Search erzeugt.
1. Was ist Top k?
Top k begrenzt die Auswahl der nächsten Tokens auf eine feste Anzahl der wahrscheinlichsten Kandidaten. Holtzman et al. (2019) betonen, dass im Gegensatz zu Top p (Nucleus Sampling), das dynamisch basierend auf der Wahrscheinlichkeitsverteilung arbeitet, Top k eine statische Begrenzung ist.
Einfach erklärt: Wenn Top k = 50 ist, betrachtet die KI nur die 50 wahrscheinlichsten nächsten Wörter und ignoriert alle anderen, egal wie die Wahrscheinlichkeitsverteilung aussieht.
1.1 Visualisierung des Konzepts
Beispiel für "Das Wetter ist heute...":
Rang | Token | Wahrscheinlichkeit | Bei k=3 | Bei k=5 |
---|---|---|---|---|
1 | schön | 0.35 | ✅ | ✅ |
2 | sonnig | 0.20 | ✅ | ✅ |
3 | bewölkt | 0.15 | ✅ | ✅ |
4 | regnerisch | 0.10 | ❌ | ✅ |
5 | windig | 0.08 | ❌ | ✅ |
6 | stürmisch | 0.05 | ❌ | ❌ |
... | ... | ... | ❌ | ❌ |
2. Interaktive Top-k Demo
Top-k Live Demo
Experimentiere mit verschiedenen Top-k-Werten und beobachte, wie sie die Token-Auswahl bei der Textgenerierung beeinflussen
Effekt bei 40:
Ausgewogene Auswahl
Beispiel-Ausgabe:
Klicke auf "Generieren" um eine Beispiel-Ausgabe mit dem aktuellen Parameter-Wert zu sehen
3. Technische Details
3.1 Der Top k Algorithmus
- Berechne die Wahrscheinlichkeiten für alle möglichen nächsten Tokens
- Sortiere die Tokens nach Wahrscheinlichkeit (absteigend)
- Behalte nur die ersten k Tokens
- Normalisiere die Wahrscheinlichkeiten der verbleibenden Tokens
- Wähle aus diesen k Tokens basierend auf ihrer relativen Wahrscheinlichkeit
def top_k_sampling(logits, k):
"""
Wendet Top-k Sampling auf die Logits an
"""
# Sortiere und behalte nur die k größten Werte
top_k_logits, top_k_indices = torch.topk(logits, k=k, dim=-1)
# Setze alle anderen Logits auf -infinity
logits_masked = torch.full_like(logits, float('-inf'))
logits_masked.scatter_(-1, top_k_indices, top_k_logits)
# Wende Softmax an für Wahrscheinlichkeiten
probs = torch.softmax(logits_masked, dim=-1)
return probs
4. Top k vs. Top p
Zhao et al. (2024) erklären in ihrer umfassenden LLM-Übersicht, dass die beiden Methoden unterschiedliche Stärken und Schwächen haben:
Eigenschaft | Top k | Top p |
---|---|---|
Anzahl Tokens | Fest (immer k) | Variabel |
Anpassung an Verteilung | Nein | Ja |
Bei flacher Verteilung | Kann zu restriktiv sein | Passt sich an |
Bei steiler Verteilung | Kann unnötige Tokens einschließen | Wählt nur relevante |
Vorhersagbarkeit | Hoch | Mittel |
4.1 Praktischer Vergleich
Szenario 1: Eindeutige Antwort
Frage: "Die Hauptstadt von Deutschland ist..."
- Berlin: 95% Wahrscheinlichkeit
- Andere Tokens: jeweils unter 1%
→ Top k=50 würde 49 unnötige Tokens berücksichtigen
→ Top p=0.9 würde nur "Berlin" wählen
Szenario 2: Viele mögliche Antworten
Frage: "Zum Frühstück esse ich gerne..."
- Viele Optionen mit ähnlichen Wahrscheinlichkeiten (2-5%)
→ Top k=10 könnte gute Optionen ausschließen
→ Top p=0.9 würde mehr Vielfalt zulassen
5. Wann solltest du Top k verwenden?
5.1 Geeignete Anwendungsfälle
- Kontrollierte Kreativität: Wenn du Vielfalt willst, aber Grenzen setzen möchtest
- Vermeidung seltener Tokens: Um ungewöhnliche oder fehlerhafte Ausgaben zu verhindern
- Konsistente Performance: Wenn die Rechenlast vorhersagbar sein soll
- Spezielle Domänen: Bei Fachsprache mit begrenztem Vokabular
5.2 Empfohlene k-Werte
Anwendungsfall | k-Wert | Begründung |
---|---|---|
Greedy Decoding | 1 | Immer das wahrscheinlichste Token |
Faktenbasierte Antworten | 5-10 | Wenig Variation, hohe Genauigkeit |
Allgemeine Konversation | 40-50 | Ausgewogene Vielfalt |
Kreatives Schreiben | 100-200 | Maximale Kreativität mit Grenzen |
6. Praktische Code-Beispiele
6.1 Anthropic Claude
import anthropic
client = anthropic.Anthropic()
# Top k für kontrollierte Kreativität
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1000,
top_k=40, # Nur die 40 wahrscheinlichsten Tokens
messages=[{
"role": "user",
"content": "Schreibe einen kurzen Dialog zwischen zwei Charakteren"
}]
)
# Sehr niedriges k für präzise Antworten
precise_response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=100,
top_k=5,
messages=[{
"role": "user",
"content": "Was ist die Quadratwurzel von 144?"
}]
)
6.2 Google Gemini mit Top k und Top p
import google.generativeai as genai
genai.configure(api_key="YOUR_API_KEY")
model = genai.GenerativeModel('gemini-pro')
# Kombination von Top k und Top p
generation_config = genai.types.GenerationConfig(
top_k=100, # Erste Filterung: Top 100 Tokens
top_p=0.8, # Zweite Filterung: 80% Wahrscheinlichkeitsmasse
temperature=0.7
)
response = model.generate_content(
"Erkläre Machine Learning in einfachen Worten",
generation_config=generation_config
)
# Nur Top k ohne Top p
strict_config = genai.types.GenerationConfig(
top_k=10,
top_p=1.0, # Deaktiviert Top p
temperature=0.5
)
response = model.generate_content(
"Liste die Planeten unseres Sonnensystems auf",
generation_config=strict_config
)
6.3 Vergleichstest verschiedener k-Werte
# Test mit verschiedenen k-Werten
k_values = [1, 5, 20, 50, 100]
prompt = "Ein kreativer Name für ein Café wäre"
results = {}
for k in k_values:
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=20,
top_k=k,
messages=[{"role": "user", "content": prompt}]
)
results[k] = response.content[0].text
# Ausgabe der Ergebnisse
for k, result in results.items():
print(f"k={k}: {result}")
# Mögliche Ausgabe:
# k=1: "Kaffeepause" (immer dasselbe)
# k=5: "Bohnenglück"
# k=20: "Traumtasse & Co."
# k=50: "Der verzauberte Löffel"
# k=100: "Wolke 7 - Kaffee & Poesie"
7. API-Verfügbarkeit
Anbieter | Verfügbar | Standardwert | Besonderheiten |
---|---|---|---|
OpenAI | ❌ | - | Nicht direkt verfügbar, nur Top p |
Anthropic Claude | ✅ | Kein Default | Für fortgeschrittene Nutzer empfohlen |
Google Gemini | ✅ | 40 | Kombinierbar mit Top p |
Cohere | ✅ | 0 (deaktiviert) | Als "k" Parameter |
Hugging Face | ✅ | 50 | Standard in Transformers |
Mistral | ✅ | Variiert | Modellabhängig |
8. Fortgeschrittene Techniken
8.1 Adaptive k-Werte
Chung et al. (2023) arbeiten an Methoden zur Verbesserung der Diversität bei gleichzeitiger Genauigkeit. Manche Systeme passen k dynamisch an den Kontext an:
def get_adaptive_k(prompt_type, confidence_threshold=0.8):
"""
Passt k basierend auf dem Prompt-Typ und der
Konfidenz der Top-Tokens an
"""
base_k_values = {
"factual": 10,
"creative": 100,
"code": 20,
"conversation": 50
}
# Analysiere die Wahrscheinlichkeitsverteilung
# Wenn Top-Token sehr wahrscheinlich, reduziere k
# Wenn Verteilung flach, erhöhe k
return adjusted_k
8.2 Kombinationsstrategien
Bei Google Gemini kann die Reihenfolge von Top k und Top p wichtig sein:
# Strategie 1: Erst k, dann p (Google Gemini Standard)
# 1. Filtere auf Top 50 Tokens
# 2. Davon nimm die, die 90% Wahrscheinlichkeit abdecken
config_k_then_p = {
"top_k": 50,
"top_p": 0.9
}
# Strategie 2: Nur k für harte Begrenzung
config_only_k = {
"top_k": 30,
"top_p": 1.0 # Deaktiviert
}
# Strategie 3: Niedriges k mit hohem p
# Für fokussierte aber nicht zu repetitive Ausgaben
config_balanced = {
"top_k": 20,
"top_p": 0.95
}
9. Debugging und Optimierung
9.1 Häufige Probleme und Lösungen
⚠️ Problem: Zu repetitive Ausgaben
Symptom: Die KI wiederholt sich ständig
Lösung: Erhöhe k von z.B. 10 auf 40-50
⚠️ Problem: Unsinnige oder inkohärente Ausgaben
Symptom: Unerwartete oder unpassende Wörter
Lösung: Reduziere k auf 20-30
⚠️ Problem: Keine Variation bei mehreren Anfragen
Symptom: Gleiche Ausgabe bei gleicher Eingabe
Lösung: k=1 ist zu niedrig, erhöhe auf mindestens 5
9.2 Test-Framework für optimale k-Werte
def test_k_values(prompt, k_range, num_samples=5):
"""
Testet verschiedene k-Werte und bewertet die Ausgaben
"""
results = []
for k in k_range:
outputs = []
for _ in range(num_samples):
response = generate_with_k(prompt, k)
outputs.append(response)
# Bewerte Vielfalt
diversity = calculate_diversity(outputs)
# Bewerte Kohärenz
coherence = calculate_coherence(outputs)
results.append({
'k': k,
'diversity': diversity,
'coherence': coherence,
'samples': outputs
})
return results
# Verwendung
k_range = [5, 10, 20, 40, 80, 160]
results = test_k_values(
"Schreibe einen Slogan für ein Umweltprojekt",
k_range
)
# Finde optimales k
optimal_k = find_optimal_k(results,
diversity_weight=0.6,
coherence_weight=0.4
)
10. Best Practices
Li et al. (2024) zeigen in ihrer Arbeit zur Verbesserung linguistischer Diversität, dass die richtige Wahl von Sampling-Parametern entscheidend ist:
- Starte mit Standardwerten: k=40 ist oft ein guter Ausgangspunkt
- Teste iterativ: Passe k basierend auf den Ergebnissen an
- Berücksichtige den Kontext: Verschiedene Aufgaben brauchen verschiedene k-Werte
- Kombiniere mit anderen Parametern: Top k + Temperature kann effektiver sein als nur ein Parameter
- Dokumentiere deine Werte: Halte fest, welche k-Werte für welche Aufgaben funktionieren