✨ Unified encode API across transformer models
The transformer model bundles — Bert, ModernBert, NomicBert, Qwen3, Roberta, XLMRoberta, and now Clip — share a single EncodeOptions struct on encode / batchEncode:
var options = EncodeOptions.bert
options.postProcess = .meanPool(normalize: true)
options.computePolicy = .cpuOnly
let encoded = try modelBundle.encode("The cat is black", options: options)EncodeOptions consolidates the previously per-model parameters:
maxLength— max tokens per input sequencepadTokenId— padding id forbatchEncode(nil→ model's own id)postProcess— pooling strategycomputePolicy—MLComputePolicyfor the underlyingMLTensorwork
🤖 Pooling & max-length derived from sentence-transformers config
When you don't pass options, each bundle uses its defaultEncodeOptions, now derived at load time from a model's sentence-transformers layout when present:
modules.json1_Pooling/config.jsonsentence_*_config.json(transformer config)- tokenizer
model_max_length
This means sentence-transformers models are pooled correctly out of the box — e.g.:
nomic-ai/nomic-embed-text-v1.5→.meanPool(normalize: false)nomic-ai/modernbert-embed-base→.meanPool(normalize: true)
For plain checkpoints with no such config, bundles fall back to a per-model static default (.bert, .modernBert, .nomicBert, .qwen3, .roberta, .xlmRoberta, .clip).
🔧 Other changes
ClipadoptedEncodeOptionsfor a consistent API; its pooling stays fixed (EOS token → projection → L2 normalize), sopostProcessis ignored.- CLI commands updated to the unified API.
- README updated to document
EncodeOptions, pooling, and thesentence-transformersauto-derivation.
⚠️ Breaking changes
encode/batchEncodeon the transformer (andClip) bundles now take a singleoptions: EncodeOptions?argument instead of individual parameters (maxLength,padTokenId,postProcess,computePolicy). Migrate by constructing anEncodeOptions(or starting from a static default /bundle.defaultEncodeOptions) and setting the fields you need.- Embedding-table bundles (
Model2Vec,StaticEmbeddings) andWord2Vecare unchanged.
Full Changelog: 0.0.30...0.1.0