Personalize this lesson
Adapt explanations and teaching visuals to your background and preferred voice.
Suppose CI run RUN-842 stops at auth_fixture_test.py:41 with an unhandled exception: expired auth fixture. Your team wants an assistant to label review comments, pull the exact run ID from a noisy 2,000-line log, and explain the failure. Those sound like jobs for different tools. Could one text model handle them through the same interface, and where would a simpler tool do better?
GPT stands for Generative Pre-trained Transformer, the model family introduced by OpenAI; large language model (LLM) is the broader category. GPT-style causal decoders generate text by predicting the next token from a prefix. That continuation interface can express classification, extraction, explanation, and bug-fix drafting. Accuracy and task fit still require evaluation.
The original Transformer debuted in 2017 as an encoder-decoder machine translation model.[1] Later work explored causal decoders, bidirectional encoders, larger training runs, instruction following, and more efficient serving. These developments overlap, and each changes a different part of the system. We'll follow RUN-842 through those design choices, asking what each one buys and what still needs to be checked.
One generation loop, many tasks
Traditional systems solve the first two jobs directly: a classifier predicts logits over a closed set of three labels, {"Bug", "Docs", "Security}, and an extraction model returns character spans [start_idx, end_idx] into the log. A generative model can attempt both through the same text-continuation interface.
A causal decoder predicts continuations using left-to-right attention. Instructions and demonstrations describe the intended output: Docs after Label:, or RUN-842 after Extracted Run ID:. Those strings may require several tokenizer pieces. A base model may not recognize a system role; a chat model expects its trained conversation format.
A software assistant encounters three standard task shapes:
- Classification: A review note states, "This docs page is stale." You want the category label
Docs. - Extraction: A CI trace contains
RUN-842inside a stack frame. You want the exact identifier. - Generation: An on-call engineer asks, "Why did tests fail?" You want a concise diagnosis grounded in the trace.
An encoder like BERT can support classification and extraction heads. Its standard masked-token objective trains bidirectional representations; a causal decoder provides the usual left-to-right explanation interface. A suitably trained causal decoder can attempt all three tasks through prompting. Here is a few-shot classification prompt:
Classify the review note into Bug, Docs, or Security.
Note: The auth test fails on main.
Label: Bug
Note: This docs page is stale.
Label: Docs
Note: The API key is printed in logs.
Label: Security
---
Note: The README still mentions the old CLI flag.
Label:The model ingests the prompt prefix, attends across the task rules and demonstrations, and predicts the continuation at the empty Label: slot. The prompt pattern sets up an inductive bias for Docs.
A fixed classifier head returns scores for its configured labels. An unconstrained generator can produce Documentation or Sure, the label is Docs. Parse and validate the result, or use supported constrained decoding with an enumerated schema. Correct syntax still needs an accuracy check. For exact extraction, compare the identifier against the source log; a regular expression may handle this job more reliably.

This code builds the review-note prompt. A model call and an accuracy evaluation are separate steps. Docs is the intended answer for this note:
def build_review_label_prompt(note: str) -> str:
examples = [
("The auth test fails on main.", "Bug"),
("This docs page is stale.", "Docs"),
("The API key is printed in logs.", "Security"),
]
header = "Classify the review note into Bug, Docs, or Security."
shots = "\n\n".join(
f"Note: {text}\nLabel: {label}" for text, label in examples
)
return f"{header}\n\n{shots}\n\n---\n\nNote: {note}\nLabel:"
prompt = build_review_label_prompt("The README still mentions the old CLI flag.")
print(prompt)
print("pattern_target=Docs")
print("why=the prompt pattern ends with a label slot")Classify the review note into Bug, Docs, or Security.
Note: The auth test fails on main.
Label: Bug
Note: This docs page is stale.
Label: Docs
Note: The API key is printed in logs.
Label: Security
---
Note: The README still mentions the old CLI flag.
Label:
pattern_target=Docs
why=the prompt pattern ends with a label slotWhy can a decoder-only model classify a review note even though its pretraining objective was next-token prediction?
Answer
The demonstrations express classification as a continuation task ending at Label:. A capable model can use that pattern without changing its output head, though the label may span multiple tokens and the prediction may be wrong. Validate the complete output and evaluate category accuracy on held-out notes.
Why encoders read both ways and decoders write left to right
Why did GPT-style decoders become common in assistants? Autoregressive generation gives the application one flexible output interface. The attention mask describes visibility; adoption and task performance require separate evidence.
The 2017 Transformer consisted of two stacks: an encoder that processed the full source sentence bidirectionally, and an autoregressive decoder that generated target tokens one by one while cross-attending to the encoder representations.[1] In 2018, researchers demonstrated useful designs with a single stack for some tasks:
- BERT (2018). Its bidirectional encoder lets a non-padding position attend to both earlier and later non-padding positions.[2] Original BERT trained with masked language modeling and next-sentence prediction. Of the 15% of positions selected for masked-token supervision, 80% were replaced by
[MASK], 10% by a random token, and 10% left unchanged. Encoder representations support classification and span heads. Sentence-BERT adds training specifically for useful sentence-similarity embeddings; arbitrary pooled BERT states need task-specific evaluation for retrieval.[3] Mask filling and adapted generation procedures are possible. GPT-style models use left-to-right training for assistant-style generation. - GPT (2018). Its causal Transformer uses self-attention and feed-forward blocks without encoder cross-attention.[4] This is more than keeping an unchanged translation decoder. A lower-triangular causal mask, including the diagonal, lets the state at position predict without seeing future tokens. Original pretraining used causal language modeling. Supervised adaptation added task objectives.
| Production requirement | Encoder-only (BERT-style) | Decoder-only (GPT-style) |
|---|---|---|
| Classify an incident report | Fine-tuned classification head, often using [CLS]. | Prompted labels or an attached classifier head. |
| Generate a failure explanation | Standard BERT needs a generation adaptation or a separate generator. | Natural autoregressive interface; evidence and evaluation still required. |
| Dense semantic search | Use an encoder trained for the intended embedding task. | Decoder embedding models also exist; compare dimensions, quality, and cost. |
| Interactive assistant | Often useful for retrieval, classification, or reranking inside the system. | Conversation-trained generator, with application-managed history and tools. |
The useful distinction is interface flexibility. Text generation lets you express many tasks through prompts; task performance still needs evaluation. Encoder-decoder models also generate text, as T5 demonstrates.[5] Keep architecture, training objective, and application quality separate.
A decoder writes left to right
In causal attention, token attends only to positions . When predicting the token after failed, the model attends to <bos>, tests, and failed; future-token positions are masked.
During teacher-forced training, the known input sequence supports parallel position computations within each layer. Mask scores strictly above the diagonal with , then normalize the allowed scores. Compare each position's logits with the following token, excluding unsupervised targets. Layer dependencies and total work remain. Basic inference selects successive tokens, while speculative methods can verify multiple candidate positions together.
tokens = ["<bos>", "tests", "failed", "<eos>"]
n = len(tokens)
causal = [[1 if col <= row else 0 for col in range(n)] for row in range(n)]
bidirectional = [[1] * n for _ in range(n)]
print("tokens:", tokens)
print("causal row for 'failed': ", causal[2])
print("bidirectional row for 'failed':", bidirectional[2])
print("future visible in causal row:", causal[2][3])tokens: ['<bos>', 'tests', 'failed', '<eos>']
causal row for 'failed': [1, 1, 1, 0]
bidirectional row for 'failed': [1, 1, 1, 1]
future visible in causal row: 0Here, 1 means allowed and 0 means blocked; the table shows visibility independent of any library's mask argument. A real bidirectional encoder also masks padding. The encoder's visibility pattern supports full-context representations; causal decoders use the shifted training contract illustrated here.
What mathematical property distinguishes a causal decoder attention matrix from an encoder attention matrix?
Answer
For full causal self-attention, the allowed positions satisfy : the diagonal is included. Mask before softmax so probabilities normalize over visible keys. Zeroing forbidden weights after softmax requires renormalization to preserve the same distribution. A bidirectional encoder permits both directions, subject to padding and any other configured restrictions.
The life of a token: prefill, KV cache, and decode
Trace the engineer's prompt through the decoder: "Why did tests fail?".
Text enters the tokenizer and breaks into a sequence of discrete token IDs. An embedding lookup table maps each ID to a vector of dimension . Position information is injected into each token's representation.
For a conventional pre-normalization decoder, the tokens flow through layers. A common arrangement is:
- Normalization rescales each position's features before its attention branch.
- Self-attention projects hidden states into Queries (), Keys (), and Values ().
- Softmax-weighted attention scores combine values across all allowed causal positions.
- An output projection maps the attended values back to .
- A normalized feed-forward branch transforms each position through nonlinear activations. Residual additions combine both branches with the running state.
After the final normalization, the last position's row vector projects through to produce vocabulary logits.[6] An implementation may instead store its transpose as . Applying softmax yields normalized probabilities. In our hand-chosen four-token fixture, greedy argmax selects Auth; stochastic decoding could select another token.
Inference splits into two distinct execution phases:
- Prefill: Process the known prompt positions and populate the KV cache. Projections can combine rows into matrix multiplications, often giving better weight reuse than a one-row operation. Long prompts may be processed in chunks. The last prompt position supplies logits for the first answer token.
- Cached decode: Feed the newly selected token as the next input. Each layer computes its new K/V entry, then the token's query scores visible keys in the previous cache plus that current entry. The cache reuses earlier tokens' K/V projections, while attention work for the new query grows with visible context. Projection and feed-forward work continue for the new token.
Long-prefill projections often have high arithmetic intensity, while small-batch decode can be limited by weight and cache bandwidth.[7] These are workload tendencies. At batch size , a decode projection processes rows, so it needn't be GEMV; batching, quantization, attention variants, hardware, and communication can change the bottleneck. Tensor-core utilization depends on the full workload and implementation.

Inspect a hand-chosen output projection and the logical cache dimensions. The stacked K/V shape below is an accounting convention; runtime layouts vary:
import math
prompt_tokens, d_model, vocab_size = 5, 4, 4
last_hidden = [0.6, -0.2, 0.4, 0.1]
output_rows = [
[0.8, 0.1, -0.2, 0.0],
[0.2, 0.5, 0.1, -0.1],
[-0.1, 0.2, 0.4, 0.3],
[0.0, -0.3, 0.2, 0.4],
]
labels = ["Auth", "The", "I", "Fix"]
logits = [sum(h * w for h, w in zip(last_hidden, row)) for row in output_rows]
peak = max(logits)
exps = [math.exp(x - peak) for x in logits]
z = sum(exps)
probs = [e / z for e in exps]
print("prompt tokens:", prompt_tokens, "d_model:", d_model, "vocab:", vocab_size)
print("last-position logits:", [round(x, 2) for x in logits])
print("argmax:", labels[logits.index(max(logits))])
print("prob sum:", round(sum(probs), 3))
layers, kv_heads, head_dim = 4, 2, 2
print("cached K/V shape per layer:", (2, 1, kv_heads, prompt_tokens, head_dim))
assert math.isclose(sum(probs), 1.0)
assert logits.index(max(logits)) == 0prompt tokens: 5 d_model: 4 vocab: 4
last-position logits: [0.38, 0.05, 0.09, 0.18]
argmax: Auth
prob sum: 1.0
cached K/V shape per layer: (2, 1, 2, 5, 2)Notice the sequence length discrepancy right after sampling. Selecting Auth adds it to the text output, bringing the sequence to 6 tokens. The KV cache still contains only 5 positions. The next decode step takes Auth as its single input token, computes its Key and Value vectors, and expands the cache to length 6.
Why might small-batch decode have less weight reuse than a long prefill?
Answer
A long prefill applies each projection's weights to many token rows; batch-one decode applies them to one new row. That can make weight transfer more costly relative to arithmetic. Increasing concurrent batch rows can improve reuse, while cache traffic and other bottlenecks remain. Profile the actual batch and context lengths before asserting which resource limits latency.
How GPT grew from text completion into assistants
To answer the engineer, a base model that continues a log line needs additional training and application controls. Transfer learning, prompt-based evaluation, instruction following, training allocation, and architecture each changed a different part of that gap, and their timelines overlap. Instruction tuning complements few-shot prompting, and fine-tuning remains useful.

1. GPT-1: Generative pretraining + task fine-tuning (2018)
Generative pretraining followed by supervised adaptation predates GPT. Radford et al. cite earlier language-model transfer work and demonstrate an influential Transformer version using BooksCorpus, a collection of over 7,000 books.[4]
GPT-1 consisted of a 12-layer decoder with 117 million parameters. Its core workflow was a two-stage process:
- Unsupervised pretraining: Train the decoder on raw text using standard autoregressive cross-entropy loss.
- Supervised fine-tuning: Add a task-specific linear output layer and update the model on labeled tasks. The paper also retains an auxiliary language-model objective.
The reported supervised adaptations use task-specific checkpoints. The paper also examines zero-shot behavior, so prompt-based evaluation didn't first appear in GPT-2.
2. GPT-2: Zero-shot transfer without task-specific weights (2019)
GPT-2 expanded the largest model to about 1.5 billion parameters and trained on WebText, roughly 40 GB of text collected from links shared on Reddit.[8] Its report evaluated tasks without task-specific parameter updates, with results that varied substantially by task.
An illustrative zero-shot task framing is Input: The service was awful. Sentiment:. The intended continuation is negative; this prompt demonstrates the format and reports no GPT-2 measurement. Zero-shot evaluation omits worked task demonstrations from the prompt; pretraining can still contain related examples or task information.
3. GPT-3: In-context few-shot emergence (2020)
Brown et al. trained models up to 175 billion parameters, about 117 times GPT-2's largest model, on 300 billion tokens.[9] Their evaluations showed stronger few-shot performance with scale on many tasks, alongside weak results on others. The 175B value is one study scale point; capability depends on data, task, and training.
Few-shot evaluation supplies input-output demonstrations in the prefix without gradient updates. The GPT-3 study often used many more than two or three examples, up to what fit its context. Demonstrations can influence predictions; that evaluation protocol leaves the internal learning mechanism unresolved. Example selection, formatting, order, and task difficulty all matter.
4. InstructGPT: Preference training (2022)
Base-model training may focus on text continuation before instruction following. Explain this test failure can elicit an answer, another question, or a continuation of a transcript. Prompting can help; a production assistant also needs evaluated instruction-following behavior.
Ouyang et al.'s InstructGPT applied an existing line of human-feedback research to instruction following.[10] Its particular RLHF pipeline was:
- Supervised Fine-Tuning (SFT): Human annotators write thousands of high-quality demonstrations of instructions and ideal responses. The base model fine-tunes on this instruction dataset, learning the conversational assistant format.
- Reward Modeling (RM): The SFT model generates multiple candidate responses for various prompts. Human labelers rank these candidates from best to worst. A reward model trains on these pairwise comparisons to output a scalar score predicting human preference.
- Reinforcement Learning (PPO): Initialize the policy from SFT and optimize a learned reward with a KL penalty relative to the SFT reference. The paper's PPO-ptx variant also mixes in a pretraining objective to reduce task regressions.
On the study's held-out API prompt distribution, labelers preferred the 1.3B InstructGPT outputs to the 175B GPT-3 outputs.[10] That result measures preference on this evaluation; knowledge coverage and performance on other tasks require separate tests. Preference training can still reward plausible mistakes.
The following fixture stores preferred and rejected responses and checks whether the preferred text repeats a required phrase. A substring check measures phrase presence; truth evaluation and preference-model training require different methods. Try adding There was no expired auth fixture: it passes the phrase check while contradicting the log.
comparisons = [
{
"prompt": "CI run RUN-842: auth_fixture_test.py:41 reports 'expired auth fixture'. Explain the failure.",
"chosen": "RUN-842 failed at auth_fixture_test.py:41: the log reports an expired auth fixture.",
"rejected": "The build failed for an unknown reason.",
"required_fact": "expired auth fixture",
},
{
"prompt": "Review note says the API key is printed in logs. Classify the issue.",
"chosen": "Security: redact the API key and rotate the exposed credential.",
"rejected": "Docs: update the README wording.",
"required_fact": "API key",
},
]
for row in comparisons:
keeps_required_fact = (
row["required_fact"] in row["prompt"]
and row["required_fact"] in row["chosen"]
)
print(f"prompt={row['prompt'][:22]}... chosen_keeps_fact={keeps_required_fact}")
print(" preferred:", row["chosen"])prompt=CI run RUN-842: auth_f... chosen_keeps_fact=True
preferred: RUN-842 failed at auth_fixture_test.py:41: the log reports an expired auth fixture.
prompt=Review note says the A... chosen_keeps_fact=True
preferred: Security: redact the API key and rotate the exposed credential.These checkpoint labels describe intended use and can overlap across training recipes. An instruct model may support multi-turn chat, and a chat model can use objectives other than PPO:
| Checkpoint type | Training objective | Expected behavior | Production role |
|---|---|---|---|
| Base model | Usually a pretraining checkpoint, often with causal language modeling. | Predicts continuations; instruction following varies. | Continued pretraining, adaptation, or evaluated completion tasks. |
| Instruct model | Instruction-oriented post-training, potentially with preference or reinforcement learning. | Trained to respond to tasks; can still make errors. | Extraction, classification, generation, and sometimes chat. |
| Chat model | Post-training using a conversation format; specific objectives vary. | Trained to use message roles and supplied conversation history. | Interactive applications, with external history, validation, and tool handling. |
A chat template serializes messages using the checkpoint's expected roles and control tokens.[11] Formats differ even between models derived from the same base. Use the checkpoint's supplied template or official encoding implementation, including its generation prefix. Some releases, such as DeepSeek-V4.1-Flash, provide an encoding implementation in place of a Jinja chat template.[12] Avoid adding duplicate special tokens if you tokenize an already formatted string. Training shapes behavior; formatting supplies the expected structure. The application must supply retained history because separate API requests carry no automatic memory.
What does the 1.3B InstructGPT preference result establish, and what does it leave open?
Answer
Labelers preferred its responses over 175B GPT-3 on the study's API prompt distribution. Instruction and preference training can matter more than scale for that evaluation. Knowledge, coding, and reasoning performance require separate tests; preference scores also need fact checks.
What scaling laws say about a fixed training budget
As teams trained larger models, an engineering question arose: given a fixed computational budget (measured in floating-point operations, or FLOPs), how should you divide your budget between adding parameters and feeding more training tokens?
Kaplan et al. (2020) fitted empirical relationships between language-model loss, parameter count , data, and training compute .[13] Their compute-allocation estimates scaled model size faster than training tokens :
Several prominent runs increased parameters while retaining roughly 300B training tokens. Gopher used 280B parameters; GPT-3 used 175B.[14] GPT-3's ratio was about 1.7 tokens per parameter. That ratio describes training allocation; evaluate task quality separately.
Hoffmann et al. varied training horizons and matched learning-rate schedules to those horizons, using over 400 models from 70M to over 16B parameters.[14] They explain that intermediate losses from a fixed long schedule can overestimate the loss achievable by a shorter run with its own schedule. Their larger-model coverage and fitted methods also differ from Kaplan's analysis. The Chinchilla study found approximately equal parameter/token scaling:
Under these fitted training conditions, doubling parameters calls for roughly doubling training tokens. About 20 tokens per parameter is a useful landmark from this study; choose an allocation for the specific data mixture, architecture, and compute range. Its three fitting approaches gave slightly different exponents.
| Historical run | Parameters | Training tokens | Tokens per parameter | Interpretation |
|---|---|---|---|---|
| Gopher | 280B | 300B | ~1.1 | Undertrained relative to Chinchilla's fitted frontier |
| GPT-3 | 175B | 300B | ~1.7 | Undertrained under that comparison |
| Chinchilla | 70B | 1.4T | 20.0 | Tests the study's predicted allocation |
| LLaMA 1 | 65B | 1.4T | ~21.5 | Public-data model emphasizing serving efficiency |
| Llama 3 | 8B | >15T | >1,875 | Smaller model trained beyond training-compute optimality |
Chinchilla used the same reported training-compute budget as Gopher and improved aggregate MMLU and BIG-bench performance.[14] Some individual tasks still favored Gopher. The LLaMA and Llama 3 rows come from their own papers; the Chinchilla paper reports the Chinchilla results.[15][16]
runs = {
"Gopher": {"params_b": 280, "tokens_b": 300},
"GPT-3": {"params_b": 175, "tokens_b": 300},
"Chinchilla": {"params_b": 70, "tokens_b": 1400},
"Llama-3-8B": {"params_b": 8, "tokens_b": 15000}, # rounded 15T landmark
}
for name, run in runs.items():
ratio = run["tokens_b"] / run["params_b"]
print(f"{name:12s} tokens/param={ratio:7.1f}")Gopher tokens/param= 1.1
GPT-3 tokens/param= 1.7
Chinchilla tokens/param= 20.0
Llama-3-8B tokens/param= 1875.0To compare allocations, a common approximation for dense Transformer training is FLOPs.[14] The factor roughly combines two FLOPs per weight multiply-add with forward and backward work. Attention, embeddings, and other operations can change the estimate; use profiling for wall-clock time and a separate formula for MoE compute.
Predict the budget change when both and double. This arithmetic example keeps the model architecture and accounting approximation fixed:
baseline_flops = 6 * 1e9 * 20e9
allocations = {
"baseline": (1e9, 20e9),
"double both": (2e9, 40e9),
"parameters only": (4e9, 20e9),
"tokens only": (1e9, 80e9),
}
for name, (parameters, tokens) in allocations.items():
budget_ratio = 6 * parameters * tokens / baseline_flops
print(f"{name:15s} compute={budget_ratio:.1f}x tokens/param={tokens / parameters:.1f}")baseline compute=1.0x tokens/param=20.0
double both compute=4.0x tokens/param=20.0
parameters only compute=4.0x tokens/param=5.0
tokens only compute=4.0x tokens/param=80.0Doubling both quantities costs roughly four times the baseline, just like the other two larger allocations. Their token/parameter ratios differ. Equal estimated compute can produce different loss values, so choose an allocation using measured scaling behavior for the data and training recipe. The 20-token ratio illustrates one allocation; use observed scaling behavior to select a compute-optimal ratio. counts training token exposures, so repeated data can increase without adding unique examples.
Training compute versus lifetime serving costs
The Chinchilla ratio represents training-compute optimality: minimizing the loss achieved for a given training budget. In real systems, total cost includes inference serving.
The original LLaMA paper explicitly considers inference efficiency.[15] Later Llama 3 work also trains smaller models beyond training-compute optimality.[16] A smaller model can reduce per-request weight storage and arithmetic, making additional pretraining worthwhile for a large serving workload. Break-even depends on request volume, model quality, hardware, quantization, and required context. An 8B model's ability to fit one GPU depends on that GPU and the complete runtime memory budget.
Why do modern production labs intentionally train 8B models on 15 trillion tokens, defying Chinchilla's compute-optimal 20:1 ratio?
Answer
Training-compute optimality minimizes loss at a fixed training budget. A serving-heavy workload can justify extra training of a smaller model to reduce inference cost while meeting a measured quality target. Inference doesn't dominate every deployment, and an 8B model doesn't automatically match a 70B model's accuracy. Estimate lifetime costs and evaluate both on the application's tasks.
Three newer building blocks: RMSNorm, SwiGLU, and RoPE
Many later models modify the 2017 architecture. RMSNorm, gated feed-forward networks, and rotary positions are common choices, including in original LLaMA.[15] Architectures still vary: original Gemma uses GeGLU instead of SwiGLU, for example.[17] Public reports provide limited detail about undisclosed hosted models.
1. Root Mean Square Normalization (RMSNorm)
Standard LayerNorm computes both the mean and variance across the feature dimension of hidden vector :[18]
Zhang and Sennrich tested a simpler normalization that omits centering.[19] Its empirical success covers their tested architectures; gradient stability still requires evaluation in each full network.
RMSNorm discards the mean calculation and the learned additive bias , scaling strictly by root mean square energy:[19][20]
RMSNorm uses a mean-square statistic; LayerNorm uses centered variance. Both normalization types can use optimized single-pass or fused kernels, so the speed difference depends on the implementation and workload. The original paper reports runtime savings in its tested models; evaluate accelerator speed and stability on the target model and workload.
2. SwiGLU activations
Early transformers used standard ReLU or GELU activations inside a two-layer feed-forward network: .
Gated Linear Units (GLUs) multiply a transformed gate projection by another projection. Shazeer's comparison found lower perplexity for selected gated variants in its tested Transformer setup.[21] Evaluate the effect under each training recipe.
SwiGLU uses the Swish (or SiLU) activation function as the gating mechanism:
Ignoring biases, a two-matrix FFN has weights and a three-matrix SwiGLU FFN has . Matching a conventional width therefore gives a SwiGLU width .[21] Rounding and architecture choices can alter this width. The matrix multiply-add budgets are comparable under these assumptions; nonlinearities, elementwise products, kernels, and wall time needn't be identical. SwiGLU's gate is signed and unbounded, unlike a sigmoid gate constrained to .
3. Rotary Position Embeddings (RoPE)
The original Transformer used added sinusoidal positions and also evaluated learned positions.[1] Sinusoids support algebraic relationships between offsets; useful extrapolation still requires evaluation. A learned position table has a finite number of rows unless extended.
Su et al. (2021) introduced Rotary Position Embeddings (RoPE).[22] Instead of adding positional vectors at the input layer, RoPE rotates 2D coordinate pairs in the Query and Key vectors inside each attention head by a position-dependent angle :
For fixed unrotated content vectors and , the positional rotation depends on the relative offset because :
Positions and have the same relative rotation. Their complete attention scores can differ because the unrotated vectors depend on content and prior layer context. Individual RoPE scores also needn't decrease monotonically with distance. Context extension can modify rotary frequencies; evaluate each method with its target model because the identity alone says nothing about extrapolation quality.
Run the mechanics of RMSNorm and SwiGLU in Python:
import math
def rms_norm(x: list[float], gamma: list[float], eps: float = 1e-6) -> list[float]:
if not x or len(x) != len(gamma):
raise ValueError("x and gamma must have the same nonzero length")
if not math.isfinite(eps) or eps <= 0:
raise ValueError("eps must be positive and finite")
d = len(x)
rms = math.sqrt(sum(xi ** 2 for xi in x) / d + eps)
return [(xi / rms) * gi for xi, gi in zip(x, gamma, strict=True)]
def silu(z: float) -> float:
if z >= 0:
return z / (1.0 + math.exp(-z))
exp_z = math.exp(z)
return z * exp_z / (1.0 + exp_z)
x = [1.2, -0.8, 2.5, -1.5]
gamma = [1.0, 1.0, 1.0, 1.0]
normed = rms_norm(x, gamma)
w_gate = [0.5, -0.3]
w_up = [1.2, 0.8]
gate_val = sum(xi * w for xi, w in zip(x[:2], w_gate))
up_val = sum(xi * w for xi, w in zip(x[:2], w_up))
swiglu_val = silu(gate_val) * up_val
print("rms_norm output:", [round(v, 4) for v in normed])
print("rms verification:", round(math.sqrt(sum(v**2 for v in normed) / len(normed)), 4))
print("gate:", round(gate_val, 4), "up:", round(up_val, 4), "swiglu:", round(swiglu_val, 4))rms_norm output: [0.7379, -0.4919, 1.5372, -0.9223]
rms verification: 1.0
gate: 0.84 up: 0.8 swiglu: 0.4694The printed RMS rounds to 1.0. Before rounding, it is slightly below one because the denominator includes positive eps. This check also uses unit gamma; learned per-feature scales can change the output's RMS.
What does the RoPE identity prove about shifting a fixed query/key pair, and what doesn't it prove?
Answer
For fixed unrotated vectors, RoPE makes the positional part of a query/key dot product depend on . Shifting both positions equally preserves that score. In a real model, content vectors change across tokens and layers; evaluate long-context accuracy and attention patterns on the target workload.
How attention design changes KV cache costs
Conventional full-attention decode reads visible cached keys and values. Sliding-window, sparse, compressed, or shared-cache architectures have different access and storage patterns. Cache size depends on these choices and batch/context lengths as well as the model's parameters.
To estimate that cost in a conventional layout, count keys and values for every cached position across the batch. With separate K/V arrays, equal head dimensions and precision, and requests each caching positions, the raw KV payload is:
Here is bytes per stored scalar (two for FP16/BF16), and the factor of two counts keys and values. For unequal request lengths, replace with the sum of cached lengths; sum layer-specific payloads when their layouts differ. Quantization metadata, page rounding, reserved capacity, weights, and runtime buffers add memory beyond this formula.
These three attention designs differ in how many K/V heads they keep for the queries:
- Multi-Head Attention (MHA): Each query head has an independent key head and value head (). For 32 query heads, you cache 32 key heads and 32 value heads.
- Multi-Query Attention (MQA): Share one key head and one value head across query heads.[23] With 32 query heads and otherwise equal cache dimensions, the raw KV payload is of MHA. Quality and speed need evaluation.
- Grouped-Query Attention (GQA): Share a KV head within each query-head group.[24] Eight KV heads for 32 query heads use one quarter of MHA's raw KV payload. The original study obtained quality close to MHA in its tested, uptrained models. Evaluate each checkpoint, task, and kernel. A trained MHA checkpoint requires compatible weights and implementation before using a GQA layout.
Compare raw payloads for a hypothetical uniform batch. These byte calculations isolate the tensor payload; GPU allocation and throughput require runtime measurements:
batch, layers, tokens, head_dim, bytes_per_value = 8, 32, 8192, 128, 2
query_heads = 32
for label, kv_heads in [("MHA", 32), ("GQA", 8), ("MQA", 1)]:
cached_values = batch * layers * tokens * kv_heads * head_dim * 2
cache_gib = cached_values * bytes_per_value / (1024 ** 3)
relative = kv_heads / query_heads
print(f"{label}: kv_heads={kv_heads:2d} cache={cache_gib:5.2f} GiB relative={relative:.3f}")MHA: kv_heads=32 cache=32.00 GiB relative=1.000
GQA: kv_heads= 8 cache= 8.00 GiB relative=0.250
MQA: kv_heads= 1 cache= 1.00 GiB relative=0.031This RoPE lab holds the content vectors fixed, isolates one coordinate pair, and checks equal relative offsets. Change key for the late case to see why equal gaps don't imply equal scores for different content:
import math
def rotate(vector: tuple[float, float], position: int, theta: float = 0.4) -> tuple[float, float]:
angle = position * theta
cosine, sine = math.cos(angle), math.sin(angle)
x, y = vector
return (cosine * x - sine * y, sine * x + cosine * y)
def dot(left: tuple[float, float], right: tuple[float, float]) -> float:
return left[0] * right[0] + left[1] * right[1]
query = (1.0, 0.2)
key = (0.3, 0.9)
same_gap_early = dot(rotate(query, 4), rotate(key, 2))
same_gap_late = dot(rotate(query, 14), rotate(key, 12))
different_gap = dot(rotate(query, 14), rotate(key, 2))
print("same gap, early:", round(same_gap_early, 6))
print("same gap, late: ", round(same_gap_late, 6))
print("different gap: ", round(different_gap, 6))
print("same gap equal:", math.isclose(same_gap_early, same_gap_late))same gap, early: 0.936998
same gap, late: 0.936998
different gap: -0.794779
same gap equal: TrueHead sharing reduces KV payload. Other serving techniques reduce attention's memory traffic or cache-allocation waste:
- FlashAttention: Compute dense attention in tiles without materializing the full score/probability arrays in HBM.[25] This reduces memory traffic and uses linear auxiliary storage in sequence length for fixed head width. Dense attention arithmetic remains quadratic. Its original HBM-access bound depends on SRAM size , ; it isn't universally linear in .
- PagedAttention: Map logical KV blocks to non-contiguous physical blocks.[26] Paging reduces allocation waste and supports cache sharing. Partial final pages and other runtime allocations still consume capacity. Reported throughput gains apply to the paper's evaluated workloads; benchmark the target runtime and traffic pattern.
Why can GQA reduce decode latency, and why isn't a 75% KV reduction a 75% latency reduction?
Answer
GQA stores fewer distinct keys and values, which can reduce cache traffic with an efficient implementation. Decode also spends time on weights, projections, feed-forward work, communication, and scheduling. Four query heads per KV head cut raw KV payload by 75% under equal dimensions; measure complete latency and task quality separately.
Sparse architectures: Mixture of Experts (MoE)
Dense transformer layers apply their attention and feed-forward projections to each position. Parameter count roughly tracks this work; embeddings use lookups, attention work depends on context, and a multiply-add convention often counts two FLOPs. Sparse experts increase available feed-forward capacity while activating only a subset per token.
Shazeer et al. (2017) introduced the sparsely gated Mixture of Experts layer, later developed in Mixtral 8x7B (Jiang et al., 2024) and DeepSeek models.[27][28]
In a Mixtral-style layer, expert feed-forward networks replace the dense FFN. The router selects experts and combines their output vectors. The following convention retains selected logits, sets all others to , then normalizes the selected weights; other MoE designs use different gates, shared experts, and values of :
The fundamental MoE tradeoff: VRAM vs FLOPs
Mixtral 8x7B contains 47 billion total parameters across its 8 experts per layer. But for any given token, only 2 experts activate, touching approximately 13 billion parameters.
The two counts answer different questions:
- Active parameters (~13B): Help estimate per-token projection work. Latency also depends on routing, expert utilization, batch size, kernels, and device communication.
- Total parameters (~47B): Determine the uncompressed checkpoint weight pool. At two bytes per weight, the rounded count gives 94 GB / 87.54 GiB before runtime overhead. A fully GPU-resident deployment must hold this pool across its GPUs. CPU/disk offloading or quantization can change GPU residency, with transfer, speed, and quality tradeoffs.[29]
Poor load balance can overload a few experts and leave others with little training signal. Routers can use an auxiliary load-balancing loss as one design option. DeepSeek-V3 primarily adjusts routing biases using observed load, while retaining a small complementary sequence-level balance loss.[30] Routing balance manages load distribution; each token can use selected experts, and an expert need not have one human-interpretable specialty.
Inspect top-2 expert routing in code:
import math
experts = ["E0", "E1", "E2", "E3"]
tokens = ["import", "assertion"]
router_logits = [
[2.4, 0.3, 0.5, -0.2],
[0.1, 2.2, 0.7, 0.0],
]
for token, logits in zip(tokens, router_logits):
ranked = sorted(range(len(logits)), key=lambda i: logits[i], reverse=True)[:2]
selected = [logits[i] for i in ranked]
peak = max(selected)
weights = [math.exp(value - peak) for value in selected]
total = sum(weights)
weights = [weight / total for weight in weights]
assert len(ranked) == 2 and math.isclose(sum(weights), 1.0)
routes = list(zip((experts[i] for i in ranked), (round(weight, 3) for weight in weights)))
print(f"{token:10s} -> {routes}")import -> [('E0', 0.87), ('E2', 0.13)]
assertion -> [('E1', 0.818), ('E2', 0.182)]Why do active parameters alone fail to predict either GPU capacity or latency?
Answer
Sparse experts reduce per-token expert arithmetic, while all model weights still need storage somewhere. A fully resident two-byte 47B checkpoint needs about 94 GB for raw weights. Offloading can reduce GPU residency but adds data movement. Routing and communication add work, so compare complete latency against a 13B dense model on the target workload.
Reasoning models and the cost of extra inference compute
An autoregressive model can generate an explanation or scratchpad before its answer. Test-time compute also includes repeated sampling, search, verification, and tool calls. Reasoning-trained models emphasize some of these behaviors; reasoning and chat describe overlapping capabilities, and a model can support both.
OpenAI o1 (2024) and DeepSeek-R1 (2025) are prominent milestones in training models to use additional inference computation for reasoning.[31][32] Test-time compute predates both systems, and its effect varies by task.
A reasoning model may generate a reasoning trace, with visibility depending on the product. That trace can include:
- Formulate a hypothesis and test it against the evidence.
- Backtrack when a reasoning path leads to a contradiction.
- Compare supplied stack frames and configurations. Retrieve commit history from the repository or include it in the prompt; additional reasoning needs evidence access.
As checked on 30 October 2026, OpenAI's Responses API exposes reasoning.effort on supported models.[33] Supported effort levels vary by model. Reasoning can occur between tool calls and visible output segments, as well as before final output. For a factual audit of RUN-842, verify the final explanation against line 41 and distinguish the reported expired fixture from the still-unconfirmed reason it expired.
OpenAI's reasoning tokens occupy context and are billed as output tokens even when the trace isn't visible.[33] Reserve budget for both reasoning and the final answer; an exhausted output budget can leave the answer incomplete. Evaluate effort levels on the same held-out cases, recording verified success, time to first useful output, complete-response latency, token costs, and tool execution costs. Include routine cases as well as hard ones.
How do reasoning models differ from standard chat models during inference?
Answer
Some reasoning-trained models allocate additional token computation to intermediate reasoning, potentially interleaved with visible output and tools. Chat describes a conversation interface; measure reasoning behavior directly. Additional effort can improve measured task success, while evidence access and trace verification remain separate requirements.
Open weights, licensing, and local serving
Meta's original LLaMA release in 2023 was influential, but downloadable language-model weights predate it.[15] Original LLaMA access was for approved non-commercial research; its terms excluded unrestricted commercial deployment.[34] Later releases have their own terms. Downloadable weights permit local execution and supported adaptation techniques, subject to licensing and runtime compatibility. Check what your team can actually do with the specific checkpoint before building around it.
When evaluating downloadable models, software teams must distinguish between three terms:
| Category | Definition | What to inspect |
|---|---|---|
| Open weights | Downloadable parameters; access and reuse terms can vary. | The exact checkpoint license, conditions, and restrictions. |
| Open-source software | Software released under terms meeting the Open Source Definition. | Code license, dependencies, and redistribution obligations. |
| Open-source AI under OSI's definition | AI with use/study/modify/share freedoms and the required code, parameters, and training-data information. | Complete training/inference code and sufficient data information in addition to model weights.[35] |
| Open data | Data made available under specified access and reuse terms. | Which data is released and what its license permits. |
OSI's AI definition requires detailed data information; sufficient documentation can meet that requirement without releasing every raw training example. Copyleft licenses can also qualify.[35]
Two releases checked on 30 October 2026 illustrate why release identity, licensing, and runtime support need separate checks. These are vendor-published specifications; use workload benchmarks to assess performance:
| Model release | Published claims | Operational realities |
|---|---|---|
| GLM-5.3 | Documentation states a 1M-token context; its card describes post-training improvements on the GLM-5.2 base.[36][37] | Its custom GLM-5.3 license adds a security-review condition for certain Model-as-a-Service businesses exceeding $10B aggregate revenue over a consecutive 12-month period.[38] Calculate storage from the exact checkpoint's tensors and precision. The original GLM-5 paper's 744B / 40B counts describe particular components; full GLM-5.3 inventory requires the checkpoint's complete tensor list.[39] |
| DeepSeek-V4.1-Flash | MIT-licensed card lists a 552B-parameter backbone, 1M context, and 8B active parameters during prefill versus 16B during decode.[12] | Uses a causal encoder-decoder arrangement, compressed/shared caches, conditional memory, and a speculative module. Apply conventional per-layer KV accounting to components that use that layout, then inspect support for the chosen checkpoint, precision, and modules. |
The local checkpoint and a hosted API alias are different identities. DeepSeek's changelog says older V4 Flash API names route to V4.1 Flash; its 17 October update maps deepseek-flash to V4.1-Flash-1017. A downloaded July checkpoint remains its own revision.[40] Pin model and runtime revisions for reproducible evaluations.
Self-hosting can keep inference inside your chosen boundary. Privacy depends on telemetry, remote tools, logging, storage, and network configuration. The team also owns capacity, uptime, updates, and serving performance.
Why is calling an open-weight model "open source" often inaccurate?
Answer
Downloadable parameters alone leave open-source freedoms and supporting artifacts unresolved. Check the checkpoint license separately from the repository's code license. Under OSI's AI definition, code, parameters, and sufficient training-data information matter; a dataset description can meet that requirement without releasing every raw training example, and copyleft licenses can qualify.
Evaluating a released model on your workload
Use public leaderboard scores to shortlist candidates, then evaluate them on your proprietary logs, company idioms, and latency constraints.
Start with a pilot set, for example 50 cases of each task: failing CI logs, review-note labels, and multi-turn debugging questions. Treat those counts as an initial planning value; choose final evaluation size based on the decision and desired uncertainty. Include missing evidence, contradictory logs, unfamiliar projects, and relevant log text that contains misleading instructions. Keep development and final evaluation cases separate, grouping related runs or repositories to avoid leakage.
Give each case an output contract and a verifiable reference. Expired auth fixture is a reported failure; a claimed root cause such as clock skew needs further evidence. Score exact IDs and label validity separately from factual correctness, citation support, and useful abstention. Test candidates on the same cases and inspect uncertainty, paired disagreements, and failures by task alongside the pooled average.
Measure latency under representative concurrency and prompt/output lengths, distinguishing first-token from complete-response latency. Account for retries, tools, and local operating costs. Apply mandatory license, privacy, quality, and latency constraints first. Then compare eligible candidates using an explicit utility or cost objective.
This scorecard uses invented measurements to illustrate a weighted tradeoff. quality is a hypothetical verified-success fraction, p95_ms is complete-response p95 for a fixed short task, and cost is USD per 1,000 requests. Live code help has a mandatory 750 ms p95 deadline; nightly audit has no hard p95 cap in this example. Both scenarios enforce license eligibility before arbitrary latency and cost weights rank the remaining candidates:
candidates = [
{"name": "hosted-fast", "quality": 0.86, "p95_ms": 250, "cost": 0.50, "license_ok": True},
{"name": "hosted-deep", "quality": 0.94, "p95_ms": 1200, "cost": 1.50, "license_ok": True},
{"name": "local-restricted", "quality": 0.90, "p95_ms": 500, "cost": 0.20, "license_ok": False},
]
def score(model: dict, latency_penalty: float, cost_penalty: float) -> float:
if not model["license_ok"]:
return float("-inf")
return 100 * model["quality"] - latency_penalty * model["p95_ms"] - cost_penalty * model["cost"]
def is_eligible(model: dict, p95_deadline_ms: int | None) -> bool:
meets_deadline = p95_deadline_ms is None or model["p95_ms"] <= p95_deadline_ms
return model["license_ok"] and meets_deadline
scenarios = {
"live code help": {"weights": (0.03, 8.0), "p95_deadline_ms": 750},
"nightly audit": {"weights": (0.003, 4.0), "p95_deadline_ms": None},
}
for scenario, policy in scenarios.items():
eligible = [model for model in candidates if is_eligible(model, policy["p95_deadline_ms"])]
if not eligible:
raise ValueError("no candidate satisfies the hard constraints")
ranked = sorted(eligible, key=lambda model: score(model, *policy["weights"]), reverse=True)
winner = ranked[0]
deadline = policy["p95_deadline_ms"]
deadline_label = f"{deadline}ms" if deadline is not None else "none"
eligible_names = ",".join(model["name"] for model in eligible)
print(f"{scenario}: p95_deadline={deadline_label}; eligible={eligible_names}; winner={winner['name']} score={score(winner, *policy['weights']):.2f}")
live_policy = scenarios["live code help"]
nightly_policy = scenarios["nightly audit"]
hosted_deep = next(model for model in candidates if model["name"] == "hosted-deep")
assert not is_eligible(hosted_deep, live_policy["p95_deadline_ms"])
assert is_eligible(hosted_deep, nightly_policy["p95_deadline_ms"])live code help: p95_deadline=750ms; eligible=hosted-fast; winner=hosted-fast score=74.50
nightly audit: p95_deadline=none; eligible=hosted-fast,hosted-deep; winner=hosted-deep score=84.40The 1,200 ms hosted-deep candidate fails live code help's 750 ms deadline and is removed before scoring. Nightly audit has no hard p95 cap in this fixture, so both licensed hosted candidates reach the weighted comparison, where hosted-deep wins. These invented values illustrate how hard constraints and preference weights play different roles.
Why does the 94% hosted-deep candidate lose for live code help but win for nightly audit?
Answer
The live task's hard 750 ms p95 deadline excludes hosted-deep at 1,200 ms before scoring. The nightly fixture has no hard p95 cap, so both licensed candidates are eligible and the stated weights give hosted-deep a score of 84.40. Measure application success and latency on the target workload before choosing a policy.
Longer context and the evidence that gets missed
Large advertised context windows can tempt us to assume a model will find anything we include. Capacity measures how much text can fit; retrieval quality depends on position and task.
Liu et al. (2023) varied evidence position in multi-document question answering and key-value retrieval.[41] Many tested models did worse with evidence in the middle than at the edges, producing a U-shaped curve. The effect varied by model and task; some synthetic retrieval settings were solved perfectly. Treat its findings as model- and task-specific; evaluate the position curve for each current model.

The observed answer-accuracy curve leaves its cause unresolved. Attention mass on initial tokens measures attention weights; evaluate separately whether the model uses that evidence faithfully. Full attention can directly connect an answer position to a distant visible key. Attribute a retrieval error to attention diffusion only after a targeted evaluation isolates that mechanism.
In the study, the query-before-and-after intervention greatly improved synthetic key-value retrieval and had little effect on the multi-document QA trend.[41] Test prompt changes on the workload you intend to improve; gains on one benchmark may not transfer to debugging.
Calculate the figure's hypothetical scores:
cases_per_position = 20
correct_by_slot = {1: 15, 5: 10, 10: 7, 15: 10, 20: 14}
for slot, correct in correct_by_slot.items():
assert 0 <= correct <= cases_per_position
print(f"slot={slot:2d} correct={correct:2d}/20 accuracy={correct / cases_per_position:.0%}")
print("fixture_only: no model was evaluated")slot= 1 correct=15/20 accuracy=75%
slot= 5 correct=10/20 accuracy=50%
slot=10 correct= 7/20 accuracy=35%
slot=15 correct=10/20 accuracy=50%
slot=20 correct=14/20 accuracy=70%
fixture_only: no model was evaluatedPractical prompt engineering mitigations
When feeding large logs or multiple retrieved documents to your developer assistant:
- Put governing instructions in the model's supported system/developer role. Mark log text as untrusted evidence and delimit it clearly.
- Compare task-before-context, task-after-context, and repeated-task layouts on the chosen model. Preserve chronology where event order matters.
- Test evidence near either boundary and in the middle. Shorten irrelevant material when possible, while keeping the context needed to support the diagnosis.
policy = "Rule: explain CI failures using cited log lines."
older_notes = [
"History: dependency cache restored.",
"History: formatter completed.",
"History: unit tests started.",
]
case = "Evidence: RUN-842 failed at auth_fixture_test.py:41 with expired auth fixture."
question = "Question: explain the failure and cite the evidence."
prompt_lines = [policy, *older_notes, case, question]
for position, line in enumerate(prompt_lines, start=1):
print(f"{position}: {line}")
print("evidence_adjacent_to_question:", prompt_lines[-2] == case)1: Rule: explain CI failures using cited log lines.
2: History: dependency cache restored.
3: History: formatter completed.
4: History: unit tests started.
5: Evidence: RUN-842 failed at auth_fixture_test.py:41 with expired auth fixture.
6: Question: explain the failure and cite the evidence.
evidence_adjacent_to_question: TrueThis code verifies adjacency in the constructed prompt. Measure model quality by comparing the layout with a position-shuffled baseline and inspecting supported answers, misses, and false diagnoses.
Why does retrieval-augmented generation (RAG) remain relevant even when models support 1-million-token context windows?
Answer
Retrieval can supply current evidence and focus a prompt, potentially reducing prefill work and context storage. It can also miss the decisive log line, add irrelevant snippets, or cost more time than it saves. A large context window and retrieval offer complementary ways to deliver evidence, while models can still show position-dependent performance. Measure retrieval recall, answer support, latency, and cost across evidence positions.
Match the architecture to the job
Different jobs around the same CI failure may call for different models. Match the architecture to the measurement you actually need:
| Pipeline task | Recommended architecture | Primary selection rationale |
|---|---|---|
| Large-scale log embedding & clustering | Task-trained embedding model, often an encoder | Compare retrieval/clustering quality, embedding size, and indexing cost. |
| Real-time code autocomplete | Compact code-trained causal generator | Measure first useful completion latency, acceptance quality, and device memory. |
| Multi-turn CI debugging assistant | Instruction/conversation-trained generator | Evaluate supported diagnosis, abstention, history handling, and tool use. |
| High-throughput multi-task API gateway | Compare dense and sparse candidates | Measure workload throughput, routing overhead, quality, and full memory cost. |
| Complex multi-file refactoring & math | Compare reasoning effort and verification strategies | Require passing tests or checked solutions and measure the total task budget. |
Common misconceptions
| Misconception | Observable symptom | Root cause | Engineering fix |
|---|---|---|---|
| "GPT means any LLM." | A model-family name is used as an architecture definition. | Conflating a named family with the broader category. | Name the exact family and checkpoint; use "LLM" for the broad category. |
| "BERT is completely obsolete." | Teams deploy 70B generative models to perform simple log classification. | Decoders dominate media coverage. | Use lightweight encoder models for embedding search, reranking, and discrete label classification. |
| "A bigger model always wins." | Selecting a checkpoint solely by parameter count. | Ignoring data, objectives, task fit, and serving constraints. | Rank candidates by held-out application quality and total cost on the target workload. |
| "Open-weight means free commercial use." | A startup builds a commercial product on a model with non-commercial license terms. | Confusing public model weights with open-source licensing. | Read the model card and license terms before integrating into commercial products. |
| "Context length guarantees recall." | Placing a stack trace in the middle of a 100k-token prompt and wondering why the model misses it. | Conflating context capacity with attention retrieval fidelity. | Place decisive evidence adjacent to the query or near prompt boundaries, and test recall empirically. |
Practice: diagnose the failing assistant
Your first prototype of the RUN-842 assistant exhibits three operational failures:
- Behavioral failure: When an engineer sends
"Explain why RUN-842 failed at line 41", the model responds by outputting:"Explain why RUN-843 failed at line 12\nExplain why RUN-844 failed at line 99". - Retrieval failure: When you provide a 20-line snippet, the model correctly identifies the expired auth fixture. When you provide the complete 50,000-line build log containing the exact same snippet in the middle, the model claims:
"The build succeeded without errors". - Memory failure: A newly proposed 47B MoE model advertises 13B active parameters per token. Your ops team attempts to deploy it on a single GPU with 24 GB of VRAM, and the container crashes immediately with an
OutOfMemoryCUDA error.
How do you diagnose and fix each of the three failures?
Answer
- Check the actual checkpoint, template, generation prefix, and examples. A base-model continuation is one explanation; incorrect serialization or a misleading prompt can produce similar behavior. Compare a known instruction checkpoint with the correct template on a short controlled case.
- Confirm that the evidence survives tokenization, truncation, retrieval, and context limits. If it does, move the same evidence to different positions while holding the task fixed. A position effect supports a lost-in-the-middle diagnosis; retrieval or parsing can help, but must retain the necessary context and be evaluated.
- For a fully resident FP16 deployment, 47B raw weights occupy about 94 GB / 87.54 GiB—almost four times a 24 GB card's capacity before cache or runtime overhead. Shard, choose a smaller model, or use supported quantization/offloading. An ideal four-bit weight payload is 23.5 GB / 21.89 GiB, leaving little room on a 24 GB card for scales, buffers, and KV cache. Test the complete serving configuration.
Validate the continuation against evidence. Size deployment from total serving memory, including weights, KV cache, scales, and runtime overhead. The RUN-842 assistant also needs the right evidence and a testable output format.