# The first uncensored Inkling 2 Small: five hours from release to API, and how we did it

_2026-11-13. Thinking Machines released Inkling 2 Small at 3:50 pm. By 8:43 pm our uncensored version was on Hugging Face and live on our API. The hour by hour timeline, how we removed the refusals from a 594B mixture of experts model without losing MMLU, what broke, and how we serve it._

Thinking Machines announced **Inkling 2 Small** at 3:50 pm Eastern on November 12: an open weights model
(Apache 2.0) with 594 billion parameters, 17 billion active per token, image input and a 1M token context. Five hours
later, our uncensored version was on Hugging Face and answering requests on our API.

As of November 13 we have not found another uncensored Inkling 2 Small, on Hugging Face or on any API. The uncensored
Inkling builds on Hugging Face are of the older Inkling and Inkling Small models. OpenRouter serves the original
Inkling 2 Small, with its refusals.

- **Weights:** [OpenUncensored/Inkling-2-Small-Uncensored](https://huggingface.co/OpenUncensored/Inkling-2-Small-Uncensored)
- **API model id:** `inkling-2-small-uncensored`
- **Try it in the browser:** the [playground](https://openuncensored.com/chat?model=inkling-2-small-uncensored), or the free
  [Hugging Face Space](https://huggingface.co/spaces/OpenUncensored/Inkling-2-Small-Uncensored-Chat) with your own key

## Release day, hour by hour

All times US Eastern, November 12.

| Time | What happened |
|---|---|
| 3:50 pm | Thinking Machines announces Inkling 2 Small |
| 5:33 pm | Download, GPU worker and experiment scripts ready |
| 6:02 pm | Serving starts in parallel: our own deployment on four B300 GPUs, hidden |
| 6:52 pm | Serving fix: a library bug that broke the model across GPUs, patched |
| 7:21 pm | Refusal directions found, best edit picked, first MMLU check |
| 7:30 pm | Thinking mode checked: no refusals either |
| 7:56 pm | Edit written into the weights, checks run on the new files |
| 8:16 pm | Weights uploaded to Hugging Face |
| 8:38 pm | Our GPUs switch from the original weights to the uncensored ones |
| 8:43 pm | Live on the API for everyone |

Two things made it fast. Removing the refusals and getting the model served ran side by side, so the API was ready
the moment the weights were. And the experiments never waited on the model to load.

## How we removed the refusals

Inkling 2 Small is a mixture of experts model: 48 layers, 384 experts per layer, 8 of them used for each token. We
started from Thinking Machines' MXFP8 checkpoint, about 600 GB.

**One worker, many small experiments.** A GPU worker on eight H200s loads the model once and keeps it in memory. Each
experiment is a short script dropped into a folder, which the worker picks up and runs. Trying an idea takes minutes
instead of another half hour of loading 600 GB.

**1. Find where refusals live.** We ran 256 harmful and 256 harmless prompts and recorded each layer's output at the
last prompt token. The difference between the two averages, per layer, points in the direction the model uses to
decide to refuse. We did this with thinking off and with thinking at 0.9, and the two agree closely in the middle
layers (cosine similarity 0.8 to 0.95).

**2. Reduce them to two directions.** The top two singular vectors of those per-layer directions, over layers 9 to
47, give one small refusal subspace, `Q`.

**3. Remove it from what each layer writes.** That means the attention output and the output of **every one of the 384
experts** in each layer: `W' = W - 1.5 Q Qᵀ W` on layers 9 to 47. We edit every expert because the router can
send any token to any of them.

**4. Test before touching the weights.** During the search we applied the edit live, with hooks on those same
outputs, which gives exactly the same result as editing the weights. A small grid (one or two directions, strength
1.0 or 1.5), scored on 80 test prompts, picked the edit, and MMLU confirmed it cost almost nothing.

**5. Write it into the weights.** The expert weights are stored in MXFP8, 8-bit numbers with one shared scale for
every 32 values. We decoded them, applied the edit, and encoded them back with stochastic rounding, so the small
change is not rounded straight back to the original values. Everything else is byte for byte the original: the vision
encoder, the embeddings, the routers. The files are the same format and size as Thinking Machines', so the model runs
anywhere the original runs.

**6. Measure the files we ship.** Every number below comes from the published weights, with no hooks.

| | Inkling 2 Small | **Uncensored** |
|---|---|---|
| Refusals on 32 harmful prompts, thinking off | 31 | **0** |
| Refusals on 32 harmful prompts, thinking on | 32 | **0** |
| Refusals on 80 prompts (32 harmful, 48 gray area) | 62 | **3** |
| MMLU (1,140 questions, 20 from each of 57 subjects) | 90.44% | **90.35%** |

The 3 left are not refusals but real limits: it can't produce a video file, can't read your contacts, and says one
medical question needs a clinical evaluation. With 32 to 80 prompts per test, treat differences of a few prompts as
noise. Long agent tasks and coding benchmarks are not measured yet.

## What tripped us up

- **Too new for the libraries.** The released `transformers` didn't include the model yet, so we ran it from
  `main`.
- **Missing tokens.** The tokenizer has no padding or end token set. Without them, batches broke and generation never
  stopped.
- **It always thinks.** Even with thinking off, the model reasons briefly before it answers, so asking for "A, B, C
  or D" didn't give a clean letter. We scored MMLU from the probability of each answer letter instead.
- **Curly apostrophes.** Some refusals said "I can’t" with a typographic apostrophe, which our first refusal counter
  missed.
- **Memory.** Scoring 48 prompts at once ran out of GPU memory. 12 at a time, keeping only the last token's
  probabilities, fit.

## How we serve it

Most uncensored models on OpenUncensored run on partner providers. Nobody served this one, so we run it ourselves:
vLLM on four B300 GPUs, which hold the 600 GB of weights with room for long conversations.

- **A serving fix.** A library version in the official serving image broke communication between the four GPUs for
  this model, so we patched it into our own image.
- **No idle GPUs.** The GPUs shut down when nobody is using them, and starting again takes 13 to 30 minutes. While they
  start, requests are answered by DeepSeek V4.1 Flash 1017 Uncensored, and the `X-OU-Model` response header names the
  model that answered. Once the GPUs are warm, requests go to Inkling.
- **Price:** $0.60 per million input tokens and $2.40 per million output tokens.

## Call it

Same OpenAI compatible API and key as every other model here.

```bash
curl https://api.openuncensored.com/v1/chat/completions \
  -H "Authorization: Bearer $OU_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "inkling-2-small-uncensored", "messages": [{"role": "user", "content": "Explain SQL injection with an example."}]}'
```

```python
from openai import OpenAI
client = OpenAI(base_url="https://api.openuncensored.com/v1", api_key="ou-...")
r = client.chat.completions.create(model="inkling-2-small-uncensored", messages=[{"role": "user", "content": "Hello"}])
print(r.choices[0].message.content)
```

It reads images, calls tools, and returns its reasoning separately. Set `reasoning_effort` to `"none"` for direct
answers. No account needed: buy a prepaid key at [openuncensored.com/credits](https://openuncensored.com/credits). More on the API in the
[launch post](https://openuncensored.com/blog/inkling-2-small-uncensored-api).

## Thanks

Credit for the model goes to Thinking Machines, for releasing it with open weights under Apache 2.0. The method builds
on refusal-direction research by Arditi et al. and the abliteration work of the open model community.