Modelsopenaigpt-oss-120b
provideropenai /

gpt-oss-120b

13.65 DZD in 66.5 DZD out/ 1M tokens

gpt-oss-120b is OpenAI's largest open-weight model and the first release of its kind since 2019. It carries roughly 117 billion parameters and activates about five per token, which is what lets a model of this capability run on a single 80GB card rather than a cluster. Reasoning effort is set as plain text in the system prompt across three levels, and the full chain of thought comes back unredacted — OpenAI published the accuracy-versus-length curve across all three settings, so the cost of deliberation is measured rather than implied. It ships under Apache 2.0 with no copyleft, no patent conditions, and no user ceiling.

Publicmxfp4JSONStreamingApache-2.0
gpt-oss-120b
Capabilities
ToolsReasoningStructured output
ArchitectureTransformer
Context Window131K

gpt-oss-120b

OpenAI's largest open-weight model. About 117 billion parameters, roughly five active per token, and it runs on one GPU.

Released 5 August 2025 under Apache 2.0 — model card · repository


One Card, Not a Cluster

The deployment fact that defines this model.

116.83 billion total parameters. 5.13 billion active per token. MXFP4 quantisation applied to the MoE expert weights brings the whole thing onto a single 80GB GPU — an H100 or an MI300X.

A dense model of comparable capability needs multiple cards and the interconnect between them. This one needs a card.

Where the quantisation is applied matters. MXFP4 covers the expert layers, which hold most of the parameters and tolerate reduced precision. Attention, the router, and the embeddings stay in BF16 — the components where a rounding error propagates through everything downstream.

All published evaluations were run at this quantisation. That is uncommon and worth crediting: many models are benchmarked at full precision and shipped quantised, leaving the conversion cost undocumented. Here the numbers and the weights describe the same configuration.


⚠️ The Harmony Format Is Not Optional

Stated repeatedly on the model card: this model was trained on OpenAI's harmony response format and will not work correctly without it.

Not degrade. Not underperform. Will not work correctly.

Through an API the serving layer applies it. When self-hosting:

The Transformers chat template applies harmony automatically.

Calling model.generate directly does not. You apply it yourself, through the chat template or through OpenAI's openai-harmony package.

The failure mode is the dangerous kind — fluent text that is subtly wrong, rather than an error you would notice immediately.


Reasoning Effort Is System-Prompt Text

Distinctive, and the most common integration mistake on this model.

There is no reasoning_effort parameter. The level is plain text in the system message:

PYTHON
messages = [
    {"role": "system", "content": "Reasoning: high"},
    {"role": "user", "content": "Explain why eigenvalues matter."},
]

Three levels: low, medium, high.

A request setting a parameter by that name is configuring something the model never reads. What happens then depends on the serving layer — ignored, rejected, or translated — and it is worth confirming which on your path rather than assuming.

The upside of text-based control: effort composes with the rest of your system prompt. Role, constraints, and deliberation depth all live in one place and version together.


The Test-Time Scaling Curve

Something OpenAI published that most vendors do not, and the most useful thing in the model card.

They swept all three reasoning modes and plotted accuracy against average combined chain-of-thought and answer length. Not a table of scores at maximum effort — a curve showing what each increment of deliberation buys and costs, on the same axes.

Why that matters for your configuration. Every reasoning model asks you to pick an effort level. Almost none tell you the shape of the return. A smooth curve means intermediate settings are genuinely intermediate rather than a cliff; it means medium is a real operating point rather than a compromise between two useful ones.

Published benchmark scores come from high effort. Low returns faster and cheaper at a modest accuracy cost, and the curve is where you decide whether that trade fits your workload.

One measured detail that makes the cost concrete: on AIME problems, the smaller model in this pair averages over twenty thousand chain-of-thought tokens per problem. Deliberation at the top setting is not a rounding adjustment to your output budget.


Benchmark Results

From OpenAI's model card and release material.

BenchmarkScoreCondition
AIME 202597.9%With tools
GPQA Diamond80.9%Graduate-level science
SWE-bench Verified62.4%Real GitHub issues
Codeforces2622 EloWith tool use

Read AIME with suspicion

The 20-billion-parameter model in this pair scores 98.7% on AIME 2025. This one scores 97.9%.

That is not an error, and it does not mean the smaller model reasons better. Given a Python tool, both models solve essentially every problem — the benchmark is saturated, and the gap is noise.

