Zum Inhalt springen
Kurzer Hinweis: flozi00 TechHub ist ein Solo-Nebenprojekt neben einem Vollzeitjob — persönliche Lernnotizen, keine offiziellen Aussagen. Kritische Schritte selbst prüfen.

Step-5-Preview: Sparse-Zugriffe sind kein komprimierter KV-Cache

Den Block-Indexer, gruppenspezifische Sparse GQA und originale K/V-Zugriffe von Step-5-Preview nachvollziehen und Cache-Bedarf sowie Prefill-Grenzen herleiten.

9 Min. Lesezeitflozi00
aillmarchitecturestepfunsparse-attentiongqakv-cacheinference

KI-Hinweis: Dieser Artikel wurde mit Unterstützung generativer KI erstellt. Redaktionell verantwortlich: Florian Zimmermeister (flozi00). Impressum und Kontakt.

StepFun veröffentlichte die Gewichte von Step-5-Preview am 15. Oktober 2026, nach der API-Veröffentlichung im September. Die Model Card beschreibt ein Text-/Vision-MoE-Modell mit ungefähr 600 Milliarden Gesamtparametern und 27 Milliarden aktiven Parametern. Dieser Artikel untersucht einen konkreten Mechanismus: Die globalen Attention-Layer durchsuchen komprimierte Proxy-Keys und berechnen anschließend Attention über ausgewählte originale Keys und Values. Die Kompression der Suchrepräsentation beseitigt nicht die originale KV-Historie.1234

Geprüft wurden der FP8-Checkpoint und sein mitgelieferter Inferenzcode in Revision 364b3b03fed2477aa0953fe855a2c4c8c48ee3cc, Stand 16. Oktober 2026. Die folgenden Tensor- und Speicherrechnungen sind aus Konfiguration und Code hergeleitet, keine Messungen von Durchsatz oder Spitzen-VRAM. Der KV-Cache-Guide erklärt die grundlegende Speicherformel; Ling-3.1-flash zeigt mit der MLA-Gewichtsabsorption einen anderen Mechanismus.

Vor der Speicherrechnung die Layer-Typen lesen

Der Text-Backbone mit 92 Layern wiederholt drei Sliding-Window-Layer und anschließend einen globalen Sparse-Layer: 69 lokale und 23 globale Layer. Letztere heißen in der Konfiguration weiterhin full_attention; sparse_config.enabled und apply_to_layer_types schalten ihre Sparse-Ausführung ein. Ohne den Sparse-Block würde daraus globale dichte Attention, kein Fenster mit 512 Tokens.35

Technische Tabellen und Formeln verwenden im Folgenden die internationale Zahlenschreibweise mit Dezimalpunkt und gegebenenfalls Komma zur Tausendergruppierung.

Backbone-EigenschaftVeröffentlichter Wert
Hidden-Breite / Vokabular4,096 / 128,896
Query-Heads / KV-Gruppen / Head-Breite64 / 4 / 192
Query-Heads je gemeinsamer KV-Gruppe16
Lokale Layer / Fenster inklusive aktuellem Token69 / 512
Globale Sparse-Layer, nullbasiert3, 7, …, 91
Konfigurierter Kontext für Eingabe plus Ausgabe1,048,576
Lokale RoPE-Dimensionen / Theta192 / 10,000
Globale RoPE-Dimensionen / Theta64 / 10,000,000
Indexer-Q-Heads / gemeinsamer K-Head / Proxy-Breite16 / 1 / 256
Provider-Gruppen / Indexer-Q-Heads je Gruppe4 / 4
Historische Blockgröße / Budget ausgewählter Blöcke8 / 512

Die Anzahl rotierter RoPE-Dimensionen ergibt sich aus head_dim × partial_rotary_factors. Der Indexer besitzt einen eigenen Rotationsbereich mit 32 Dimensionen. Das missverständlich benannte Feld yarn_only_types belegt hier kein YaRN: Der gespeicherte Typ von rope_scaling lautet llama3, mit Faktor 1,0. Maßgeblich sind das tatsächliche Skalierungsobjekt und die Implementierung, nicht der Feldname.35

Hinzu kommen drei MTP-Layer außerhalb des Backbones, sämtlich mit Sliding Attention. Die gespeicherten Layer-Typ-Arrays enthalten deshalb 95 statt 92 Einträge. Der Backbone besitzt 88 MoE-FFNs an den Indizes 3–90, mit acht von 352 gerouteten Experts pro Token und einem zusätzlichen Shared Expert. Attention-Auswahl und Expert-Auswahl sind getrennte Operationen; das Expert-Budget beschreibt nicht den KV-Speicherbedarf.35

