LeetLLM
My PlanLearnGlossaryTracksPracticeBlog
LeetLLM

Your go-to resource for mastering AI & LLM systems.

Product

  • Learn
  • Glossary
  • Tracks
  • Practice
  • Blog
  • RSS

Legal

  • Terms of Service
  • Privacy Policy

© 2026 LeetLLM. All rights reserved.

All Topics
Your Progress
0%

0 of 196 articles completed

🛠️Computing Foundations0/9
Git, Shell, Linux for AIDocker for Reproducible AIPython for AI EngineeringNumPy and Tensor ShapesCUDA for ML TrainingMPS & Metal for ML on MacData Structures for AISQL and Data ModelingAlgorithms for ML Engineers
📊Math & Statistics0/9
Gradients and BackpropVectors, Matrices & TensorsLinear Algebra for MLAdam, Momentum, SchedulersProbability for Machine LearningBayesian Inference from EvidenceStatistics and UncertaintyDistributions and SamplingHypothesis Tests, Intervals, and pass@k
📚Preparation & Prerequisites0/13
Neural Networks from ScratchCNNs from ScratchTraining & BackpropagationSoftmax, Cross-Entropy & OptimizationRNNs, LSTMs, GRUs, and Sequence ModelingAutoencoders and VAEsThe Transformer Architecture End-to-EndLanguage Modeling & Next TokensFrom GPT to Modern LLMsPrompt Engineering FundamentalsCalling LLM APIs in ProductionFirst AI App End-to-EndThe LLM Lifecycle
🧮ML Algorithms & Evaluation0/15
Linear Regression from ScratchLogistic Regression and MetricsDecision Trees, Forests, and BoostingReinforcement Learning BasicsValidation and LeakageStatistical Learning and GeneralizationConformal Prediction and UncertaintyClustering and PCAProbabilistic Generative ModelsCore Retrieval AlgorithmsDecoding AlgorithmsExperiment Design and A/B TestingCausal Inference and CounterfactualsPyTorch Training LoopsDataset Pipelines and Data Quality
📦Production ML Systems0/6
Feature Engineering for Production MLBatch and Streaming Feature PipelinesGradient Boosted Trees in ProductionRanking and Recommendation SystemsForecasting and Anomaly DetectionMonitoring Predictive Models
🧪Core LLM Foundations0/8
The Bitter Lesson & ComputeBPE, WordPiece, and SentencePieceStatic to Contextual EmbeddingsPerplexity & Model EvaluationFile Ingestion for AIChunking StrategiesLLM Benchmarks & LimitationsInstruction Tuning & Chat Templates
🧰Applied LLM Engineering0/25
Dimensionality Reduction for EmbeddingsCoT, ToT & Self-Consistency PromptingFunction Calling & Tool UseMCP & Tool Protocol StandardsContext EngineeringPrompt Injection DefenseResponsible AI GovernancePrivacy-Preserving Machine LearningData Labeling and Human FeedbackEvaluating AI AgentsProduction RAG PipelinesHybrid Search: Dense + SparseReranking and Cross-Encoders for RAGRAG Evaluation for Reliable AnswersLLM-as-a-Judge EvaluationBias & Fairness in LLMsHallucination Detection & MitigationLLM Observability & MonitoringExperiment Tracking with MLflow and W&BPrompt Optimization with DSPyModel Versioning & DeploymentSemantic Caching & Cost OptimizationLLM Cost Engineering & Token EconomicsModel Gateways, Routing, and FallbacksDesign an Automated Support Agent
🎓Portfolio Capstones0/9
Capstone: Delivery ETA PredictionCapstone: Product RankingCapstone: Demand ForecastingCapstone: Image Damage ClassifierCapstone: Production ML PipelineCapstone: Document QACapstone: Eval DashboardCapstone: Fine-Tuned ClassifierCapstone: Reproducible ML Study
🧠Transformer Deep Dives0/8
Sentence Embeddings & Contrastive LossEmbedding Similarity & QuantizationScaled Dot-Product AttentionVision Transformers and Image EncodersPositional Encoding: RoPE & ALiBiLayer Normalization: Pre-LN vs Post-LNMechanistic InterpretabilityDecoding Strategies: Greedy to Nucleus
🧬Advanced Training & Adaptation0/17
Scaling Laws & Compute-Optimal TrainingPre-training Data at ScaleBuild GPT from Scratch LabJAX for PyTorch ResearchersContinued Pretraining for Domain ShiftSynthetic Data PipelinesSupervised Fine-Tuning PipelineMixed Precision TrainingDistributed Training: FSDP & ZeROLoRA & Parameter-Efficient TuningTraining Run OperationsReward Modeling from Preference DataRLHF & DPO AlignmentConstitutional AI & Red TeamingRLVR & Verifiable RewardsKnowledge Distillation for LLMsModel Merging and Weight Interpolation
🤖Advanced Agents & Retrieval0/16
Vector DB Internals: HNSW & IVFAdvanced RAG: HyDE & Self-RAGGraphRAG & Knowledge GraphsRAG Security & Access ControlStructured Output GenerationReAct & Plan-and-ExecuteGuardrails & Safety FiltersCode Generation & SandboxingComputer-Use / GUI / Browser AgentsHuman-in-the-Loop Agent ArchitectureAI Coding Workflow with AgentsAgent Memory & PersistenceAgent Failure & RecoveryRecursive Language Models (RLM)Multi-Agent OrchestrationCapstone: Production Agent
⚡Inference & Production Scale0/31
Inference: TTFT, TPS & KV CacheMulti-Query & Grouped-Query AttentionKV Cache & PagedAttentionPrefix Caching and Prompt CachingFlashAttention & Memory EfficiencyContinuous Batching & SchedulingScaling LLM InferenceModel Parallelism for LLM InferenceAccelerator Architecture Field GuideCorrect GPU Profiling and BenchmarkingGPU Kernel Performance Engineering LabGPU Parallel Primitives LabGPU Compilers and Kernel LanguagesGEMM From Naive CUDA to Tensor CoresLow-Precision GPU ProgrammingGPU Runtime Execution LabAI-Generated Kernel EngineeringModel Quantization: GPTQ, AWQ & GGUFLocal LLM DeploymentSLM Specialization & Edge DeploymentSpeculative DecodingLong Context Window ManagementMixture of Experts ArchitectureMamba & State Space ModelsReasoning & Test-Time ComputeAdvanced MLOps & DevOps for AIGPU Serving & AutoscalingGPU Failure OperationsDistributed Inference Data PlaneServing Benchmark EngineeringA/B Testing for LLMs
🏗️System Design Capstones0/9
Content Moderation SystemCode Completion SystemMulti-Tenant LLM PlatformLLM-Powered Search EngineVision-Language Models & CLIPMultimodal LLM ArchitectureDiffusion Models: Images & TextReal-Time Voice AI AgentReasoning Agent System Design
🎤AI Lab Interviewing0/4
AI Lab Coding Interview: Python SystemsAI Lab System Design InterviewAI Lab Behavioral InterviewAI Lab Technical Presentation
🔬Project Deep Dives0/17
Deep Dive - vLLMDeep Dive - SkyRLDeep Dive - FlashAttentionDeep Dive - FlashInferDeep Dive - DeepGEMMDeep Dive - NCCLDeep Dive - MegatronDeep Dive - DeepSpeedDeep Dive - RayDeep Dive - MLflowDeep Dive - PyTorchDeep Dive - TransformersDeep Dive - SGLangDeep Dive - slimeDeep Dive - DeepEPDeep Dive - TinkerDeep Dive - Light-PEFT
Back to Topics
LearnInference & Production ScaleReasoning & Test-Time Compute
📈HardReasoning & Scaling

Reasoning & Test-Time Compute

Understand how reasoning models trade extra inference compute for better answers, and what that means for search, verifiers, KV cache pressure, and routing.

42 min read
Learning path
Step 160 of 196 in the full curriculum
Mamba & State Space ModelsAdvanced MLOps & DevOps for AI

Personalize this lesson

Adapt explanations and teaching visuals to your background and preferred voice.

A familiar on-call trade-off arrives as capacity_math: estimate GPU memory for eight concurrent branches sharing a 4,000-token prompt, each producing 1,000 continuation tokens, while the queue is already busy. One pass is cheap, but it can omit a KV term. Eight candidates may expose the omission, then occupy the cache headroom needed by the next request. The real question isn't “can the model think harder?” It’s “which extra evidence earns its TTFT, memory, and cost?”

State-space models showed one way to keep decode state from growing with context length by compressing history into recurrent state. Reasoning models make a different trade: keep working longer, branch, or check an answer when task difficulty makes that useful. The system buys a chance to catch its own plausible mistake before it commits.

Count the r's in strawberry one position at a time. A quick association can stop at two; marking the letters gives three. A single-pass capacity estimate has the same failure mode: it can sound finished until someone walks through KV bytes, branch count, and the latency SLO.

Classic scaling work focused on train-time compute: more parameters, more data, and more pretraining FLOPs (floating-point operations).[1]Reference 1Scaling Laws for Neural Language Modelshttps://arxiv.org/abs/2001.08361

