LLM Inference

Input Representation

Token

  • Unit of information LLM works with
Input: It ain't worth it
Tokens: It| ain|'t| worth| it
  • English has ~600k words
  • A tokenizer’s vocabulary is the set of token IDs it can produce
    • Its size varies by model
  • Some LLMs have ~32k tokens
  • A token may represent a whole word, part of a word, punctuation, whitespace, or a sequence of bytes
  • Each LLM has special tokens
    • BOS: Beginning of Sequence
    • EOS: End of Sequence
      • Examples:
        • <|endoftext|> for GPT4
        • <end_of_turn> for Gemma
    • PAD: Padding Token
    • UNK: Unknown Token

Chat Templates and Roles

[
    {"role": "system", "content": "You are a helpful assistant focused on technical topics."},
    {"role": "user", "content": "Can you explain what a chat template is?"},
    {"role": "assistant", "content": "A chat template structures conversations between users and AI models..."},
    {"role": "user", "content": "How do I use it ?"},
]
  • Chat Template for SmolLM2
{% for message in messages %}
{% if loop.first and messages[0]['role'] != 'system' %}
<|im_start|>system
You are a helpful AI assistant named SmolLM, trained by Hugging Face
<|im_end|>
{% endif %}
<|im_start|>{{ message['role'] }}
{{ message['content'] }}<|im_end|>
{% endfor %}
  • Final Result
<|im_start|>system
You are a helpful assistant focused on technical topics.<|im_end|>
<|im_start|>user
Can you explain what a chat template is?<|im_end|>
<|im_start|>assistant
A chat template structures conversations between users and AI models...<|im_end|>
<|im_start|>user
How do I use it ?<|im_end|>
  • Example of Llama3.2 model
User: How are you?
AI: Hello, How is your day going so far?


-------- Converted using special tokens -------

<|begin_of_text|>

<|start_header_id|>user<|end_header_id|>
How are you?
<|eot_id|>

<|start_header_id|>assistant<|end_header_id|>
Hello, How is your day going so far?
<|eot_id|>

Inference Process

---
title: LLM Inference Process
---
flowchart TD
  A["Input Text"] --> B["Tokenizer"]
  B --> C["Input Token IDs"]

  subgraph LLM["Raw LLM (Learned Weights)"]
      direction TD
      D["Embedding Layer"]
      E["Transformer Blocks"]
      F["Final Normalization"]
      G["Output Projection"]
      H["Vocabulary Logits"]

      D --> E --> F --> G --> H
  end

  C --> D
  H --> I["Decoding<br/>(Greedy, Temperature, Top-p, etc.)<br/>Select Next Token ID"]

  I --> J{"Stop token or<br/>length limit?"}
  J -- No --> C
  J -- Yes --> K["Detokenizer"]
  K --> L["Generated Text"]

  classDef input fill:#e8f2ff,stroke:#3973ac,color:#142b45
  classDef model fill:#eaf7ed,stroke:#36834b,color:#173d22
  classDef inference fill:#fff1db,stroke:#bd7c21,color:#54340b

  class A,B,C,K,L input
  class D,E,F,G,H model
  class I,J inference
def generate(prompt_tokens, max_new_tokens):
    """Autoregressive LLM generation."""
 
    # Phase 1: Prefill
    next_token_logits, kv_cache = prefill(prompt_tokens)
 
    # Phase 2: Decode
    output_tokens = []
 
    for _ in range(max_new_tokens):
        token = select_token(next_token_logits)
 
        if token == EOS_TOKEN:
            break
 
        output_tokens.append(token)
 
        if len(output_tokens) >= max_new_tokens:
            break
 
        next_token_logits, kv_cache = decode_step(token, kv_cache)
 
    return output_tokens

Prefill Phase

  • This phase is compute-bound because it needs to process all input tokens at once.
  • Steps:
    • Processes all input (prompt) tokens in parallel through the LLM
    • Produces the initial logits used to select the first generated token
    • Builds the initial KV Cache for reuse during decoding

Decode Phase

  • This phase is where the actual text generation happens
  • Generates one token at a time in an autoregressive process
    • meaning output from one pass becomes input to the next one
  • This phase is memory-bandwidth-bound because the model needs to keep track of all previously generated tokens and their relationships
  • Steps (repeated until a stopping condition is met):
    • Token Selection: Selects the next token using the current logits and a decoding strategy (e.g., greedy, temperature, top-p)
    • Continuation Check: Stops if an EOS token or another stopping condition is reached; otherwise, continues
    • KV Cache Update: Stores the latest token’s keys and values for subsequent iterations
    • Logits Generation: Processes the latest token using the LLM and KV Cache to produce logits for the next token