Zwei Pfade beginnen beim selben Hidden State

NN bezeichnet die gepackten Tokens dieses Forward-Aufrufs, nicht die reservierte Kontextkapazität. Ohne Tensorparallelismus haben die Hidden States zunächst die Form X∈RN×4096X\in\mathbb{R}^{N\times4096}. Der Hauptpfad projiziert Q∈RN×64×192Q\in\mathbb{R}^{N\times64\times192} sowie K,V∈RN×4×192K,V\in\mathbb{R}^{N\times4\times192}. Er normalisiert Q/K und wendet das partielle RoPE des jeweiligen Layers an.5

Der Indexer erzeugt davon unabhängig die folgenden Tensoren. Seine Proxy-Keys sind nicht die 192-dimensionalen Keys der eigentlichen Attention. Vier Provider-Gruppen verwenden denselben komprimierten Proxy-Key-Speicher, berechnen jedoch unterschiedliche Scores und Auswahlen. Gruppe gg steuert die 16 Haupt-Query-Heads, die KV-Gruppe gg gemeinsam nutzen.54

Indexer-TensorForm ohne ShardingAufgabe
qIq^I[N,4,4,256][N,4,4,256]Vier Such-Heads je Provider-Gruppe
kIk^I[N,1,256][N,1,256]Gemeinsamer normalisierter, positionsrotierter Proxy-Key
zz[N,1,256][N,1,256]Gelernte koordinatenweise Kompressions-Logits
ww[N,4,4][N,4,4]Vorzeichenbehaftete Such-Head-Gewichte, mit 4−1/24^{-1/2} skaliert
cc[⌈T/8⌉,1,256][\lceil T/8\rceil,1,256]Kapazität der Blockzusammenfassungen einer Anfrage der Länge TT

Indexer-Queries verwenden RMSNorm, Keys verwenden LayerNorm; auf beide wirkt die 32-dimensionale Rotation. Die Kompressions-Logits bleiben eine separate Projektion. Weder Vokabular-Lookup noch Engram-Tabelle oder externer Retrieval-Index sind beteiligt: Die Zusammenfassungen entstehen aus den Hidden States dieser Anfrage und gehören zu ihrem layerspezifischen Cache.54

Acht Tokens ergeben einen Such-Key – koordinatenweise

Für einen abgeschlossenen Block rr mit acht Tokens berechnet der Kernel pro Proxy-Koordinate dd die folgende Zusammenfassung. Zur numerischen Stabilisierung wird vor der Exponentiation ein gemeinsames Maximum von den Logits abgezogen.4

aj,d=exp⁡(zj,d)∑u∈rexp⁡(zu,d),cr,d=∑j∈raj,dkj,dI.a_{j,d}=\frac{\exp(z_{j,d})}{\sum_{u\in r}\exp(z_{u,d})}, \qquad c_{r,d}=\sum_{j\in r}a_{j,d}k^I_{j,d}.

Das ist kein gewöhnliches Mean-Pooling und auch kein einzelnes Attention-Gewicht für einen vollständigen Key-Vektor. Jede Koordinate besitzt eigene Gewichte. Zwar bleibt jede Koordinate innerhalb des koordinatenweisen Wertebereichs der Keys; der gesamte Zusammenfassungsvektor muss aber nicht in der konvexen Hülle der acht vollständigen Vektoren liegen.

Der gepinnte Kernel akkumuliert die Reduktion in FP32 und rundet das Ergebnis zur Speicherung über BF16 nach E4M3. Beim Decode puffert er Proxy-Keys und Logits des unvollständigen Blocks und erzeugt dessen Zusammenfassung erst mit dem achten Token. Die originalen K/V des Hauptpfads werden unabhängig davon geschrieben und aufbewahrt.4

Auswahl per gewichtetem ReLU-Score, nicht per Attention-Softmax

Für Query-Position tt, Provider-Gruppe gg und historischen Block rr implementiert der Code den folgenden Score. Q8\mathcal{Q}_8 bezeichnet seine E4M3-Rundung mit anschließender verlustfreier Erweiterung nach BF16 für die Score-Matrixmultiplikation. Die vier Gewichte sind vorzeichenbehaftete Ausgaben einer linearen Projektion, bereits inklusive Vorskalierung.4

