Skip to content

OPENNLP-1838: Adopt BertTokenizer in opennlp-dl components#1075

Merged
mawiesne merged 3 commits into
apache:mainfrom
ai-pipestream:OPENNLP-1838
Jun 13, 2026
Merged

OPENNLP-1838: Adopt BertTokenizer in opennlp-dl components#1075
mawiesne merged 3 commits into
apache:mainfrom
ai-pipestream:OPENNLP-1838

Conversation

@krickert

Copy link
Copy Markdown
Contributor

Note

Stacked on #1072, #1073 and #1074. This branch includes their commits because it depends on BertTokenizer from #1073. Once those merge, this PR will be rebased onto main and the diff collapses to the OPENNLP-1838 changes only. Draft until then.

What

  • SentenceVectorsDL, DocumentCategorizerDL and NameFinderDL now tokenize with BertTokenizer (basic tokenization / normalization, then wordpiece) instead of raw WordpieceTokenizer.
  • Lower casing defaults follow each component's commonly used models:
    • SentenceVectorsDL and DocumentCategorizerDL: true (the README-recommended models are uncased)
    • NameFinderDL: false (recommended NER models such as dslim/bert-base-NER are cased; capitalization is a core signal for entity boundaries)
  • Overridable via the new tri-state InferenceOptions.setLowerCase(boolean) or the new SentenceVectorsDL(model, vocab, lowerCase) constructor. RoBERTa-style special-token detection is preserved.

Why

See OPENNLP-1838 and OPENNLP-1837: without basic tokenization, uncased models receive [UNK] for every capitalized or accented word, severely degrading results.

Validation

  • New CreateTokenizerTest covers lower-casing vs. case-preserving tokenizers, RoBERTa special-token selection, and the InferenceOptions default resolution.
  • Verified end-to-end with the sentence-transformers all-MiniLM-L6-v2 ONNX export: the existing SentenceVectorsDLEval pinned values still hold, and a capitalized variant of the eval sentence now produces vectors identical to the lowercase one (previously every capitalized word mapped to [UNK]). Added as an eval assertion.
  • Verified with the real dslim/bert-base-NER vocabulary that all NameFinderDLEval input sentences tokenize identically before and after this change, so the NER eval expectations remain valid.

Note for eval-data owners

DocumentCategorizerDLEval expectations will shift because lower casing changes the tokens sent to the uncased sentiment models (that is the intended fix). The pinned values need to be regenerated against the canonical eval-data ONNX files, which are not publicly available. Happy to update the pins if someone can run the eval and share the new values.

@rzo1

rzo1 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Will look into this once the other stacked onces are done.

@rzo1 rzo1 requested review from mawiesne and rzo1 June 12, 2026 09:57
@mawiesne

Copy link
Copy Markdown
Contributor

@krickert Ready for rebase, as all other changes in in main now.

@krickert krickert marked this pull request as ready for review June 12, 2026 15:19
@krickert

Copy link
Copy Markdown
Contributor Author

@krickert Ready for rebase, as all other changes in in main now.

Rebased, ready for review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the opennlp-dl ONNX-based components to use BertTokenizer (basic normalization + wordpiece) instead of raw WordpieceTokenizer, and introduces a tri-state lower-casing option to match common model expectations (uncased vs cased).

Changes:

  • Switch tokenization in SentenceVectorsDL, DocumentCategorizerDL, and NameFinderDL to BertTokenizer, with component-appropriate lower-casing defaults.
  • Add InferenceOptions.lowerCase (nullable) and resolution logic in AbstractDL to combine component defaults with per-instance overrides.
  • Add unit/eval tests covering tokenizer creation behavior, lower-casing resolution, and an eval assertion for uncased-model capitalization invariance.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
opennlp-eval-tests/src/test/java/opennlp/dl/vectors/SentenceVectorsDLEval.java Adds an eval assertion that capitalization does not change vectors for an uncased model.
opennlp-core/opennlp-ml/opennlp-dl/src/test/java/opennlp/dl/CreateTokenizerTest.java New unit tests for tokenizer selection (BERT vs RoBERTa special tokens) and lower-casing option resolution.
opennlp-core/opennlp-ml/opennlp-dl/src/main/java/opennlp/dl/vectors/SentenceVectorsDL.java Defaults sentence-vector tokenization to uncased behavior; adds constructor to control lower-casing.
opennlp-core/opennlp-ml/opennlp-dl/src/main/java/opennlp/dl/namefinder/NameFinderDL.java Uses BertTokenizer with default case-preserving behavior for NER, overrideable via InferenceOptions.
opennlp-core/opennlp-ml/opennlp-dl/src/main/java/opennlp/dl/InferenceOptions.java Introduces nullable lowerCase option to support component defaults with overrides.
opennlp-core/opennlp-ml/opennlp-dl/src/main/java/opennlp/dl/doccat/DocumentCategorizerDL.java Uses BertTokenizer with default lower-casing enabled for classification, overrideable via InferenceOptions.
opennlp-core/opennlp-ml/opennlp-dl/src/main/java/opennlp/dl/AbstractDL.java Adds BertTokenizer factory + lower-case resolution helper shared by components.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread opennlp-core/opennlp-ml/opennlp-dl/src/main/java/opennlp/dl/AbstractDL.java Outdated
Comment thread opennlp-eval-tests/src/test/java/opennlp/dl/vectors/SentenceVectorsDLEval.java Outdated
@rzo1

