Step-5-Preview
Step 5 Preview is StepFun's flagship for agentic work — 600 billion parameters with 27 billion active per token, a one-million-token window that output can fill as fully as input, and image understanding alongside text. It always reasons: deliberation runs on every request, controlled across three levels rather than switched off. StepFun position it for repository-scale software engineering, long-horizon execution with repeated tool calls, and professional knowledge work, with particular strength in finance. After launching through an API, its weights were released openly in three precisions, under a licence that carries attribution and commercial conditions of its own.

Use Step-5-Preview in VS Code, Cursor and Antigravity
DEVUP Code, the DEVUP AI extension, is free to install. Requests are paid from your DEVUP balance.
Step 5 Preview
StepFun's flagship for agentic work. Six hundred billion parameters, twenty-seven active, and it always reasons.
API First, Weights Second
Step 5 Preview launched as an API-only model. Its open weights followed on 15 October 2026, in three precisions:
| Checkpoint | Size |
|---|---|
| Step-5-Preview (FP8) | 604B |
| Step-5-Preview-BF16 | 604B |
| Step-5-Preview-NVFP4 | 321B |
Which gives the model an unusual history for an open release. It was used through a hosted API before anyone could run it themselves — so its behaviour in production was established before its architecture could be inspected.
The repository lists 604 billion parameters; the model card describes 600 billion. Use the card's figure for comparison and the repository's for sizing hardware.
⚠️ It Always Reasons
Deliberation runs on every request. It cannot be switched off — only made shorter or longer.
Settings that disable reasoning on other models have no effect here. reasoning_effort: "none" and
reasoning.enabled: false do not return an error — and reasoning still runs.
Which is the trap worth naming. An integration written for a model where none disables reasoning
will send it here, receive no error, and still spend tokens on a reasoning pass it believed it had
switched off.
Three documented levels
| Level | |
|---|---|
low | Shortest reasoning |
medium | |
high | The setting used for every published result |
Use these three. Other level names are not documented for this model, and none in particular does
not do what its name suggests.
Small budgets break
Reasoning shares the output budget, and it comes first. A small max_tokens can be exhausted by
deliberation before the answer begins — the response arrives truncated, with reasoning and no answer.
Size max_tokens for reasoning plus answer, every time. A ceiling sized for the answer alone is a
ceiling the model can use up before it starts answering.
Reasoning tokens are not broken out
Reasoning is counted inside completion_tokens, but the separate reasoning-token field in the usage
object reports zero.
So the total is right and the split is missing. You can see the reasoning in completion_tokens;
you cannot see how much of that figure was deliberation. If you need the split — to compare effort
levels, or to understand where a budget went — measure the trace yourself.
A Million In, a Million Out
| Context window | Up to 1M tokens |
| Maximum output | Up to 1M tokens |
The output ceiling matches the window. Most models in this catalogue cap generation far below their context; this one does not.
Which means one shared budget rather than two caps. Input and output draw from the same million tokens — a request sending eight hundred thousand tokens has two hundred thousand left for reasoning and answer together.
And reasoning is inside that budget. A long generation at high effort spends part of its allowance
on deliberation before the answer begins.
WINDOW = 1_048_576
def output_budget(estimated_input: int, want: int = 65_536) -> int:
"""Output available once the input is accounted for — reasoning included."""
remaining = WINDOW - estimated_input - 2_048
if remaining <= 0:
raise ValueError(f"input of ~{estimated_input:,} tokens leaves no room in {WINDOW:,}")
return min(want, remaining)Architecture
A sparse Mixture-of-Experts model: 600 billion total parameters, 27 billion active per token.
StepFun's card does not publish a layer-by-layer breakdown. What is known about the internal structure comes from a third-party test slice built directly from the released weights, which keeps one decoder layer of each kind the model contains:
| Layer kind | Attention | Feed-forward |
|---|---|---|
| 1 | Sliding-window | Dense MLP |
| 2 | Full sparse attention | MoE — FP8 |
| 3 | Sliding-window | MoE — FP8 |
| 4 | Sliding-window | MoE — BF16 |
| 5 | Full sparse attention | Dense MLP |
Five distinct layer types, combining two attention mechanisms with two feed-forward designs. The slice also retains a vision tower and identifies multi-token-prediction layers — and its source layer indices place the decoder at at least ninety-two layers.
Two details stand out.
Sliding-window and full sparse attention are mixed. Local layers attend to a neighbourhood at fixed cost; full layers carry long-range retrieval — the pattern that makes a million-token window affordable.
Expert precision varies by layer. Some MoE layers ship with FP8 experts and others with BF16 — a deliberate choice about where precision matters, made layer by layer rather than across the model.
Treat this section as an inspection of the weights, not a specification. StepFun may publish a fuller description; until then, this is what the files themselves show.
⚠️ Video: The Card Disagrees With Itself
The model card's introduction says the model accepts text, images, and video. Its own specification table lists the input as text and image.
Both statements are on the same page. One of them is incomplete.
Image input is supported. Video is not confirmed. The vision tower is present in the weights; test video input on your own material before building on it.
Built for Three Kinds of Work
Software engineering
Repository-level work, frontend and visual development, and programming for devices. StepFun describe it navigating large codebases, coordinating changes across files, running and verifying code, and iterating on the results.
"Programming for devices" is the unusual inclusion — embedded and device-level code is rarely named in a general model's positioning.
Long-horizon agentic execution
Tasks requiring repeated tool calls, execution, verification, and revision, drawing on long-context information throughout the workflow.
The phrase "throughout the workflow" is the operative one. An agent that reads a specification at step one and still uses it correctly at step two hundred is the capability being claimed — and it is what a million-token window is for.
Professional knowledge work
Research, multimodal understanding, and tool use combined — analysing long documents, charts, screenshots, and images, and producing structured reports.
A Focus on Finance
Named as the model's particular strength: financial tasks that combine quantitative reasoning with analysis of financial data and supporting documents.
Read the two halves together. Quantitative reasoning alone is mathematics. Document analysis alone is extraction. Finance work is both at once — reconciling a figure in a filing against a calculation, reading a chart and checking it against the table it summarises.
That combination is where image input, long context, and always-on reasoning meet. A filing read as images, a model holding hundreds of pages, and deliberation on every figure.
And it is where correctness has consequences. Evaluate on your own financial material before depending on it; a benchmark claim in this domain is a starting point rather than a guarantee.
Performance

Read the chart with its evaluation notes:
All Step 5 Preview results use the high reasoning setting.
GDPval-AA v2.1 scores come from Artificial Analysis, as of 20 September 2026 — an independent measurement rather than a vendor run, which makes it the figure worth weighting most.
DeepSWE v1.1 uses the SWE-agent harness at temperature 1.0 and top-p 0.95.
The default you deploy may not be high. Every published figure describes the top of the effort
range.
Sampling
Recommended inference settings:
| Parameter | Value |
|---|---|
temperature | 1.0 |
top_p | 0.95 |
top_k | 0 |
top_k=0 disables top-k filtering — sampling is constrained by top-p alone.
Temperature 1.0 is unconstrained by convention, and it is what StepFun recommend. Measure before lowering it, even for tasks that seem to want determinism.
⚠️ Read the Licence
StepFun Model License 1.0 — covering the weights, parameters, configuration, tokenizer, model-specific code, and documentation.
StepFun describe it as Apache-2.0-style, with additional attribution and commercial-licence conditions specific to the model's use, modification, and distribution.
That is not Apache 2.0. Earlier open releases in the Step family were; this one is not. The additional conditions are exactly the part that matters for a commercial deployment, and they are defined in the licence text rather than summarised on the card.
Read LICENSE.txt in the repository before building a product on the weights. Accompanying materials
marked with a different licence — sample code, datasets, third-party components — follow their own
terms.
Specifications
| Model ID | stepfun-ai/Step-5-Preview |
| Architecture | Sparse Mixture-of-Experts |
| Total parameters | 600B |
| Active parameters | 27B |
| Context window | Up to 1M tokens |
| Maximum output | Up to 1M tokens |
| Input | Text, image |
| Output | Text |
| Reasoning | Always on — low, medium, high |
| Checkpoints | FP8 · BF16 · NVFP4 |
| Licence | StepFun Model License 1.0 |
| Status | Preview |
| Open weights released | 15 October 2026 |
| Developer | StepFun |
Capabilities
| Capability | Value |
|---|---|
input_types | text, image — video stated in the card's introduction, not its specification |
output_types | text |
context_window | 1048576 |
max_output_tokens | Up to the window |
reasoning | Always on — returned in its own field |
reasoning_effort | low, medium, high |
reasoning_disable | Not supported — none and enabled: false have no effect |
reasoning_tokens_reported | No — included in completion_tokens, not broken out |
streaming | Supported |
tool_calling | Supported — auto, required, none, named function |
json_mode | Supported — json_object |
json_schema | Not documented |
requires_prompt | Yes — text prompt required, image optional |
Using Step 5 Preview on DEVUP AI
Base URL: https://api.devupai.com/v1 · Model ID: stepfun-ai/Step-5-Preview
Python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["DEVUP_API_KEY"],
base_url="https://api.devupai.com/v1",
)
response = client.chat.completions.create(
model="stepfun-ai/Step-5-Preview",
messages=[
{"role": "user", "content": "Hello world!"}
],
max_tokens=4096,
)
print(response.choices[0].message.content)Node.js
import DevupAI from "devupai";
const client = new DevupAI({
apiKey: process.env.DEVUP_API_KEY,
});
async function main() {
const response = await client.chat.completions.create({
model: "stepfun-ai/Step-5-Preview",
messages: [{ role: "user", content: "Hello world!" }],
max_tokens: 4096,
});
console.log(response.choices[0].message.content);
}
main();cURL
curl -X POST "https://api.devupai.com/v1/chat/completions" \
-H "Authorization: Bearer $DEVUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "stepfun-ai/Step-5-Preview",
"messages": [
{ "role": "user", "content": "Hello world!" }
],
"max_tokens": 4096
}'Even "Hello world!" reasons. The examples use a 4,096-token ceiling rather than 1,024 because the budget covers deliberation as well as the answer, and a small ceiling can be used up before the answer starts.
Setting the Effort
DOCUMENTED = {"low", "medium", "high"}
def ask(prompt: str, *, effort: str = "medium", want: int = 16_384) -> str:
"""Send a request at a documented reasoning level."""
if effort not in DOCUMENTED:
raise ValueError(
f"'{effort}' is not a documented level — use low, medium, or high. "
"Reasoning cannot be turned off on this model; 'none' has no effect."
)
response = client.chat.completions.create(
model="stepfun-ai/Step-5-Preview",
messages=[{"role": "user", "content": prompt}],
max_tokens=want,
temperature=1.0,
top_p=0.95,
extra_body={"reasoning_effort": effort},
)
choice = response.choices[0]
if choice.finish_reason == "length":
raise ValueError(
f"truncated at {response.usage.completion_tokens:,} tokens — "
f"raise max_tokens or lower the effort from '{effort}'"
)
return choice.message.contentReject undocumented levels in your own code. Only three levels are documented, and none does not
turn reasoning off — validating before sending means a request never silently behaves differently from
what it asked for.
low for mechanical work, high for the hard step. Reasoning cannot be removed, so the lever is how
long it runs.
Reading the reasoning
message = response.choices[0].message
trace = getattr(message, "reasoning_content", None)
if trace:
logger.debug("reasoning: %d characters", len(trace))
print(message.content)Measure the trace length yourself if you need to know what deliberation cost — the usage object does not split it out.
Keep the trace out of anything a user reads. It is a working draft, not the answer.
Tool Calling
Four tool_choice modes: auto, required, none, and a named function.
import json
TOOLS = [
{
"type": "function",
"function": {
"name": "get_filing",
"description": "Return the text of a company filing for a given ticker and period.",
"parameters": {
"type": "object",
"properties": {
"ticker": {"type": "string"},
"period": {"type": "string", "description": "e.g. 2026-Q2"},
},
"required": ["ticker", "period"],
},
},
},
]
response = client.chat.completions.create(
model="stepfun-ai/Step-5-Preview",
messages=[{"role": "user", "content": "Compare operating margin across the last two quarters for ACME."}],
tools=TOOLS,
tool_choice="required",
max_tokens=8192,
extra_body={"reasoning_effort": "low"},
)
for call in response.choices[0].message.tool_calls or []:
try:
arguments = json.loads(call.function.arguments or "{}")
except json.JSONDecodeError as exc:
raise ValueError(f"malformed arguments for {call.function.name}: {exc}") from exc
print(call.function.name, arguments)required forces a call where a step must produce one. A named function narrows it to a single
tool when your code already knows which one is needed:
tool_choice={"type": "function", "function": {"name": "get_filing"}}low effort on a dispatch step. Deciding which tool to call rarely needs long deliberation; the
analysis that follows may. And keep max_tokens generous even here — the reasoning still runs before the
call.
JSON Output
json_object mode constrains the response to a valid JSON object.
import json
response = client.chat.completions.create(
model="stepfun-ai/Step-5-Preview",
messages=[
{
"role": "system",
"content": "Return a single JSON object with keys: city, country. Use null for anything unknown.",
},
{"role": "user", "content": "Algiers"},
],
response_format={"type": "json_object"},
max_tokens=4096,
extra_body={"reasoning_effort": "low"},
)
try:
data = json.loads(response.choices[0].message.content)
except json.JSONDecodeError as exc:
raise ValueError(f"model did not return parseable JSON: {exc}") from exc
missing = {"city", "country"} - data.keys()
if missing:
raise ValueError(f"JSON is valid but missing keys: {sorted(missing)}")json_object guarantees the output parses, not that it has your keys. Describe the shape in the
prompt and check it after parsing.
The budget still covers reasoning. A four-thousand-token ceiling for a two-key object looks excessive; on a model that always reasons, it is what lets the object arrive at all.
Schema-constrained output (json_schema) is not documented for this model — rely on json_object
plus your own validation.
A Long-Horizon Agent Session
The workload StepFun position this model for — repeated tool calls, execution, verification, revision.
import json
import time
WINDOW = 1_048_576
COMPACT_AT = 0.80
TOOLS = [
{
"type": "function",
"function": {
"name": "read_file",
"description": "Read a file relative to the repository root.",
"parameters": {
"type": "object",
"properties": {"path": {"type": "string"}},
"required": ["path"],
},
},
},
{
"type": "function",
"function": {
"name": "run_tests",
"description": "Run the test suite and return pass/fail counts with failure output.",
"parameters": {"type": "object", "properties": {}},
},
},
]
def read_file(path: str) -> dict:
"""Replace with your real, sandboxed file access."""
raise NotImplementedError
def run_tests() -> dict:
"""Replace with your real, sandboxed test runner."""
raise NotImplementedError
HANDLERS = {"read_file": read_file, "run_tests": run_tests}
session = [
{
"role": "system",
"content": (
"You are working inside a git repository. Investigate before changing anything, run the "
"tests after every edit, and verify each change before moving to the next. If a failure "
"is not explained by your last change, say so and stop rather than guessing."
),
},
{"role": "user", "content": "The DZD invoice test fails on totals ending in .005. Find the cause."},
]
CEILING = 200
start = time.monotonic()
for step in range(CEILING):
response = client.chat.completions.create(
model="stepfun-ai/Step-5-Preview",
messages=session,
tools=TOOLS,
max_tokens=32_768,
temperature=1.0,
top_p=0.95,
extra_body={"reasoning_effort": "medium"},
)
used = response.usage.prompt_tokens / WINDOW
if used > COMPACT_AT:
print(f"step {step}: {used:.0%} of the window — compact before continuing")
break
message = response.choices[0].message
session.append(message)
if not message.tool_calls:
print(message.content)
break
for call in message.tool_calls:
handler = HANDLERS.get(call.function.name)
if handler is None:
outcome = {"error": "unknown tool", "name": call.function.name}
else:
try:
outcome = handler(**json.loads(call.function.arguments or "{}"))
except Exception as exc:
outcome = {"error": type(exc).__name__, "detail": str(exc)}
session.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(outcome)})
else:
print(f"Reached the {CEILING}-step ceiling.")
print(f"{step + 1} steps, {(time.monotonic() - start) / 60:.1f} min")"Verify each change before moving to the next" matches the loop StepFun describe — execution, verification, revision — and makes it an instruction rather than a hope.
medium effort across the loop. Every step reasons regardless; on a two-hundred-step session,
running each at high multiplies the cost of the whole run.
Financial Documents
Where image input, long context, and always-on reasoning meet.
import base64
from pathlib import Path
pages = [
{
"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{base64.b64encode(p.read_bytes()).decode()}"},
}
for p in sorted(Path("filing").glob("page_*.png"))
]
response = client.chat.completions.create(
model="stepfun-ai/Step-5-Preview",
messages=[
{
"role": "user",
"content": pages + [
{
"type": "text",
"text": (
"Extract revenue, operating income, and net income for each period shown. "
"Recompute operating margin from the extracted figures and flag any period "
"where your computation differs from a margin printed in the document. "
"Separate printed values from values read off a chart. Mark anything "
"illegible as unreadable rather than estimating it."
),
},
],
}
],
max_tokens=32_768,
extra_body={"reasoning_effort": "high"},
)Recompute, then compare. The instruction asks the model to do the quantitative half and the document half together — which is the combination StepFun name as this model's particular strength.
high effort here, deliberately. Reconciling figures is where reasoning earns its tokens.
Send pages at full resolution. Downscaling discards the detail that distinguishes a 6 from an 8 in a dense table.
Self-Hosting
Three official checkpoints: FP8 at 604 billion parameters, BF16 at 604 billion, and NVFP4 listed at 321 billion — roughly half the size of the others.
A dedicated vLLM image is published for this model, and StepFun specify that a framework build including Step 5 Preview support is required — for the reasoning parser, the tool-call parser, and the speculative decoding features the serving commands use.
The parsers are model-specific: --reasoning-parser step5 and --tool-call-parser step5, with
automatic tool choice enabled. Earlier Step models used different parser names; a configuration carried
over from them will not parse this model's output correctly.
SGLang is also supported, with the same parsers.
The FP8 checkpoint serves at four-way tensor parallelism in the reference configuration; BF16 runs across nodes.
A standalone Transformers implementation is provided for offline generation.
Where It Fits
Repository-scale software engineering — navigating large codebases, coordinated multi-file changes, run-and-verify loops.
Frontend, visual, and device programming, all named in StepFun's positioning.
Long-horizon agents with repeated tool calls across a million-token window, with forced and named tool choice.
Financial analysis combining quantitative reasoning with documents and charts — the named strength.
Long-document and screenshot analysis producing structured reports, with JSON-mode output.
Self-hosted deployment, under a licence whose commercial conditions you have read.
Not for work that must not reason. Deliberation cannot be switched off.
Not for audio. Video input is unconfirmed.
Practical Notes
Size max_tokens for reasoning plus answer on every request — a small ceiling can be used up by
reasoning before the answer starts.
Use low, medium, or high only; reject other effort values in your own code.
Do not send none expecting to save tokens — it has no effect.
Use low for dispatch and mechanical steps, high for the steps that reconcile or decide.
Reasoning is included in completion_tokens; measure the trace itself if you need the split.
Budget input and output against one shared million-token window.
Use temperature 1.0, top-p 0.95, and no top-k.
Read published benchmarks as high-effort results.
Use json_object with your own key validation.
Treat video input as unconfirmed.
Send document images at full resolution.
Verify agent claims against the system, not the transcript.
Read the StepFun Model License before commercial use of the weights.
If self-hosting: a Step 5-aware framework build, and the step5 parsers.
Limitations
Reasoning cannot be turned off. none and enabled: false return no error and have no effect.
Three documented effort levels — low, medium, high.
Small output budgets break. Reasoning comes first and can exhaust a modest max_tokens before the
answer starts.
Reasoning tokens are not reported separately. They are included in completion_tokens; the separate
reasoning-token field shows zero.
One shared budget. Input, reasoning, and answer all draw from the same million tokens.
Schema-constrained JSON is not documented. json_object is the supported structured mode.
Video input is contradicted by the card itself — stated in its introduction, absent from its specification.
Published results use high effort, the top of the range.
A preview release. Behaviour may change before a general release.
Not Apache-licensed. The StepFun Model License adds attribution and commercial conditions to an Apache-style base.
The architecture is not fully documented by StepFun. Layer-level details here come from inspection of the released weights.
27 billion active parameters per token, 600 billion loaded. The MoE saving is in compute, not memory.
Reasoning traces are working notes. Unpolished, sometimes exploring abandoned branches, and occasionally contradicting the answer that follows.