st,g,r=∑h=14wt,g,h ReLU⁡ ⁣(Q8(qt,g,hI)TQ8(cr)).s_{t,g,r}=\sum_{h=1}^{4}w_{t,g,h}\, \operatorname{ReLU}\!\left( \mathcal{Q}_8(q^I_{t,g,h})^{\mathsf T}\mathcal{Q}_8(c_r) \right).

Das ReLU liegt innerhalb der Summe; durch die vorzeichenbehafteten Gewichte kann der Endscore trotzdem negativ sein. In diesem Pfad gibt es keinen Softmax über die Indexer-Scores. Obwohl die Konfiguration sparse_indexer_softmax_variant: "ssmax" speichert, registriert die Referenz ssmax_s nur zur Checkpoint-Kompatibilität und verwendet es nicht für die Bewertung. Ein Softmax-Indexer würde eine andere Funktion implementieren.54

Bei nullbasierten Token-Positionen konkurrieren nur Blöcke r<⌊t/8⌋r<\lfloor t/8\rfloor um die 512 historischen Top-k-Plätze. Bei gleichen Scores entscheidet die aufsteigende logische Block-ID. Der Block mit Token tt wird zwingend ergänzt, beschränkt auf seine kausal sichtbaren Positionen. „512 ausgewählte Tokens“ wäre also falsch: Das historische Budget beträgt 512 Blöcke = 4.096 Tokens, zuzüglich bis zu acht Tokens des aktuellen Blocks.4

Rt,g=TopK⁡512{st,g,r:0≤r<⌊t/8⌋},Jt,g=⋃r∈Rt,g{8r,…,8r+7}  ∪  {8⌊t/8⌋,…,t},∣Jt,g∣≤4096+8=4104.\begin{aligned} R_{t,g}&=\operatorname{TopK}_{512}\{s_{t,g,r}:0\le r<\lfloor t/8\rfloor\},\\ J_{t,g}&=\bigcup_{r\in R_{t,g}}\{8r,\ldots,8r+7\} \;\cup\;\{8\lfloor t/8\rfloor,\ldots,t\},\\ |J_{t,g}|&\le4096+8=4104. \end{aligned}

Die kausale Beschränkung ist beim Prefill entscheidend: Eine vollständige Blockzusammenfassung kann Positionen nach einer früheren Query enthalten. Ein solcher Block darf nicht in deren historische Kandidaten gelangen; für den aktuellen Block werden stattdessen nur originale K/V bis zur Query verwendet. Ein unbeschränktes Top-k über sämtliche vorab berechneten Zusammenfassungen würde Informationen aus der Zukunft einfließen lassen.

Die eigentliche Attention liest weiterhin originale K/V

Für einen Haupt-Query-Head hh sei g(h)=⌊h/16⌋g(h)=\lfloor h/16\rfloor. Die Attention berechnet gewöhnliche skalierte Skalarprodukte und einen Softmax über die ausgewählten originalen Tokens dieser Gruppe, nicht über die Zusammenfassungen. Der resultierende Head-Vektor wird vor Konkatenation und Ausgabeprojektion mit einem Sigmoid-Gate gewichtet.54

αt,h,j=exp⁡(Qt,hTKj,g(h)/192)∑u∈Jt,g(h)exp⁡(Qt,hTKu,g(h)/192),Ot,h=∑j∈Jt,g(h)αt,h,jVj,g(h),Yt=WOconcat⁡h ⁣[σ((WGXt)h) Ot,h].\begin{aligned} \alpha_{t,h,j}&= \frac{\exp(Q_{t,h}^{\mathsf T}K_{j,g(h)}/\sqrt{192})} {\sum_{u\in J_{t,g(h)}}\exp(Q_{t,h}^{\mathsf T}K_{u,g(h)}/\sqrt{192})},\\ O_{t,h}&=\sum_{j\in J_{t,g(h)}}\alpha_{t,h,j}V_{j,g(h)},\\ Y_t&=W_O\operatorname{concat}_h\!\left[ \sigma((W_GX_t)_h)\,O_{t,h}\right]. \end{aligned}

Zwei unterschiedliche Approximationen sind zu trennen. Zusammenfassungskompression und Indexer-Rundung können ändern, welche Blöcke ausgewählt werden. Die eingeschränkte Haupt-Softmax verändert gegenüber dichter Attention Nenner und Ausgabe. Exakter Softmax auf der gewählten Menge beweist keine Gleichheit mit vollständiger Attention; „originale K/V bleiben erhalten“ beweist keine unveränderte Modellqualität.

