Starlings.Tokenizers 0.3.2

dotnet add package Starlings.Tokenizers --version 0.3.2
                    
NuGet\Install-Package Starlings.Tokenizers -Version 0.3.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Starlings.Tokenizers" Version="0.3.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Starlings.Tokenizers" Version="0.3.2" />
                    
Directory.Packages.props
<PackageReference Include="Starlings.Tokenizers" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Starlings.Tokenizers --version 0.3.2
                    
#r "nuget: Starlings.Tokenizers, 0.3.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Starlings.Tokenizers@0.3.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Starlings.Tokenizers&version=0.3.2
                    
Install as a Cake Addin
#tool nuget:?package=Starlings.Tokenizers&version=0.3.2
                    
Install as a Cake Tool

Starlings.Tokenizers

Hugging Face tokenizer.json files in pure .NET, with the same token ids, offsets and decoded text as the Python and Rust tokenizers library, checked case by case.

using Starlings.Tokenizers;

Tokenizer tokenizer = Tokenizer.FromFile("tokenizer.json");
TokenEncoding encoding = tokenizer.Encode("Hello, world!");
string text = tokenizer.Decode(encoding.Ids.AsSpan(), skipSpecialTokens: true);
  • Faithful. Every supported tokenizer has a profile: a pinned tokenizer.json (full commit SHA and SHA-256) with reference outputs from huggingface/tokenizers for multilingual text, emoji, combining marks, control characters, pairs, truncation and padding. CI fails on any difference.
  • Explicit. A tokenizer.json that uses a component this library does not implement fails at load with UnsupportedTokenizerComponentException, naming the JSON path. Nothing is approximated, and unknown fields are rejected rather than ignored.
  • Plain .NET. No native code, no package dependencies, net10.0. Instances are immutable and thread-safe. A 17 MB vocabulary loads in about 0.27 s, about half the time the Rust library takes on the same machine.

Part of Starling, .NET implementations of AI models with reproducible evidence of what works.

0.x. The public API can still change between minor versions. A profile's status is in its file under profiles/; the Starling model profiles that use a profile pin the exact tokenizer version they were qualified with.

Install

dotnet add package Starlings.Tokenizers

Usage

using Starlings.Tokenizers;

Tokenizer tokenizer = Tokenizer.FromFile("tokenizer.json")            // also FromStream, FromUtf8Json
    .WithTruncation(new TruncationOptions(MaxLength: 512))
    .WithPadding(new PaddingOptions(PadId: 1, PadToken: "<pad>"));      // no FixedLength: pad to the batch's longest

TokenEncoding one = tokenizer.Encode("query: how much protein should a female eat");
TokenEncoding pair = tokenizer.Encode("What is the capital of France?", "Paris is the capital of France.");
IReadOnlyList<TokenEncoding> batch = tokenizer.EncodeBatch(["first text", "second, longer text"]);

int[] ids = [.. one.Ids];                    // also Tokens, TypeIds, AttentionMask, SpecialTokensMask, SequenceIds
TokenOffset span = one.Offsets[1];           // UTF-16 code units: slice the C# string with these
TokenOffset scalars = one.ScalarOffsets[1];  // Unicode scalar values: the unit Python tokenizers reports

string decoded = tokenizer.Decode(one.Ids.AsSpan(), skipSpecialTokens: true);
int? eos = tokenizer.TokenToId("</s>");
  • WithTruncation and WithPadding return new instances that share the loaded pipeline. Without them, the file's own truncation and padding sections apply.
  • Encode(text, addSpecialTokens: false) skips the post-processor's special tokens. Special tokens written in the input text are still matched as added tokens.
  • Input containing unpaired UTF-16 surrogates is rejected with ArgumentException.
  • tokenizer.Components lists the pipeline stages the file uses, for example model:BPE.

Supported tokenizers

A model is supported when its tokenizer.json uses only supported components. A profile is the evidence: one pinned file and the cases it matches.