rzo1 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Happy to update the pins if someone can run the eval and share the new values.

You find the eval data here: https://nightlies.apache.org/opennlp/

You can also trigger a eval build using your ASF credentials here: https://ci-builds.apache.org/job/OpenNLP/job/eval-tests-configurable/

I have triggered one for you: https://ci-builds.apache.org/job/OpenNLP/job/eval-tests-configurable/48/

@mawiesne mawiesne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All fine with this PR, thx @krickert !

UPDATE
Given Eval build works again: Let's wait for the Eval build data / input to adapt numbers.

@mawiesne

Copy link
Copy Markdown
Contributor

I have triggered one for you: https://ci-builds.apache.org/job/OpenNLP/job/eval-tests-configurable/48/

@rzo1 Something seems odd with this run:

Run time is way too fast, confirmed by this output:

[INFO] --- surefire:3.5.5:test (default-test) @ opennlp-eval-tests ---
[INFO] Tests are skipped.

@krickert

Copy link
Copy Markdown
Contributor Author

Thanks @rzo1 @mawiesne. Eval build #48 didn't actually exercise the new DL evals. opennlp-eval-tests sets surefire <skip>true</skip> in the base build config, and the eval-tests profile adds includes but never overrides
the skip - so the module compiles the eval sources and runs nothing.

You can see it in the build log: the module finishes in ~1.2s and no *DLEval class appears anywhere in the console output. The 53 minutes of eval work all happened in the classic suites.

This also means the DocumentCategorizerDLEval pin shift described in the PR text has not been observed by CI yet. It turns out the doccat ONNX eval models are in the nightlies eval data (onnx/doccat/), so I'm running the DL evals locally against it right now and will push the regenerated pinned values to this branch shortly - please
hold off merging until that commit lands.

The surefire skip issue itself is a pre-existing bug on main (it affects every eval class in the module, not just the DL ones).

@mawiesne mawiesne marked this pull request as draft June 12, 2026 19:47
@rzo1

rzo1 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Not related to this PR, see https://ci-builds.apache.org/job/OpenNLP/job/eval-tests/ (a few minutes only for the last days), so yes what Kristian says needs to be fixed on main

@mawiesne mawiesne added java Pull requests that update Java code tests Pull requests that add or update test code labels Jun 12, 2026
krickert added 3 commits June 12, 2026 16:13
Without basic tokenization, uncased models received the unknown token
for every capitalized or accented word. SentenceVectorsDL,
DocumentCategorizerDL and NameFinderDL now tokenize with BertTokenizer.

Lower casing defaults follow each component's commonly used models:
true for SentenceVectorsDL and DocumentCategorizerDL (uncased),
false for NameFinderDL (cased NER models rely on capitalization).
The default is overridable via InferenceOptions.setLowerCase or the
new SentenceVectorsDL constructor.
Validate that a RoBERTa-style vocabulary contains a supported unknown
token instead of silently selecting one that is absent, and compare
eval vectors with a tolerance rather than exact float equality.
Lower casing now sends correct tokens to the uncased sentiment models,
shifting the score distributions. All predicted categories are unchanged;
the models are simply more confident. Values regenerated against the
canonical eval-data ONNX models from the nightlies archive.
@mawiesne mawiesne marked this pull request as ready for review June 12, 2026 20:20
@mawiesne

mawiesne commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

@krickert I just noticed you're working via a branch on a fork. Forget my last question / comment related to a rebase...

For the records, here's a eval run kicked for fixed main branch:
https://ci-builds.apache.org/job/OpenNLP/job/eval-tests-configurable/49/

@mawiesne

mawiesne commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

In roughly 4 hours time, this build should kick in for your fork + branch:

https://ci-builds.apache.org/job/OpenNLP/job/eval-tests-configurable/51

Note: URL will only work once build no. 49 has terminated.

UPDATE
Build No. 50 got stuck for non obvious reasons in the pre eval-tests phase...

@krickert

Copy link
Copy Markdown
Contributor Author

@mawiesne for some reason the URL isn't working for me but I'm on a phone browser. Did this run get stuck too?

@rzo1

rzo1 commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

50/51 did succeed. Onto evals are quite slow. Perhaps another investigstion target next time

@krickert

Copy link
Copy Markdown
Contributor Author

Looks like it passed. Squash and merge ok?

@mawiesne mawiesne merged commit 9ebcaaa into apache:main Jun 13, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

java Pull requests that update Java code tests Pull requests that add or update test code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants