Vorbereitung auf LLM- und Generative-KI-Interviews

LLM- und Generative-KI-Ingenieur-Interviewfragen

15 ausgewählte LLM- und Generative-KI-Interviewfragen, gruppiert nach Erfahrungsstufe. Nutzen Sie diese zur Überprüfung von Grundlagen, praktischen Abwägungen und dem produktionsrelevanten Denken auf Senior-Niveau.

LLM- und Generative-KI-Interview startenKeine Kreditkarte erforderlich. 1 kostenlose Sitzung verfügbar.
Technisches Interview-Training auf EnglischEin Modus, in dem Nicht-Muttersprachler technische Interviews üben können.

Junior-Fragen

1Erläutern Sie die Subword-Tokenisierung und warum sie gegenüber der Tokenisierung auf Wort- oder Zeichenebene in modernen Sprachmodellen bevorzugt wird.

Die Subword-Tokenisierung ist ein hybrider Textsegmentierungsansatz, der Text in morphologische Blöcke variabler Länge oder frequenzbasierte Teilstrings (wie 'un', 'break', 'able') zerlegt, anstatt in ganze Wörter oder einzelne Zeichen. Algorithmen wie Byte-Pair Encoding (BPE), WordPiece und Unigram LM lernen ein Vokabular fester Größe aus einem Trainingskorpus, wobei häufige Wörter als einzelne Tokens erhalten bleiben, während seltene oder unbekannte Wörter in bekannte Subword-Einheiten zerlegt werden. Die Subword-Tokenisierung wird in modernen Sprachmodellen bevorzugt, da sie Vokabulargröße, Sequenzlänge und Robustheit gegenüber Out-of-Vocabulary-Tokens (OOV) ausgleicht. Eine reine Tokenisierung auf Wortebene erfordert ein übermäßig großes Vokabular (was zu riesigen Embedding-Matrizen führt) und leidet immer noch unter OOV-Tokens, die auf generische '[UNK]'-Tokens abgebildet werden. Umgekehrt eliminiert eine reine Tokenisierung auf Zeichenebene OOV-Probleme, erzeugt aber sehr lange Sequenzen, die die rechnerische Komplexität bei Aufmerksamkeitsmechanismen (die quadratisch mit der Sequenzlänge skalieren) drastisch erhöhen und die semantische Dichte pro Token verdünnen. Die Subword-Tokenisierung erzielt einen optimalen Kompromiss, indem sie Sequenzlängen handhabbar hält, Vokabulargrößen praktisch macht (typischerweise 32k bis 128k Tokens) und OOV-Raten bei Null hält (insbesondere in Kombination mit Byte-Level-Fallback-Mechanismen).

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained('gpt2')
text = 'unbelievable'
tokens = tokenizer.tokenize(text)
token_ids = tokenizer.encode(text)

print('Tokens:', tokens)
print('Token IDs:', token_ids)
Diese Frage mit einem KI-Coach beantworten

2Erklären Sie den Unterschied zwischen statischen Worteinbettungen, kontextuellen Einbettungen und Transformer-Hidden-States.

Statische Worteinbettungen, kontextuelle Einbettungen und Transformer-Hidden-States stellen progressive Entwicklungen in der Art und Weise dar, wie Textrepräsentationen Bedeutung und syntaktischen Kontext erfassen. 1. **Statische Worteinbettungen** (z.B. Word2Vec, GloVe, FastText) weisen jedem Vokabel-Token einen einzigen, festen Vektor zu, unabhängig vom Satzkontext. Bei diesem Paradigma haben polyseme Wörter wie 'Bank' (Flussufer vs. Finanzinstitut) oder 'Apple' (Frucht vs. Technologieunternehmen) in allen Kontexten identische Vektorrepräsentationen, basierend auf einer statischen Nachschlagetabelle. 2. **Kontextuelle Einbettungen** (z.B. frühe ELMo, BERT Token-Repräsentationen oder Satz-Einbettungen von Bi-Encodern) erzeugen Repräsentationen, bei denen der Vektor für ein Token eine dynamische Funktion seines umgebenden Kontexts ist. In BERT oder ELMo erhält 'Bank' in 'Flussufer' einen völlig anderen Einbettungsvektor als 'Bank' in 'Geld bei der Bank einzahlen'. 3. **Transformer-Hidden-States** beziehen sich auf die intermediären Vektorrepräsentationen, die in jeder einzelnen Schicht eines Transformer-Netzwerks während eines Forward Pass erzeugt werden. Ausgehend von den Eingabe-Token-Einbettungen in Schicht 0 wendet jede aufeinanderfolgende Transformer-Schicht Self-Attention- und Feed-Forward-Transformationen an, die eine Sequenz von Hidden-State-Vektoren h_l in Schicht l erzeugen. Während die Hidden-States der letzten Schicht als hochrangige kontextuelle Einbettungen dienen, erfassen die unteren und mittleren Hidden-States lexikalische, syntaktische und strukturelle Merkmale auf niedriger Ebene. Somit umfassen Transformer-Hidden-States das gesamte vertikale Kontinuum der schichtweisen Repräsentationen über das Netzwerk hinweg.

import torch
from transformers import AutoTokenizer, AutoModel

tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
model = AutoModel.from_pretrained('bert-base-uncased', output_hidden_states=True)

text1 = 'River bank'
text2 = 'Bank deposit'

inputs1 = tokenizer(text1, return_tensors='pt')
inputs2 = tokenizer(text2, return_tensors='pt')

