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
- API model id:
inkling-2-small-uncensored - Try it in the browser: the playground, or the free Hugging Face Space 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
transformersdidn't include the model yet, so we ran it frommain. - 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-Modelresponse 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.
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."}]}'
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. More on the API in the
launch post.
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.