Work from 2024 onward made a second axis hard to ignore. On hard reasoning tasks, extra compute during generation can improve the answer.[2]Reference 2Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.https://arxiv.org/abs/2408.03314[3]Reference 3Learning to reason with LLMshttps://openai.com/index/learning-to-reason-with-llms/ That is test-time compute scaling. OpenAI's o1 launch post and DeepSeek-R1 made the shift visible, while Snell et al. showed in evaluated math settings that a smaller model with a well-chosen inference policy can beat a much larger model answering once.[3]Reference 3Learning to reason with LLMshttps://openai.com/index/learning-to-reason-with-llms/[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948[2]Reference 2Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.https://arxiv.org/abs/2408.03314

Provider APIs expose this choice as an effort or thinking control, with names and supported values that vary by model. A useful production skill follows: measure where another token, branch, or check changes correctness, then stop when its latency and cost outweigh that gain. More thinking isn't automatically better.[5]Reference 5Does Thinking More Always Help? Mirage of Test-Time Scaling in Reasoning Modelshttps://arxiv.org/abs/2506.04210[6]Reference 6Reasoning modelshttps://developers.openai.com/api/docs/guides/reasoning

We’ll use capacity_math throughout. Easy lookups stay single-pass. For this request, extra samples, a verifier, or a longer trace might change the answer, but each option consumes budget. Keep the earlier picture of how transformers predict the next token, then choose among single-pass, best-of-N, and guided search by the evidence each path can add. Routing and token budgets are part of that choice, not cleanup after the algorithm.

Measured reasoning-budget sweep: accuracy rises from 71% at 0 tokens to 83% at 512 tokens, then falls to 80% at 2048 tokens. Latency stays under a 1000 ms SLO through 610 ms at 512 tokens, then jumps to 1840 ms at 2048 tokens, so the measured pick is 512, not the longest trace.
On this eval table, accuracy peaks at 512 thinking tokens. The 2048-token budget is both less accurate and over the 1000 ms latency SLO, so the longest trace is not the one you ship.

Treat the values as a teaching fixture, not a hardware benchmark. A real sweep records model version, hardware, prompt distribution, sampling policy, verifier, correctness metric, and p50/p99 latency beside each budget.

What does test-time compute scaling add that train-time scaling alone doesn't?

Answer

Train-time scaling spends compute before deployment to improve the model. Test-time scaling spends extra compute during generation through longer traces, more samples, revision, or search, so hard tasks can get more deliberation than easy tasks.

Fast answers miss checks

Start with the operation, then attach Kahneman's labels. Read strawberry as a sequence of positions and mark each r: the answer is three. Reading it as a familiar word and blurting out “two” is the fast path.

In Kahneman's framework, that fast, pattern-driven response is System 1. The slower, deliberate count is System 2. The labels help us describe a serving trade-off, but they aren't an architecture taxonomy. A low-budget single-pass call can lean on learned patterns; a larger budget can buy checks, alternate samples, or tool calls.

The miss isn't a knowledge gap. Counting requires deliberate step-by-step verification, while pretraining's next-token objective rewards a fluent continuation more directly than a checked final answer. capacity_math fails in the same place: a plausible GPU count collapses once KV bytes are multiplied by sequence length.

Test-time compute addresses that failure mode only when it buys useful evidence. A model or wrapper can explore several approaches, inspect intermediate steps, and select a candidate before committing. If every branch repeats the same mistake, extra tokens add cost without adding confidence.

Why is counting the r letters in strawberry a System 2 task for a model?

Answer

The answer isn't a stored fact or a fluent association. The model must inspect positions and verify the count before answering, which is exactly the kind of work extra reasoning tokens can support.

When does extra inference compute help most?

Answer

It helps when the task requires verifiable multi-step reasoning, search, or correction. It helps much less for fluent pattern-matching tasks such as simple extraction, translation, or sentiment classification.

The two axes of compute scaling

Separate when the bill arrives. Train-time compute is spent before deployment to improve fixed weights. Test-time compute is spent during a live request: trying alternate fixes, checking evidence, and verifying an answer before committing.

Traditional scaling changes model parameters NNN or training tokens DDD. Empirical studies fit loss with an approximate power law of compute CCC; Kaplan et al. use roughly 6ND6ND6ND as a training-compute estimate in their scaling analysis:[1]Reference 1Scaling Laws for Neural Language Modelshttps://arxiv.org/abs/2001.08361

Ltrain(C)∝C−α,C=6NDL_{\text{train}}(C) \propto C^{-\alpha}, \quad C = 6NDLtrain​(C)∝C−α,C=6ND

Within the measured regime, that relationship is predictable enough to guide how a team spends pretraining compute. It says nothing by itself about which live request deserves a longer rollout.

That live decision adds a second axis, inference compute CinferC_{\text{infer}}Cinfer​. A useful model treats accuracy as a function of compute, task shape, policy, and verifier quality:

accuracy=g(Cinfer,task,policy,verifier)\text{accuracy} = g(C_{\text{infer}}, \text{task}, \text{policy}, \text{verifier})accuracy=g(Cinfer​,task,policy,verifier)

In an evaluated operating range, more inference compute can improve accuracy with diminishing returns. It can plateau or even reduce accuracy when a trace overthinks, samples remain correlated, or a verifier picks the wrong branch. Compute may arrive as a longer trace, repeated samples, a revision loop, or explicit search with a verifier.[2]Reference 2Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.https://arxiv.org/abs/2408.03314[5]Reference 5Does Thinking More Always Help? Mirage of Test-Time Scaling in Reasoning Modelshttps://arxiv.org/abs/2506.04210

Snell et al. don't claim one law for every model and benchmark. Their operational result is narrower and more useful: in their math evaluations, a well-allocated inference budget let a smaller model outperform a larger model sampled once.[2]Reference 2Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.https://arxiv.org/abs/2408.03314

Why does test-time compute have diminishing returns?

Answer

Early extra samples or reasoning steps often find obvious mistakes. Later compute tends to explore correlated candidates, repeat work, or hit verifier limits, so each additional token or branch buys less improvement.

That distinction changes how a system spends compute on a hard prompt:

text
1Traditional approach: Train bigger → Answer once → Done 2Reasoning approach: Train reasoner → Think longer → Search for best answer

The next cell turns that distinction into a selection rule. It reuses the opening eval table and chooses the highest measured accuracy that fits a 1000 ms latency limit.

measured-budget-sweet-spot.py
1budgets = [0, 128, 512, 2048] 2verified_accuracy = [0.71, 0.78, 0.83, 0.80] 3latency_ms = [220, 310, 610, 1840] 4latency_limit_ms = 1000 5 6eligible = [ 7 (accuracy, budget, latency) 8 for budget, accuracy, latency in zip(budgets, verified_accuracy, latency_ms) 9 if latency <= latency_limit_ms 10] 11accuracy, budget, latency = max(eligible) 12print(f"chosen_budget={budget} accuracy={accuracy:.0%} latency_ms={latency}") 13print(f"max_budget_is_best={verified_accuracy[-1] == max(verified_accuracy)}")
Output
1chosen_budget=512 accuracy=83% latency_ms=610 2max_budget_is_best=False

The output answers a production question, not a theory question: among the tested budgets, which one gives the best measured quality while meeting the service-level objective? Here, 512 wins. A longer trace would need new evidence before it earns its extra latency.

How reasoning models work

Reasoning-oriented training and inference policies allocate additional tokens or branches before returning an answer. You may see decomposition, checks, or revision, but none of those behaviors is guaranteed on every request. Treat them as policies to measure.

Extended chain-of-thought

Reasoning models often generate a long scratchpad or intermediate trace around a final answer. A provider may expose that trace, return a summary, or hide it. Some APIs also interleave non-visible reasoning with visible output or tool calls. For this chapter, the important distinction is operational: can the model or wrapper spend additional inference compute before it commits?

Built-in reasoning also differs from prompted chain-of-thought (CoT)[7]Reference 7Chain-of-Thought Prompting Elicits Reasoning in Large Language Models.https://arxiv.org/abs/2201.11903. Training can shape the policy through Reinforcement Learning (RL), distillation, or both, instead of relying on prompt wording alone. A serving policy can vary the budget by request difficulty, and a trace may backtrack or revise a dead end. Providers can account for and bill that work without exposing raw intermediate tokens.

Current reasoning APIs make the accounting concrete. OpenAI's docs describe reasoning tokens as non-visible output tokens that still consume context budget and count as billed output tokens. They also describe interleaved thinking for some current models, where visible output or tool calls can appear between reasoning steps.[6]Reference 6Reasoning modelshttps://developers.openai.com/api/docs/guides/reasoning

Thinking depth is now a control surface, but the contract is model- and endpoint-specific. OpenAI's reasoning.effort accepts a model-dependent subset of none, minimal, low, medium, high, xhigh, and max; lower effort favors speed and lower token use, while higher effort favors more complete reasoning.[6]Reference 6Reasoning modelshttps://developers.openai.com/api/docs/guides/reasoning

