Skip to content

GH-1392: Add padding strategies for SentenceVectorsDL.embedAll and pad on a GPU by default - #1474

Open
krickert wants to merge 4 commits into
mainfrom
feat/GH-1392-embed-padding
Open

krickert wants to merge 4 commits into
mainfrom
feat/GH-1392-embed-padding

Conversation

@krickert

@krickert krickert commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

So when embedding on a GPU there are 3 padding strategies we are testing. I've tried all 3 of these strategies before, and a embeddings fine-tuner this is one aspect to get a max vertical scaling. As you can see from below, you can save a lot of compute time and energy consumption when digging this deep.

SentenceVectorsDL.embedAll can batch texts of different lengths together on a GPU, reducing the number of inference calls. SentenceVectorsOptions selects pooling, normalization, maximum token length and padding; InferenceOptions supplies the ONNX session settings separately.

PaddingStrategy supports:

  • AUTO, the default: LONGEST on a GPU for token-output models whose vocabulary has a padding token, EXACT_LENGTH otherwise. Models with pooled output retain EXACT_LENGTH because they may ignore the attention mask.
  • EXACT_LENGTH: group texts by tokenized length without padding.
  • LONGEST: order texts by length and pad each batch to its longest text.
  • MAX_LENGTH: pad every input to the configured maximum token length, including single embed calls. If construction must probe an unknown output dimension, that inference also uses the maximum length, which must fit the model's position limit.

The onnx provider accepts auto, exact_length, longest and max_length in any letter case. Its CPU session resolves AUTO to EXACT_LENGTH. Null padding is rejected. The unreleased seven-argument constructor is removed; callers supplying session settings use the constructor accepting SentenceVectorsOptions and InferenceOptions. Older convenience constructors remain.

Padding uses the vocabulary's [PAD] token, or for RoBERTa. Attention-mask entries for padding are zero, and pooling excludes padded positions. Vectors match up to floating-point rounding when the model honors the mask. A pooled output that ignores the mask can change with explicit padding. Batches are capped at 16,384 token positions, except that a single wider row runs alone.

Release note: GPU sentence-vector sessions now select LONGEST automatically for eligible models. Mixed-length batches can introduce small floating-point differences. Set PaddingStrategy.EXACT_LENGTH in SentenceVectorsOptions to retain unpadded GPU batches. The README migration notes, InferenceOptions.setGpu Javadoc and manual document this behavior.

The existing benchmark measurements on all-MiniLM-L6-v2, RTX 4080 SUPER, with texts of 4 to 40 words are retained below. They were not rerun for this API and documentation follow-up.

Texts EXACT_LENGTH LONGEST
8 3603 us 862 us
32 11431 us 2152 us
128 23815 us 7443 us

Tests cover batch boundaries, input order, vocabulary padding IDs, mask behavior, pooled output, single-input MAX_LENGTH, automatic defaults, null validation, case-insensitive provider values, and CPU/GPU parity. The follow-up tests first failed with 2 failures and 9 errors before implementation.

Validation: JDK 21 reactor verify for opennlp-dl-gpu and opennlp-docs with their dependencies reports 8,495 unit cases and 19 integration cases, zero failures/errors, and 12 unit skips. All 1,313 GPU-module tests ran without skips on RTX 4080 SUPER with CUDA 13 libraries. Packaging, Javadoc, Checkstyle, forbidden APIs, RAT and manual generation passed. The existing NameFinderDL Javadoc reference warning remains. A corpus eval build is still required before merge.

Quick merge note -
This pull request and #1472 both change SentenceVectorsDL.run. The one merged later needs to be reconciled with the other so padding uses the pooled direct buffers.

Fixes #1392

@krickert
krickert force-pushed the feat/GH-1391-embed-batch-cap branch from dc68fd7 to f2a2206 Compare October 11, 2026 22:39
@krickert
krickert force-pushed the feat/GH-1392-embed-padding branch from cc4df6c to 3d639ac Compare October 11, 2026 22:40
@krickert
krickert force-pushed the feat/GH-1391-embed-batch-cap branch from f2a2206 to e540ab2 Compare October 12, 2026 01:20
@krickert
krickert force-pushed the feat/GH-1392-embed-padding branch from 3d639ac to bc0c2b1 Compare October 12, 2026 01:21
@krickert
krickert force-pushed the feat/GH-1391-embed-batch-cap branch from e540ab2 to 8517809 Compare October 13, 2026 19:36
@krickert
krickert force-pushed the feat/GH-1392-embed-padding branch from bc0c2b1 to 01fef7d Compare October 13, 2026 19:40
@krickert
krickert force-pushed the feat/GH-1391-embed-batch-cap branch from 8517809 to 72f83f4 Compare October 15, 2026 13:29
@krickert
krickert force-pushed the feat/GH-1392-embed-padding branch from 01fef7d to dc5935d Compare October 15, 2026 13:31
@krickert
krickert force-pushed the feat/GH-1391-embed-batch-cap branch from 72f83f4 to 210d160 Compare October 18, 2026 12:54
@krickert
krickert force-pushed the feat/GH-1392-embed-padding branch from dc5935d to 3f9d989 Compare October 18, 2026 13:30
Base automatically changed from feat/GH-1391-embed-batch-cap to main October 21, 2026 19:24
@krickert
krickert force-pushed the feat/GH-1392-embed-padding branch from 3f9d989 to 32b95ce Compare October 21, 2026 23:54
@krickert
krickert marked this pull request as ready for review October 21, 2026 23:59
@krickert
krickert requested review from mawiesne and rzo1 and removed request for rzo1 October 21, 2026 23:59
@krickert
krickert requested a review from rzo1 October 24, 2026 17:58

