dart_sentencepiece_tokenizer
A lightweight, pure Dart implementation of SentencePiece tokenizer. Supports BPE (Gemma) and Unigram (Llama) algorithms.
1.3.2
13K downloads/mo
#2618 most downloaded on pub.dev
brody-0125/dart_sentencepiece_tokenizer
What this package is like to depend on
Last release 4 months ago
07 Apr 2026
Release timing varies
gaps range from 1 weeks to 2 months
Nearly every release is documented
notes for 8 of 8 stable releases
Nothing withdrawn
no release was ever pulled
7 months old
8 releases · first in 2026
8 releases in the last 12 months
see the full history below
Release timeline
8 releases · Jan 2026 to Apr 2026Releases
latest 8-
1.3.207 Apr 2026Release notes
Open source →What's New
GitHub Actions CI Pipeline (#19)
Automated continuous integration is now configured for the project:
- Analyze job — Enforces
dart formatconsistency anddart analyze --fatal-infoswith zero tolerance for warnings. - Test job — Runs the full test suite across a matrix of Dart stable and Dart 3.10.7 (minimum supported SDK version).
- Minimal permissions (
contents: read) and concurrency groups to cancel stale runs.
Improvements
- Code formatting — Applied
dart formatto 23 source files for consistent code style across the codebase. - Static analysis cleanup — Resolved all
dart analyze --fatal-infosissues:- Removed deprecated
avoid_returning_null_for_futurelint rule. - Added curly braces to
ifstatements,constconstructors, andfinallocal variables where required.
- Removed deprecated
- Documentation (#21) — Added inline comments clarifying
google/sentencepieceproto spec compliance for default token IDs (unkId=0,bosId=1,eosId=2,padId=-1).
Notes
This is a maintenance release with no API changes or breaking changes. Focus: CI infrastructure, code hygiene, and documentation clarity.
Full Changelog: v1.3.1...v1.3.2
Release notes
Open source →Added
- GitHub Actions CI Pipeline (#9, #19)
analyzejob -dart format --set-exit-if-changedanddart analyze --fatal-infostestjob - Matrix testing across Dart stable and 3.10.7 (minimum supported version)- Minimal permissions (
contents: read) and concurrency group to cancel stale runs
Changed
- Applied
dart formatto 23 files for consistent code style - Resolved all
dart analyze --fatal-infosissues- Removed deprecated
avoid_returning_null_for_futurelint rule - Added curly braces to if statements,
constconstructors,finallocal variables
- Removed deprecated
- Added documentation comments clarifying
google/sentencepieceproto spec compliance for default token IDs (unkId=0, bosId=1, eosId=2, padId=-1) (#20)
- Analyze job — Enforces
-
1.3.103 Apr 2026Release notes
Open source →Load HuggingFace tokenizers directly from
tokenizer.json— no conversion step required.What's New
HuggingFace
tokenizer.jsonFormat SupportYou can now load any HuggingFace
tokenizer.jsonfile without converting it to SentencePiece.modelformat first. This makes it straightforward to use tokenizers published on the HuggingFace Hub.// Load from file final tokenizer = await HuggingFaceTokenizerLoader.fromJsonFile('tokenizer.json'); // Load from a pre-parsed map final tokenizer = HuggingFaceTokenizerLoader.fromMap(jsonMap); // Auto-detection — works transparently with TokenizerJsonLoader final tokenizer = await TokenizerJsonLoader.fromJsonFile('tokenizer.json');
Supported model types:
- Unigram — Llama, T5, ALBERT, XLNet, and other Unigram-based models
- BPE — Gemma, GPT-2, RoBERTa, and other BPE-based models
Automatic configuration inference:
- Special tokens (
unk,bos,eos,pad) are detected from theadded_tokenssection - Normalizer settings (
addDummyPrefix,escapeWhitespaces) are inferred from the HuggingFace normalizer config - Post-processor flags (
addBosToken,addEosToken) are parsed fromTemplateProcessing - Byte fallback behavior is detected from the decoder configuration
- Tokens beyond the base vocabulary are handled automatically
Format detection:
TokenizerJsonLoader.isHuggingFaceFormat()lets you check whether a JSON map uses the HuggingFace format. When you callTokenizerJsonLoader.fromJsonFile(), HuggingFace format is detected and delegated automatically — no code changes needed if you already useTokenizerJsonLoader.Install / Upgrade
dependencies: dart_sentencepiece_tokenizer: ^1.3.1
Full Changelog: https://github.com/brody-0125/dart_sentencepiece_tokenizer/blob/develop/CHANGELOG.md
Release notes
Open source →Added
- HuggingFace
tokenizer.jsonFormat SupportHuggingFaceTokenizerLoaderclass for loading HuggingFace tokenizer.json files directlyfromJsonString()/fromMap()- Parse from JSON string or pre-parsed mapfromJsonFile()/fromJsonFileSync()- Load from file (async/sync)
- Supports both Unigram (Llama) and BPE (Gemma) model types
- Automatic detection of special tokens (unk, bos, eos, pad) from
added_tokenssection - Normalizer settings inference (addDummyPrefix, escapeWhitespaces) from HuggingFace normalizer config
- Post-processor configuration parsing (addBosToken, addEosToken) from TemplateProcessing
- Byte fallback detection from decoder configuration
- Added tokens handling beyond base vocabulary
TokenizerJsonLoader.isHuggingFaceFormat()- Helper to detect HuggingFace format- Auto-detection in
TokenizerJsonLoader- Automatically delegates toHuggingFaceTokenizerLoaderwhen HuggingFace format is detected
-
1.3.002 Feb 2026Release notes
Open source →What's Changed
- feat: add HuggingFace TextStreamer compatible streaming API by @brody-0125 in #8
Full Changelog: 1.2.2...1.3.0
Release notes
Open source →Added
- Streaming API (HuggingFace TextStreamer Compatible)
BaseStreamer- Abstract interface for streaming token decoders withput()andend()methodsTextStreamer- HuggingFace TextStreamer-compatible class for real-time LLM token decodingput(int tokenId)- Add tokens as they are generatedend()- Signal end of generation and flush remaining contentonFinalizedTextcallback for custom text handlingskipSpecialTokensoption to filter BOS/EOS/PAD tokensskipPromptoption to skip initial prompt tokenspromptLengthoption to skip multiple prompt tokens- Word boundary heuristics for clean text emission (newlines, CJK, spaces)
SentencePieceTokenizer.createTextStreamer()- Factory for TextStreamerSentencePieceTokenizer.decodeStream()- Stream-based token decodingSentencePieceTokenizer.decodeWithCallback()- Callback-based token decoding
Usage Examples
TextStreamer (HuggingFace-compatible):
final streamer = tokenizer.createTextStreamer(); for (final id in llmOutput) { streamer.put(id); } streamer.end(); // With custom callback final streamer = tokenizer.createTextStreamer( onFinalizedText: (text, {required streamEnd}) { myTextController.append(text); if (streamEnd) myTextController.complete(); }, );Stream-based decoding:
final textStream = tokenizer.decodeStream(llmTokenStream); await for (final chunk in textStream) { stdout.write(chunk); }Callback-based decoding:
tokenizer.decodeWithCallback( tokenIds, (chunk) => stdout.write(chunk), ); -
1.2.228 Jan 2026Release notes
Open source →What's Changed
- feat: optimize memory usage and refactor tests for v1.2.2 by @brody-0125 in #7
Full Changelog: 1.2.1...1.2.2
Release notes
Open source →Changed
- Extracted duplicate surrogate pair decoding logic in
Trieinto shared_decodeCodePointhelper - Cached computed
sequenceIdsinEncodingto avoid O(n) recomputation on repeated access - Added merge cache size limit (10,000 entries) to
BpeAlgorithmandBpeAlgorithmOptimizedto prevent unbounded memory growth - Replaced manual loops with
fillRangefor padding initialization inEncoding.withPadding()
-
1.2.127 Jan 2026Release notes
Open source →What's Changed
- feat: add JSON Serialization API, Dynamic Token Addition API and Optimized BPE Algorithm by @brody-0125 in #5
Full Changelog: 1.2.0...1.2.1
Release notes
Open source →Changed
- Optimized batch
addTokens()to use single typed array allocation instead of per-token expansion (O(N) instead of O(N²)) - Added input validation and defensive error handling in JSON deserialization (
TokenizerJsonLoader) - Consolidated duplicate
_kMaxInputLengthconstant declarations
-
1.2.017 Jan 2026Release notes
Open source →Added
-
JSON Serialization - HuggingFace-compatible tokenizer.json format
toJson()- Serialize tokenizer to JSON stringsaveToJson()/saveToJsonSync()- Save to fileTokenizerJsonLoader.fromJsonString()- Load from JSON stringTokenizerJsonLoader.fromJsonFile()/fromJsonFileSync()- Load from file
-
Dynamic Token Addition API
addTokens(List<String>)- Add new tokens to vocabularyaddSpecialTokens(Map<String, String>)- Add special tokens (pad, mask, etc.)getAddedVocab()- Get map of dynamically added tokensisAddedToken(String)- Check if token was added dynamicallygetVocab({withAddedTokens})- Get full vocabulary as Map<String, int>
-
HuggingFace-compatible Methods
tokenize(String)- Returns List<String> of tokenstokenizeBatch(List<String>)- Batch tokenization
-
Optimized BPE Algorithm (
BpeAlgorithmOptimized)- O(n log n) complexity using priority queue (heap)
- ~35% faster than original algorithm on medium-length text
Changed
SpVocabularynow uses growable list for dynamic token addition support
-
-
1.1.003 Jan 2026Release notes
Open source →What's Changed
- feat: improve BPE Algorithm by @brody-0125 in #1
- feat: improve BPE Algorithm (#1) by @brody-0125 in #2
- feat: add JSON Serialization API, Dynamic Token Addition API and Optimized BPE Algorithm by @brody-0125 in #3
Full Changelog: 1.0.0...1.2.0
Release notes
Open source →Added
- Input length validation (max 500,000 characters) to prevent OOM
- Example usage file (
example/example.dart)
Changed
- Improved BPE algorithm efficiency
- Enhanced error messages for input validation
-
1.0.002 Jan 2026Release notes
Open source →Release notes
Open source →Added
- Initial release of dart_sentencepiece_tokenizer
- Pure Dart implementation with zero external dependencies
- Support for BPE (Byte Pair Encoding) algorithm used by Gemma models
- Support for Unigram algorithm used by Llama models
- Viterbi algorithm implementation for optimal Unigram segmentation
- Byte fallback support for handling unknΩown characters
- Unicode-aware Trie for efficient vocabulary lookup
- Memory-efficient typed arrays (Int32List, Uint8List) for encodings
Features
-
SentencePieceTokenizer- Main tokenizer classfromBytes()- Load from protobuf bytesfromModelFile()/fromModelFileSync()- Load from .model fileencode()- Encode single textencodeBatch()- Encode multiple textsencodeBatchParallel()- Parallel batch encoding using IsolatesencodePair()- Encode text pairs for sequence classificationencodePairBatch()- Batch encode text pairsdecode()/decodeBatch()- Decode token IDs back to text
-
Encodingclass with:ids- Token IDs (Int32List)tokens- Token stringstypeIds- Segment type IDs (Uint8List)attentionMask- Attention mask (Uint8List)specialTokensMask- Special token indicators (Uint8List)offsets- Character offsets for each tokenwithPadding()/withTruncation()- Post-processing methodstruncatePair()- Static method for pair truncation
-
Predefined configurations:
SentencePieceConfig.llama- Llama-style (BOS only)SentencePieceConfig.gemma- Gemma-style (BOS + EOS)
-
Truncation strategies:
longestFirst- Truncate longer sequence firstonlyFirst- Only truncate first sequenceonlySecond- Only truncate second sequencedoNotTruncate- No truncation
-
Padding options:
- Left/right padding direction
- Fixed length or pad to longest
- Pad to multiple of N
Performance
- Efficient Trie-based vocabulary lookup
- Memory-optimized typed arrays reduce memory usage by ~78%
- Parallel batch processing with configurable chunk size
- Lazy evaluation where possible
Compatibility
- Dart SDK 3.10.7+
- Compatible with Llama, Gemma, and other SentencePiece models
- HuggingFace-compatible API design