perf(utils): simpler and faster numpy padding fallback, test numba in CI - #11
Merged
Merged
Conversation
The no-numba fallback built per-element row and column index arrays via repeat/cumsum/searchsorted to do one vectorised scatter. Filling row by row is both shorter and much faster, because numpy already copies each row at C speed and the index arrays were pure overhead: 16 short 7.2 us -> 6.4 us 64 mixed 37.1 us -> 18.9 us 256 mixed 321.2 us -> 68.8 us 8 very ragged 35.2 us -> 4.9 us CI installed ".[dev]", never ".[fast]", so the numba path -- the fast one this package advertises -- was never executed in CI at all. Added an extras axis to the matrix so both padding paths run against both transformers versions. Measured numba against the fallback to confirm the extra is worth keeping, since an earlier audit pass suspected it was not: numba wins decisively (16.3 us vs 68.8 us at 256 rows, 4.6 us vs 18.9 us at 64), one-time JIT compile 179 ms. So the README now recommends the [fast] extra rather than burying it. Note the fallback is now algorithmically close to pad_bytearrays_to_tensor_loop, which tests use as a reference. The new "dev,fast" CI leg keeps that comparison meaningful, and the independent torch pad_sequence reference in test_utils covers the plain leg. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Audit item #1 — but the conclusion is the opposite of what that audit proposed, now that I have measurements.
The audit was wrong about numba; here are the numbers
I originally suspected numba was an unnecessary dependency. With it actually installed, it wins decisively:
5–20× faster, one-time JIT compile 179 ms. The
fastextra earns its place. Retracting that part of the audit.What actually needed fixing: the fallback
The no-numba path built per-element row and column index arrays (
repeat/cumsum/searchsorted) to perform a single vectorised scatter. Filling row by row is shorter and much faster — numpy already copies each row at C speed, so the index arrays were pure overhead:4.7× faster at 256 rows (321 → 69 µs), 7× on ragged input (35 → 4.9 µs), 15 lines → 6.
The bigger find: the fast path was never tested
CI ran
uv pip install ".[dev]"and never".[fast]". So numba — the path this package advertises for speed — was not executed by CI at all. Added an extras axis so both padding paths run against both transformers versions:Four jobs instead of two.
README
Since numba is a 5–20× win, it should not be buried in an optional extra nobody discovers:
pip install "utf8-tokenizer[fast]"...with a note that the plain install still works and falls back to numpy.
One honest caveat
The new fallback is algorithmically close to
pad_bytearrays_to_tensor_loop, whichtest_utilsuses as a reference — so in the plaindevleg, those 16 comparisons are less independent than before. Two things keep it honest: the newdev,fastleg meanspad_bytearrays_to_tensorgoes through numba there, making the comparison meaningful again, andtest_utilshas 9 assertions against an independenttorch.nn.utils.rnn.pad_sequencereference that cover the plain leg.Verification
ruff check .clean.🤖 Generated with Claude Code
Note
Low Risk
Performance and test-matrix changes in padding utilities and docs; no auth or API contract changes.
Overview
Replaces the no-numba padding fallback in
_fill_paddedwith a short row-by-row copy loop instead of building scatter index arrays, improving performance whennumbais not installed.CI now runs four jobs (transformers
<5/>=5×dev/dev,fast) so tests exercise both the pure-numpy and numba padding paths; install uses".[${{ matrix.extras }}]".README recommends
pip install "utf8-tokenizer[fast]"and notes that the plain install still works with the numpy fallback.Reviewed by Cursor Bugbot for commit 465043b. Bugbot is set up for automated code reviews on this repo. Configure here.