@rzo1 rzo1 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.

Hi @krickert - thanks, nice speedup on the GPU. Some remarks inline. In addition, .gitignore needs a negation for tiny-masked.onnx like for the other tiny models.

WDYT?

@rzo1 rzo1 added this to the 3.0.0 milestone Oct 25, 2026
@krickert
krickert force-pushed the feat/GH-1392-embed-padding branch from 32b95ce to 347eab4 Compare October 26, 2026 02:42
@krickert
krickert requested a review from rzo1 October 27, 2026 06:12

@rzo1 rzo1 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.

My earlier points are addressed. Whichever of this and #1472 lands second needs a rebase, both touch run().

krickert and others added 2 commits November 2, 2026 11:17
…d on a GPU by default

embedAll grouped texts by exact tokenized length, so on natural text
most inferences took one or two texts. PaddingStrategy.LONGEST orders
texts by length and pads each batch to its longest member, MAX_LENGTH
pads every input to the maximum length, and EXACT_LENGTH behaves as
before. Under every strategy no inference takes more than 16384 token
positions, except a single row wider than that, which runs alone. The
onnx provider gets a padding option.

A session built without a strategy uses LONGEST on a GPU when the model
has a token output and the vocabulary has a padding token ([PAD], or
<pad> for RoBERTa), and EXACT_LENGTH otherwise. A model with a pooled
sentence_embedding output is not padded by default, since it may ignore
the attention mask. The CPU default, DEFAULT_CPU_PADDING, is unchanged.
Padded positions are 0 in the attention mask and mean pooling skips
them, so vectors match up to floating-point rounding when the model
honors the mask.

tiny-masked.onnx, generated by gen_tiny_masked_model.py next to it, sums
the ids times the attention mask so tests can tell masked padding from
unmasked.

SentenceVectorsDLBenchmark on all-MiniLM-L6-v2, RTX 4080 SUPER, texts of
4 to 40 words, embedAll time per call before and after:

  8 texts:     3603 us ->  862 us
  32 texts:   11431 us -> 2152 us
  128 texts:  23815 us -> 7443 us

Fixes #1392

Signed-off-by: Kristian Rickert <kristian@apache.org>
Co-authored-by: Claude Code 2.1.296 (Opus 5.5) <noreply@anthropic.com>
Replace the new padding constructor with a constructor accepting
SentenceVectorsOptions for pooling, normalization, maximum length and
padding. Preserve the existing constructors and device defaults, and
remove the private constructor with swapped parameters. Update the
provider, tests and manual example to use the options record.

Tests were added first. Before implementation, test compilation failed
with "cannot find symbol: class SentenceVectorsOptions" and "no suitable
constructor found for SentenceVectorsDL". The full reactor suite now
passes: 7,158 cases, zero failures or errors, and 11 skips, including
all 12 new options tests without skips. Package and Javadoc generation
also pass.

Assisted-by: OpenAI Codex
Signed-off-by: Kristian Rickert <kristian@apache.org>
@rzo1
rzo1 force-pushed the feat/GH-1392-embed-padding branch from 1a4c3ec to 4c488f3 Compare November 2, 2026 10:17
Pin the automatic default, reject null padding, and accept padding names in lowercase, uppercase and mixed case. Before the fix, 47 cases report 2 failures, 9 errors and 1 CUDA skip: the default is null, null padding is accepted, and automatic or differently cased provider values are rejected.

Assisted-by: OpenAI Codex
Signed-off-by: Kristian Rickert <kristian@apache.org>
Use AUTO for device-selected padding, reject null strategies, and accept provider padding names in any letter case. Remove the unreleased seven-argument constructor and route callers through vector and inference options. Restore MIN_LENGTH and document GPU rounding differences and the MAX_LENGTH dimension probe.

The preceding test commit failed with 2 failures and 9 errors. JDK 21 reactor verify passes 8,495 unit tests and 19 integration tests, with zero failures or errors and 12 skips. All 1,313 GPU-module tests run without skips on the RTX 4080 SUPER with CUDA 13 libraries. Packaging, Javadoc, manual generation, Checkstyle, forbidden APIs and RAT checks pass.

Assisted-by: OpenAI Codex
Signed-off-by: Kristian Rickert <kristian@apache.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Padding strategies for SentenceVectorsDL.embedAll

2 participants