Top k
Top k ist ein Sampling-Parameter, der die Textgenerierung auf die k wahrscheinlichsten Tokens beschränkt. Diese Methode hilft dabei, unwahrscheinliche oder unsinnige Ausgaben zu vermeiden.
Was ist Top k?
Top k begrenzt die Auswahl der nächsten Tokens auf eine feste Anzahl der wahrscheinlichsten Kandidaten. Im Gegensatz zu Top p, das dynamisch basierend auf der Wahrscheinlichkeitsverteilung arbeitet, ist Top k eine statische Begrenzung.
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.
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 | ❌ | ❌ |
... | ... | ... | ❌ | ❌ |
Technische Details
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
Top k vs. Top p
Die beiden Methoden haben unterschiedliche Stärken und Schwächen:
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 |
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
Wann solltest du Top k verwenden?
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
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 |
Praktische Code-Beispiele
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?"
}]
)
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
)
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"
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 |
Fortgeschrittene Techniken
Adaptive k-Werte
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
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
}
Debugging und Optimierung
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
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
)
Best Practices
- 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