with torch.no_grad():
    out1 = model(**inputs1)
    out2 = model(**inputs2)

# Layer 0 (Input token embeddings - static lookup before self-attention)
static_bank_1 = out1.hidden_states[0][0, 2] # 'bank'
# Layer 12 (Final contextual hidden state after all attention layers)
contextual_bank_1 = out1.hidden_states[12][0, 2]
contextual_bank_2 = out2.hidden_states[12][0, 1]

print('Cosine similarity of bank in different contexts (Layer 12):',
      torch.cosine_similarity(contextual_bank_1, contextual_bank_2, dim=0).item())
Diese Frage mit einem KI-Coach beantworten

3Erläutern Sie, was ein Einbettungsraum repräsentiert und wie die Kosinus-Ähnlichkeit für Texteinbettungen interpretiert wird.

Ein Einbettungsraum ist ein kontinuierlicher, hochdimensionaler Vektorraum R^d, in dem diskrete textuelle Entitäten (Wörter, Sätze oder Dokumente) so abgebildet werden, dass semantische, syntaktische oder relationale Ähnlichkeiten geometrischer Nähe und direktionalen Beziehungen entsprechen. In diesem Raum spiegeln Distanzen und Winkel die semantische Verwandtschaft wider. Die Kosinus-Ähnlichkeit misst den Kosinus des Winkels Theta zwischen zwei Vektoren u und v, berechnet als: `Kosinus-Ähnlichkeit(u, v) = (u . v) / (||u|| ||v||)` Die Kosinus-Ähnlichkeit wird in Texteinbettungen wie folgt interpretiert: - **Bereich & Orientierung**: Sie erzeugt einen skalaren Wert, der typischerweise im Bereich von [-1, 1] (oder [0, 1] für nicht-negative Einbettungen) liegt. Ein Wert nahe 1.0 deutet darauf hin, dass die beiden Vektoren praktisch in die gleiche Richtung zeigen, was eine hohe semantische Ähnlichkeit oder thematische Übereinstimmung widerspiegelt. Ein Wert nahe 0.0 impliziert Orthogonalität (semantische Unabhängigkeit oder Nicht-Verwandtschaft), und negative Werte deuten auf entgegengesetzte Orientierungen hin. - **Unabhängigkeit von der Betragsgröße**: Im Gegensatz zur Euklidischen Distanz (L2-Distanz) oder dem Skalarprodukt normalisiert die Kosinus-Ähnlichkeit nach der Vektorlänge. In Texteinbettungen kann die Vektorbetragsgröße manchmal mit der Sequenzlänge, Token-Frequenz oder Term-Spezifität korrelieren. Durch die reine Konzentration auf die direktionale Ausrichtung isoliert die Kosinus-Ähnlichkeit die semantische Orientierung von Unterschieden in der Vektorbetragsgröße.

import numpy as np