Google's current Interactions API uses generation_config.thinking_level and lists supported levels per Gemini model. Its docs represent thoughts and signatures differently in the generateContent API, so a client should follow the selected endpoint's schema instead of copying a knob between APIs.[8]Reference 8Gemini thinkinghttps://ai.google.dev/gemini-api/docs/thinking

Anthropic's docs distinguish adaptive thinking (thinking.type: "adaptive") on newer models from manual budget_tokens on models that support extended thinking. Manual mode is deprecated on Claude 4.6 and rejected on Claude 4.7 and later, while support remains model-specific.[9]Reference 9Building with extended thinkinghttps://docs.claude.com/en/docs/build-with-claude/extended-thinking

Open-weight systems expose related controls, though their interfaces still differ. GLM-5.2 is documented as a 744B-A40B MoE with 1M text context, reasoning_effort values of high or max, and a thinking switch.[10]Reference 10GLM-5.2 Model Cardhttps://huggingface.co/zai-org/GLM-5.2[11]Reference 11GLM-5 Repositoryhttps://github.com/zai-org/GLM-5[12]Reference 12GLM-5.2 Model Documentationhttps://docs.z.ai/guides/llm/glm-5.2

DeepSeek-V4-Flash-0731 documents low, high, and max effort with a 1M text context.[13]Reference 13DeepSeek-V4-Flash-0731 Model Cardhttps://huggingface.co/deepseek-ai/DeepSeek-V4-Flash-0731[14]Reference 14Use DeepSeek with Codexhttps://api-docs.deepseek.com/quick_start/agent_integrations/codex/ The V4 paper sizes Flash at 284B total and 13B active; the 0731 checkpoint attaches a speculative module, which explains why hosted parameter counts can read higher.[15]Reference 15DeepSeek-V4: Towards Highly Efficient Million-Token Context Intelligencehttps://arxiv.org/abs/2606.19348

Across these systems, higher effort can improve difficult work, but it also increases latency, output volume, and GPU occupancy. Start with clear constraints, tune the supported knob, and evaluate the result instead of assuming a chain-of-thought prompt helps.

Test-time compute can mean a longer single trace or multiple sampled traces. OpenAI's o1 launch post reported one benchmark example on AIME 2024, a math competition: accuracy rose from one sample to consensus over 64 samples, then to learned reranking over 1000 samples.[3]Reference 3Learning to reason with LLMshttps://openai.com/index/learning-to-reason-with-llms/ Keep the scope attached to the number. That result belongs to one evaluation, not a promise for another task, model, or selector.

Why can provider-reported non-visible reasoning tokens affect cost and capacity even when users never see them?

Answer

When the provider accounts for non-visible reasoning tokens, they still consume billed output tokens and context budget. They can also add wall-clock work. Transformer runtimes that materialize them autoregressively retain temporary key-value (KV) state while generating them, so a short visible answer can still be expensive.

Deliberation and search at inference time

Test-time compute is an umbrella term, not a single algorithm. Some systems sample many complete answers and pick a winner. Some iteratively critique and revise one candidate. Others run explicit search over partial reasoning states using a verifier or reward model. All of these patterns branch from the same idea: spend extra compute to explore, score, and refine before returning an answer.

Reasoning search tree: one prompt branches into three candidate paths, a verifier prunes two low-scoring paths, and one selected answer returns.
Reasoning delays commitment: branch, score, prune, then return the path worth trusting.

Not every reasoning model literally runs beam search or a PRM at inference time. The shared pattern is optional inference compute allocation. A good routing policy keeps easy requests cheap and assigns more tokens, branches, or verification only where evaluation shows a payoff.

What is the shared pattern behind longer traces, best-of-N, revision loops, and tree search?

Answer

They allocate more inference compute before committing to an answer. The system explores, verifies, revises, or selects among candidates instead of returning the first plausible completion.

Provider-reported hidden reasoning

Suppose the dashboard shows a short answer but a large output-token count. Some hosted APIs report non-visible reasoning in usage accounting while returning only final text; others interleave visible output or tool calls with non-visible work. OpenAI's reasoning-token documentation describes both patterns.[6]Reference 6Reasoning modelshttps://developers.openai.com/api/docs/guides/reasoning An open-weight deployment, explicit search wrapper, or provider with summarized thinking may expose and account for intermediate work differently, so inspect the actual response schema.

Provider usage split for one request: 1,220 non-visible reasoning tokens and 180 visible answer tokens, totaling 1,400 billed output tokens. Visible text is only 12.9% of the bill.
In this usage report, non-visible reasoning is 1,220 of 1,400 billed output tokens (about 87%). Visible text alone understates output cost and temporary KV state for runtimes that materialize those tokens.

For an API that reports them, non-visible tokens consume context window space and may count toward billing even though users never see them.[6]Reference 6Reasoning modelshttps://developers.openai.com/api/docs/guides/reasoning A transformer runtime that materializes those tokens autoregressively also spends decode work and holds temporary key-value (KV) cache state while generation runs. Exact cache behavior belongs to the provider and engine, not to this accounting shortcut.

Why should prompts for a hosted reasoning model usually start simple and direct?

Answer

Clear task constraints, success criteria, and output requirements give a good evaluation baseline. Then follow the selected model's prompting guidance rather than assuming visible chain-of-thought instructions improve its non-visible reasoning.

The next cell bills the same 180 visible + 1,220 hidden split as the figure, at an illustrative $10 per million output tokens.

hidden-token-accounting.py
1visible_tokens = 180 2reasoning_tokens = 1220 3output_price_per_million = 10.0 4 5billed_output_tokens = visible_tokens + reasoning_tokens 6cost = billed_output_tokens / 1_000_000 * output_price_per_million 7print(f"visible={visible_tokens} billed_output={billed_output_tokens}") 8print(f"visible_fraction={visible_tokens / billed_output_tokens:.1%} output_cost=${cost:.4f}")
Output
1visible=180 billed_output=1400 2visible_fraction=12.9% output_cost=$0.0140

Use the provider's usage schema and pricing table for a real implementation. The example gives a capacity lesson: a dashboard that counts visible text alone can understate both spend and active KV state.

Test-time compute strategies

When capacity_math is uncertain, extra work can take three forms: parallel candidates, sequential repair, or a branching search that scores partial work. The right pattern follows from what can be checked and how much latency the request can spend.

1. Best-of-N sampling

Start with parallel alternatives. Sample NNN candidates for the same capacity_math prompt, then keep the candidate with the best verifier score or the most common extracted answer. More attempts raise the chance of seeing a fix only when they add useful diversity and the selector can recognize it. Shared model biases make samples correlated, so the independence assumption is only a baseline.

Best-of-N is easy to parallelize, which keeps wall-clock time manageable. The cost remains high: every completion consumes tokens, memory, and capacity, even though only one candidate returns to the user.

The sketch below assumes a model.generate method. The testable math is in the next two cells.

1-best-of-n-sampling.py
1from collections import Counter 2 3def extract_answer(completion: str) -> str: 4 lines = [line.strip() for line in completion.splitlines() if line.strip()] 5 return lines[-1] if lines else "" 6 7def best_of_n( 8 model, 9 prompt: str, 10 n: int = 16, 11 reward_model=None 12) -> str: 13 """Generate N responses and return the best-scored candidate completion. 14 15 Cost: O(N) forward passes, embarrassingly parallel. 16 Best for: Problems with verifiable correctness (math, code). 17 """ 18 candidates = [model.generate(prompt) for _ in range(n)] 19 20 if reward_model: 21 scores = [reward_model.score(prompt, c) for c in candidates] 22 return candidates[scores.index(max(scores))] 23 else: 24 # Self-consistency: majority vote on final answer 25 answers = [extract_answer(c) for c in candidates] 26 answer_counts = Counter(answers) 27 best_answer = answer_counts.most_common(1)[0][0] 28 return next(c for c in candidates if extract_answer(c) == best_answer)

Scaling behavior

Ask first what an ideal selector would achieve. With an oracle verifier and independent samples, the chance of generating at least one correct answer in NNN tries follows:

Psuccess=1−(1−p)NP_{\text{success}} = 1 - (1 - p)^NPsuccess​=1−(1−p)N

Here ppp is the base probability that one attempt is correct. For the toy value p=0.25p=0.25p=0.25, four independent attempts give 1−(0.75)4=68.4%1-(0.75)^4=68.4\%1−(0.75)4=68.4%. Real systems fall below that ideal because candidates correlate and selectors make mistakes, but the equation shows where the gain comes from. OpenAI's o1 launch post reported the same pattern on AIME 2024: 74% with one sample, 83% with 64-sample consensus, and 93% when a learned scorer reranked 1000 samples.[3]Reference 3Learning to reason with LLMshttps://openai.com/index/learning-to-reason-with-llms/