Was wird günstiger, und was bleibt längenabhängig?

Bei T=1,048,576T=1,048,576 durchsucht der Indexer ungefähr 131.072 Blockzusammenfassungen statt einer Million einzelner Proxy-Keys. Der Hauptpfad liest je Query höchstens 4.104 originale Token-Positionen pro KV-Gruppe. Das Verhältnis T/4104≈255.5T/4104\approx255.5 ist ein Vergleich der Anzahl gelesener Token-Positionen, kein End-to-End-Speedup: Suche, Top-k, Projektionen, Experts, Kommunikation, Batching und Kernel-Auslastung bleiben bestehen.

Bei festen Dimensionen bleibt die Indexbewertung im Decode O(T/8)O(T/8); die Haupt-Attention verarbeitet O(512×8)O(512\times8) ausgewählte Positionen. Werden alle Prefill-Queries bewertet, bleibt ein Term O(T2/8)O(T^2/8). Das ist weder lineare Attention noch eine Rekurrenz mit konstantem Speicher. Der technische Blog beschreibt das Zusammenfassen überlappender Auswahlen benachbarter Queries zur besseren Auslastung. Diese Optimierung darf nicht pauschal jedem Referenz- oder Serving-Kernel zugeschrieben werden.46

Cache-Kapazität: 4.104 Zugriffe bedeuten nicht 4.104 gespeicherte Tokens

In der Standalone-Implementierung reserviert jeder globale Layer originale K/V für die Anfragekapazität. Bei BF16 benötigt ein Token in einem Layer 2×4×192×2=30722\times4\times192\times2=3072 Bytes für getrennte K und V. Lokale Layer verwenden stattdessen Ringpuffer mit 512 Plätzen. T≥512T\ge512 bezeichnet die globale Kapazität nach dem Aufrunden auf eine 16-Token-Seitengrenze. Für eine Anfrage ergibt sich folgende einmalige, nicht replizierte Backbone-Datennutzlast:54

MKV(T)=3072 (23T+69×512),Msummary(T)=23⌈T8⌉256bytes (E4M3).\begin{aligned} M_{\rm KV}(T)&=3072\,(23T+69\times512),\\ M_{\rm summary}(T)&=23\left\lceil\frac{T}{8}\right\rceil256 \quad\text{bytes (E4M3)}. \end{aligned}
Komponente bei T=1,048,576T=1,048,576, eine AnfrageHergeleitete einmalige Nutzlast
Originale globale K/V, 23 Layer69 GiB
Lokale K/V-Ringpuffer, 69 Layer103.5 MiB
Gemeinsame Indexzusammenfassungen, 23 Layer736 MiB
Summe dieser drei Komponenten69.819824 GiB

Das ist keine Schätzung des Spitzen-VRAM. Nicht enthalten sind Gewichte, drei MTP-Layer, Puffer unvollständiger Blöcke, Seitentabellen, Längenzähler, RoPE-Tabellen, Aktivierungen, Score-/Auswahl-Arbeitsbereiche, Kommunikation und Allocator-Overhead. Die Referenz rundet globale Kapazitäten zudem auf Vielfache von 16 Tokens. FP8-Expert-Gewichte bedeuten keine FP8-K/V im Hauptpfad; die veröffentlichten SGLang-Rezepte fordern ausdrücklich BF16-KV an.542

Die „einmalige Nutzlast“ ist auch nicht die Summe über alle Geräte. Im gepinnten Standalone-Layout mit TP=8 besitzt jeder Rank acht Haupt-Query-Heads, speichert aber eine vollständige KV-Gruppe. Jede der vier globalen KV-Gruppen liegt deshalb auf zwei Ranks. Alle acht Ranks halten außerdem den gemeinsamen Zusammenfassungsspeicher. Die drei Komponenten summieren sich damit über alle Ranks auf 2×(69 GiB+103.5 MiB)+8×736 MiB=143.9521482\times(69\text{ GiB}+103.5\text{ MiB})+8\times736\text{ MiB}=143.952148 GiB, vor den ausgeschlossenen Allokationen. Dieser Replikationsfaktor darf nicht ungeprüft auf andere Engines oder Parallel-Layouts übertragen werden.54

Ein konfiguriertes Millionen-Token-Fenster ist kein validierter Start damit