Profile Model Algorithm Evidence
xlmr-unigram-e5 intfloat/multilingual-e5-small SentencePiece Unigram 49/49 cases exact, with truncation and padded batch
gliner2-base-v1-unigram fastino/gliner2-base-v1 SentencePiece Unigram (DeBERTa-v3) per-word and 10 whole-text cases; offsets, pairs and decode untested
qwen2-bpe-kev jaredpalmer/kev-0.8b (Qwen2/Qwen3 regex) byte-level BPE 137/137 cases exact, 0 mismatches in 1.15 M randomized encodes
qwen35-bpe-chat Qwen/Qwen3.5-0.8B byte-level BPE 137/137 cases exact, 0 mismatches in 1.15 M randomized encodes
gemma-bpe-embeddinggemma2 google/embeddinggemma-2 SentencePiece-style BPE, byte fallback 49/49 cases exact, 0 mismatches in 1.7 M randomized encodes

All five are experimental. BERT-family WordPiece files (for example sentence-transformers/all-MiniLM-L6-v2 and BAAI/bge-small-en-v1.5) load and pass component-level reference cases, but have no profile yet. Other files may load and work too. Without a profile, matching the reference is untested, not promised.

The full list of components and options, and what fails at load, is in docs/supported-components.md. Not offered: pre-tokenized input, word ids, overflowing windows (truncation stride), incremental (streaming) decode, and chat templates.

Need a tokenizer that is not here? Open a tokenizer request with the error Tokenizer.FromFile gives you.

Documentation

Page Contents
Supported components Every tokenizer.json component and option, byte fallback and regex details
Adding a tokenizer From a new model's tokenizer.json to a released profile
Architecture How the interpreter is built and where each stage lives
Performance Load and encode measurements against the Rust library
Releasing Versions, the tag-to-NuGet workflow, one-time setup
Changelog What changed in each version
llms.txt A compact guide for language models and coding assistants using this library

Contributing

See CONTRIBUTING.md. Coding agents should read AGENTS.md first.

License

Copyright (c) 2026 StarlingHq. Licensed under either of

at your option. Use it in open-source or commercial software, modify it, and ship it without releasing your own code. Apache-2.0 adds an explicit patent grant. Unless you state otherwise, any contribution you submit for inclusion is dual-licensed the same way, with no additional terms.

Some files are ported or adopted from huggingface/tokenizers, SentencePiece and spm_precompiled (Apache-2.0), dotnet/machinelearning (MIT), darts-clone (BSD 2-Clause), serde_json and unicode-normalization-alignments (MIT OR Apache-2.0), and Unicode data (Unicode License V3). All of these are permissive, and none of them adds conditions beyond keeping their notices. The notices are in THIRD-PARTY-NOTICES.md, which ships inside the package, so distributing the package as-is satisfies them. File-by-file origins are in PROVENANCE.md. Each model's tokenizer.json keeps its owner's terms and is never included in the package.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on Starlings.Tokenizers:

Package Downloads
Starlings.Generation.OnnxGenAI

Text generation on ONNX Runtime GenAI 0.17.1 behind a Starling adapter: model loading with explicit provider selection (no silent fallback, TF32 off by default), runtime config overlays, reference-counted disposal, and an owned decode loop over pre-tokenized ids (greedy or seeded sampling, max new tokens, stop token ids and stop strings, streaming with UTF-8-safe incremental detokenization through the owned tokenizer Starlings.Tokenizers, cancellation between decode steps, usage accounting). References only Microsoft.ML.OnnxRuntimeGenAI.Managed: the application adds Microsoft.ML.OnnxRuntimeGenAI (CPU) or Microsoft.ML.OnnxRuntimeGenAI.Cuda. Maturity is per model profile (Stable, Preview or Experimental): see the README, generated from the model registry.

Starlings.Models.Qwen35

