michaelfeil / michaelfeil/infinity
Expose a tokenizer API (/tokenize + /decode), aligned with TEI/Cohere
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.9k
- Forks
- 206
- PR merge metrics
- No merged PRs in 30d
Description
## Feature request
Expose a tokenizer API on the inference server: `POST /tokenize` and `POST /decode`, aligned with the shape used by Text Embeddings Inference (TEI) — and equivalently by Cohere (`/tokenize` + `/detokenize`) and vLLM.
- `POST /tokenize` — `{model, inputs, add_special_tokens?}` → per input, a list of `{id, text, special, start, stop}` (with `start`/`stop` as character offsets) plus a token count.
- `POST /decode` — `{model, ids, skip_special_tokens?}` → text.
These primitives cover three client scenarios. In priority order for me:
1. **Truncate** an input to *N* tokens before sending it.
2. **Chunk** one input into *K* segments of at most *N* tokens each.
3. **Tokenize** an input to get token ids and character offsets.
(1) and (2) are my main interest; (3) is the primitive they build on. No popular tokenizer API standardises chunking, so I'd suggest either shipping the primitives only and letting clients chunk from the offsets, or adding a thin, clearly-Infinity-specific convenience layer (e.g. `max_tokens` to head-truncate, `chunk_size`/`chunk_overlap` to split) that reuses the truncation logic already present for reranking. Happy to follow your preference here.
## Motivation
Clients that send long inputs have to guess how the served model's tokenizer treats them. Without a server-side tokenizer endpoint, every client has to ship and pin the matching `tokenizers`/`transformers` version per model, keep it in sync with the model Infinity actually serves, and reimplement chunking. That logic differs per model (BERT vs. XLM-R vs. a custom merge), so it drifts easily and is a common source of "works locally, mismatched in prod" mismatches.
Infinity already holds the right tokenizer in process (`_infinity_tokenizer` in the SentenceTransformer and CrossEncoder backends) and already truncates by tokens for reranking (`truncate_texts_to_tokens`, plus the `max_query_tokens` / `max_tokens_per_doc` / `max_pair_tokens` budgets on `/rerank`). Exposing that capability lets clients reuse the exact tokenizer of the served model instead of duplicating it.
The intent is to match an existing popular API rather than invent a custom one. TEI is the closest precedent, since Infinity already positions itself as a TEI/OpenAI alternative; `/tokenize` + `/decode` carries the character offsets needed for chunking and lets existing TEI clients work unchanged. Cohere's `/tokenize` + `/detokenize` naming is an alternative that matches Infinity's existing Cohere-aligned `/rerank`.
Two open questions for you:
1. TEI-aligned `/tokenize` + `/decode`, or Cohere-aligned `/tokenize` + `/detokenize` (matching the existing `/rerank`)?
2. Primitives only, or include the truncate/chunk convenience layer?
## Your contribution
Yes — I'm happy to open a PR once the endpoint shape and the two questions above are agreed.
References: [TEI API](https://huggingface.github.io/text-embeddings-inference/), [Cohere /tokenize](https://docs.cohere.com/reference/tokenize), [vLLM tokenizer endpoints](https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the `_infinity_tokenizer` usage in the SentenceTransformer and CrossEncoder backends, then inspect `truncate_texts_to_tokens` and the `/rerank` token budgets. Resolve the `/decode` versus `/detokenize` and primitives-versus-convenience-layer questions; done means the agreed endpoints expose the specified token data, offsets, counts, and decoded text.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100