The GPT model naming history reflects OpenAI’s shift from research checkpoints to productized model families. Understanding the progression from GPT-3 through GPT-5 helps you pick the right model for production workloads, anticipate deprecation timelines, and structure your routing logic. This guide breaks down each generation, what the suffixes actually mean, and how to handle transitions in your inference pipeline.
The GPT-3 era: base models and instruction tuning
GPT-3 launched in 2020 as a single base model with four sizes: ada, babbage, curie, and davinci. These were raw completion models — no chat formatting, no system prompts. You sent text, it completed text.
# GPT-3 base completion (legacy)
import openai
response = openai.Completion.create(
model="davinci", # or curie, babbage, ada
prompt="Write a Python function to parse JSON:",
max_tokens=150,
temperature=0.7
)
The instruction-tuned variants arrived later as text-davinci-001, text-davinci-002, text-davinci-003. The numbering tracked RLHF training runs, not model architecture changes. text-davinci-003 was the workhorse for most of 2022.
Pitfall: Base models (davinci, curie, etc.) are deprecated. If you have legacy code referencing them, migrate to the chat completions endpoint with gpt-3.5-turbo-instruct — the closest drop-in replacement.
GPT-3.5: the chat completions pivot
March 2023 introduced the chat completions endpoint and gpt-3.5-turbo. This was the first model where “turbo” signaled “optimized for chat, cheaper, faster” rather than a distinct architecture.
# Chat completions — the new standard
response = openai.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a senior Python engineer."},
{"role": "user", "content": "Write a JSON parser with error handling."}
],
temperature=0.3
)
Snapshot versions vs. rolling aliases
OpenAI introduced dated snapshots (gpt-3.5-turbo-0301, gpt-3.5-turbo-0613, gpt-3.5-turbo-1106) alongside the rolling gpt-3.5-turbo alias. The rolling alias auto-updates to the latest snapshot — convenient for prototypes, dangerous for production.
# Production: pin to a snapshot
MODEL = "gpt-3.5-turbo-0125" # frozen behavior
# Development: use rolling alias
MODEL = "gpt-3.5-turbo" # auto-updates
Tradeoff: Snapshots guarantee reproducibility but require manual updates for bug fixes and safety improvements. Rolling aliases stay current but can break prompts silently. Most teams pin in production, use rolling in staging, and run eval suites before promoting.
The 16k context expansion
gpt-3.5-turbo-16k (later gpt-3.5-turbo-0125 with 16k default) doubled context at 2x the price. The naming didn’t distinguish context length in the base alias — you had to know the snapshot’s capabilities.
{
"model": "gpt-3.5-turbo-0125",
"max_tokens": 4096,
"context_window": 16384
}
GPT-4: multimodal, reasoning, and the “o” series
GPT-4 (March 2023) introduced the first multimodal model, but the API initially exposed only text. The naming split into two tracks:
| Model | Context | Modality | Notes |
|---|---|---|---|
gpt-4 |
8k | Text | Rolling alias |
gpt-4-0314 / gpt-4-0613 |
8k | Text | Snapshots |
gpt-4-32k / gpt-4-32k-0613 |
32k | Text | 2x price of 8k |
gpt-4-turbo / gpt-4-turbo-2024-04-09 |
128k | Text + vision | “Turbo” = optimized + cheaper |
gpt-4o / gpt-4o-2024-05-13 |
128k | Text + vision + audio | “o” = omni (native multimodal) |
gpt-4o-mini / gpt-4o-mini-2024-07-18 |
128k | Text + vision | Cheaper, smaller “o” variant |
The “turbo” meaning shift
In GPT-3.5, “turbo” meant “chat-optimized.” In GPT-4, “turbo” means “optimized inference, lower latency, lower cost, same or better capability.” gpt-4-turbo is not a distilled model — it’s the same architecture with kernel-level optimizations.
The “o” series: native multimodality
gpt-4o (May 2024) and gpt-4o-mini (July 2024) are natively multimodal — one model weights, shared representation space for text, vision, and audio. Earlier gpt-4-turbo with vision used a separate vision encoder bolted on.
# gpt-4o: single model handles image + text natively
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}
]
}]
)
Pitfall: gpt-4o-mini does not support audio input despite the “omni” branding. Audio requires gpt-4o or the Realtime API.
The reasoning models: o1, o3, and the new paradigm
September 2024 introduced o1-preview and o1-mini — models trained with reinforcement learning to “think” before answering. The naming breaks the GPT pattern entirely.
| Model | Reasoning effort | Context | Use case |
|---|---|---|---|
o1-preview |
High | 128k | Complex math, code, science |
o1-mini |
Medium | 128k | STEM reasoning, cheaper |
o1 (Dec 2024) |
High | 200k | Production reasoning |
o3-mini (Jan 2025) |
Configurable | 200k | Tunable reasoning depth |
Reasoning tokens and the reasoning_effort parameter
These models emit hidden reasoning tokens you pay for but don’t see. The reasoning_effort parameter (low/medium/high) controls the budget.
# o1 and o3-mini: control reasoning depth
response = openai.chat.completions.create(
model="o3-mini",
messages=[{"role": "user", "content": "Prove Fermat's Last Theorem"}],
reasoning_effort="high" # low, medium, high
)
Tradeoff: High reasoning effort can 10x token costs. Set reasoning_effort="low" for simple classification, “high” for novel algorithm design. Monitor your usage dashboard — reasoning tokens appear as completion_tokens with no visibility into the split.
Structured outputs requirement
Reasoning models require response_format with type: "json_schema" for structured output. They don’t support the older function_calling flow reliably.
from pydantic import BaseModel
class CodeReview(BaseModel):
issues: list[str]
severity: str
suggested_fix: str
response = openai.beta.chat.completions.parse(
model="o3-mini",
messages=[...],
response_format=CodeReview,
reasoning_effort="medium"
)
GPT-4.5 and the research preview naming
February 2025 brought gpt-4.5-preview — a research preview, not a GA model. The “.5” signals “between generations,” and “preview” means: no SLA, potential breaking changes, limited quota, and possible retirement without migration path.
# Treat previews as experimental only
MODEL = "gpt-4.5-preview" # don't build production deps on this
Common pitfall: Teams ship features against preview models, then scramble when the preview ends. If you need GPT-4.5 capabilities in production, wait for the GA release (likely gpt-4.5 or folded into gpt-5).
GPT-5: the unified model family
GPT-5 (expected 2025) consolidates the fragmented naming into a single model with configurable reasoning. Early signals suggest:
- One base model:
gpt-5 - Reasoning controlled via
reasoning_effort(like o3-mini) - Native multimodality: text, vision, audio, video
- Context window: 256k+ tokens
- No more “turbo,” “mini,” “o” suffixes — capability is a runtime parameter
# Hypothetical GPT-5 API (based on o3-mini pattern)
response = openai.chat.completions.create(
model="gpt-5",
messages=[...],
reasoning_effort="auto", # model decides based on prompt complexity
modalities=["text", "audio"], # request audio output
max_completion_tokens=8192
)
Migration strategy for GPT-5
When GPT-5 lands, plan a staged rollout:
- Shadow traffic: Route 5% of requests to
gpt-5withreasoning_effort="low", compare latency/cost/quality againstgpt-4o - Eval suite: Run your golden dataset — classification, extraction, coding, reasoning — against both models
- Gradual ramp: Increase traffic share as evals pass; keep
gpt-4oas fallback - Deprecate: Once GPT-5 matches or beats GPT-4o across your workloads, sunset the old model
# Fallback routing pattern (pseudocode)
async def complete_with_fallback(messages, model="gpt-5", fallback="gpt-4o"):
try:
return await openai.chat.completions.create(
model=model,
messages=messages,
reasoning_effort="auto",
timeout=30
)
except (RateLimitError, APIError, Timeout) as e:
logger.warning(f"{model} failed: {e}, falling back to {fallback}")
return await openai.chat.completions.create(
model=fallback,
messages=messages,
timeout=30
)
Quick reference: decoding any GPT model name
| Component | Meaning | Examples |
|---|---|---|
gpt- |
Base architecture prefix | gpt-4o, gpt-3.5-turbo |
3.5, 4, 4.5, 5 |
Generation | gpt-4, gpt-4.5-preview |
turbo |
Optimized inference (GPT-3.5/4) | gpt-3.5-turbo, gpt-4-turbo |
o |
Omni — native multimodal | gpt-4o, gpt-4o-mini |
mini |
Distilled/smaller variant | gpt-4o-mini, o1-mini |
preview |
Research preview, no SLA | gpt-4.5-preview, o1-preview |
YYYY-MM-DD |
Frozen snapshot | gpt-4o-2024-05-13 |
32k, 16k |
Context window (legacy) | gpt-4-32k, gpt-3.5-turbo-16k |
Production checklist for model selection
- Pin snapshots in production — never use rolling aliases (
gpt-4o,gpt-3.5-turbo) without a snapshot fallback - Match context to task — don’t pay for 128k if 16k suffices; use
gpt-4o-minifor high-volume classification - Budget reasoning tokens — set
reasoning_effortexplicitly for o1/o3 models; monitorcompletion_tokensspikes - Test fallback paths — implement automatic fallback to previous generation; log every fallback event
- Run evals on every model swap — including snapshot updates (e.g.,
gpt-4o-2024-05-13→gpt-4o-2024-08-06) - Track deprecation notices — OpenAI announces deprecations 6-12 months ahead; subscribe to their changelog
The naming pattern going forward
OpenAI is converging on: one model per generation, capability as configuration. GPT-5 drops the suffix salad. Future models will likely follow gpt-{n} with reasoning_effort, modalities, and max_completion_tokens as the control knobs.
For now, maintain a model registry in your codebase that maps logical roles to concrete model IDs:
# models.py — single source of truth
MODEL_REGISTRY = {
"default_chat": "gpt-4o-2024-08-06",
"cheap_classification": "gpt-4o-mini-2024-07-18",
"complex_reasoning": "o3-mini-2025-01-31",
"vision_extraction": "gpt-4o-2024-08-06",
"legacy_completion": "gpt-3.5-turbo-instruct-0914",
"fallback": "gpt-4o-2024-05-13"
}
def get_model(role: str) -> str:
return MODEL_REGISTRY.get(role, MODEL_REGISTRY["default_chat"])
Update this registry, not your call sites, when snapshots rotate or GPT-5 ships. That’s the only sustainable way to manage the GPT model naming history in production.