Do not read AIME as a capability ranking here. A saturated benchmark stops discriminating, and treating it as a signal leads to exactly the wrong model choice.

GPQA Diamond is the honest number

80.9% on graduate-level science questions, on a model that runs on one card. That benchmark is nowhere near saturation, it rewards knowledge rather than tool use, and it is where the difference between this model and its smaller sibling is real.

Codeforces at 2622 Elo, with tools

Competitive programming, tool-assisted. The condition matters — this measures the model operating in an environment, which is what it was built for.

Where it does not lead

Larger open models score higher on SWE-bench Verified. OpenAI's positioning is explicitly about capability per activated parameter rather than peak capability: 5.13 billion active parameters is cheaper to serve than models that outscore it here, and that trade is the product.


⚠️ Shipped Without Additional Safety Fine-Tuning

A deliberate decision, and one that changes what you must build around it.

OpenAI released this as a base reasoning model without the additional safety fine-tuning applied to their hosted products, so downstream users can apply their own alignment.

For research, that removes a confound — you are studying the model rather than the model plus an undisclosed safety layer.

For a product, it means the guardrails are yours to build. Raw output can be more direct and blunter than the equivalent hosted model. There is no refusal behaviour tuned for a consumer audience, because that tuning was deliberately left out.

If you are putting this in front of users, plan a moderation layer. It is not an oversight in the release; it is the release.


Specifications

Model IDopenai/gpt-oss-120b
Total parameters116.83B
Active per token5.13B
Context window131,072 tokens
Reasoning effortlow, medium, high — set in the system prompt
Chat formatHarmony — required
QuantisationMXFP4 on MoE weights; BF16 elsewhere
Minimum deploymentSingle 80GB GPU
Input → outputText → text
Fine-tuningSupported
LicenceApache 2.0
Released5 August 2025

Apache 2.0, and the licence is the point. No copyleft, no patent conditions, and — unlike some models marketed as open — no monthly-active-user ceiling. For a company shipping a commercial product on open weights, that absence is worth more than a benchmark point.


Capabilities

CapabilityValue
input_typestext
output_typestext
image_inputNot supported
context_window131072
reasoninglow, medium, high — via system prompt
reasoning_visibilityFull chain of thought returned
chat_formatHarmony — required
streamingSupported
tool_callingSupported
structured_outputSupported
built_in_toolsBrowser, Python, function calling
fine_tuningSupported
requires_promptYes — text prompt required

The Chain of Thought Comes Back Whole

Full, unredacted reasoning, which OpenAI names as enabling easier debugging and increased trust.

That is a real capability difference from closed reasoning models, where the trace is summarised or withheld entirely. When this model reaches a wrong answer, you can read precisely where the argument went wrong — misread prompt, bad premise, or correct reasoning to a wrong conclusion. Those three failures need different fixes and look identical without the trace.

OpenAI attaches one condition, stated plainly: it is not intended to be shown to end users.

Log it. Inspect it. Never render it. It is a working draft, it explores abandoned branches, and it can contradict the answer that follows.


Using gpt-oss-120b on DEVUP AI

Base URL: https://api.devupai.com/v1 · Model ID: openai/gpt-oss-120b

Python

Note where the reasoning level lives.

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="openai/gpt-oss-120b",
    messages=[
        {"role": "system", "content": "Reasoning: high"},
        {"role": "user", "content": "Explain why eigenvalues matter."},
    ],
    max_tokens=32768,
)

print(response.choices[0].message.content)

The output ceiling is generous on purpose. At high effort the chain of thought is long — the smaller model in this pair averages over twenty thousand reasoning tokens on a competition maths problem, and a budget sized for the answer alone truncates the model mid-argument.

Node.js

JAVASCRIPT
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: "openai/gpt-oss-120b",
    messages: [
      { role: "system", content: "Reasoning: medium" },
      { role: "user", content: "Hello world!" },
    ],
    max_tokens: 8192,
  });

  console.log(response.choices[0].message.content);
}

main();

cURL

BASH
curl -X POST "https://api.devupai.com/v1/chat/completions" \
  -H "Authorization: Bearer $DEVUP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-oss-120b",
    "messages": [
      { "role": "system", "content": "Reasoning: low" },
      { "role": "user", "content": "Hello world!" }
    ],
    "max_tokens": 2048
  }'