best_of_n_budget.py
1def success_probability(p: float, n: int) -> float: 2 return 1 - (1 - p) ** n 3 4base_hit_rate = 0.25 5tokens_per_attempt = 800 6 7for n in [1, 4, 16, 64]: 8 success = success_probability(base_hit_rate, n) 9 output_tokens = n * tokens_per_attempt 10 print(f"N={n:>2} success={success:5.1%} output_tokens={output_tokens:>5}")
Output
1N= 1 success=25.0% output_tokens= 800 2N= 4 success=68.4% output_tokens= 3200 3N=16 success=99.0% output_tokens=12800 4N=64 success=100.0% output_tokens=51200

The toy curve makes the trade-off visible: ideal success rises quickly while cost grows linearly with every completion. Correlation and selector errors pull the deployed curve down. The next cell applies an 80% selector recall after N>1N > 1N>1, matching the gap drawn in the figure.

best-of-n-with-selection-errors.py
1def selected_success_probability(candidate_success: float, selector_recall: float, n: int) -> float: 2 return candidate_success if n == 1 else candidate_success * selector_recall 3 4base_hit_rate = 0.25 5selector_recall = 0.80 6for n in [1, 4, 16]: 7 oracle_success = 1 - (1 - base_hit_rate) ** n 8 deployed_success = selected_success_probability(oracle_success, selector_recall, n) 9 print(f"N={n:>2} oracle={oracle_success:5.1%} with_selector={deployed_success:5.1%}")
Output
1N= 1 oracle=25.0% with_selector=25.0% 2N= 4 oracle=68.4% with_selector=54.7% 3N=16 oracle=99.0% with_selector=79.2%

The selector is deliberately simple. One candidate has no selection step. Once branches exist, generation and selection become separate failure surfaces: a correct answer can appear and still be discarded.

Best-of-N success curves: oracle selection for 10%, 25%, and 45% base hit rates rises fast then plateaus, while a 25% model with 80% selector recall caps near 80% even as N grows, showing generation and selection as separate failure surfaces.
Oracle best-of-N helps most when the base model already has a meaningful hit rate. Once a selector with 80% recall has to pick among candidates, deployed success plateaus well below the oracle curve, so more samples mostly buy repeated work.

What must be true for best-of-N to pay off?

Answer

The base model must have a non-trivial chance of producing a correct candidate, the samples must add useful diversity, and the verifier or selection rule must reliably identify better answers.

Train for the test-time policy you plan to use

Training and serving need to agree on what counts as success. Supervised fine-tuning with cross-entropy (CE) puts more probability on each demonstrated target, which fits a pass@1 system. Best-of-N needs coverage across samples. If CE concentrates probability on one trace family, extra draws become near-duplicates and the search budget stops buying exploration.

Chen et al. report this mismatch in mathematical reasoning and theorem-proving settings: longer CE training can raise confidence while lowering pass@N, while a confidence-limiting objective better matches later search.[16]Reference 16Rethinking Fine-Tuning when Scaling Test-Time Compute: Limiting Confidence Improves Mathematical Reasoninghttps://proceedings.neurips.cc/paper_files/paper/2025/hash/e8f4eae0a41cab67fdead3aa6b77f083-Abstract-Conference.html CE isn't a failed objective. Evaluate it against the policy you will ship: next-token loss, pass@1, candidate diversity, and pass@N at the actual sample budget.

Why can cross-entropy SFT improve pass@1 yet hurt a best-of-N search policy?

Answer

CE can concentrate probability on one demonstrated trace and make samples less diverse. Pass@N needs coverage of at least one correct candidate, so training should be evaluated against the deployed sample budget and selection policy.

2. Sequential revision

Now make the work sequential. Draft the capacity_math answer, check it against the KV formula and latency SLO, then repair the weak step. Each pass sees the previous answer, unlike best-of-N's independent attempts.

The loop is draft, critique, and regenerate when needed. The sketch stops when the critique reports "no errors found"; a deployed system would replace that string match with a trained verifier or structured critique schema. Every round adds dependency and latency, so a plateau should end the loop.

2-sequential-revision.py
1def iterative_refinement(model, prompt: str, max_rounds: int = 5) -> str: 2 """Generate, critique, and refine until convergence. 3 4 Cost: O(rounds) sequential passes, each building on previous. 5 Best for: Open-ended tasks (writing, analysis, planning). 6 """ 7 response = model.generate(prompt) 8 9 for _ in range(max_rounds): 10 critique = model.generate( 11 f"Find errors or improvements in this response:\n" 12 f"Question: {prompt}\nResponse: {response}" 13 ) 14 15 if "no errors found" in critique.lower(): 16 break 17 18 response = model.generate( 19 f"Question: {prompt}\n" 20 f"Previous response: {response}\n" 21 f"Critique: {critique}\n" 22 f"Provide an improved response:" 23 ) 24 25 return response

When is sequential revision a better fit than best-of-N?

Answer

Use sequential revision when each pass can improve a draft through critique, editing, or repair. Use best-of-N when candidates are independent and the answer can be scored directly.

The next cell applies that stopping rule to measured scores. Once a round gains less than 0.01, later rounds would spend budget on a plateau.

revision-early-stop.py
1verified_scores = [0.61, 0.76, 0.78, 0.781, 0.781] 2minimum_gain = 0.01 3used_rounds = 1 4 5for previous, current in zip(verified_scores, verified_scores[1:]): 6 if current - previous < minimum_gain: 7 break 8 used_rounds += 1 9 10print(f"used_rounds={used_rounds} selected_score={verified_scores[used_rounds - 1]:.3f}") 11print(f"skipped_rounds={len(verified_scores) - used_rounds}")
Output
1used_rounds=3 selected_score=0.780 2skipped_rounds=2

3. Tree search with process reward models

Tree search spends compute before a path is complete. For capacity_math, one branch might multiply KV bytes correctly, another might keep the wrong branch count, and a third might violate the SLO. A process reward model scores each intermediate step, so the controller can prune a bad path before paying for its remaining steps. An outcome score waits for the final answer.

The simplified beam search below starts with one prompt state. Each round proposes several next steps, scores them with the PRM, and keeps the highest-scoring unfinished paths. A branch whose next step starts with Final: moves into a separate completed pool, where it can't be expanded or displaced by an unfinished trace that keeps accumulating score. Search continues until no active branch remains or the step budget runs out.

The return value makes completion explicit. It selects the highest-scoring completed chain when one exists. If every branch exhausts the budget without a final answer, it returns the best partial chain with status="incomplete"; the caller can retry, increase the budget, or escalate instead of presenting partial reasoning as an answer. model.generate_step and prm.score_step remain conceptual interfaces here.

3-tree-search-with-process-reward-models.py
1def is_final_answer(step: str) -> bool: 2 return step.lstrip().lower().startswith("final:") 3 4def beam_search_with_prm( 5 model, 6 prm, 7 prompt: str, 8 beam_width: int = 4, 9 branch_factor: int = 4, 10 max_steps: int = 20 11): 12 """Guided tree search using per-step reward scores. 13 14 Cost: O(beam_width × branch_factor × max_steps) forward passes. 15 Best for: Multi-step mathematical or logical reasoning. 16 """ 17 if min(beam_width, branch_factor, max_steps) < 1: 18 raise ValueError("beam_width, branch_factor, and max_steps must be positive") 19 20 active = [{"steps": [], "score": 0.0, "text": prompt}] 21 completed = [] 22 23 for _ in range(max_steps): 24 candidates = [] 25 for beam in active: 26 # Generate next reasoning step 27 new_steps = [ 28 model.generate_step(beam["text"]) 29 for _ in range(branch_factor) 30 ] 31 32 for new_step in new_steps: 33 # Score each step with the process reward model 34 step_score = prm.score_step( 35 prompt, beam["steps"], new_step 36 ) 37 candidate = { 38 "steps": beam["steps"] + [new_step], 39 "score": beam["score"] + step_score, 40 "text": beam["text"] + "\n" + new_step, 41 } 42 if is_final_answer(new_step): 43 completed.append(candidate) 44 else: 45 candidates.append(candidate) 46 47 # Only unfinished branches remain eligible for expansion. 48 active = sorted( 49 candidates, 50 key=lambda candidate: candidate["score"], 51 reverse=True, 52 )[:beam_width] 53 54 if not active: 55 break 56 57 if completed: 58 best = max(completed, key=lambda candidate: candidate["score"]) 59 return {**best, "status": "completed"} 60 61 best = max(active, key=lambda candidate: candidate["score"]) 62 return {**best, "status": "incomplete"}

The tagged fallback is part of the API contract, not a cosmetic field. A high process score means a partial trace looked promising; it doesn't turn that trace into a final answer. The sketch sums step scores to keep the mechanics visible. A deployed scorer also needs a cross-length rule such as a calibrated mean, minimum-step score, or length penalty, or a longer chain can win merely because it collected more terms.

Beam search also tends to collapse onto near-duplicate paths. More capable systems inject diversity, backtrack, or use Monte Carlo Tree Search-style expansion. The tree is easier to write than a verifier that reliably knows which partial step deserves more budget.

The deterministic fixture below exercises both boundaries. In the first run, an unfinished branch reaches a higher score than either final branch, but the selector still returns the best completed answer. In the second run, no branch finishes, so the result is visibly incomplete.

