Příprava na pohovor z LLM a generativní umělé inteligence
Otázky k pohovorům pro inženýry LLM a generativní umělé inteligence
15 vybraných otázek k pohovorům z oblasti LLM a generativní umělé inteligence, seskupených podle úrovně seniority. Použijte je k zopakování základů, praktických kompromisů a úvah pro produkční prostředí na úrovni seniora.
1Vysvětlete subword tokenizaci a proč je preferována před tokenizací na úrovni slov nebo znaků v moderních jazykových modelech.
Subword tokenizace je hybridní přístup k segmentaci textu, který rozděluje text na morfologické části proměnné délky nebo podřetězce založené na frekvenci (jako 'un', 'break', 'able'), spíše než na celá slova nebo jednotlivé znaky. Algoritmy jako Byte-Pair Encoding (BPE), WordPiece a Unigram LM se učí slovník pevné velikosti z tréninkového korpusu, kde častá slova zůstávají nedotčena jako samostatné tokeny, zatímco vzácná nebo neviděná slova jsou rozložena na známé subword jednotky. Subword tokenizace je preferována v moderních jazykových modelech, protože vyvažuje velikost slovníku, délku sekvence a robustnost vůči slovům mimo slovník (OOV). Čistě slovní tokenizace vyžaduje nadměrně velký slovník (vedoucí k obrovským vkládacím maticím) a stále trpí OOV tokeny mapovanými na generické '[UNK]' tokeny. Naopak čistě znaková tokenizace eliminuje problémy s OOV, ale vede k velmi dlouhým sekvencím, které drasticky zvyšují výpočetní složitost v mechanismech pozornosti (které škálují kvadraticky s délkou sekvence) a ředí sémantickou hustotu na token. Subword tokenizace dosahuje optimálního kompromisu udržováním zvladatelných délek sekvencí, praktickými velikostmi slovníků (typicky 32k až 128k tokenů) a nulovými mírami OOV (zejména v kombinaci se zálohami na úrovni bajtů).
2Vysvětlete rozdíl mezi statickými vloženími slov (static word embeddings), kontextovými vloženími (contextual embeddings) a skrytými stavy transformátorů (transformer hidden states).
Statická vložení slov (static word embeddings), kontextová vložení (contextual embeddings) a skryté stavy transformátorů (transformer hidden states) představují postupný vývoj v tom, jak textové reprezentace zachycují význam a syntaktický kontext.
1. Statická vložení slov (např. Word2Vec, GloVe, FastText) přiřazují každému tokenu ve slovníku jeden pevný vektor bez ohledu na jeho kontext ve větě. V tomto paradigmatu mají polysémantická slova jako 'bank' (říční břeh vs. finanční banka) nebo 'apple' (ovoce vs. technologická společnost) v každém kontextu identické vektorové reprezentace, spoléhající na statickou vyhledávací tabulku.
2. Kontextová vložení (např. rané ELMo, BERT tokenové reprezentace nebo větná vložení z Bi-Enkodérů) produkují reprezentace, kde je vektor pro token dynamickou funkcí jeho okolního kontextu. V BERT nebo ELMo dostane 'bank' ve výrazu 'river bank' zcela odlišný vektor vložení než 'bank' ve výrazu 'deposit money at the bank'.
3. Skryté stavy transformátorů odkazují na mezilehlé vektorové reprezentace produkované v každé jednotlivé vrstvě transformátorové sítě během dopředného průchodu. S ohledem na vstupní tokenová vložení ve vrstvě 0, každá následující transformátorová vrstva aplikuje samo-pozornost (self-attention) a dopředné transformace (feed-forward transformations), čímž vytváří sekvenci skrytých stavových vektorů h_l ve vrstvě l. Zatímco skryté stavy poslední vrstvy fungují jako kontextová vložení vysoké úrovně, nižší a střední skryté stavy zachycují syntaktické, lexikální a strukturální prvky nízké úrovně. Skryté stavy transformátorů tak zahrnují celé vertikální kontinuum reprezentací vrstvu po vrstvě napříč sítí.
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())
3Vysvětlete, co představuje vkládací prostor (embedding space) a jak se interpretuje kosinová podobnost (cosine similarity) pro textová vložení (text embeddings).
Vkládací prostor (embedding space) je spojitý, vícerozměrný vektorový prostor R^d, kam jsou mapovány diskrétní textové entity (slova, věty nebo dokumenty) tak, že sémantické, syntaktické nebo relační podobnosti odpovídají geometrické blízkosti a směrovým vztahům. V tomto prostoru vzdálenosti a úhly odrážejí sémantickou příbuznost.
Kosinová podobnost (Cosine similarity) měří kosinus úhlu theta mezi dvěma vektory `u` a `v`, vypočítaný jako:
`Cosine Similarity(u, v) = (u . v) / (||u|| ||v||)`
Kosinová podobnost se v textových vloženích interpretuje následovně:
- **Rozsah a orientace**: Vytváří skalární hodnotu typicky v rozmezí [-1, 1] (nebo [0, 1] pro nezáporná vložení). Hodnota blízká 1.0 naznačuje, že oba vektory směřují prakticky stejným směrem, což odráží vysokou sémantickou podobnost nebo tematické sladění. Hodnota blízká 0.0 naznačuje ortogonalitu (sémantickou nezávislost nebo nesouvisející) a záporné hodnoty naznačují opačné orientace.
- **Invariantnost vůči velikosti (Magnitude Invariance)**: Na rozdíl od Euklidovské vzdálenosti (L2 vzdálenosti) nebo skalárního součinu (dot product) kosinová podobnost normalizuje délku vektoru. V textových vloženích může velikost vektoru někdy korelovat s délkou sekvence, frekvencí tokenů nebo specificitou termínu. Tím, že se zaměřuje čistě na směrové sladění, kosinová podobnost izoluje sémantickou orientaci od rozdílů ve velikosti vektoru.
4Vysvětlete rozdíl mezi tokenovými vnořeními, pozičními vnořeními a segmentovými nebo typovými vnořeními ve vstupech transformátoru.
Ve vstupech transformátoru (zejména v architekturách stylu BERT) je vstupní reprezentace pro každý token typicky tvořena sčítáním prvek po prvku tří odlišných vektorů vnoření: 1. Tokenové vnoření: Mapuje ID diskrétních tokenů ze slovníku do hustých vektorů reprezentujících základní sémantickou a lexikální identitu tokenů. 2. Poziční vnoření: Vnáší do reprezentace informaci o pořadí tokenů a jejich sekvenčním indexu, čímž kompenzuje skutečnost, že mechanismus self-attention je inherentně permutačně invariantní. 3. Segmentové (nebo typové) vnoření: Rozlišuje mezi různými úseky textu nebo větami zabalenými do jedné vstupní sekvence (například Věta A vs. Věta B v úlohách párové klasifikace nebo odpovídání na otázky). Kombinace těchto vnoření poskytuje jeden hustý vstupní tenzor, který kóduje význam tokenů, jejich pozici a seskupení sekvencí před předáním do první vrstvy transformátoru.
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)
5Vysvětlete pozornost (attention) jako mechanismus pro vzájemné provázání tokenů v sekvenci, včetně dotazů (queries), klíčů (keys), hodnot (values) a vícehlavé pozornosti (multi-head attention).
Pozornost je mechanismus, který umožňuje tokenům v sekvenci dynamicky směrovat informace a vážit relevanci všech ostatních tokenů na základě kontextové shody. Lineární projekce převádějí vstup každého tokenu na tři vektory: - Dotaz (Q): Představuje, jaké informace aktuální token hledá. - Klíč (K): Představuje, jaké atributy nebo obsah token nabízí k porovnání s dotazy. - Hodnota (V): Obsahuje skutečnou informační náplň, která má být agregována. Ve škálované bodové pozornosti (scaled dot-product attention) se skóre pozornosti počítají násobením dotazů a klíčů ($Q K^T$), škálované faktorem $\frac{1}{\sqrt{d_k}}$ pro zabránění mizení gradientu napříč velkými dimenzemi, a normalizované funkcí softmax. Konečný výstup je vážený součet hodnot: $$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$ Vícehlavá pozornost (Multi-Head Attention, MHA) promítá $Q$, $K$ a $V$ do více nezávislých reprezentativních podprostorů (hlav) paralelně. To umožňuje modelu souběžně se zaměřit na různé typy vztahů (např. syntaktickou strukturu, koreferenci, závislosti na dlouhé vzdálenosti) napříč pozicemi. Výstupy hlav jsou zřetězeny a lineárně promítnuty zpět do dimenze modelu.
6Vysvětlete, jak se maskování pozornosti (attention masking) liší u kauzálních dekodérů oproti obousměrným kodérům a jaké chování umožňuje nebo brání.
Maskování pozornosti (attention masking) řídí, kterým tokenům je dovoleno věnovat pozornost jiným tokenům, a to nastavením logitů pozornosti (skóre před softmaxem) na $-\infty$ pro nepovolené páry, čímž zajišťuje, že jejich váha pozornosti po softmaxu je striktně 0. 1. Kauzální dekodéry (např. GPT, LLaMA): Používají dolní trojúhelníkovou kauzální (autoregresivní) masku. Token na pozici $i$ může věnovat pozornost pouze pozicím $j \le i$. To zabraňuje věnování pozornosti budoucím tokenům, což umožňuje autoregresivní generování token po tokenu během inferencí a zabraňuje úniku popisků budoucích tokenů během paralelizovaného tréninku. 2. Obousměrné kodéry (např. BERT): Nepoužívají kauzální masku; každý token může věnovat pozornost všem minulým i budoucím tokenům v celé sekvenci. Používají masky pro vyplnění (padding masks), aby se zabránilo platným tokenům věnovat pozornost prázdným tokenům `[PAD]` v dávkových sekvencích. Obousměrná pozornost produkuje bohaté, všestranné kontextové reprezentace, které jsou ideální pro úlohy porozumění, ale zabraňuje přímému jednoprůchodovému autoregresivnímu generování textu.
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)
7Vysvětlete rozdíl mezi architekturami transformátorů pouze s encoderem (encoder-only), pouze s decoderem (decoder-only) a encoder-decoder pro jazykové úlohy.
Tři primární architektury transformátorů se zásadně liší ve svých vzorech maskování pozornosti (attention masking patterns) a cílových operačních cílech: 1. Pouze s encoderem (Encoder-Only) (např. BERT, RoBERTa): Používá obousměrnou self-attention, kde se každý token může souběžně zaměřit na všechny ostatní tokeny v sekvenci. Produkuje bohaté kontextové reprezentace pro celou vstupní sekvenci, což ji činí ideální pro klasifikaci, extrakční úlohy otázek a odpovědí (extractive QA) a reprezentaci rysů. Nemůže přirozeně generovat autoregresivní text. 2. Pouze s decoderem (Decoder-Only) (např. GPT-3, Llama, Mistral): Používá kauzální (jednosměrnou) self-attention, kde se token $i$ může zaměřit pouze na tokeny na pozicích $j \le i$. Je trénována autoregresivně pomocí predikce dalšího tokenu a slouží jako standardní architektura pro generativní jazykové modely, generování kódu a otevřenou konverzaci. 3. Encoder-Decoder (např. T5, BART): Kombinuje obousměrný encoder s autoregresivním kauzálním decoderem. Kromě kauzální self-attention přes generované tokeny používá decoder vrstvy křížové pozornosti (cross-attention layers), které se dotazují na výstupní reprezentace encoderu. Tato architektura je účelově postavena pro úlohy transformace sekvence na sekvenci, jako je překlad a sumarizace.
8Vysvětlete, jak volba tokenizátorů – např. na úrovni bytů (byte-level), s podporou Unicode (Unicode-aware) a vícejazyčných – ovlivňuje kvalitu modelu, náklady a spravedlnost napříč jazyky.
Volby návrhu tokenizátorů – jako je segmentace na úrovni bytů (byte-level) vs. s podporou Unicode (Unicode-aware) a alokace vícejazyčného slovníku – přímo ovlivňují kvalitu následného modelu, náklady na inferenci/trénink a lingvistickou spravedlnost.
Z hlediska nákladů a spravedlnosti tokenizátory trénované převážně na anglických nebo latinkových korpusech alokují většinu položek slovníku anglickým slovům a morfémům. V důsledku toho angličtina dosahuje vysoké komprese (např. ~1,3 tokenu na slovo), zatímco nelatinské skripty (např. arabština, dévanágarí, thajština, čínština) nebo jazyky s nízkými zdroji jsou často fragmentovány do více podlov (subwords) nebo čistých UTF-8 bytů (často 3 až 6 tokenů na slovo). Tato disproporce se často nazývá „daň z tokenů“ nebo „nerovnováha míry plodnosti“ (fertility rate imbalance): uživatelé, kteří nehovoří anglicky, platí podstatně více za jednotku sémantického obsahu v rámci účtování API, mnohem rychleji vyčerpávají limity kontextového okna a trpí vyšší latencí.
Z hlediska kvality tokenizátory na úrovni bytů (jako je BPE na úrovni bytů – Byte-level BPE v GPT-2/GPT-4 nebo SentencePiece s návratem na byty – byte fallback v LLaMA) zcela zabraňují pádům kvůli neviděným znakům a chybám mimo slovník (out-of-vocabulary – UNK), protože jakýkoli platný řetězec UTF-8 se rozkládá na bajtové tokeny. Nicméně nadměrná fragmentace na úrovni bytů snižuje kvalitu reprezentace, protože transformátor musí strávit vrstvy rekombinací bytových fragmentů do sémantických konceptů, než provede uvažování na vysoké úrovni. Zvětšení velikosti vícejazyčného slovníku (např. rozšíření z 32 tisíc na 128 tisíc+ tokenů) vyrovnává míry plodnosti a zlepšuje výkon následných úloh (downstream task performance) napříč různými jazyky, a to za cenu mírně větší vstupní/výstupní vkládací vrstvy (embedding layer).
9Jaké artefakty tokenizace se objevují při numerickém uvažování, generování kódu nebo ve vzácném textu Unicode a jak je mohou specializované tokenizéry omezit?
Artefakty tokenizace nastávají, když subword tokenizéry nekonzistentně rozdělují strukturovaný, numerický nebo vzácný text, čímž brání modelu rozpoznat základní sémantickou nebo syntaktickou regularitu. Mezi klíčové artefakty patří: 1. Artefakty numerického uvažování: Standardní tokenizéry BPE (Byte Pair Encoding) trénované na obecném textu rozdělují čísla na libovolně dlouhé kusy na základě frekvence (např. '12345' se může tokenizovat jako ['12', '345'], zatímco '12346' jako ['123', '46']). Toto nekonzistentní seskupení narušuje zarovnání podle řádových míst (jednotky, desítky, stovky) a brání aritmetickému uvažování. 2. Artefakty generování kódu: Odsazení (úvodní mezery/tabulátory) a víceznakové operátory (např. '==', '!=', '->') se často nepravidelně rozdělují přes hranice mezi mezerami a znaky, což vede k chybám odsazení, nafouknutým počtům tokenů v hluboce odsazeném kódu a poškození syntaxe. 3. Artefakty vzácného Unicode a emotikonů: Vícebajtové sekvence UTF-8 (Unicode Transformation Format - 8-bit) (jako složité emotikony se spojovacími znaky nulové šířky nebo vzácné skripty) jsou rozděleny na syrové bajtové tokeny, které nenesou individuální sémantický význam, což způsobuje halucinované znaky nebo poškozené vykreslování glyfů při generování. Specializované tokenizéry snižují tyto artefakty pomocí přizpůsobených pravidel před-tokenizace a omezení slovníku: - Rozdělení číslic: Vynucení tokenizace po jednotlivých číslicích (např. dělení každé číslice `0-9` pomocí regulárních výrazů na vlastní token) zajišťuje jednotnou reprezentaci podle řádových míst pro matematické uvažování. - Vyhrazené tokeny pro mezery/odsazení: Přidání explicitních tokenů pro vícečetná odsazení mezerami (např. 2, 4, 8 mezer) a zachování klíčových slov/operátorů programovacích jazyků. - Před-tokenizace pomocí regulárních výrazů / záložní řešení na úrovni bajtů: Použití děličů na základě regulárních výrazů (jako jsou regexy GPT-4/tiktoken), které oddělují interpunkci, písmena a čísla do přísných kategorií před výpočtem BPE sloučení, čímž se zabrání sloučení napříč kategoriemi (např. zabránění sloučení 'a=10' do jednoho tokenu).
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)])
10Zhodnoťte kompromisy pozornostních mechanismů s dlouhým kontextem, včetně kvadratické plné pozornosti, pozornosti s posuvným oknem, řídké nebo globální pozornosti, nákladů na KV-cache a rozředění pozornosti.
Škálování pozornostních mechanismů na dlouhá kontextová okna představuje kompromisy napříč výpočetní náročností, paměťovou stopou a věrností modelu: 1. Kvadratická plná pozornost vs. pozornost s posuvným oknem / řídká pozornost: Standardní plná pozornost se škáluje kvadraticky ($O(N^2)$) ve výpočetní náročnosti a paměti pro aktivace s délkou sekvence $N$. Pozornost s posuvným oknem (lokální) omezuje pozornost na fixní okolí $W$, čímž snižuje složitost na $O(N \cdot W)$, ale vyžaduje více vrstev k šíření informací mezi vzdálenými tokeny. Řídké nebo globální vzorce pozornosti kombinují lokální okna s vybranými globálními kotevními tokeny, aby si udržely škálování $O(N)$ a zároveň umožnily komunikaci na dlouhé vzdálenosti. 2. Paměťové náklady KV-cache: Během autoregresivního generování jsou klíče a hodnoty pro všechny předchozí tokeny uloženy v cache, aby se zabránilo redundantním výpočtům. Paměť KV-cache (cache klíčů a hodnot) se škáluje lineárně s délkou sekvence ($O(B \cdot L \cdot H_{KV} \cdot D \cdot N)$). Pro velmi dlouhé kontexty (32k–128k+ tokenů) spotřebovává KV-cache desítky gigabajtů VRAM (Video RAM) GPU (Graphics Processing Unit) na dávku, čímž omezuje maximální velikost dávky a propustnost paměti. 3. Rozředění pozornosti (Ztraceno uprostřed): Jak kontext roste, jmenovatel softmaxu sčítá desítky tisíc tokenů, čímž se pravděpodobnostní hmota rozptýlí řídce napříč irelevantním kontextem. Tento nárůst entropie rozředí ostrost pozornosti a zhoršuje schopnost modelu spolehlivě si vybavit konkrétní informace vložené uprostřed dlouhých promptů (výzev).
11Porovnejte Multi-Head Attention (MHA), Multi-Query Attention (MQA) a Grouped-Query Attention (GQA) a vysvětlete, jak ovlivňují paměť KV-cache a propustnost dekódování.
Multi-Head Attention (MHA), Multi-Query Attention (MQA) a Grouped-Query Attention (GQA) se liší v tom, jak jsou hlavy klíčů ($K$) a hodnot ($V$) sdíleny mezi hlavami dotazů ($Q$):
1. **Multi-Head Attention (MHA)**: Má stejný počet $Q$, $K$ a $V$ hlav ($H_Q = H_{KV}$, poměr 1:1). Každá hlava dotazu se zaměřuje na své vlastní nezávislé reprezentace klíčů/hodnot. I když je expresivní, vyžaduje ke cachování odlišných KV matic pro každou hlavu.
2. **Multi-Query Attention (MQA)**: Používá více $Q$ hlav ($H$), ale pouze 1 sdílenou $K$ hlavu a 1 sdílenou $V$ hlavu (poměr $H:1$). To snižuje velikost KV-cache faktorem $H$, ale může vést k mírné ztrátě kvality nebo nestabilitě trénování.
3. **Grouped-Query Attention (GQA)**: Seskupuje $Q$ hlavy do $G$ oddílů, kde každá skupina sdílí jednu $K$ a $V$ hlavu (např. 8 $Q$ hlav na jednu KV hlavu). GQA nabízí optimální kompromis, kdy virtuálně obnovuje veškerou kvalitu modelování MHA a zároveň zachovává paměťové výhody MQA.
**Dopad na KV-Cache a propustnost dekódování:**
Autoregresivní generování tokenů (dekódování) je omezeno propustností paměti, protože GPU musí přenést celou KV-cache z paměti s vysokou propustností (HBM) do on-chip SRAM pro každý jednotlivý generovaný token. Snížením počtu KV hlav o $H/G$ (např. $4\times$ až $8\times$ v GQA, nebo $32\times+$ v MQA) se dosáhne:
- Paměťová stopa KV-cache je úměrně snížena, což umožňuje mnohem větší velikosti dávek při obsluze (inference) v GPU VRAM.
- Provoz čtení z paměti HBM na token výrazně klesá, což dramaticky zvyšuje propustnost dekódování tokenů.
# 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}%")
12Vysvětlete, jak FlashAttention zrychluje přesný výpočet pozornosti, aniž by měnil výstupy pozornosti.
FlashAttention zrychluje výpočet pozornosti tím, že algoritmus je „IO-aware“ – minimalizuje provoz čtení a zápisu paměti mezi pomalou GPU HBM (High Bandwidth Memory) a rychlou on-chip SRAM, namísto snahy snížit celkový počet aritmetických operací (FLOP count). Standardní pozornost (attention) materializuje mezilehlé matice N x N skóre pozornosti a pravděpodobností v HBM, což způsobuje zásadní úzké hrdlo propustnosti paměti. FlashAttention to překonává pomocí tří klíčových mechanismů:
1. **Dláždění (Tiling):** Rozděluje matice Query, Key a Value na bloky, které se zcela vejdou do on-chip SRAM GPU.
2. **Online Softmax:** Počítá softmax inkrementálně přes bloky sledováním průběžných maxim a součtů normalizátorů, aktualizuje dílčí výstupy, aniž by potřeboval celou materializovanou matici N x N v paměti.
3. **Přesný přepočet (Exact Recomputation):** Během zpětného průchodu (backward pass) nečte uložené mezilehlé matice pozornosti z HBM; místo toho je přepočítává za běhu v SRAM z uložených průběžných statistik. Protože nejsou použity žádné aproximace, faktorizace nízké hodnosti (low-rank factorizations) nebo heuristiky pro vynechávání tokenů (token-dropping heuristics), výstup je matematicky přesný až na numerickou přesnost s plovoucí desetinnou čárkou, přičemž se snižuje paměťová stopa HBM z O(N^2) na O(N).
13Navrhněte deterministické agentní pracovní postupy (agentic workflows) pomocí plánovačů, stavových automatů, DAGů (Directed Acyclic Graphs), typovaného mezilehlého stavu, omezených opakovaných pokusů a ověření výsledků nástrojů namísto neomezených smyček agentů.
Neomezené smyčky agentů (např. neomezené autonomní smyčky ReAct) v produkčním prostředí často trpí nedeterministickým větvením, nekonečnými smyčkami, nekontrolovatelným utrácením tokenů a driftem stavu. Deterministický agentní pracovní postup nahrazuje volné smyčky strukturovaným, pozorovatelným řídicím tokem: 1. **Stavové automaty a DAGy:** Řídicí tok je definován jako explicitní orientovaný acyklický graf (DAG) nebo konečný stavový automat (např. LangGraph, Temporal, AWS Step Functions). Přechody uzlů závisí na explicitních podmínkách a typovaných výsledcích, spíše než na neomezených rozhodnutích modelu. 2. **Typovaný mezilehlý stav:** Stav sdílený mezi uzly je modelován s přísnými schématy (např. Pydantic modely nebo `dataclasses`). Uzly provádějí validované operace čtení a zápisu, čímž zabraňují driftu schématu nebo chybnému stavu. 3. **Plánovače:** Strukturované plánovače vydávají omezený plán předem (např. uspořádaný seznam kroků založených na enumech) nebo vybírají z omezené množiny platných přechodů stavů, namísto volného rozhodování o dalších akcích bez omezení. 4. **Ověření výsledků nástrojů:** Výstupy vrácené nástroji jsou deterministicky validovány proti schématům a obchodním pravidlům před aktualizací stavu nebo předáním následným krokům LLM. 5. **Omezené opakované pokusy a záložní mechanismy:** Každý krok vynucuje explicitní rozpočty pro opakované pokusy, exponenciální zpomalení (exponential backoffs), časové limity (timeouts) a záložní přechody (např. eskalace k lidskému přezkoumání nebo spuštění bezpečné abstinence), aby se zaručilo ukončení.
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
14Navrhněte politiku spolehlivosti a zdržení se odpovědi pro asistenta s velkým jazykovým modelem (LLM) odpovídajícího na otázky z regulovaných domén.
V regulovaných doménách (jako je zdravotnictví, bankovnictví, právo a dodržování předpisů) nesprávné odpovědi nesou regulační sankce, právní odpovědnost a bezpečnostní rizika. Robustní politika spolehlivosti a zdržení se odpovědi kombinuje kalibrované hodnocení spolehlivosti z více signálů, stupňovité prahy pro odpovědi a deterministické pracovní postupy eskalace:
1. **Kalibrace spolehlivosti z více signálů:** Nezpracované logaritmické pravděpodobnosti (logprobs) velkého jazykového modelu (LLM) jsou často špatně kalibrovány pro dotazy mimo doménu. Skóre spolehlivosti by mělo syntetizovat více nezávislých signálů:
* **Skóre ukotvení (grounding) vyhledávání:** Sémantická podobnost a spolehlivost přeřazení (re-ranking) načtených částí důkazů.
* **Implikace na úrovni tvrzení (Natural Language Inference – NLI):** Modely přirozeného jazykového odvozování (NLI) ověřující, že každé extrahované tvrzení je odvozeno z načteného zdrojového kontextu.
* **Sémantická entropie / vnitřní konzistence:** Měření sémantické konzistence napříč více vzorkovanými generacemi.
* **Logaritmické pravděpodobnosti tokenů modelu:** Minimum a průměrné logaritmické pravděpodobnosti pro klíčové pojmenované entity a faktické tokeny.
2. **Stupňovitá politika zdržení se odpovědi:**
* **Vysoká spolehlivost (Skóre >= Vysoký práh):** Přímo poskytněte vygenerovanou odpověď s citacemi přímo v textu.
* **Střední spolehlivost / nejednoznačné (Nízký práh <= Skóre < Vysoký práh):** Poskytněte konzervativní odpověď s výslovnými upozorněními, zřeknutím se odpovědnosti nebo požádejte uživatele o upřesňující detaily.
* **Nízká spolehlivost / mimo rozsah (Skóre < Nízký práh):** Úplné zdržení se odpovědi se standardizovanou odmítací zprávou.
3. **Eskalace a auditovatelnost souladu s předpisy:**
* **Deterministická eskalace:** Zdržení se odpovědi nebo kritické nesrovnalosti jsou automaticky směrovány do front pro zásah člověka do smyčky (Human-in-the-loop – HITL) nebo do systémů lístků pro agenty s úplným kontextem.
* **Auditní záznam a původ (linage):** Kompletní telemetrie – včetně hashovacích kódů promptů, ID načtených dokumentů, jednotlivých skóre komponent spolehlivosti a konečných rozhodnutí o směrování – musí být zaznamenána pro regulační auditovatelnost.
15Navrhněte strategii směrování modelů, která vybírá mezi malými, středními a velkými modely na základě složitosti požadavků, nákladů, rizika a požadavků na kvalitu.
Produkční architektura směrování modelů směruje příchozí požadavky napříč malými (např. 1B–8B SLM (Small Language Models)), středními (např. 14B–70B modely) a velkými (např. průlomové nebo velké MoE (Mixture of Experts) modely) úrovněmi vyvažováním složitosti, latence, rizika a nákladů na výpočet. Pracovní postup směrování obecně kombinuje statická pravidla, prediktivní směrování a dynamické kaskády záložních řešení:
1. **Deterministické/statické politické brány:** Filtrují požadavky podle úrovně zákazníka, pevných SLA (Service Level Agreements) pro latenci, regulačního/doménového rizika (např. lékařská diagnóza nebo právní návrhy směrované přímo k modelům nejvyšší úrovně) nebo jednoduchých úloh shodných s pravidly (např. základní regulární výrazy/formátování pro malé modely).
2. **Prediktivní směrování složitosti:** Rychlý, odlehčený klasifikátor (jako je vyhledávání podobnosti v embeddingech, křížový kodér nebo malý směrovač SLM) hodnotí složitost požadavku, hloubku uvažování a doménovou nejednoznačnost, aby předem vybral nákladově nejefektivnější úroveň.
3. **Dynamické provádění a eskalace kaskád:** Prompt je nejprve odeslán menšímu modelu a vyhodnotí se spolehlivost výstupu (pomocí logaritmických pravděpodobností/entropie tokenů, validity strukturovaného schématu nebo kontrolních mechanismů). Pokud je spolehlivost pod prahem nebo ověření selže, směrovač eskaluje na střední nebo velký model. Klíčové systémové kompromisy zahrnují režii latence směrovače oproti úsporám výpočetního výkonu, rozpočty časových limitů pro záložní řešení během špiček provozu a průběžné hodnocení (např. stínové hodnocení pro sledování odchylek kvality výstupu napříč úrovněmi).
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)