microsoft / microsoft/onnxruntime-extensions

Request to expose WordPiece/BERT as a runtime tokenizer type in `OrtxCreateTokenizer` (already exists as graph ops)

Open
#1,119 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
479
Forks
144
Avg merge
1d 8h
Merged PRs (30d)
11

Description

How is this feature request related to a problem?

OrtxCreateTokenizer cannot load a HuggingFace WordPiece/BERT tokenizer.json. Loading one (e.g. sentence-transformers/all-MiniLM-L6-v2, or any tokenizer_class: "BertTokenizer") fails with kOrtxErrorNotImplemented (error code 8). Multiple other models also uses this WordPiece tokeniser and it's not supported by the onnxruntime extension yet.

Onnxruntime-extensions already implements WordPiece and BERT tokenization — but only as graph custom operators (WordpieceTokenizer / BertTokenizer), not as a first-class type in the runtime tokenizer C-API. So users who want a standalone tokenizer (outside an ONNX graph) for BERT-family encoders have no supported path, even though the algorithm already lives in the codebase.

Probable cause (current code)

  • operators/tokenizer/tokenizer_jsconfig.hppenum class TokenType { kUnknown, kUnigram, kBPE }; has no kWordPiece, and kTokenizerDict maps only BPE + Unigram/SentencePiece class names. BertTokenizer/DistilBertTokenizer/etc. are absent, so GetTokenType() returns kUnknown (after stripping a trailing "Fast"), which surfaces as error 8.
  • shared/api/tokenizer_impl.ccTokenizerImpl::LoadTokenizer only dispatches to the BPE and Unigram/SPM backends.
  • Meanwhile the WordPiece logic already exists at operators/tokenizer/bert_tokenizer.{hpp,cc}, operators/tokenizer/wordpiece_tokenizer.{hpp,cc}, and operators/tokenizer/basic_tokenizer.{hpp,cc} (registered for graphs in tokenizers.cc).

Reproduction

extError_t e = OrtxCreateTokenizer(&tokenizer, "path/to/minilm_tokenizer_dir");
// e == kOrtxErrorNotImplemented (8); "Unsupported tokenizer class"

Proposed solution

Wire the existing WordPiece implementation into the runtime tokenizer path:

  1. Add kWordPiece to enum class TokenType.
  2. Add the BERT-family class names to kTokenizerDict ("BertTokenizer", "DistilBertTokenizer", "MobileBertTokenizer", "ElectraTokenizer", …) → kWordPiece, and/or detect model.type == "WordPiece" from tokenizer.json.
  3. Add a kWordPiece case in TokenizerImpl::LoadTokenizer that reuses the existing greedy WordPiece + basic-tokenizer code.
  4. Add a test/pp_api_test case that loads a BERT tokenizer.json and checks encode/decode against HF.

Alternatives considered

  • Graph custom ops (BertTokenizer/WordpieceTokenizer) — works, but forces embedding tokenization into an ONNX graph; not usable as a standalone tokeniser API.
  • BPE/Unigram fallback — not applicable; WordPiece is a distinct algorithm.

Willingness to contribute
Locally, I have implemented the WordPiece tokeniser and verified the output with multiple different test cases. They matches exact same to the Python transformers' AutoTokenizer library tokenizer = AutoTokenizer.from_pretrained("minilm_tokenizer_dir").
Happy to submit a PR implementing the above if the maintainers agree with the approach.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with operators/tokenizer/tokenizer_jsconfig.hpp and shared/api/tokenizer_impl.cc to trace tokenizer type detection and runtime dispatch. Read the existing WordPiece, BERT, and basic tokenizer files under operators/tokenizer/, then inspect test/pp_api_test. Done means OrtxCreateTokenizer loads a BERT-family tokenizer.json and encode/decode results match Hugging Face AutoTokenizer.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, huggingface
Domain
api, backend-api-design
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.