Token Selection Strategies

  • Greedy decoding
    • Selects the highest-probability next token at each step
    • Generally same as 0 temperature sampling
    • OpenAI APIs do not expose a dedicated greedy-decoding strategy parameter
  • Beam search
    • Keeps several high-scoring candidate sequences at each step, then selects the best-scoring completed sequence
    • Not exposed as a standard beam-search option in OpenAI’s public text-generation APIs
  • Sampling
    • Selects the next token from a probability distribution, allowing varied outputs. Sampling controls include temperature, top-k, and top-p

Sampling Parameters

  • These parameters are used during inference that control how LLM selects its next token and when generation stops

Core Parameters

  • Temperature
    • Range: [0,1] or [0, 2] (OpenAI)
    • Increasing temperature increases randomness and more creative output
    • Use lower temperature for tasks like fact based QA
    • Use higher temperature for tasks like poem generation
  • Top P
    • Range: (0, 1]
    • aka Nucleus sampling
    • controls how deterministic the model is
    • Top P cuts off the sample pool as soon as the sum of the probabilities of the top words reaches the value P
      • higher Top P means more tokens considered
      • Set to 1 to consider all tokens
    • Increase Top P for diverse responses
    • Keep Top P low for factual responses
    • Either change Temperature or Top P but not both
  • Top K
    • Consider only top K number of candidates
    • k = 1 effectively selects the highest-probability token
    • Some APIs use 0 or -1 to disable the restriction
  • Max Tokens
    • Number of tokens the model generates
    • Limits output length and helps control generation cost

Penalties and Repetition Control

  • Frequency Penalty
    • Applies penalty on the next token proportional to how many times that token already appeared in the response and prompt
    • Higher frequency penalty reduces chance of model repeating the same word
  • Presence Penalty
    • Same as frequency penalty, but penalty is same for all repeated tokens
    • a token that appeared twice and the one that appears 10 times are penalized same
    • Increase Presence penalty for Diverse and creative outputs

Sequence Control

  • Stop Sequence
    • It is a string that stops the model from generating tokens
    • Example \n or User:
    • Whether the stop string appears in the returned output depends on the API

Inference Engine

  • Software runtime that executes an LLM and manages the inference lifecycle
  • Model Execution: Loads the model and runs its forward pass during prefill and decode to produce logits
  • Memory management:
    • Manages model weights, KV cache, and accelerator memory
    • May use techniques such as Quantization and PagedAttention to improve memory efficiency
  • Request scheduling: Schedules requests and supports batching to improve throughput
  • Decoding: Supports token selection strategies such as:
    • Greedy decoding
    • Temperature sampling
    • Top-p sampling
  • Performance optimization: Applies techniques to improve inference speed, throughput, and resource utilization, such as:
    • Kernel optimization and fusion for efficient execution
    • FlashAttention to reduce attention memory traffic
    • Continuous batching to improve throughput
    • Speculative decoding to potentially reduce generation latency
  • Output handling: Exposes generated token IDs, decoded text, or both, depending on its API

vLLM Inference API

LLM()

ConfigParamsComments
Modelmodel, revisionModel name and version
Tokenizertokenizer
tokenizer_revision
Tokenizer name and version of the model
tokenizer_modeauto (autoselect mistral and hf)
mistral, hf, deepseek_v41, kimi_k3
PrecisiondtypeData type for model weights and activations
Quantizationquantizationawq, gptq, fp8
KV Cachegpu_memory_utilizationThe ratio (between 0 and 1) of GPU memory to reserve for the model weights, activations, and KV cache
kv_cache_memory_bytesSize of KV Cache per GPU in bytes
Chat Formattingchat_templateDefault Chat format
ReproducibilityseedDefault Seed

LLM.chat()

ConfigParamsComment
MessagesmessagesSequence of Conversations
ToolstoolsTools to make available to the model
Chat Templatechat_templateThe template to use for structuring the chat.
Overrides default chat template
chat_template_content_formatstring, openai
chat_template_kwargsAdditional kwargs to pass to the chat template
Tokenization Optionstokenization_kwargsOverrides for tokenizer.encode
LORAlora_requestLoRA request to use for generation
Sampling ParamstemperatureControls the randomness of the sampling
top_kControls the number of top tokens to consider
top_pControls the cumulative probability of the top tokens to consider
max_tokens, min_tokensMax/Min tokens to generate per output sequence
stop, stop_token_idsString(s)/Token(s) that stop the generation when they are generated
presence_penalty
frequency_penalty
repetition_penalty
nNumber of outputs to return for the given prompt request
best_of
logprobsNumber of log probabilities to return per output token
seedRandom seed to use for the generation
structured_outputsParams for configuring structured outputs
thinking_token_budgetMax tokens allowed for thinking
watermarkingWhether to apply the engine’s configured watermark to this request
bad_wordsWords not allowed to be generated