Die Standalone-Funktion score_regions allokiert eine FP32-Matrix der Form [GlocalN,R][G_{\rm local}N,R], dimensioniert nach vorhandenen Zusammenfassungen statt reservierter Kapazität. Für einen Prefill mit einer Million Tokens gilt N=T=1,048,576N=T=1,048,576 und R=⌊(T−1)/8⌋=131,071R=\lfloor(T-1)/8\rfloor=131,071. Bei TP=8 ist Glocal=1G_{\rm local}=1; allein dieser Tensor benötigt daher 511,996094 GiB pro Rank. Das ist keine GPU-Messung, sondern ergibt sich direkt aus der Form. Damit scheidet ein naiver Standalone-Prefill dieser Länge auf dem dokumentierten H200-Setup aus.4

Die Referenz lehnt einen zweiten Prefill-Chunk auf einem vorhandenen Cache ab und unterstützt danach einzelne Decode-Tokens pro Schritt. Ihr internes Chunking für Sliding-Prefill begrenzt nur die temporäre Maske dieses Pfads; es beseitigt nicht die vollständige Score-Matrix des Sparse-Indexers. Diese Einschränkung betrifft die gepinnte Standalone-Implementierung, nicht die Architektur in jeder denkbaren Engine.5

Die Veröffentlichung liefert separate Serving-Images für SGLang/vLLM. Die SGLang-Rezepte verwenden --chunked-prefill-size 16384, BF16-KV und architekturspezifische Attention-Backends. Die Model Card unterscheidet B300 mit FA4/MegaMoE von H200 mit FA3/Triton. Eine angeforderte Maximallänge oder Parallelität belegt nicht, dass sämtliche Anfragen diese Länge gleichzeitig ausschöpfen können.2

Laut Standalone-README wurde FP8-Text-/Bildgenerierung auf acht H200-GPUs mit TP=EP=8 validiert. Die BF16-Validierung des vollständigen Modell-Forward-Pfads verwendete 16 H200-GPUs, Batchgröße eins und einen Bild-Prompt mit 943 Tokens. Gemeldet werden 76,37 GiB/GPU maximale PyTorch-Allokation, ohne NCCL-/CUDA-Kontext-Allokationen. Lange Kontexte und Durchsatz wurden dort nicht validiert; auch der vollständige dateibasierte BF16-Workflow von der Shard-Konvertierung bis zur Generierung wurde nicht durchgehend ausgeführt. Diese Bedingungen belegen keine produktive Millionen-Token-Kapazität.7

Für den Betrieb sind Checkpoint und Digest des Serving-Images festzuschreiben und der unterstützte Sparse-Attention-Pfad zu prüfen. Danach folgen Tests mit tatsächlichen Prompt-Längen, Ausgabebudgets, Parallelität, Prefix-Wiederverwendung und Qualität. Die Image-Tags der Model Card sind veränderliche Namen, keine unveränderlichen Runtime-Revisionen. Wir haben das Modell nicht ausgeführt und die Herstellertests auf dessen Hardware nicht reproduziert. Die eigene StepFun Model License 1.0 verlangt ebenfalls eine Prüfung des konkreten Einsatzes; herunterladbare Gewichte bedeuten keine uneingeschränkte Open-Source-Lizenz.28

Die technische Kernaussage lautet: Index komprimieren, Zugriffe begrenzen, auswählbare Historie behalten. Step-5-Preview verkleinert den Working Set der globalen Attention, macht seine originale globale KV-Historie aber nicht konstant groß. Dieser Unterschied ist sowohl für die Speicherplanung als auch für die Wahl einer Implementierung entscheidend, die den vorgesehenen Kontext tatsächlich vorverarbeiten kann.

Primärquellen

Footnotes

  1. StepFun model announcement, September 20, 2026; October 15 weight-release date. ↩

  2. Step-5-Preview model card and serving recipes, pinned revision. ↩ ↩2 ↩3 ↩4

  3. Released text/vision, sparse attention, RoPE and quantization configuration. ↩ ↩2 ↩3 ↩4

  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

  5. Standalone model: Step5Config, Step5Cache, Step5Attention and layer construction. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12

  6. StepFun, Inside Step 5 Preview, October 15, 2026, Sparse GQA section. ↩

  7. Standalone validation conditions, supported workflow and limitations. ↩

  8. StepFun Model License 1.0, released checkpoint terms. ↩