beam-completion-contract.py
1from collections import defaultdict 2 3class ScriptedModel: 4 def __init__(self, choices): 5 self.choices = choices 6 self.calls = defaultdict(int) 7 8 def generate_step(self, text): 9 index = self.calls[text] 10 self.calls[text] += 1 11 return self.choices[text][index] 12 13class ScriptedPRM: 14 def __init__(self, scores): 15 self.scores = scores 16 17 def score_step(self, prompt, previous_steps, new_step): 18 return self.scores[new_step] 19 20model = ScriptedModel({ 21 "capacity_math": ["keep checking", "Final: early guess"], 22 "capacity_math\nkeep checking": ["continue unchecked", "Final: verified"], 23 "capacity_math\nkeep checking\ncontinue unchecked": [ 24 "still unfinished A", 25 "still unfinished B", 26 ], 27}) 28prm = ScriptedPRM({ 29 "keep checking": 0.9, 30 "Final: early guess": 0.7, 31 "continue unchecked": 0.9, 32 "Final: verified": 0.8, 33 "still unfinished A": 0.9, 34 "still unfinished B": 0.8, 35}) 36 37selected = beam_search_with_prm( 38 model, 39 prm, 40 "capacity_math", 41 beam_width=1, 42 branch_factor=2, 43 max_steps=3, 44) 45print(f"selected={selected['steps'][-1]} status={selected['status']}") 46 47unfinished = beam_search_with_prm( 48 ScriptedModel({ 49 "capacity_math": ["keep checking"], 50 "capacity_math\nkeep checking": ["still checking"], 51 }), 52 ScriptedPRM({"keep checking": 0.9, "still checking": 0.8}), 53 "capacity_math", 54 beam_width=1, 55 branch_factor=1, 56 max_steps=2, 57) 58print(f"selected={unfinished['steps'][-1]} status={unfinished['status']}")
Output
1selected=Final: verified status=completed 2selected=still checking status=incomplete

Why can't the controller return the highest-scoring unfinished beam after the search budget expires?

Answer

A process score ranks partial progress; it doesn't certify that a branch produced an answer. The controller must choose from completed chains, or tag the best partial chain as incomplete so the caller can retry or escalate.

Why is verifier quality the bottleneck in search-based reasoning?

Answer

Search only helps if bad branches are pruned and good branches survive. A weak verifier can reward fluent wrong steps, discard correct paths, or collapse the search into near-duplicate traces.

Process reward models vs. outcome reward models

The reward model determines when search gets evidence. If a branch fails only at its final answer, all earlier work is sunk. If partial steps predict failure reliably, the controller can spend the next token on a different branch.

Outcome reward model versus process reward model: ORM scores only the final answer after a full rollout, while a reliable PRM scores intermediate steps and prunes a low-scoring branch early.
ORMs grade completed answers. A sufficiently reliable PRM can score intermediate steps and prune low-scoring branches before they burn a full rollout.

Final scoring and step scoring answer different questions. An ORM asks whether the completed answer works: “the GPU count matches” or “it doesn't.” No intermediate failure location reaches the search controller. A PRM asks about intermediate decisions: “KV formula used,” “branch count held at eight,” “prefix sharing applied.” That denser feedback costs more to build and can discard a good path when wrong. Reliable step scores can still save work by redirecting search early.

Outcome reward models (ORMs)

Outcome Reward Models (ORMs) evaluate a completed trajectory rather than its intermediate steps. The outcome signal may be binary correctness, a probability or scalar score, or a preference-derived comparison. Exact-answer math makes binary grading convenient, but that isn't part of the ORM definition.

Their supervision boundary is relatively simple: labels attach to completed outputs rather than every reasoning step. Verifiable tasks can supply labels automatically; subjective tasks may need learned or human preference signals. During search, though, the ORM has to wait. A generator can make a fatal error in step 1 and produce 100 more steps before the final score rejects the trajectory, so no early branch pruning is available.

How PRMs work

Process Reward Models (PRMs) evaluate the validity of each intermediate step in a chain of thought. A PRM scores a step conditioned on the problem and preceding steps, which gives search a chance to abandon a path when it first becomes weak. That can improve efficiency only when the intermediate score predicts final correctness.

PRMs also need step-level supervision. Lightman et al. trained their strongest PRM with human step labels, while methods such as Math-Shepherd derive process targets from rollout outcomes.[17]Reference 17Let's Verify Step by Step.https://arxiv.org/abs/2305.20050[18]Reference 18Math-Shepherd: Verify and Reinforce LLMs Step-by-step without Human Annotationshttps://arxiv.org/abs/2312.08935 A process score is earlier evidence for keeping or abandoning a branch, not proof that a kept step is correct.

This side-by-side pseudocode shows when each model can act. The labels are qualitative so they don't imply calibrated probabilities from an unevaluated scorer:

how-prms-work.py
1# ORM: can only evaluate after the full solution is generated. 2orm_decision = orm.evaluate( 3 question="What is 847 × 293?", 4 full_solution="847 × 293 = 248,271", 5) # "fail", but only after the complete rollout 6 7# PRM: evaluates each step given the question and preceding steps. 8# This lets the search algorithm prune bad paths before they grow. 9step_decisions = prm.evaluate_steps( 10 question="What is 847 × 293?", 11 steps=[ 12 "Break this into 847 × 300 - 847 × 7", # pass 13 "847 × 300 = 254,100", # pass 14 "254,100 - 5,929 = 248,271", # low 15 ], 16) # ["pass", "pass", "low"] -> prune branch

Snell et al. reported that compute-optimal test-time scaling can use up to 4× less test-time compute than a best-of-N baseline in their math-reasoning evaluation, and that a smaller model plus test-time compute can outperform a model about 14× larger answering once on problems where the small model already has a non-trivial hit rate.[2]Reference 2Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.https://arxiv.org/abs/2408.03314 Lightman et al. reported that process supervision outperformed outcome supervision on MATH.[17]Reference 17Let's Verify Step by Step.https://arxiv.org/abs/2305.20050 These results motivate testing PRM-guided pruning on verifiable workloads. They don't establish that every PRM or task benefits.

