Model comparison · 2026-08-24

What was Ling 3.0 Tiny, and why did it close? A migration guide to Ling 3.0 Flash

Ling 3.0 Tiny explained: its 7.9B MoE architecture, why the provider withdrew the route, the 410 the gateway returns, and the two things that change in your code when you move to Ling 3.0 Flash.

Plain diagram showing the Ling 3.0 Tiny row closing, the gateway 410 that names its successor, and the model identifier and thinking suffix that both change when migrating to Ling 3.0 Flash.

What was Ling 3.0 Tiny?

Ling 3.0 Tiny was InclusionAI's small Mixture-of-Experts model: only 1.3 billion of its 7.9 billion parameters ran per token. It was a good example of combining the speed and cost of a small model with the knowledge capacity of a larger one.

It had two modes. In the default Thinking mode it reasoned step by step before answering and returned that chain separately in `reasoning_content`. In Instant mode it answered directly. It supported native tool calling, read repeated prompts from a prompt cache, and offered a 262,144-token context window. A single response could be at most 32,768 tokens.

On LLMTR it was served on the free tier with a daily usage quota. The rest of this article is about why that route no longer answers and what to use in its place.

Why does Ling 3.0 Tiny no longer answer?

The provider withdrew the route. This was confirmed on 18 August 2026 by calling the provider's own endpoint rather than reading it off our error: the row now appears in its model listing with a closed status code and no pricing block at all, and a chat request answers `500 MODEL_NOT_AVAILABLE`. The same account with the same credential answers 200 on `ling-3.0-flash`.

That distinction matters: the problem is not the server, the account, or anything on the LLMTR side — it is the model id itself. The provider first reported it unavailable on 15 August, and the outage was mistaken for a server-side fault several times before it was traced correctly.

LLMTR did not delete the row from the catalog. A retired model stays in the listing and at its own URL, so someone searching the model name still reaches the right page and gets pointed at the successor. Deleting or hiding the record would mean sending that person nowhere at all.

Calling `inclusionai/ling-3.0-tiny` today does not give you a bare 400 or 502. The gateway returns `410`, naming both the retirement date (15 August 2026, the day the provider first reported it unavailable) and the successor. The `details` block is machine-readable, so you can read the successor's identifier out of it and automate the migration on your side.

The response to a request for the retired model: the error names its successor

{
  "error": {
    "message": "Model \"inclusionai/ling-3.0-tiny\" was retired on 2026-08-15. Use \"inclusionai/ling-3.0-flash\" instead.",
    "type": "model_retired",
    "details": {
      "model": "inclusionai/ling-3.0-tiny",
      "retirement_date": "2026-08-15",
      "replacement_model": "inclusionai/ling-3.0-flash",
      "status": "retired"
    }
  }
}

Why don't we silently reroute your request to Flash?

It was technically possible: we could have rewritten `ling-3.0-tiny` calls to `ling-3.0-flash` behind the scenes and no client would have broken. We deliberately did not, and the reason fits in one sentence: Tiny was free and Flash is metered.

A silent reroute would mean a user running on a free quota stays unaware of a price change until they see a line on an invoice. Nobody should learn about a price change from their bill. So the gateway refuses the request, says why, and leaves the decision to you.

There is also no free successor left in this provider's catalog — no equivalent $0 route to forward to. The choice is therefore a real one: move to metered Flash, or look at a different free row in the catalog.

Ling 3.0 Flash: what the successor offers

Ling 3.0 Flash is the markedly larger member of the same family: a 124-billion-parameter MoE running roughly 5.1 billion parameters per token. It is tuned for token efficiency in agentic workloads.

The context window and output ceiling are unchanged from Tiny, so code built around those two limits works as it is. What changes is the model size, the price, and the way you turn thinking off.

Ling 3.0 Tiny compared with Ling 3.0 Flash. Source: LLMTR model catalog, 24 August 2026.
PropertyLing 3.0 Tiny (retired)Ling 3.0 Flash
Total parameters7.9 billion124 billion
Active parameters1.3 billion per tokenRoughly 5.1 billion per token
Context window262,144 tokens262,144 tokens
Output ceiling32,768 tokens32,768 tokens
Input priceFree, daily quotaUSD 0.06 per 1M tokens
Cache readFree, daily quotaUSD 0.012 per 1M tokens
Output priceFree, daily quotaUSD 0.18 per 1M tokens
Turning thinking off`:fast` suffix`:none` suffix
StatusClosed at the providerActive

The two things that change in your code

The first is the model identifier: `inclusionai/ling-3.0-flash` in place of `inclusionai/ling-3.0-tiny`. The base URL, the client and the message format all stay the same.

The second is easy to miss: the mechanism for turning thinking off changes. On Tiny you did it with the `:fast` suffix, or by sending `reasoning` as `false` in the body. On Flash the mechanism is different: you need the `:none` suffix, or `reasoning_effort` set to `none`.

Carry the old `:fast` suffix over to Flash and you get a 400; the gateway names the supported levels in the response. That is deliberate: rather than passing a meaningless parameter to the provider and letting it be silently ignored, we prefer to refuse the request with a clear error.

Migration: the identifier and the thinking suffix change together

import os

from openai import OpenAI

