Talk to us

Only the PII,
in black.

Noir is a small LLM built for masking. It takes a document and an instruction saying what to mask, and returns a list of the places that match. Documents can be processed on in-house CPUs alone before they go out. As you scroll, a line of light sweeps across the documents.

JA担当の山田太郎です。お電話は03-0000-1234までお願いします。

ENPlease call Emily Carter at (555) 010-4477 before March 3.

DEFrau Anna Becker wohnt in der Lindenstraße 12, 10115 Berlin.

HRIvan Horvat (42 godine) javio je da je na bolovanju.

Size0.8B・0.67GB
Languages4 languagesJapanese, English, German, Croatian
Types masked48 types

* All sample texts, names and numbers are fictional. The animation above is a replayed sample.

Give the instruction
in plain words.

"Personal information." "Contact details." "But not age." Give the instruction the way you would normally say it, and the places masked change, even in the same document. Press a button, or just watch.

Subject: Confirming your contract, Example Trading

Mr. John Sample, General Affairs, Example Trading

Thank you as always for your business. This is Hannah Sanders of Nekodata Inc.

On Friday, November 20, I would like to talk with you about renewing your contract. The monthly fee stays at $480.

I heard that your contact, Mr. Ian Sullivan (age 42), is out today with back pain.

You can reach me at 212-555-0134 or [email protected].

Ship to: 123 Example Street, 5th Floor, Anytown, NY 10001

* This box is a sample of the behavior, replaying fixed answers (no actual model is running). All sample texts are fictional.

Less over-masking
than 120B.

On 100 documents each in Japanese and English, we gave gpt-oss-120b (117 billion parameters) the same instructions and compared the results. The sheets above are samples of each kind of mistake. The bars below show how often that mistake happened; shorter is better.

* Measured on a test we built ourselves (November 2026, Q4_K_M, combined with general-purpose rules for emails, phone numbers, URLs and dates). Detailed conditions are at the end of the page.

The vaguer the instruction,
the wider the gap.

We compare the number of misses on a balance scale. The side with more misses goes down. With instructions that clearly list the types, the two are even. With vague instructions like "personal information," or when "but not ..." is added, the gap widens.

Noir0%

gpt-oss-120b0%

* Japanese and English combined. Miss rate (%, 1 cell = 1%). Instructions by kind: 69 with types listed, 104 vague, 27 with an exception.

4 languages,
each with its own results.

There is a dedicated Noir for each language (Japanese and English share one). Yellow marks the figures that are better than gpt-oss-120b's.

  • For Croatian and German, the miss rate is about the same as gpt-oss-120b's. Most of the misses were European-style dates and times, such as "02.11.2026" and "14:12 Uhr."
  • By our estimate, adding two rules that catch dates and times in this form brings the miss rate down from 31% to 23% for Croatian and from 25% to 15% for German, below gpt-oss-120b (24% and 19%). We plan to build this into the product. planned

What comes back
is JSON.

Noir returns the places it found as a list, with mentions of the same thing grouped together. The strings are exactly as written in the document, so you can search the text for them and replace them as they are.

We will send this to your contact, Mr. Ian Sullivan.
Mr. Sullivan's phone is 212-555-0134,
and his email is [email protected].
  • id: The same person or thing is grouped into one ("Ian Sullivan" and "Sullivan").
  • type: The name of one of the 48 labels. It comes back in the language of the prompt ("person name" in English).
  • mentions: The strings exactly as written in the document. If nothing matches, [].
Find everything in the document below that
matches the target. … (omitted)
Output a JSON array only: [{"id": "E1",
 "type": "...", "mentions": ["..."]}]
Target:
PII, except age
Mode: redact: do not include "replacements".

Document:
(document goes here)

One document,
about 20 seconds.

On a laptop CPU (no GPU), this replays everything from reading a document of about 900 characters to returning the places to mask. Playback is at 5x speed; the clock shows the real seconds.

0.0splaying at 5x speed

Read the documentWrite the places to mask

Places masked 0 / 0

Instruction
person name, phone number, email address, street address
Reading
About 140 tokens/s
Writing
About 24 tokens/s
Hardware
Core i7-11800H, 8 threads

  • Working through documents one by one at this speed, a single machine handles about 170,000 characters an hour.
  • With 16 processed at a time on a GPU, 100 documents took about 20 seconds (gpt-oss-120b: about 90 seconds). measured in-house

* The document and the masked places are samples (no model is running on this page). The time is calculated from the reading and writing speeds we measured in-house. Different ways of referring to the same person are grouped into one and masked together.

Cut it up,
1,000 characters at a time.

Long documents are cut into chunks of about 1,000 characters and passed in one at a time. Matching the length seen in training means fewer misses. At the end, the results are put together and combined with rules that catch the fixed formats of emails, phone numbers, URLs and dates.

Launch (llama.cpp)

llama-server -m noir-ja-en-Q4_K_M.gguf \
  -c 16384 -t 8 -np 1 --jinja --port 8191

ReleasedDownload the weights →

  • Use it with thinking mode off (enable_thinking: false) and temperature 0.
  • Choose the model by language: ja-en for Japanese and English, de-en for German, hr-en for Croatian.
  • On a CPU (Core i7-11800H, 8 threads), a 1,000-character chunk takes about 20 seconds. measured in-house

One instruction changes
what gets masked.

Pick an instruction and try it on a sample document. Change the instruction, and the places masked change, even in the same document. You can also see the prompt sent to the model and the JSON that comes back, exactly as they are.

1Choose a document

2Choose an instructionRuns as soon as you choose

Or pick the types yourself

Prompt sent to the model

JSON returned

[]

How we measured.
Then, let's talk.

  • Documents: 100 each in Japanese, English, German and Croatian. They are fictional documents written for testing, such as emails, meeting minutes, HR memos, invoices and medical records, with the places that should be masked marked as the correct answers.
  • Instructions: one of three kinds per document: types listed, vague wording, or with an exception. We gave gpt-oss-120b (reasoning effort medium) the same prompt.
  • Measures: misses = the share of correct answers left unmasked; over-masking = the share of masked places that didn't need masking; off-target = the share of masks on types outside the instruction.
  • Conducted: November 2026, Q4_K_M. To be reviewed before the official release.

Try it on your documents →

Run Noir on your own machine

One zip with the model weights, sample inference code and a short manual. Unzip it, follow the README, and it runs.

Download the zipcatsai-noir.zip · 672 MBHugging Face: catsaiagency/Noir-0.8B-ja-en-GGUF →

Licence

The Noir model comes under the CatsAI Model License. The five main points:

  • Trying it is free, on any machine: a PC or a server.
  • Using it for actual work needs a paid licence for each machine the model is installed on. A development PC counts too, if it is used for actual work.
  • Personal, educational and academic research use is free.
  • The licence covers the model weights only. The sample code stays open source.
  • You may redistribute and fine-tune the model. The same licence then still applies.
Full licence terms (PDF)EnglishAsk about a licence →

This is a summary. The full text in the PDF is what counts.

DEMO | Own-test figures, rest placeholder