Not every reasoning system uses a learned PRM or ORM. DeepSeek-R1-Zero trained with rule-based accuracy and format rewards rather than a neural reward model, which is one reason you should treat test-time compute as a family of techniques, not a single stack.[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948

What is the practical difference between an ORM and a PRM during search?

Answer

An ORM scores only the final answer, so it can't prune based on intermediate evidence. A PRM scores intermediate steps, so a search policy can prune low-scoring branches early when the process scores are reliable.

The next cell counts generated steps when three of four branches are pruned early. That's the upside case. A deployment eval also has to count false pruning of branches that would have ended correct.

prm-pruning-budget.py
1branch_lengths = [8, 8, 8, 8] 2prune_at_step = [None, 2, 3, 1] 3 4orm_scored_steps = sum(branch_lengths) 5prm_scored_steps = sum( 6 full_length if stop is None else stop 7 for full_length, stop in zip(branch_lengths, prune_at_step) 8) 9print(f"orm_steps={orm_scored_steps} prm_steps={prm_scored_steps}") 10print(f"saved_steps={orm_scored_steps - prm_scored_steps}")
Output
1orm_steps=32 prm_steps=14 2saved_steps=18

DeepSeek-R1-Zero and DeepSeek-R1

DeepSeek's contribution separates into two experiments. DeepSeek-R1-Zero tested whether large-scale RL with verifiable rewards could induce strong reasoning without supervised cold start data.[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948 DeepSeek-R1 kept the reasoning RL idea, then added data and post-training to make the behavior more stable and readable.[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948

Training pipeline

The final DeepSeek-R1 pipeline therefore isn't “pure RL” end to end. The paper describes two supervised fine-tuning (SFT) stages around two RL stages. Each stage answers a concrete product problem: seed readable traces, reinforce checkable reasoning, filter useful rollouts, then broaden behavior.

  1. Base model: Start with DeepSeek-V3-Base, a 671B Mixture-of-Experts (MoE) model with 37B active parameters per token.[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948
  2. Cold-start Supervised Fine-Tuning (SFT): Collect thousands of long CoT examples and fine-tune the base model. The seed traces address the readability and language-mixing issues reported for R1-Zero.
  3. Reasoning-oriented RL: Run GRPO (Group Relative Policy Optimization)-based RL on reasoning tasks with verifiable, rule-based rewards, keeping the feedback tied to checkable outcomes.[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948
  4. Rejection sampling + second SFT: Use the RL checkpoint to generate high-quality reasoning traces, mix them with supervised data from DeepSeek-V3 for non-reasoning domains, and retrain the base model. This recovers broader language behavior around the specialized reasoning policy.
  5. Final RL for all scenarios: Run another RL stage across a broader prompt mix to produce DeepSeek-R1, rather than stopping with a math-only specialist.
Diagram showing V3-Base, Cold-start SFT, Reasoning RL, and Reject + SFT.
V3-Base, Cold-start SFT, Reasoning RL, and Reject + SFT.

The sequence matters when you diagnose a result. “Pure RL” describes R1-Zero, not R1. R1's readability and breadth came from the supervised stages around its RL stages.[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948

Why is "DeepSeek-R1 was pure RL" an inaccurate summary?

Answer

DeepSeek-R1-Zero was trained with large-scale RL without a supervised cold start. DeepSeek-R1 added cold-start SFT, reasoning RL, rejection sampling plus another SFT stage, and final broad RL.

Emergent reasoning

R1-Zero displayed self-verification, backtracking, and longer rollouts, while the paper also reports readability issues and occasional language mixing.[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948 Both observations belong in the same diagnosis: verifiable rewards can induce useful reasoning, but raw RL rollouts still need cleanup before they serve as a general-purpose product.

What did R1-Zero prove, and what did it not solve by itself?

Answer

It showed that verifiable rewards can induce reasoning behaviors like self-verification and backtracking. It didn't by itself solve readability, language mixing, or broad product polish.

Compute-optimal inference: when to think harder

More thinking changes different workloads in different ways. Ghosal et al. found an inverted-U pattern across reasoning models: accuracy rose with some extra thinking, then fell as traces grew.[5]Reference 5Does Thinking More Always Help? Mirage of Test-Time Scaling in Reasoning Modelshttps://arxiv.org/abs/2506.04210 Their analysis attributes part of the early gain to higher output variance, not only better reasoning, and recommends parallel sampling over extending one trace indefinitely.

An Anthropic study found a related inverse-scaling effect on several tasks, where longer reasoning amplified distractions and errors.[19]Reference 19Inverse Scaling in Test-Time Computehttps://alignment.anthropic.com/2025/inverse-scaling/ Budget is therefore an evaluated operating point, not a slider to max out.

Use task shape to choose a starting experiment, then check quality and latency on your workload:

Problem TypeCandidate strategy to evaluateExample
Factual recallSingle pass"What is the CLI flag for dry-run deploys?"
Simple reasoningShort reasoning budget or brief scratchpad"Can this migration run after the schema lock is released?"
Multi-step mathLonger scratchpad or best-of-Ncapacity_math GPU-memory estimate
Complex codeDeliberation plus search or repair loopsMulti-file debugging and repair
Open-ended analysisSequential revisionIncident review or rollout-risk analysis

The cross-over point

A task family may have a measured compute budget where a smaller model plus a test-time policy beats a larger single-pass model:

Qsmall+policy(C∗)>Qlarge,singleQ_{\text{small+policy}}(C^*) > Q_{\text{large,single}}Qsmall+policy​(C∗)>Qlarge,single​

Here, QQQ is measured quality and C∗C^*C∗ is one evaluated inference budget. A crossover at C∗C^*C∗ isn't a promise that every larger budget keeps helping. Quality can plateau or fall, and the preferred path changes with task difficulty, latency limits, verifier quality, and request volume.

Snell et al. observed in FLOPs-matched evaluations that a smaller model with additional test-time compute can outperform a model roughly 14× larger answering in one pass, when the smaller model already has a non-trivial success rate.[2]Reference 2Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.https://arxiv.org/abs/2408.03314 Treat longer thinking as a candidate for that evaluated task family, not a general replacement for a larger model.

Compute allocation router: task signals for difficulty, stakes, and latency SLO feed a route decision that sends easy work to single-pass, uncertain verifiable work to best-of-N, and hard checkable work to guided search, then returns one selected answer.
A production router should decide whether `capacity_math` earns the expensive path. Difficulty, stakes, latency budget, and verifier availability matter as much as the model name.

What is the compute-optimal routing question for a reasoning workload?

Answer

Ask whether extra inference compute on a smaller or cheaper model beats a larger model answering once for this task family, latency budget, verifier quality, and target accuracy.

The router turns those measurements into a product decision. It can inspect task signals, stakes, and the remaining latency budget, then send easy work to one pass and uncertain, checkable work to a more expensive path. The values in the next cell are illustrative measurements, not a benchmark claim.

measured-routing-policy.py
1routes = [ 2 {"name": "single-pass", "quality": 0.78, "latency_ms": 240, "cost": 0.002}, 3 {"name": "bounded-reasoning", "quality": 0.86, "latency_ms": 780, "cost": 0.010}, 4 {"name": "guided-search", "quality": 0.90, "latency_ms": 2600, "cost": 0.045}, 5] 6latency_slo_ms = 1000 7minimum_quality = 0.84 8 9eligible = [ 10 route for route in routes 11 if route["latency_ms"] <= latency_slo_ms and route["quality"] >= minimum_quality 12] 13chosen = min(eligible, key=lambda route: route["cost"]) 14print(f"route={chosen['name']} quality={chosen['quality']:.0%}") 15print(f"latency_ms={chosen['latency_ms']} cost=${chosen['cost']:.3f}")
Output
1route=bounded-reasoning quality=86% 2latency_ms=780 cost=$0.010

That route avoids an intelligence tax: extra latency and cost for a reasoning path when a single-pass baseline already matches measured quality. Sentiment classification and ticket-ID extraction usually have little to gain. capacity_math earns the expensive path only if its measured gain survives the SLO.

Why should a production system route tasks before invoking an expensive reasoning path?

Answer

Reasoning paths add latency, output tokens, KV cache pressure, and cost. Routing reserves that budget for tasks where extra reasoning is likely to improve verifiable quality.

Diagram showing Request, Budget router, Hidden + visible decode, and TTFT and cost OK?.
Request, Budget router, Hidden + visible decode, and TTFT and cost OK?.

Production considerations

Once a request takes the expensive route, its hidden work becomes a serving problem. Longer traces and more branches raise cache residency, first-token delay, and cost even when the visible answer stays short. A quality gain that exhausts the queue is not a free gain.

KV cache pressure and prefix sharing

Reasoning workloads stress an inference engine differently from ordinary chat because they can generate many intermediate tokens before or between visible outputs. Start with the cache, not the final answer length.

For every generated token, the server appends a Key vector and a Value vector for every layer:

KV bytes per token=2×L×nkv×dh×b\text{KV bytes per token} = 2 \times L \times n_{kv} \times d_h \times bKV bytes per token=2×L×nkv​×dh​×b

Here LLL is the number of layers, nkvn_{kv}nkv​ the number of KV heads, dhd_hdh​ the head dimension, and bbb bytes per value. The scaling fact to carry forward is KV cache memory grows linearly with sequence length. A rollout that spends 10,000 tokens thinking creates roughly 10,000 tokens of KV state, which can collapse batch size before raw FLOPs become the bottleneck.

PagedAttention stores KV cache in fixed-size blocks to reduce fragmentation and make long-context scheduling practical.[20]Reference 20Efficient Memory Management for Large Language Model Serving with PagedAttention.https://arxiv.org/abs/2309.06180 Prefix-sharing runtimes reuse a cached prompt or partial trace when branches still share it, rather than duplicating that state. SGLang's RadixAttention is one example.[21]Reference 21SGLang: Efficient Execution of Structured Language Model Programshttps://arxiv.org/abs/2312.07104 Best-of-N, self-consistency, and tree search can benefit because candidates often diverge only near their leaves. The next cell measures that saving for capacity_math: eight branches, a 4,000-token prompt, and 1,000 continuation tokens per branch.

prefix-sharing-cache-accounting.py
1prompt_tokens = 4000 2continuation_tokens = 1000 3branches = 8 4kv_bytes_per_token = 128 * 1024 5 6without_sharing = branches * (prompt_tokens + continuation_tokens) 7with_sharing = prompt_tokens + branches * continuation_tokens 8saved_gib = (without_sharing - with_sharing) * kv_bytes_per_token / 1024 ** 3 9print(f"tokens_without_sharing={without_sharing:,}") 10print(f"tokens_with_sharing={with_sharing:,} saved_kv_gib={saved_gib:.2f}")
Output
1tokens_without_sharing=40,000 2tokens_with_sharing=12,000 saved_kv_gib=3.42

Why do reasoning workloads stress KV cache more than ordinary chat?

Answer

Non-visible-token modes and branching search can generate many extra tokens before or between visible outputs. In transformer serving paths that materialize those tokens, each one appends K/V state across layers, reducing batch size and concurrency unless the runtime pages, shares, or evicts cache efficiently.

TTFT vs. inter-token latency

Test-time compute changes which latency the user feels first. A provider or wrapper that generates non-visible reasoning before revealing an answer can push TTFT (time to first token) up substantially.[6]Reference 6Reasoning modelshttps://developers.openai.com/api/docs/guides/reasoning An interleaved mode can pause between visible chunks or tool calls. ITL (inter-token latency) may still look healthy once answer text streams, while the request already feels slow.

Hidden reasoning is still decode load for the fleet. Under continuous batching it occupies KV residency and memory bandwidth, raises other tenants' ITL, and reduces goodput (offered request rate under joint TTFT and decode SLOs). A reasoning router therefore controls capacity as well as quality: a long rollout must leave headroom for co-tenant latency and for its own TTFT budget.

Why can a reasoning model feel slow even if decode tokens per second are healthy?

Answer

In a mode that generates non-visible reasoning first, those tokens raise TTFT. In an interleaved mode, additional thinking can also create pauses between visible chunks or tool calls. ITL during answer streaming can still look normal.

The next cell converts a thinking-token budget into a simple TTFT estimate at 80 decode tokens per second. It rejects budgets that miss a 3000 ms first-token SLO. Treat the arithmetic as a capacity screen, not a provider benchmark.

ttft-budget-slo.py
1base_ttft_ms = 180 2decode_tokens_per_second = 80 3budgets = [0, 128, 512, 1024] 4ttft_slo_ms = 3000 5 6for budget in budgets: 7 ttft_ms = base_ttft_ms + budget / decode_tokens_per_second * 1000 8 status = "fits" if ttft_ms <= ttft_slo_ms else "reject" 9 print(f"budget={budget:>4} ttft_ms={ttft_ms:>7.0f} {status}")
Output
1budget= 0 ttft_ms= 180 fits 2budget= 128 ttft_ms= 1780 fits 3budget= 512 ttft_ms= 6580 reject 4budget=1024 ttft_ms= 12980 reject

Latency vs. quality trade-off

Reasoning models add latency, but the exact numbers depend on hardware, batching policy, and provider implementation:

StrategyUser-visible behaviorBest fit
Single-pass generationLow TTFT, short answersChat, extraction, classification
Reasoning or search-heavy generationHigher TTFT, variable token budget, sometimes hidden intermediate workMath, code, planning, verification

For strict interactive latency budgets, a long reasoning path needs measured gains to justify its delay. Larger budgets fit better in:

  • Batch processing (code review, data analysis)
  • High-stakes analyst workflows (incident review, safety analysis, compliance analysis)
  • Asynchronous workflows (software engineering, research)

Cost implications

Extended reasoning is expensive even when the final answer is short. Hosted APIs may charge directly for hidden reasoning tokens. OpenAI's reasoning docs, for example, count them as output tokens even though the API doesn't return them verbatim.[6]Reference 6Reasoning modelshttps://developers.openai.com/api/docs/guides/reasoning Open-weight deployments pay through wall-clock time, lower throughput, and higher KV residency. Either path reduces how many concurrent requests the same GPU can serve.

Three controls keep that bill tied to evidence:

  1. Routing: send only hard or high-stakes tasks to expensive reasoning paths
  2. Token budgets: cap how long a rollout may think before the marginal gain stops being worth it
  3. Early stopping: terminate search when verifier scores stop improving

Without them, an ambiguous or unsolvable prompt can burn inference budget without producing a better answer.

What three controls keep reasoning costs bounded in production?

Answer

Route only hard or high-stakes tasks to reasoning paths, cap reasoning tokens or branches, and stop early when verifier scores or expected gains plateau.

Distillation: making reasoning affordable

Distillation moves work from serving to training. A larger reasoner writes detailed capacity_math traces; a smaller student trains on them and can solve similar sizing problems with less live compute. The student may inherit a solution style without inheriting the teacher's full search behavior.

DeepSeek-R1 showed that reasoning capabilities can be distilled into much smaller models:

Distilled ModelSourceAIME 2024 (pass@1: accuracy on first attempt)
DeepSeek-R1-Distill-Qwen-1.5BR1 → Qwen2.5-Math-1.5B28.9%
DeepSeek-R1-Distill-Qwen-7BR1 → Qwen2.5-Math-7B55.5%
DeepSeek-R1-Distill-Qwen-32BR1 → Qwen2.5-32B72.6%
DeepSeek-R1 (full)-79.8%

In DeepSeek's reported AIME evaluation, the 7B and 32B distilled models retain substantial benchmark accuracy at lower parameter counts than R1. Parameter count is only a proxy: deployment cost also depends on active parameters, quantization, batch size, and engine choice. Distillation can lower reasoning cost, but routing and token budgets still decide the serving bill.

What can reasoning distillation transfer, and what can it fail to transfer?

Answer

It can transfer solution traces, formats, and many task patterns from a stronger teacher. It may not transfer the teacher's full search policy, verifier behavior, or reliability on unfamiliar tasks.

Trace cloning has a scaling ceiling. Setlur et al. compare verifier-free methods that distill or clone successful traces with verifier-based methods using rewards, RL, or search.[22]Reference 22Scaling Test-Time Compute Without Verification or RL is Suboptimalhttps://arxiv.org/abs/2502.12118 Under their assumptions and evaluated reasoning tasks, verifier-free methods become increasingly suboptimal as rollout length and test-time budget grow: the student sees successful traces, but not which alternative traces a verifier would reward.

That result doesn't make distillation useless. The DeepSeek numbers show that a smaller student can gain substantial capability. It sets a boundary: more teacher traces won't reproduce verifier-guided improvement indefinitely. Filter traces with reliable checks, retain a verifier during evaluation, or use verifier-guided RL when the workload supplies trustworthy rewards.

Why doesn't cloning more reasoning traces guarantee the same scaling as verifier-guided RL or search?

Answer

Cloning teaches the student to imitate observed successful traces. It doesn't directly teach a reward over alternative traces, so the gap can widen as rollout length and search budget grow. Distillation remains useful, but its ceiling should be measured with a verifier-backed evaluation.

The next cell turns that boundary into a tiny serving gate. Send extra reasoning only when the request is verifiable and its predicted quality gain clears a threshold. capacity_math passes; extraction and unverifiable copy stay single-pass.

serving-budget-gate.py
1requests = [ 2 {"kind": "extract", "verifiable": True, "predicted_gain": 0.00}, 3 {"kind": "capacity_math", "verifiable": True, "predicted_gain": 0.09}, 4 {"kind": "creative_copy", "verifiable": False, "predicted_gain": 0.03}, 5] 6minimum_gain = 0.05 7 8for request in requests: 9 use_reasoning = request["verifiable"] and request["predicted_gain"] >= minimum_gain 10 route = "reasoning" if use_reasoning else "single-pass" 11 print(f"{request['kind']}: {route}")
Output
1extract: single-pass 2capacity_math: reasoning 3creative_copy: single-pass

What to remember and where to go next

  1. Inference is a second scaling axis: on hard reasoning tasks, spending more compute at request time can beat a larger model answering once.[2]Reference 2Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.https://arxiv.org/abs/2408.03314

  2. The axis has several policies: a longer scratchpad, repeated samples, revision, and explicit search all spend compute before commitment.

  3. Evidence sets the ceiling: Snell et al. report up to 4× less test-time compute than a best-of-N baseline in their evaluation, while a reliable PRM can prune a weak path before its final answer.[2]Reference 2Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.https://arxiv.org/abs/2408.03314[17]Reference 17Let's Verify Step by Step.https://arxiv.org/abs/2305.20050

  4. Training history changes the behavior: R1-Zero used pure RL with verifiable rewards; DeepSeek-R1 added cold-start data, another SFT stage, and broader RL to make the behavior more readable and usable.[4]Reference 4DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learninghttps://arxiv.org/abs/2501.12948

  5. Budget is a measured dial: provider controls vary by model and endpoint, and accuracy can follow an inverted-U as a trace grows. Tune the supported control against quality, latency, and cost.[6]Reference 6Reasoning modelshttps://developers.openai.com/api/docs/guides/reasoning[8]Reference 8Gemini thinkinghttps://ai.google.dev/gemini-api/docs/thinking[9]Reference 9Building with extended thinkinghttps://docs.claude.com/en/docs/build-with-claude/extended-thinking[5]Reference 5Does Thinking More Always Help? Mirage of Test-Time Scaling in Reasoning Modelshttps://arxiv.org/abs/2506.04210

  6. Serving decides whether gains ship: long traces grow KV state linearly, so prefix sharing, routing, and token budgets belong in the design.[20]Reference 20Efficient Memory Management for Large Language Model Serving with PagedAttention.https://arxiv.org/abs/2309.06180[21]Reference 21SGLang: Efficient Execution of Structured Language Model Programshttps://arxiv.org/abs/2312.07104

Return to the opening checks: count the r's instead of trusting a quick association; ask whether traces, search, or distillation recover measured math quality; then route capacity_math only when its evidence justifies another GPU millisecond.

Complete the lesson

Mastery Check

Answer every question, then check your score. Score 75% or higher to mark this lesson complete.

1.A team routes sentiment classification and ticket-ID extraction to a reasoning model. Evaluation shows the same accuracy as a single-pass baseline, but median latency rises from 400 ms to 8 s and cost quadruples. Which diagnosis fits?

Correct answer: The team is paying an intelligence tax: extra reasoning cost on tasks with no measured multi-step benefit.

The intelligence tax is the extra latency and cost from using reasoning on tasks that don't need it. Sentiment classification and simple extraction usually have strong single-pass baselines, so the reasoning route should be justified by measured gains, not by the model seeming more capable.

2.A deployed model is unchanged. Easy CLI-flag lookups get one pass. For capacity_math it samples several KV estimates, checks the formula and the latency SLO, then returns a selected answer. Which scaling view explains this setup?

Correct answer: It's test-time compute scaling because extra inference work is allocated during generation based on request difficulty.

Train-time scaling spends compute before deployment by changing model size, data, or pretraining FLOPs. Here the weights are fixed, and the system spends extra per-request inference compute through sampling and verification only when capacity_math is hard enough to justify it.

3.A team uses cross-entropy SFT to clone one accepted reasoning trace per problem, then expects pass@N to keep improving as it samples longer student rollouts. Which risk should it test?

Correct answer: CE can over-concentrate probability and reduce pass@N diversity, while trace cloning may not inherit the verifier-guided reward or search policy needed for longer-rollout scaling.

Pass@1 and pass@N are different objectives. CE can improve likelihood on demonstrated traces while making independent samples less diverse, and verifier-free cloning teaches imitation rather than a reward over alternative traces. The team should measure candidate coverage at its deployed N and compare against a verifier-guided training or search baseline.

4.An engineer says, "DeepSeek-R1 was trained purely with RL from start to finish, just like DeepSeek-R1-Zero." Which correction accurately distinguishes DeepSeek-R1-Zero from DeepSeek-R1?

Correct answer: R1-Zero used RL without cold-start SFT; R1 added cold-start SFT, rejection-sampling SFT, and additional RL.

Only R1-Zero fits the pure-RL shorthand. DeepSeek-R1 added supervised cold-start data, a reasoning RL stage, rejection sampling followed by another SFT stage, and final broader RL to improve usability and stability.

5.A reasoning budget evaluation gives accuracies and latencies: 0 tokens: 71%, 220 ms; 128 tokens: 78%, 310 ms; 512 tokens: 83%, 610 ms; 2048 tokens: 80%, 1840 ms. The latency limit is 1000 ms. Which budget should be selected if the objective is highest measured accuracy within the limit?

Correct answer: 512 tokens.

Only 0, 128, and 512 tokens satisfy the 1000 ms latency limit. Among those eligible budgets, 512 tokens has the highest measured accuracy at 83%. The 2048-token budget is both over the latency limit and less accurate, showing why the maximum thinking budget is not automatically optimal.

6.A hosted reasoning API reports 180 visible output tokens and 1,220 non-visible reasoning tokens. Its docs bill both as output tokens, and transformer serving materializes the hidden tokens autoregressively. At $10 per million output tokens, what should a dashboard count for output cost and why?

Correct answer: 1,400 billed output tokens costing $0.0140, and the hidden tokens can also add decode work and temporary KV state.

The dashboard should add visible and reasoning tokens: 180 + 1,220 = 1,400 billed output tokens. At 10permillionoutputtokens,thatcosts1,400/1,000,000x10 per million output tokens, that costs 1,400 / 1,000,000 x 10permillionoutputtokens,thatcosts1,400/1,000,000x10 = $0.0140. If the runtime materializes those hidden tokens, they also consume decode work and temporary KV cache state even though users never see them.

7.Four reasoning branches would each take 8 steps to complete. An outcome reward model can score only completed branches. A reliable process reward model prunes three bad branches at steps 2, 3, and 1 while one branch runs all 8 steps. How many generated steps are avoided compared with the outcome-only approach?

Correct answer: 18 steps.

The outcome-only approach must generate all four full branches, so it uses 4 x 8 = 32 steps. With reliable process pruning, the system generates 8 + 2 + 3 + 1 = 14 steps. The avoided work is 32 - 14 = 18 steps. This saving depends on the PRM pruning the right branches; false pruning can discard a correct path.

8.A model has a 25% chance to generate a correct answer per attempt. With N=4 independent attempts, an oracle would have a 68.4% chance to include a correct answer. In deployment, the selector finds a correct candidate only 80% of the time when one exists. What success rate should be used for the selected answer?

Correct answer: 54.7%, because generating a correct candidate and selecting it are separate failure surfaces.

The oracle chance of including a correct answer is 68.4%, but the deployed system also has to select that candidate. Multiplying by 80% selector recall gives 0.684 x 0.80 = 0.547, or 54.7%. Best-of-N only pays off when sampling adds useful candidates and the selector can identify them reliably.

9.A PRM beam search reaches its step budget with a completed chain scored at 1.7 and an unfinished chain scored at 2.7. Which return policy preserves the answer contract?

Correct answer: Return the best completed chain; if none completed, label the best partial chain incomplete for retry or escalation.

A process score ranks partial reasoning but doesn't certify a final answer. Completed and active pools must stay separate. When no chain completes, a tagged incomplete result prevents downstream code from presenting promising partial work as a verified answer.

10.Eight search branches share a 4,000-token prompt and then each generate a 1,000-token continuation. Without prefix sharing, KV storage is counted for 8 x (4,000 + 1,000) tokens. With prefix sharing, it is counted for 4,000 + 8 x 1,000 tokens. What does prefix sharing avoid?

Correct answer: 28,000 duplicate prompt-token KV entries, about 3.42 GiB if each token's KV state is 128 KiB.

Without sharing, the branches count 40,000 KV-token entries. With sharing, they count 12,000: one shared 4,000-token prompt plus eight 1,000-token continuations. The avoided duplicate prompt work is 28,000 entries, and 28,000 x 128 KiB is about 3.42 GiB.

10 questions remaining.

Next Step
Continue to Advanced MLOps & DevOps for AI

You can now treat thinking budgets, routers, and verifiers as production controls, not just decoding tricks. The next chapter versions those controls: GitOps for prompts and model aliases, feature stores, shadow traffic, canaries, lineage, and automated rollback when an effort knob or judge change regresses quality.

PreviousMamba & State Space Models
Share this article
XFacebookLinkedInBlueskyRedditHacker NewsEmail
References

Scaling Laws for Neural Language Models

Kaplan et al. · 2020

https://arxiv.org/abs/2001.08361

Scaling LLM Test-Time Compute Optimally Can Be More Effective Than Scaling Model Parameters.

Snell, C., et al. · 2024 · arXiv preprint

https://arxiv.org/abs/2408.03314

Learning to reason with LLMs

OpenAI · 2024

https://openai.com/index/learning-to-reason-with-llms/

DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning

DeepSeek-AI · 2025

https://arxiv.org/abs/2501.12948

Does Thinking More Always Help? Mirage of Test-Time Scaling in Reasoning Models

Ghosal, S. S., Chakraborty, S., Reddy, S., et al. · 2025

https://arxiv.org/abs/2506.04210

Reasoning models

OpenAI · 2026

https://developers.openai.com/api/docs/guides/reasoning

Chain-of-Thought Prompting Elicits Reasoning in Large Language Models.

Wei, J., et al. · 2022 · NeurIPS

https://arxiv.org/abs/2201.11903

Gemini thinking

Google · 2025

https://ai.google.dev/gemini-api/docs/thinking

Building with extended thinking

Anthropic · 2025

https://docs.claude.com/en/docs/build-with-claude/extended-thinking

GLM-5.2 Model Card

Z.AI · 2026

https://huggingface.co/zai-org/GLM-5.2

GLM-5 Repository

Z.AI · 2026

https://github.com/zai-org/GLM-5

GLM-5.2 Model Documentation

Z.AI · 2026

https://docs.z.ai/guides/llm/glm-5.2

DeepSeek-V4-Flash-0731 Model Card

DeepSeek-AI · 2026

https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash-0731

Use DeepSeek with Codex

DeepSeek · 2026

https://api-docs.deepseek.com/quick_start/agent_integrations/codex/

DeepSeek-V4: Towards Highly Efficient Million-Token Context Intelligence

DeepSeek-AI · 2026

https://arxiv.org/abs/2606.19348

Rethinking Fine-Tuning when Scaling Test-Time Compute: Limiting Confidence Improves Mathematical Reasoning

Chen, F., Raventos, A., Cheng, N., Ganguli, S., & Druckmann, S. · 2025 · NeurIPS 2025

https://proceedings.neurips.cc/paper_files/paper/2025/hash/e8f4eae0a41cab67fdead3aa6b77f083-Abstract-Conference.html

Let's Verify Step by Step.

Lightman, H., et al. · 2023 · ICLR

https://arxiv.org/abs/2305.20050

Math-Shepherd: Verify and Reinforce LLMs Step-by-step without Human Annotations

Wang, P., et al. · 2023

https://arxiv.org/abs/2312.08935

Inverse Scaling in Test-Time Compute

Anthropic · 2025

https://alignment.anthropic.com/2025/inverse-scaling/

Efficient Memory Management for Large Language Model Serving with PagedAttention.

Kwon, W., et al. · 2023 · SOSP 2023

https://arxiv.org/abs/2309.06180

SGLang: Efficient Execution of Structured Language Model Programs

Zheng, L., Yin, L., Xie, Z., et al. · 2023 · arXiv:2312.07104

https://arxiv.org/abs/2312.07104

Scaling Test-Time Compute Without Verification or RL is Suboptimal

Setlur, A., Rajaraman, N., Levine, S., & Kumar, A. · 2025

https://arxiv.org/abs/2502.12118

Discussion

Questions and insights from fellow learners.

Discussion loads when you reach this section.