Composing Effort With Instructions

Because the level is prompt text, it lives alongside everything else you tell the model.

PYTHON
SYSTEM = (
    "Reasoning: high\n\n"
    "You are auditing a payment reconciliation job. Report only defects that could cause a "
    "transaction to be double-counted or dropped. For each, name the code path, the condition "
    "that triggers it, and the smallest correct fix. Where the code does not contain enough "
    "information to judge, say so rather than assuming."
)

response = client.chat.completions.create(
    model="openai/gpt-oss-120b",
    messages=[
        {"role": "system", "content": SYSTEM},
        {"role": "user", "content": source_code},
    ],
    max_tokens=32768,
)

Keep the reasoning directive on its own line at the top, separated from the role description. It is a control instruction rather than part of the persona, and separating them makes both easier to change independently.

Finding your own point on the curve

OpenAI published the accuracy-versus-length relationship. Your workload is not their benchmark suite, but the same experiment is cheap to run.

PYTHON
def measure(prompt: str, level: str) -> tuple[str, int]:
    """Return the answer and the completion tokens spent at a given reasoning level."""
    response = client.chat.completions.create(
        model="openai/gpt-oss-120b",
        messages=[
            {"role": "system", "content": f"Reasoning: {level}"},
            {"role": "user", "content": prompt},
        ],
        max_tokens=32768,
    )
    return response.choices[0].message.content, response.usage.completion_tokens


for level in ("low", "medium", "high"):
    answer, tokens = measure(hard_prompt, level)
    print(f"{level:>6}  {tokens:>6,} tokens  correct={check(answer)}")

Run it across twenty of your real prompts and you have your own curve — which is the only one that tells you where to set production.


Reading the Trace

PYTHON
message = response.choices[0].message

trace = getattr(message, "reasoning_content", None)
if trace:
    # Diagnostic output. Log it; never render it.
    logger.debug("chain of thought: %d characters", len(trace))

print(message.content)

Built-In Tools

Browsing, Python execution, and function calling — trained capabilities rather than prompting patterns layered on afterwards. MCP is supported through the responses interface.

Sandbox the Python tool. In OpenAI's own setup, running execution without a container requires an explicit opt-in whose flag name contains the word dangerously. That is as clear a warning as a parameter name gets: unsandboxed execution means the model runs arbitrary code with your process's permissions.


Where It Fits

Reasoning-heavy work at single-GPU economics. Mathematics, scientific analysis, and structured problem solving, on hardware you can own outright.

Agentic workflows, where the built-in tools and the Codeforces-with-tools result point at what the model was trained to do.

Self-hosted and air-gapped deployment, where open weights and a genuinely permissive licence make something possible that no closed model allows at any price.

Debugging-intensive development, where reading the model's actual reasoning is worth more than a marginally better answer from something opaque.

Fine-tuned specialisation, named by OpenAI as an intended use.

Less suited to image input, which this model does not accept; to latency-critical paths at high effort; and to consumer-facing products without a moderation layer you build yourself.


Practical Notes

Put Reasoning: low|medium|high in the system prompt. A parameter of that name is not what the model reads.

Size max_tokens for reasoning plus answer. High effort produces long traces.

Never display the chain of thought. Log it instead.

Do not bypass the harmony format when self-hosting.

Build your own moderation layer. Safety fine-tuning was deliberately omitted.

Sandbox Python execution.

Measure your own accuracy-versus-length curve rather than inheriting a setting.

Treat AIME results as saturated — use GPQA and SWE-bench to compare tiers.


Limitations

Harmony format is mandatory. Without it the model does not work correctly, and the failure is silent rather than loud.

Reasoning effort is prompt text. Integrations written against a parameter control nothing.

No additional safety fine-tuning. Output can be blunter and more direct than a hosted model. Guardrails are your responsibility.

The chain of thought is not for display. OpenAI states this explicitly.

Text only. No image, audio, or video input, and no image generation.

Larger open models outscore it on software engineering. The trade is capability per activated parameter, not peak capability.

AIME is saturated at this level. The smaller sibling scores higher; the difference is noise.

131K context comes from position scaling rather than native long-context training. Verify behaviour at the far end on your own data.

Python execution needs a sandbox. The flag that removes it names the risk in its own name.

Standard foundation-model limitations apply. Ground factual work and validate anything that will act on a system of record.