AI disclosure: This article was prepared with generative AI assistance. Editorial responsibility: Florian Zimmermeister (flozi00). Legal notice and contact.
StepFun released Step-5-Preview's weights on October 15, 2026, following its September API release. The model card describes a text/vision MoE model with approximately 600B total and 27B active parameters. This article examines one specific mechanism: its global attention layers search compressed proxy keys, then attend to selected original keys and values. Compressing the search representation does not compress away the original KV history.1234
The audit uses the FP8 checkpoint and its bundled inference code at revision 364b3b03fed2477aa0953fe855a2c4c8c48ee3cc, checked on October 16, 2026. Tensor and memory calculations below are derived from that configuration and code, not measured throughput or peak VRAM. The KV-cache guide provides the baseline storage formula; Ling-3.1-flash illustrates a different mechanism, MLA weight absorption.
Read the layer types before counting memory
The 92-layer text backbone repeats three sliding-window layers followed by one sparse global layer: 69 local layers and 23 global layers. In the configuration, the latter retain the name full_attention; sparse_config.enabled and apply_to_layer_types make them sparse in execution. Disabling the sparse block would restore global dense attention, not a 512-token window.35
| Backbone property | Released value |
|---|---|
| Hidden width / vocabulary | 4,096 / 128,896 |
| Query heads / KV groups / head width | 64 / 4 / 192 |
| Query heads sharing each KV group | 16 |
| Local layers / window, including current token | 69 / 512 |
| Sparse global layers, zero-based | 3, 7, β¦, 91 |
| Configured input-plus-output context | 1,048,576 |
| Local RoPE span / theta | 192 / 10,000 |
| Global RoPE span / theta | 64 / 10,000,000 |
| Indexer Q heads / shared K head / proxy width | 16 / 1 / 256 |
| Provider groups / indexer Q heads per group | 4 / 4 |
| Historical block size / selected block budget | 8 / 512 |
The RoPE spans follow head_dim Γ partial_rotary_factors. The indexer has its own 32-dimensional rotary span. The misleadingly named yarn_only_types field does not establish YaRN here: the saved rope_scaling type is llama3, with factor 1.0. Read the actual scaling object and implementation, not the field name.35
There are also three MTP layers outside the backbone, all sliding-attention layers. Consequently, the saved layer-type arrays contain 95 entries, not 92. The backbone has 88 MoE FFNs at indices 3β90, with eight of 352 routed experts per token and an additional shared expert. Attention selection and expert selection are separate operations; an expert budget does not describe KV storage.35
Two paths leave the same hidden state
Let denote the packed tokens processed in this forward call, not the reserved context capacity. Ignoring tensor parallelism initially, hidden states have shape . The main path projects and . It normalizes Q/K and applies the layer-specific partial RoPE.5
The indexer independently produces the tensors below. Its proxy keys are not the main attention's 192-wide keys. Four provider groups use the same compressed proxy-key store but compute different scores and selections; group controls the 16 main query heads that share KV group .54
| Indexer tensor | Unsharded shape | Role |
|---|---|---|
| Four search heads per provider group | ||
| Shared normalized, position-rotated proxy key | ||
| Learned coordinate-wise compression logits | ||
| Signed search-head weights, scaled by | ||
| Capacity for block summaries of a length- request |
Indexer queries use RMSNorm, keys use LayerNorm, and the 32-dimensional rotary transform applies to both. The compression logits remain a separate projection. No vocabulary lookup, Engram table or external retrieval index participates in this operation: these summaries are generated from this request's hidden states and belong to its per-layer cache.54
Eight tokens become one search key, coordinate by coordinate
For completed block containing eight tokens, the kernel computes the following summary for each proxy coordinate . A stable implementation subtracts a common maximum from the logits before exponentiation.4
This is not ordinary mean pooling, and not one attention weight per whole key vector. Each coordinate has its own weights. Although every coordinate stays within the corresponding keys' coordinate-wise range, the complete summary need not lie in the convex hull of the eight complete vectors.
The pinned kernel accumulates the reduction in FP32 and rounds the result through BF16 into E4M3 for storage. During decode it buffers the incomplete block's proxy keys and logits, producing its summary only when the eighth token arrives. Original main-path K/V are written independently and retained.4
Selection is a weighted ReLU score, not attention softmax
For query position , provider group and historical block , the implemented score is below. Here denotes the code's E4M3 rounding followed by lossless widening to BF16 for the score matmul. The four weights are signed linear-projection outputs with the prescale already included.4
The ReLU is inside the sum; signed weights mean the final score can still be negative. There is no softmax over indexer scores in this path. Despite sparse_indexer_softmax_variant: "ssmax" in the saved configuration, the reference registers ssmax_s only for checkpoint compatibility and does not use it in scoring. Replacing this code with a softmax-based indexer would implement a different function.54
With zero-based token positions, only blocks compete for the top 512 historical slots. Equal scores are resolved by ascending logical block ID. The block containing is appended unconditionally, restricted to its causally visible positions. This is why β512 selected tokensβ is incorrect: the historical budget is 512 blocks = 4,096 tokens, plus up to eight current-block tokens.4
The causal restriction is essential during prefill: a completed block summary may include positions later than an earlier query. Such a block cannot enter that query's historical candidates; its current block instead uses only original K/V up to the query. An unrestricted top-k over every precomputed summary would leak future information.
Main attention still reads original K/V
For a main query head , let . Attention computes ordinary scaled dot products and a softmax over that group's selected original tokens, not over the summaries. The resulting head vector is sigmoid-gated before concatenation and output projection.54
Two distinct approximations should not be conflated. Summary compression and indexer rounding can change which blocks are chosen. Restricting the main softmax changes its denominator and output relative to dense attention. Exact softmax on the chosen set is not proof of equality to full attention, and βretains the original K/Vβ is not proof of unchanged model quality.
What gets cheaper, and what stays length-dependent?
At , the indexer searches about 131,072 block summaries, rather than a million individual proxy keys. The main path reads at most 4,104 original token positions per KV group for one query. The ratio describes a token-read-count comparison, not an end-to-end speedup: search, top-k, projections, experts, communication, batching and kernel utilization remain.
For fixed dimensions, decode index scoring remains and main attention uses selected positions. Scoring every prefill query still has an term. This is not linear attention or constant-memory recurrence. The technical blog discusses grouping adjacent queries' overlapping selections for utilization; that optimization should not be assumed to exist identically in every reference or serving kernel.46
Cache capacity: 4,104 reads do not mean 4,104 stored tokens
In the standalone implementation, every global layer reserves original K/V for the request capacity. At BF16, one token in one layer uses bytes for separate K and V. Local layers instead use 512-slot ring buffers. Let be the global capacity after rounding up to a 16-token page boundary. For one request, the unique, unreplicated backbone data payload is:54
| Component at , one request | Derived unique payload |
|---|---|
| Original global K/V, 23 layers | 69 GiB |
| Local K/V rings, 69 layers | 103.5 MiB |
| Shared index summaries, 23 layers | 736 MiB |
| Sum of these three components | 69.819824 GiB |
This is not a peak-VRAM estimate. It excludes weights, three MTP layers, incomplete-block buffers, page tables, lengths, RoPE tables, activations, score/selection workspaces, communication and allocator overhead. The reference also page-rounds global capacity to 16-token multiples. FP8 expert weights do not imply FP8 main K/V; the released SGLang recipes explicitly request BF16 KV.542
Nor is βunique payloadβ the sum across devices. In the pinned standalone TP=8 layout, each rank owns eight main query heads but caches one entire KV group. Each of the four global KV groups is therefore present on two ranks. All eight ranks also retain the shared summary store. The three components above consequently sum to GiB across ranks, before the excluded allocations. Do not apply this replication factor to a different engine or parallel layout without inspecting its cache implementation.54
A configured million-token window is not a validated million-token launch
The standalone score_regions allocates a FP32 matrix shaped , sized to live summaries rather than reserved capacity. At a one-million-token prefill, and . At TP=8, , so this one tensor alone requires 511.996094 GiB per rank. This allocation is not a GPU measurement; it follows directly from the shape. It rules out naively running that standalone prefill on the documented H200 setup.4
The reference rejects a second prefill chunk on an existing cache and supports subsequent one-token decode steps. Its internal sliding-prefill chunking only bounds that path's temporary mask; it does not remove the sparse indexer's full score matrix. The limitation belongs to this pinned standalone implementation, not to the architecture in every possible engine.5
The release supplies separate SGLang/vLLM serving images. The SGLang recipes use --chunked-prefill-size 16384, BF16 KV and architecture-specific attention backends. The card distinguishes B300's FA4/MegaMoE recipe from H200's FA3/Triton recipe. A command requesting a maximum length or concurrency is not evidence that every request can fill that length simultaneously.2
The standalone README reports FP8 text/image generation validation on 8 H200 GPUs, TP=EP=8. Its BF16 full-model forward validation used 16 H200 GPUs, batch one and a 943-token image prompt, with reported peak PyTorch allocation of 76.37 GiB/GPU, excluding NCCL/CUDA-context allocations. Long-context workloads and throughput were not validated there; the complete BF16 file-shard conversion-to-generation workflow was also not run end to end. Those conditions do not establish a million-token production capacity.7
For deployment, pin both checkpoint and serving-image digest, inspect the supported sparse attention path, then test actual prompt lengths, output budgets, concurrency, prefix reuse and quality. The card's image tags are mutable names, not immutable runtime revisions. We did not run the model or reproduce the vendor's hardware tests. The custom StepFun Model License 1.0 also needs a use-specific review; downloadable weights do not imply an unrestricted open-source license.28
The engineering takeaway is precise: compress the index, bound the reads, retain the selectable history. Step-5-Preview reduces the global attention working set without making its original global KV history constant-size. That distinction matters both when estimating memory and when choosing an implementation that can actually prefill the intended context.
Primary sources
Footnotes
-
StepFun model announcement, September 20, 2026; October 15 weight-release date. β©
-
Step-5-Preview model card and serving recipes, pinned revision. β© β©2 β©3 β©4
-
Released text/vision, sparse attention, RoPE and quantization configuration. β© β©2 β©3 β©4
-
Sparse kernels: compression, weighted-ReLU scoring, causal selection, DSALayerCache and score_regions. β© β©2 β©3 β©4 β©5 β©6 β©7 β©8 β©9 β©10 β©11 β©12 β©13 β©14
-
Standalone model: Step5Config, Step5Cache, Step5Attention and layer construction. β© β©2 β©3 β©4 β©5 β©6 β©7 β©8 β©9 β©10 β©11 β©12
-
StepFun, Inside Step 5 Preview, October 15, 2026, Sparse GQA section. β©
-
Standalone validation conditions, supported workflow and limitations. β©