def cosine_sim(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# Hypothetical 3D embeddings
v_king = np.array([0.9, 0.1, 0.4])
v_queen = np.array([0.85, 0.15, 0.42])
v_apple = np.array([0.1, 0.9, -0.2])

print('Sim(king, queen):', round(cosine_sim(v_king, v_queen), 4))
print('Sim(king, apple):', round(cosine_sim(v_king, v_apple), 4))
Diese Frage mit einem KI-Coach beantworten

4Erklären Sie den Unterschied zwischen Token-Embeddings, Positional-Embeddings und Segment- oder Typ-Embeddings in Transformer-Eingaben.

Bei Transformer-Eingaben (insbesondere bei Architekturen im BERT-Stil) wird die Eingabedarstellung für jedes Token typischerweise durch die elementweise Summation von drei verschiedenen Embedding-Vektoren gebildet: 1. **Token-Embeddings**: Bilden diskrete Vokabular-Token-IDs in dichte Vektoren ab, die die semantische und lexikalische Kernidentität der Tokens repräsentieren. 2. **Positionale Embeddings**: Fügen Informationen über die Token-Reihenfolge und sequentielle Indizes in die Darstellung ein, um die Tatsache zu kompensieren, dass Self-Attention (Selbst-Aufmerksamkeit) von Natur aus permutationsinvariant ist. 3. **Segment- (oder Token-Typ-) Embeddings**: Unterscheiden zwischen verschiedenen Textabschnitten oder Sätzen, die in einer einzigen Eingabesequenz zusammengefasst sind (z. B. Satz A vs. Satz B in gepaarten Klassifikations- oder Frage-Antwort-Aufgaben). Die Kombination dieser Embeddings liefert einen einzigen dichten Eingabetensor, der die Token-Bedeutung, -Position und -Sequenzgruppierung kodiert, bevor er an die erste Transformer-Schicht weitergegeben wird.

import torch
import torch.nn as nn

vocab_size, max_seq_len, num_segments, d_model = 30522, 512, 2, 768
tok_embed = nn.Embedding(vocab_size, d_model)
pos_embed = nn.Embedding(max_seq_len, d_model)
seg_embed = nn.Embedding(num_segments, d_model)

input_ids = torch.tensor([[101, 7592, 102, 2023, 102]]) # Token IDs
type_ids = torch.tensor([[0,   0,    0,   1,    1  ]]) # Segment IDs (Sentence A vs B)
positions = torch.arange(input_ids.size(1)).unsqueeze(0)   # Indices: [0, 1, 2, 3, 4]

# Final representation is the element-wise sum
input_rep = tok_embed(input_ids) + pos_embed(positions) + seg_embed(type_ids)
print(input_rep.shape)
Diese Frage mit einem KI-Coach beantworten

5Erklären Sie Attention als Mechanismus zur Verknüpfung von Tokens in einer Sequenz, einschließlich Queries, Keys, Values und Multi-Head Attention.

Attention ist ein Mechanismus, der es Tokens in einer Sequenz ermöglicht, Informationen dynamisch weiterzuleiten und die Relevanz aller anderen Tokens basierend auf kontextueller Übereinstimmung zu gewichten. Lineare Projektionen wandeln den Input jedes Tokens in drei Vektoren um: - Query (Q): Repräsentiert, welche Information das aktuelle Token sucht. - Key (K): Repräsentiert, welche Attribute oder Inhalte ein Token anbietet, um mit Queries übereinzustimmen. - Value (V): Enthält die tatsächliche Informationsnutzlast, die aggregiert werden soll. Bei der skalierten Punktprodukt-Attention werden Attention-Scores durch Multiplikation von Queries und Keys ($Q K^T$) berechnet, skaliert um $\frac{1}{\sqrt{d_k}}$, um das Verschwinden von Gradienten über große Dimensionen hinweg zu verhindern, und mit einer Softmax-Funktion normalisiert. Das Endergebnis ist die gewichtete Summe der Values: $$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$ Multi-Head Attention (MHA) projiziert $Q$, $K$ und $V$ parallel in mehrere unabhängige Repräsentationsunterräume (Köpfe). Dies ermöglicht es dem Modell, gleichzeitig auf verschiedene Arten von Beziehungen zu achten (z. B. syntaktische Struktur, Koreferenz, Langstreckenabhängigkeiten) über Positionen hinweg. Die Head-Outputs werden konkateniert und linear zurück auf die Modell-Dimension projiziert.

import torch
import torch.nn.functional as F

# Q, K, V: [batch_size, seq_len, head_dim]
Q = torch.randn(1, 4, 64)
K = torch.randn(1, 4, 64)
V = torch.randn(1, 4, 64)
d_k = Q.size(-1)

scores = torch.matmul(Q, K.transpose(-2, -1)) / (d_k ** 0.5)
attn_weights = F.softmax(scores, dim=-1)
output = torch.matmul(attn_weights, V)

print("Output shape:", output.shape)
Diese Frage mit einem KI-Coach beantworten

6Erläutern Sie, wie sich Aufmerksamkeitsmaskierung für kausale Decoder im Vergleich zu bidirektionalen Encodern unterscheidet und welche Verhaltensweisen sie ermöglicht oder verhindert.

Aufmerksamkeitsmaskierung steuert, welche Tokens welchen anderen Tokens Aufmerksamkeit schenken dürfen, indem sie Aufmerksamkeits-Logits (Werte vor der Softmax-Funktion) für unzulässige Paare auf $-\infty$ setzt, wodurch deren Aufmerksamkeitsgewicht nach Softmax streng 0 wird. 1. Kausale Decoder (z.B. GPT, LLaMA): Verwenden eine untere Dreiecksmatrix-kausale (autoregressive) Maske. Ein Token an Position $i$ kann nur auf Positionen $j \le i$ achten. Dies verhindert die Aufmerksamkeit auf zukünftige Tokens, ermöglicht die autoregressive Token-für-Token-Generierung während der Inferenz und verhindert das Label-Leakage zukünftiger Tokens während des parallelisierten Trainings. 2. Bidirektionale Encoder (z.B. BERT): Verwenden keine kausale Maske; jedes Token kann auf alle vergangenen und zukünftigen Tokens in der Sequenz achten. Sie verwenden Padding-Masken, um zu verhindern, dass gültige Tokens auf leere `[PAD]`-Tokens in gebatchten Sequenzen achten. Bidirektionale Aufmerksamkeit erzeugt reichhaltige, allumfassende kontextuelle Repräsentationen, die ideal für Verständnisaufgaben sind, verhindert jedoch die direkte autoregressive Textgenerierung in einem einzigen Durchgang.

import torch
import torch.nn.functional as F

scores = torch.randn(3, 3)
# Create upper-triangular mask for future positions
causal_mask = torch.triu(torch.ones(3, 3, dtype=torch.bool), diagonal=1)

# Mask future positions with -inf before softmax
masked_scores = scores.masked_fill(causal_mask, float('-inf'))
atten_weights = F.softmax(masked_scores, dim=-1)
print(atten_weights)
Diese Frage mit einem KI-Coach beantworten

7Erklären Sie den Unterschied zwischen Encoder-Only-, Decoder-Only- und Encoder-Decoder-Transformer-Architekturen für Sprachaufgaben.

Die drei primären Transformer-Architekturen unterscheiden sich grundlegend in ihren Aufmerksamkeits-Maskierungsmustern und angestrebten operationellen Zielen: 1. **Encoder-Only** (z.B. BERT, RoBERTa): Verwendet bidirektionale Selbstaufmerksamkeit, bei der jedes Token gleichzeitig alle anderen Token in der Sequenz beachten kann. Es erzeugt reichhaltige kontextuelle Repräsentationen für eine gesamte Eingabesequenz, wodurch es ideal für Klassifikation, extraktives QA (Question Answering, Fragebeantwortung) und Merkmalsrepräsentation ist. Es kann von Natur aus keinen autoregressiven Text generieren. 2. **Decoder-Only** (z.B. GPT-3, Llama, Mistral): Verwendet kausale (unidirektionale) Selbstaufmerksamkeit, bei der Token $i$ nur Token an Positionen $j \le i$ beachten kann. Es wird autoregressiv unter Verwendung der Vorhersage des nächsten Tokens trainiert und dient als Standardarchitektur für generative Sprachmodelle, Code-Generierung und offene Konversationen. 3. **Encoder-Decoder** (z.B. T5, BART): Kombiniert einen bidirektionalen Encoder mit einem autoregressiven kausalen Decoder. Zusätzlich zur kausalen Selbstaufmerksamkeit über generierte Token verwendet der Decoder Cross-Attention-Schichten, die die Ausgaberepräsentationen des Encoders abfragen. Diese Architektur ist speziell für Sequenz-zu-Sequenz-Transformationsaufgaben wie Übersetzung und Zusammenfassung konzipiert.

# Causal mask (Decoder-Only) vs Full mask (Encoder-Only)
import torch

seq_len = 4
encoder_mask = torch.ones(seq_len, seq_len)  # Full bidirectional attention
decoder_causal_mask = torch.tril(torch.ones(seq_len, seq_len))  # Lower-triangular

print("Encoder Mask:
", encoder_mask)
print("Decoder Causal Mask:
", decoder_causal_mask)
Diese Frage mit einem KI-Coach beantworten

Middle-Fragen

8Erläutern Sie, wie die Wahl von Tokenizern auf Byte-Ebene, Unicode-sensitiven und mehrsprachigen Tokenizern die Modellqualität, Kosten und Fairness über Sprachen hinweg beeinflusst.

Tokenizer-Designentscheidungen – wie Segmentierungen auf Byte-Ebene versus Unicode-sensitiv sowie mehrsprachige Vokabularzuweisungen – wirken sich direkt auf die nachgelagerte Modellqualität, die Inferenz-/Trainingskosten und die sprachliche Fairness aus. Hinsichtlich Kosten und Fairness weisen Tokenizer, die überwiegend auf englischen oder Latein-Schrift-Korpora trainiert wurden, die meisten Vokabulareinträge englischen Wörtern und Morphemen zu. Infolgedessen erreicht Englisch eine hohe Komprimierung (z. B. ~1,3 Tokens pro Wort), während nicht-lateinische Schriften (z. B. Arabisch, Devanagari, Thai, Chinesisch) oder ressourcenarme Sprachen oft in mehrere Subwörter oder rohe UTF-8-Bytes fragmentiert werden (oft 3 bis 6 Tokens pro Wort). Diese Disparität wird oft als „Token-Steuer“ oder „Fertilitätsraten-Ungleichgewicht“ bezeichnet: Nicht-englische Nutzer zahlen pro semantischer Inhaltseinheit in der API-Abrechnung deutlich mehr, verbrauchen Kontextfenster-Limits viel schneller und leiden unter höherer Latenz. Bezüglich der Qualität vermeiden Tokenizer auf Byte-Ebene (wie Byte-level BPE in GPT-2/GPT-4 oder SentencePiece mit Byte-Fallback in LLaMA) Abstürze durch unbekannte Zeichen und Out-of-Vocabulary (UNK)-Fehler vollständig, da jede gültige UTF-8-Zeichenkette in Byte-Tokens zerlegt wird. Eine übermäßige Byte-Fragmentierung verschlechtert jedoch die Repräsentationsqualität, da der Transformer Schichten darauf verwenden muss, Byte-Fragmente wieder zu semantischen Konzepten zusammenzusetzen, bevor er hochrangige Schlussfolgerungen ziehen kann. Eine Vergrößerung des mehrsprachigen Vokabulars (z. B. eine Erweiterung von 32k auf 128k+ Tokens) gleicht die Fertilitätsraten aus und verbessert die Leistung bei nachgelagerten Aufgaben über verschiedene Sprachen hinweg, auf Kosten einer moderat größeren Ein-/Ausgabe-Embedding-Schicht.

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained('gpt2')

english_text = 'Hello world'
hindi_text = 'नमस्ते दुनिया'

print('English tokens:', tokenizer.tokenize(english_text))
print('Hindi tokens:', tokenizer.tokenize(hindi_text))
print('English token count:', len(tokenizer.encode(english_text)))
print('Hindi token count:', len(tokenizer.encode(hindi_text)))
Diese Frage mit einem KI-Coach beantworten

9Welche Tokenisierungs-Artefakte treten beim numerischen Schlussfolgern, bei der Code-Generierung oder bei seltenem Unicode-Text auf, und wie können spezialisierte Tokenizer diese reduzieren?

Tokenisierungs-Artefakte entstehen, wenn Subwort-Tokenizer strukturierte, numerische oder seltene Texte inkonsistent aufteilen, was das Modell daran hindert, die zugrunde liegende semantische oder syntaktische Regelmäßigkeit zu erkennen. Zu den wichtigsten Artefakten gehören: 1. **Artefakte beim numerischen Schlussfolgern:** Standard BPE (Byte Pair Encoding)-Tokenizer, die auf allgemeinem Text trainiert sind, teilen Zahlen basierend auf der Häufigkeit in willkürliche Blocklängen auf (z.B. könnte '12345' als ['12', '345'] tokenisiert werden, während '12346' als ['123', '46'] tokenisiert wird). Diese inkonsistente Gruppierung verletzt die Stellenwertausrichtung (Einer, Zehner, Hunderter) und erschwert arithmetische Schlussfolgerungen. 2. **Artefakte bei der Code-Generierung:** Einrückungen (führende Leerzeichen/Tabs) und Mehrzeichen-Operatoren (z.B. '==', '!=', '->') werden oft unregelmäßig über Leerzeichen-Grenzen hinweg aufgeteilt, was zu Einrückungsfehlern, aufgeblähten Token-Anzahlen in tief eingerücktem Code und Syntaxfehlern führt. 3. **Artefakte bei seltenen Unicode- und Emoji-Zeichen:** Multibyte-UTF-8-Sequenzen (wie komplexe Emojis mit Zero-Width Joiner (ZWJ) oder seltene Skripte) werden in rohe Byte-Tokens aufgeteilt, die keine individuelle semantische Bedeutung tragen, was zu halluzinierten Zeichen oder beschädigter Glyphen-Darstellung bei der Generierung führt. Spezialisierte Tokenizer reduzieren diese Artefakte durch maßgeschneiderte Vor-Tokenisierungsregeln und Vokabularbeschränkungen: - **Ziffernaufteilung:** Das Erzwingen einer Einzelziffern-Tokenisierung (z.B. Regex-Aufteilung jeder Ziffer `0-9` in ein eigenes Token) gewährleistet eine einheitliche Stellenwertdarstellung für mathematisches Schlussfolgern. - **Dedizierte Leerzeichen-/Einrückungs-Tokens:** Hinzufügen expliziter Tokens für mehrfache Leerzeichen-Einrückungen (z.B. 2, 4, 8 Leerzeichen) und Beibehaltung von Schlüsselwörtern/Operatoren der Programmiersprache. - **Regex-Vor-Tokenisierung / Byte-Level-Fallbacks:** Verwendung von Regex-Splittern (wie GPT-4/tiktoken Regexes), die Satzzeichen, Buchstaben und Zahlen vor der Berechnung von BPE-Merges in strikte Kategorien trennen, wodurch kategorieübergreifende Zusammenführungen verhindert werden (z.B. wird verhindert, dass 'a=10' zu einem einzelnen Token zusammengeführt wird).

import tiktoken

# tiktoken cl100k_base (GPT-4 / ChatGPT) enforces digit and whitespace handling
enc = tiktoken.get_encoding('cl100k_base')

num1 = '12345'
num2 = '12346'
code_indent = '    def foo():'

print('Tokens num1:', [enc.decode([t]) for t in enc.encode(num1)])
print('Tokens num2:', [enc.decode([t]) for t in enc.encode(num2)])
print('Tokens code:', [enc.decode([t]) for t in enc.encode(code_indent)])
Diese Frage mit einem KI-Coach beantworten

10Erklären Sie die Kompromisse bei der Attention mit langem Kontext, einschließlich quadratischer vollständiger Attention, Sliding-Window-Attention, spärlicher oder globaler Attention, KV-Cache-Kosten und Attention-Verdünnung.

Die Skalierung der Attention auf lange Kontextfenster bringt Kompromisse hinsichtlich Berechnung, Speicherbedarf und Modellgenauigkeit mit sich: 1. **Quadratische vollständige Attention vs. Sliding-Window- / spärliche Attention:** Standardmäßige vollständige Attention skaliert quadratisch ($O(N^2)$) in Rechenleistung und Aktivierungsspeicher mit der Sequenzlänge $N$. Sliding-Window- (lokale) Attention beschränkt die Attention auf eine feste Nachbarschaft $W$, wodurch die Komplexität auf $O(N \cdot W)$ reduziert wird, aber mehrere Schichten erfordert, um Informationen über entfernte Tokens hinweg zu verbreiten. Spärliche oder globale Attention-Muster kombinieren lokale Fenster mit ausgewählten globalen Anker-Tokens, um die $O(N)$-Skalierung beizubehalten und gleichzeitig Langstreckenkommunikation zu ermöglichen. 2. **KV-Cache-Speicherkosten:** Während der autoregressiven Generierung werden Schlüssel (Keys) und Werte (Values) für alle vorherigen Tokens zwischengespeichert, um redundante Berechnungen zu vermeiden. Der KV-Cache-Speicher skaliert linear mit der Sequenzlänge ($O(B \cdot L \cdot H_{KV} \cdot D \cdot N)$). Bei sehr langen Kontexten (32k–128k+ Tokens) verbraucht der KV-Cache Dutzende von Gigabyte GPU VRAM pro Batch, was die maximale Batch-Größe und Speicherbandbreite einschränkt. 3. **Attention-Verdünnung (Lost-in-the-Middle):** Wenn der Kontext wächst, summiert sich der Softmax-Nenner über Zehntausende von Tokens, wodurch die Wahrscheinlichkeitsmasse dünn über irrelevanten Kontext verteilt wird. Dieser Entropieanstieg verwässert die Schärfe der Attention und beeinträchtigt die Fähigkeit des Modells, spezifische Informationen, die in der Mitte langer Prompts eingebettet sind, zuverlässig abzurufen.

def kv_cache_gb(batch_size, seq_len, layers=32, kv_heads=8, head_dim=128, bytes_per_elem=2):
    # 2 for Key and Value
    total_bytes = batch_size * seq_len * layers * kv_heads * head_dim * 2 * bytes_per_elem
    return total_bytes / (1024 ** 3)

print(f"32k context: {kv_cache_gb(4, 32768):.2f} GB")
print(f"128k context: {kv_cache_gb(4, 131072):.2f} GB")
Diese Frage mit einem KI-Coach beantworten

11Vergleichen Sie MHA (Multi-Head Attention), MQA (Multi-Query Attention) und GQA (Grouped-Query Attention) und erklären Sie, wie sie sich auf den Key-Value (KV)-Cache-Speicher und den Dekodier-Durchsatz auswirken.

Multi-Head Attention (MHA), Multi-Query Attention (MQA) und Grouped-Query Attention (GQA) unterscheiden sich darin, wie Key ($K$)- und Value ($V$)-Heads über Query ($Q$)-Heads hinweg geteilt werden: 1. **Multi-Head Attention (MHA)**: Hat eine gleiche Anzahl von $Q$-, $K$- und $V$-Heads ($H_Q = H_{KV}$, Verhältnis 1:1). Jeder Query-Head achtet auf seine eigenen unabhängigen Key/Value-Repräsentationen. Obwohl dies ausdrucksstark ist, erfordert es das Caching separater KV-Matrizen für jeden Head. 2. **Multi-Query Attention (MQA)**: Verwendet mehrere $Q$-Heads ($H$), aber nur 1 geteilten $K$-Head und 1 geteilten $V$-Head (Verhältnis $H:1$). Dies reduziert die KV-Cache-Größe um den Faktor $H$, kann aber zu einem leichten Qualitätsverlust oder Instabilität beim Training führen. 3. **Grouped-Query Attention (GQA)**: Gruppiert $Q$-Heads in $G$ Partitionen, wobei jede Gruppe einen einzelnen $K$- und $V$-Head teilt (z.B. 8 $Q$-Heads pro KV-Head). GQA bietet einen optimalen Kompromiss, indem es praktisch die gesamte Modellierungsqualität von MHA wiederherstellt, während die Speichervorteile von MQA erhalten bleiben. **Auswirkungen auf den KV-Cache und den Dekodier-Durchsatz:** Die autoregressive Token-Generierung (Dekodierung) ist durch die Speicherbandbreite begrenzt, da die GPU (Graphics Processing Unit) für jedes einzelne generierte Token den gesamten KV-Cache vom HBM (High-Bandwidth Memory) in den On-Chip-SRAM (Static Random-Access Memory) übertragen muss. Durch die Reduzierung der Anzahl der KV-Heads um $H/G$ (z.B. $4\times$ bis $8\times$ bei GQA oder $32\times+$ bei MQA): - Der Speicherbedarf des KV-Caches wird proportional reduziert, was viel größere Batch-Größen für das Serving im GPU VRAM (Video Random-Access Memory) ermöglicht. - Der HBM-Speicherleseverkehr pro Token sinkt erheblich, was den Dekodier-Token-Durchsatz dramatisch erhöht.

# Model with 32 Query Heads
num_q_heads = 32

mha_kv_heads = 32 # 1:1 ratio
gqa_kv_heads = 8  # 4:1 ratio (4 query heads per KV head)
mqa_kv_heads = 1  # 32:1 ratio (1 shared KV head)

print(f"KV Cache Size Relative to MHA:")
print(f"MHA: {mha_kv_heads / mha_kv_heads * 100:.1f}%")
print(f"GQA: {gqa_kv_heads / mha_kv_heads * 100:.1f}%")
print(f"MQA: {mqa_kv_heads / mha_kv_heads * 100:.1f}%")
Diese Frage mit einem KI-Coach beantworten

12Erklären Sie, wie FlashAttention die exakte Attention-Berechnung beschleunigt, ohne die Attention-Ausgaben zu ändern.

FlashAttention beschleunigt die Attention-Berechnung, indem es den Algorithmus I/O-bewusst gestaltet – es minimiert den Lese- und Schreibspeicherverkehr zwischen dem langsamen GPU High Bandwidth Memory (HBM) und dem schnellen On-Chip SRAM, anstatt zu versuchen, die Gesamtzahl der arithmetischen FLOPs zu reduzieren. Standard-Attention materialisiert zwischenzeitliche N x N Attention-Score- und Wahrscheinlichkeitsmatrizen im HBM, was einen erheblichen Speicherbandbreitenengpass verursacht. FlashAttention überwindet dies durch drei Schlüsselmechanismen: 1. **Tiling:** Es teilt die Query-, Key- und Value-Matrizen in Blöcke auf, die vollständig in den GPU On-Chip SRAM passen. 2. **Online-Softmax:** Es berechnet Softmax inkrementell über Blöcke, indem es laufende Maxima und Normalisierersummen verfolgt und Teilergebnisse aktualisiert, ohne die vollständige materialisierte N x N Matrix im Speicher zu benötigen. 3. **Exakte Neuberechnung:** Während des Backward Pass liest es keine gespeicherten zwischenzeitlichen Attention-Matrizen aus dem HBM; stattdessen berechnet es diese on-the-fly im SRAM aus den gespeicherten laufenden Statistiken neu. Da keine Approximationen, Low-Rank-Faktorisierungen oder Token-Dropping-Heuristiken verwendet werden, ist die Ausgabe mathematisch exakt bis auf die numerische Präzision von Gleitkommazahlen, während der HBM-Speicherbedarf von O(N^2) auf O(N) reduziert wird.

import torch

def online_softmax_step(m_prev, l_prev, out_prev, scores_block, v_block):
    # scores_block: (B, H, Br, Bc), v_block: (B, H, Bc, D)
    m_block = scores_block.max(dim=-1, keepdim=True).values
    m_new = torch.maximum(m_prev, m_block)
    
    # Rescale previous and current accumulators
    p_prev_scale = torch.exp(m_prev - m_new)
    p_block = torch.exp(scores_block - m_new)
    
    l_new = p_prev_scale * l_prev + p_block.sum(dim=-1, keepdim=True)
    out_new = (p_prev_scale * l_prev * out_prev + p_block @ v_block) / l_new
    return m_new, l_new, out_new
Diese Frage mit einem KI-Coach beantworten

Senior-Fragen

13Entwerfen Sie deterministische agentische Workflows unter Verwendung von Planern, Zustandsmaschinen, DAGs, typisiertem Zwischenzustand, begrenzten Wiederholungsversuchen und Tool-Ergebnisverifizierung anstelle von offenen Agenten-Loops.

Offene Agenten-Loops (z.B. unbegrenzte autonome ReAct Loops) in der Produktion leiden oft unter nicht-deterministischer Verzweigung, Endlosschleifen, unkontrolliertem Token-Verbrauch und Zustandsdrift. Ein deterministischer agentischer Workflow ersetzt freie Loops durch einen strukturierten, beobachtbaren Kontrollfluss: 1. Zustandsmaschinen und DAGs: Der Kontrollfluss wird als expliziter gerichteter azyklischer Graph (DAG) oder endliche Zustandsmaschine (z.B. LangGraph, Temporal, AWS Step Functions) definiert. Knotenübergänge hängen von expliziten Bedingungen und typisierten Ergebnissen ab, anstatt von offenen Modellentscheidungen. 2. Typisierter Zwischenzustand: Der über Knoten hinweg geteilte Zustand wird mit strikten Schemata (z.B. Pydantic-Modelle oder Dataclasses) modelliert. Knoten führen validierte Lese- und Schreiboperationen durch, wodurch Schema-Drift oder fehlerhafter Zustand verhindert wird. 3. Planer: Strukturierte Planer geben einen eingeschränkten Plan im Voraus aus (z.B. eine geordnete Liste von Enumerations-gestützten Schritten) oder wählen aus einer eingeschränkten Menge gültiger Zustandsübergänge, anstatt frei über die nächsten Aktionen ohne Einschränkungen zu entscheiden. 4. Tool-Ergebnisverifizierung: Von Tools zurückgegebene Ausgaben werden deterministisch gegen Schemata und Geschäftsregeln validiert, bevor der Zustand aktualisiert oder an nachgelagerte LLM-Schritte weitergegeben wird. 5. Begrenzte Wiederholungsversuche und Fallbacks: Jeder Schritt erzwingt explizite Wiederholungsbudgets, exponentielle Backoffs, Timeouts und Fallback-Übergänge (z.B. Eskalation zur menschlichen Überprüfung oder Auslösen sicherer Enthaltung), um die Beendigung zu garantieren.

from pydantic import BaseModel
from typing import Optional, Literal

class WorkflowState(BaseModel):
    user_query: str
    extracted_id: Optional[str] = None
    verification_status: Literal["PENDING", "VERIFIED", "FAILED"] = "PENDING"
    retry_count: int = 0
    max_retries: int = 3

def execute_validation_node(state: WorkflowState) -> WorkflowState:
    if state.retry_count >= state.max_retries:
        state.verification_status = "FAILED"
        return state
    try:
        result = call_verification_service(state.extracted_id)
        state.verification_status = "VERIFIED" if result.is_valid else "FAILED"
    except Exception:
        state.retry_count += 1
    return state
Diese Frage mit einem KI-Coach beantworten

14Entwickeln Sie eine Vertrauens- und Enthaltungsstrategie für einen LLM-Assistenten (Large Language Model), der Fragen aus regulierten Bereichen beantwortet.

In regulierten Bereichen (wie dem Gesundheitswesen, Bankwesen, Rechtswesen und Compliance) führen inkorrekte Antworten zu behördlichen Strafen, rechtlicher Haftung und Sicherheitsrisiken. Eine robuste Vertrauens- und Enthaltungsstrategie kombiniert multi-signal-kalibrierte Konfidenzbewertung, gestufte Antwortschwellenwerte und deterministische Eskalations-Workflows: 1. **Multi-Signal-Konfidenzkalibrierung:** Rohe LLM-Log-Wahrscheinlichkeiten (Logprobs) sind bei Out-of-Domain-Anfragen oft falsch kalibriert. Die Konfidenzbewertung sollte mehrere unabhängige Signale synthetisieren: * **Retrieval Grounding Score:** Semantische Ähnlichkeit und Neubewertungskonfidenz der abgerufenen Evidenz-Chunks. * **Claim-Level Entailment (NLI):** Natural Language Inference (NLI)-Modelle, die verifizieren, dass jede extrahierte Behauptung durch den abgerufenen Quellkontext impliziert wird. * **Semantische Entropie / Selbstkonsistenz:** Messung der semantischen Konsistenz über mehrere gesampelte Generierungen hinweg. * **Modell-Token-Log-Wahrscheinlichkeiten:** Minimum- und Durchschnitts-Log-Wahrscheinlichkeiten für wichtige benannte Entitäten und faktische Token. 2. **Gestufte Enthaltungsrichtlinie:** * **Hohe Konfidenz (Score >= Hoher Schwellenwert):** Die generierte Antwort direkt mit Inline-Zitaten bereitstellen. * **Mittlere Konfidenz / Mehrdeutig (Niedriger Schwellenwert <= Score < Hoher Schwellenwert):** Eine konservative Antwort mit expliziten Vorbehalten, Haftungsausschlüssen oder der Aufforderung an den Benutzer, klärende Details anzugeben. * **Geringe Konfidenz / Außerhalb des Geltungsbereichs (Score < Niedriger Schwellenwert):** Harte Enthaltung mit einer standardisierten Ablehnungsnachricht. 3. **Eskalation und Überprüfbarkeit der Compliance:** * **Deterministische Eskalation:** Enthaltungen oder kritische Diskrepanzen werden automatisch an Mensch-in-der-Schleife (HITL)-Warteschlangen oder Agenten-Ticketing-Systeme mit vollem Kontext weitergeleitet. * **Audit-Trail & Herkunftsnachweis:** Die vollständige Telemetrie – einschließlich Prompt-Hashes, IDs der abgerufenen Dokumente, Einzelbewertungen der Konfidenzkomponenten und endgültige Routing-Entscheidungen – muss für die behördliche Überprüfbarkeit protokolliert werden.

from dataclasses import dataclass
from typing import Literal

@dataclass
class DecisionResult:
    action: Literal["SERVE", "SERVE_WITH_CAVEAT", "ABSTAIN_AND_ESCALATE"]
    confidence_score: float
    reason: str

def evaluate_confidence_policy(retrieval_score: float, nli_entailment_score: float, semantic_entropy: float) -> DecisionResult:
    # Composite calibrated confidence index [0, 1]
    composite_score = (0.4 * retrieval_score) + (0.4 * nli_entailment_score) + (0.2 * (1.0 - semantic_entropy))
    
    if composite_score >= 0.85:
        return DecisionResult("SERVE", composite_score, "High evidence grounding")
    elif composite_score >= 0.60:
        return DecisionResult("SERVE_WITH_CAVEAT", composite_score, "Partial evidence support")
    else:
        return DecisionResult("ABSTAIN_AND_ESCALATE", composite_score, "Insufficient ground truth")
Diese Frage mit einem KI-Coach beantworten

15Entwickeln Sie eine Modell-Routing-Strategie, die zwischen kleinen, mittleren und großen Modellen basierend auf Anfragedkomplexität, Kosten, Risiko und Qualitätsanforderungen wählt.

Eine Produktions-Modell-Routing-Architektur leitet eingehende Anfragen über kleine (z. B. 1B–8B SLMs (Small Language Models)), mittlere (z. B. 14B–70B Modelle) und große (z. B. Frontier- oder große MoE (Mixture of Experts)-Modelle) Stufen, indem sie Komplexität, Latenz, Risiko und Rechenkosten ausbalanciert. Der Routing-Workflow kombiniert im Allgemeinen statische Regeln, prädiktives Routing und dynamische Fallback-Kaskaden: 1. **Deterministische/Statische Policy-Gates:** Filtern Anfragen nach Kundentier, strikten Latenz-SLAs (Service Level Agreements), regulatorischem/domänenspezifischem Risiko (z. B. medizinische Diagnose oder juristische Textgestaltung werden direkt an Top-Tier-Modelle weitergeleitet) oder einfachen regelbasierten Aufgaben (z. B. grundlegende Regex/Formatierung an kleine Modelle). 2. **Prädiktives Komplexitäts-Routing:** Ein schneller, leichtgewichtiger Klassifikator (wie eine Embedding-Ähnlichkeitssuche, ein Cross-Encoder oder ein kleiner SLM-Router) bewertet die Anfragedkomplexität, Argumentationstiefe und Domänen-Ambiguität, um die kosteneffizienteste Stufe im Voraus auszuwählen. 3. **Dynamische Ausführungs- & Eskalationskaskaden:** Senden Sie den Prompt zuerst an ein kleineres Modell und bewerten Sie die Ausgabekonfidenz (über Token-Log-Wahrscheinlichkeiten/-Entropie, Validität strukturierter Schemata oder Guardrail-Checks). Wenn die Konfidenz unter dem Schwellenwert liegt oder die Validierung fehlschlägt, eskaliert der Router an ein mittleres oder großes Modell. Wichtige Systemkompromisse umfassen den Latenz-Overhead des Routers versus Rechenkosteneinsparungen, Fallback-Timeout-Budgets bei Lastspitzen und kontinuierliche Evaluierung (z. B. Shadow-Evaluierung zur Verfolgung der Drift der Ausgabequalität über die Stufen hinweg).

class DynamicModelRouter:
    def __init__(self, small_client, medium_client, large_client, classifier, guardrail):
        self.small = small_client
        self.medium = medium_client
        self.large = large_client
        self.classifier = classifier
        self.guardrail = guardrail

    async def route_and_execute(self, request):
        # 1. Deterministic Risk Gate
        if request.risk_level == "high" or request.domain in ["legal", "medical_compliance"]:
            return await self.large.generate(request.prompt)
        
        # 2. Predictive Complexity Classifier
        complexity = self.classifier.predict_complexity(request.prompt) # 0.0 to 1.0
        
        if complexity < 0.35:
            response = await self.small.generate(request.prompt)
            if self.guardrail.is_acceptable(response):
                return response
            return await self.medium.generate(request.prompt) # Fallback
            
        if complexity < 0.75:
            response = await self.medium.generate(request.prompt)
            if self.guardrail.is_acceptable(response):
                return response
            return await self.large.generate(request.prompt) # Fallback
            
        # 3. High complexity frontier execution
        return await self.large.generate(request.prompt)
Diese Frage mit einem KI-Coach beantworten