client = OpenAI(
    base_url="https://llmtr.com/v1",
    api_key=os.environ["LLMTR_API_KEY"],
)

# OLD (now returns 410):
#   model="inclusionai/ling-3.0-tiny"        # thinking on
#   model="inclusionai/ling-3.0-tiny:fast"   # thinking off

# NEW: the identifier changed, and so did the suffix that turns thinking off.
response = client.chat.completions.create(
    model="inclusionai/ling-3.0-flash:none",   # thinking off
    messages=[{"role": "user", "content": "Label this support ticket in one word."}],
    max_tokens=32,
)

# For thinking on, send no suffix at all; it reasons by default.
analysis = client.chat.completions.create(
    model="inclusionai/ling-3.0-flash",
    messages=[{"role": "user", "content": "Assess the risks of this architectural decision."}],
    max_tokens=8192,
)

print(response.usage.completion_tokens, analysis.usage.completion_tokens)

Why does reasoning_effort offer only one level?

On many OpenAI-compatible models `reasoning_effort` is a five-step dial. On the Ling family it is not, and rather than assume, we measured.

The table below is a measurement taken on Ling 3.0 Tiny on 6 August 2026: the character length of the reasoning chain produced at each level. The result is not a dial, it is noise. The `low` level produces twice the reasoning of `high`, and an invalid value — "banana" — lands somewhere in the middle, which means the provider accepts the value and ignores it.

The only level that is real is `none`: it switches reasoning off. That is why Ling 3.0 Flash advertises only `none` in the catalog. Ask for any other level and the gateway returns a clear 400. We prefer that to forwarding it and answering 200 while nothing at all changes, because in that case you would believe the parameter worked.

Reasoning length produced per reasoning_effort level. Measured on Ling 3.0 Tiny, 6 August 2026.
reasoning_effort valueReasoning produced (characters)Reading
none0The only real level: switches reasoning off
minimal3,463No ordering
low30,239The longest reasoning — despite being "low"
medium21,878No ordering
high15,787About half of what "low" produced
xhigh13,582The highest level, among the shortest chains
"banana" (invalid)19,354An invalid value is accepted too
"" (empty)9,105An empty value is accepted too

Tool calling: forcing a named function really works here

Ling 3.0 Flash supports tool calling natively, and there is a detail in this family worth noting: all three uses of `tool_choice` worked in measurement. `auto`, `required`, and forcing one specific function by name all returned `finish_reason=tool_calls` with well-formed arguments.

That is not true of every model in the catalog. On the Tencent Hy3 and Nemotron 3 Ultra 262K deployments, for instance, forcing a named function is not reliable — the model may call whichever tool fits the prompt rather than the one you named. If your flow depends on a specific tool being called, that difference bears directly on which model you pick.

Prompt caching was measured too: a repeated prefix of roughly 30,000 tokens was served from cache from the second call onwards. With cache reads at a fifth of the input price, that makes a meaningful difference in flows built on a fixed system prompt.

  • `tool_choice: "auto"` — works.
  • `tool_choice: "required"` — works.
  • Forcing one named function — works on this model.
  • Schema-enforced JSON output — not supported.
  • Image and audio input — not supported.

Who should move to Flash, and who should look elsewhere?

If you were running Tiny in production and your workload is tool calling, long context or agent flows, Flash is its direct successor: same context window, same output ceiling, larger model. A million input tokens costs USD 0.06, so at small scale the cost is small too.

If you were using Tiny purely because it was free, the decision is different. No free successor remains at this provider, so you need to look at the other free rows in the catalog. Free rows are marked with a status badge in the model listing.

In both cases the model runs on third-party infrastructure outside Turkey. Prompts and completions may be logged by the provider; it is not an LLMTR model hosted in Turkey. For prompts containing personal data, consider the Turkey-hosted rows in the catalog instead.

Frequently asked questions

Why does Ling 3.0 Tiny return a MODEL_NOT_AVAILABLE error?

The provider withdrew the route. Confirmed on 18 August 2026: the row appears in the provider's model listing with a closed status code and no pricing, and a chat request answers 500 MODEL_NOT_AVAILABLE. Called through LLMTR you get a 410 that names the successor.

What should I use instead of Ling 3.0 Tiny?

inclusionai/ling-3.0-flash. It is the larger member of the same family: a 124B MoE with the same 262,144-token context window and the same 32,768-token output ceiling. Tiny was free; Flash is metered at USD 0.06 input and USD 0.18 output per 1M tokens.

Why are my requests not rerouted to Flash automatically?

Tiny was free and Flash is metered. A silent reroute would mean a user on a free quota learning about a price change from their invoice. The gateway therefore refuses the request, names the successor, and leaves the decision to you.

How do I turn thinking off on Ling 3.0 Flash?

Append the :none suffix to the model identifier, or send reasoning_effort as none in the request body. The :fast suffix from Tiny does not work on Flash; the mechanism is different and carrying the old suffix over returns a 400.

Why doesn't reasoning_effort accept low, medium or high?

In measurement those levels do not change reasoning length in any ordered way: low produced twice the reasoning of high, and even an invalid value was accepted. Since none is the only level with a real effect, the catalog advertises only that one and returns a clear 400 for the others.

Related posts