Qwen/Qwen3.5-0.8B (revision 2fc06364) chat generation in-process on ONNX Runtime GenAI 0.17.1: the pinned chat template rendered in C# for text and tool-calling conversations (system, user, assistant and tool messages, tool definitions and calls, thinking switch; images rejected), a parser for the template's tool-call format (whole or streamed), prompt ids from the owned tokenizer (Starlings.Tokenizers profile qwen35-bpe-chat: no Microsoft.ML.Tokenizers, no GenAI tokenizer), and Starling's decode loop (greedy or seeded sampling, stop tokens and strings, streaming, cancellation between steps, usage). Ships the asset lock, not the weights. Profiles qwen3.5-0.8b/ortgenai-fp32x (CPU; CUDA with TF32 off) and ortgenai-fp16x (CUDA), Linux x64, Stable. The application adds Microsoft.ML.OnnxRuntimeGenAI or Microsoft.ML.OnnxRuntimeGenAI.Cuda. Maturity is per model profile (Stable, Preview or Experimental): see the README, generated from the model registry.

Starlings.Models.EmbeddingGemma2

google/embeddinggemma-2 (revision 914f7f89) text and image embeddings on ONNX Runtime, from text through the owned tokenizer (Starlings.Tokenizers, profile gemma-bpe-embeddinggemma2: no Microsoft.ML.Tokenizers, no native tokenizer) or from token ids: right-padded batching, mean pooling over every token including the prompt, L2 normalization, Matryoshka sizes 768/512/256/128, explicit named prompts (never added silently), inputs above 8,192 tokens rejected. Images: image-only and interleaved text-and-image embeddings from already-decoded RGB (no native dependency; the upstream processor restated bit for bit, including PyTorch's uint8 antialiased bicubic resize), default budget 280 soft tokens, vision graph plus multimodal text graph; text-only input keeps the released text graph. Videos: video-only and interleaved text/image/video embeddings from decoded RGB frames at the checkpoint settings (1 fps, at most 32 frames, 140 soft tokens per frame, no timestamps; upstream sampling restated exactly; frames without timing rejected unless opted in), same graphs; decoding is the optional FFmpeg adapter. Audio is not supported. Ships the asset locks (Starling's ONNX graphs and the pinned tokenizer.json), not the weights; acquire them explicitly. Profiles embeddinggemma-2/onnx-fp32-cpu, onnx-fp32-cuda, image-fp32-cpu, image-fp32-cuda, video-fp32-cpu and video-fp32-cuda (Linux x64). Apache-2.0 weights; deployments must adhere to the Gemma Prohibited Use Policy. The application adds the ONNX Runtime native package. Maturity is per model profile (Stable, Preview or Experimental): see the README, generated from the model registry.

Starlings.Models.E5

intfloat/multilingual-e5-small (revision 614241f6) sentence embeddings on ONNX Runtime, from text through the owned tokenizer (Starlings.Tokenizers: no Microsoft.ML.Tokenizers, no native tokenizer) or from token ids: right padding, mean pooling, L2 normalization. Ships the model's asset lock, not the weights; acquire them explicitly. Profiles multilingual-e5-small/onnx-fp32-cpu and onnx-fp32-cuda. The application adds the ONNX Runtime native package. Maturity is per model profile (Stable, Preview or Experimental): see the README, generated from the model registry.

Starlings.Models.Gliner2

fastino/gliner2-base-v1 (revision f9634218, GLiNER2 2.0.0) English entity extraction with labels and a threshold on ONNX Runtime: GLiNER2's Python text semantics (normalization, word splitter, lower-casing) and schema prefix through the owned tokenizer (Starlings.Tokenizers: no Microsoft.ML.Tokenizers, no native tokenizer), one ONNX graph, GLiNER2's span decoding, offsets into the original text. Ships the asset lock, not the weights; acquire them explicitly. Profiles gliner2-base-v1/onnx-fp32-cpu and onnx-fp32-cuda. The application adds the ONNX Runtime native package. Maturity is per model profile (Stable, Preview or Experimental): see the README, generated from the model registry.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.2 88 10/21/2026
0.3.2-preview.1 41 10/21/2026
0.3.1 118 10/19/2026
0.3.1-preview.1 47 10/19/2026
0.3.0 799 10/17/2026
0.3.0-preview.1 1,774 10/13/2026