Skip to content

feat: rework python bindings - #2391

Merged
SBrandeis merged 35 commits into
feat/train_encode_splitfrom
feat/rework-python-bindings
Sep 15, 2026
Merged

SBrandeis merged 35 commits into
feat/train_encode_splitfrom
feat/rework-python-bindings

Conversation

@SBrandeis

@SBrandeis SBrandeis commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

TL;DR

Rework of the Python bindings to make them slimmer (minimalistic API)

Some caveats:

  • Unclear whether this runs properly on free-threaded python

@SBrandeis
SBrandeis force-pushed the feat/rework-python-bindings branch from 6f591e2 to 20cd29c Compare September 3, 2026 11:13
@SBrandeis
SBrandeis marked this pull request as ready for review September 3, 2026 12:18
@SBrandeis SBrandeis changed the title python bindings v2 feat: rework python bindings Sep 3, 2026
@lhoestq

lhoestq commented Sep 3, 2026

Copy link
Copy Markdown
Member

I could confirm that pickling, multiprocessing and pickle-dump-hash determinism are all good wrt datasets.

I can try e2e with transformers tokenizers once ready !

Comment thread bindings/python/python/tokenizers/tokenizers.pyi Outdated
pipeline: Pipeline,
// Needs a mutex so a concurrent thread can access the value while
// encode is running.
padding: Mutex<Option<PaddingParams>>,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

fine, its also fine if its just copied across threads tbf

Comment thread bindings/python/tests/test_tokenizer.py Outdated
Comment thread bindings/python/tests/test_tokenizer.py Outdated
Comment thread bindings/python/tools/stub-gen/Cargo.toml
Comment thread bindings/python/Makefile
Comment thread bindings/python/README.md
tokenizer.save("./path/to/directory/my-bpe.tokenizer.json")
from tokenizers import Padding, Tokenizer

tokenizer = Tokenizer.from_file("tokenizer.json")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

needs from pretrained + a big disclaimer that this is v1 only!

Comment thread bindings/python/README.md
Comment thread bindings/python/README.md
Comment on lines +64 to +65
with multiprocessing.get_context("spawn").Pool(4) as pool:
encoded = pool.starmap(encode, [(tokenizer, chunk) for chunk in chunks])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

we need to check, potentially disabling the parallelism automatically when in subprocess -> user wants to handle it himself

@SBrandeis

Copy link
Copy Markdown
Contributor Author

Hey @ArthurZucker I addressed some of your concerns:

  • verbose tests
  • from_pretrained
  • stub_gen built as a runnable binary

PTAL at those changes 🤗

@SBrandeis
SBrandeis force-pushed the feat/rework-python-bindings branch from cf1c073 to 8145032 Compare September 14, 2026 09:48
Comment thread bindings/python/.cargo/config.toml Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Mmm interesting that this is no longer needed

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Comment thread bindings/python/python/tokenizers/tokenizers.pyi
Comment thread bindings/python/tools/stub-gen/python_members.py Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

😢 hahah all the efforts I did to get this right I am sadddd

@hf-security-analysis

hf-security-analysis Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

🚨 Workflow security review — 4 critical, 3 high, 3 medium, 4 low, 1 informational

Scanned 1 workflow file(s) with zizmor, pinact, OSV/GHSA, Claude, in full.

.github/workflows/python.yml

  • 🚨 CRITICAL impostor-commit — .github/workflows/python.yml:26 (via zizmor)
    commit with no history in referenced repository — uses a commit that doesn't belong to the specified org/repo

    Fix: The pinned SHA is not reachable from any branch or tag of the action's repository — it may come from a fork or a force-pushed ref. Re-pin from an upstream tag.

  • 🚨 CRITICAL impostor-commit — .github/workflows/python.yml:60 (via zizmor)
    commit with no history in referenced repository — uses a commit that doesn't belong to the specified org/repo

    Fix: The pinned SHA is not reachable from any branch or tag of the action's repository — it may come from a fork or a force-pushed ref. Re-pin from an upstream tag.

  • 🚨 CRITICAL impostor-commit — .github/workflows/python.yml:112 (via zizmor)
    commit with no history in referenced repository — uses a commit that doesn't belong to the specified org/repo

    Fix: The pinned SHA is not reachable from any branch or tag of the action's repository — it may come from a fork or a force-pushed ref. Re-pin from an upstream tag.

  • 🚨 CRITICAL impostor-commit — .github/workflows/python.yml:161 (via zizmor)
    commit with no history in referenced repository — uses a commit that doesn't belong to the specified org/repo

    Fix: The pinned SHA is not reachable from any branch or tag of the action's repository — it may come from a fork or a force-pushed ref. Re-pin from an upstream tag.

  • ⚠️ HIGH unpinned-action — .github/workflows/python.yml:76 (via pinact · also flagged by zizmor)
    Action is not pinned to an immutable commit SHA: uses: astral-sh/setup-uv@v6

    Fix: Replace with uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0

  • ⚠️ HIGH unpinned-action — .github/workflows/python.yml:86 (via pinact)
    Action is not pinned to an immutable commit SHA: uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4

    Fix: Replace with uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0

  • ⚠️ HIGH unpinned-action — .github/workflows/python.yml:128 (via pinact · also flagged by zizmor)
    Action is not pinned to an immutable commit SHA: uses: astral-sh/setup-uv@v6

    Fix: Replace with uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0

  • 🟡 MEDIUM ref-version-mismatch — .github/workflows/python.yml:63 (via zizmor)
    action's hash pin has mismatched or missing version comment — tag points to commit c19371144df3

    Fix: The # vX.Y.Z comment does not match the pinned SHA. Either the comment is stale or the pin was tampered with — re-resolve it.

  • 🟡 MEDIUM ref-version-mismatch — .github/workflows/python.yml:117 (via zizmor)
    action's hash pin has mismatched or missing version comment — tag points to commit c19371144df3

    Fix: The # vX.Y.Z comment does not match the pinned SHA. Either the comment is stale or the pin was tampered with — re-resolve it.

  • 🟡 MEDIUM ref-version-mismatch — .github/workflows/python.yml:164 (via zizmor)
    action's hash pin has mismatched or missing version comment — tag points to commit c19371144df3

    Fix: The # vX.Y.Z comment does not match the pinned SHA. Either the comment is stale or the pin was tampered with — re-resolve it.

  • 🔵 LOW parse-error — .github/workflows/python.yml:26 (via pinact)
    pinact could not parse this file: failed to handle a line: SHA-pinned action requires a version comment for verifiability

    Fix: Check the workflow YAML is valid.

  • 🔵 LOW parse-error — .github/workflows/python.yml:60 (via pinact)
    pinact could not parse this file: failed to handle a line: SHA-pinned action requires a version comment for verifiability

    Fix: Check the workflow YAML is valid.

  • 🔵 LOW parse-error — .github/workflows/python.yml:112 (via pinact)
    pinact could not parse this file: failed to handle a line: SHA-pinned action requires a version comment for verifiability

    Fix: Check the workflow YAML is valid.

  • 🔵 LOW parse-error — .github/workflows/python.yml:161 (via pinact)
    pinact could not parse this file: failed to handle a line: SHA-pinned action requires a version comment for verifiability

    Fix: Check the workflow YAML is valid.

``

  • ℹ️ INFORMATIONAL degraded-pin-audit(via pinact)
    pinact stopped early, so the pinning check may be incomplete: failed to handle a line: SHA-pinned action requires a version comment for verifiability

    Fix: Usually one reference pinact could not resolve — a SHA that is not in the action's repository, or a release it could not date. Fix or remove that reference and the rest of the file is checked.

🔀 A fix PR is open against this branch: #2409

Pinning and static findings are deterministic. Findings marked (via Claude) are model judgements — check them before acting.

hf-security-analysis Bot and others added 2 commits September 15, 2026 16:20
Co-authored-by: hf-security-analysis[bot] <265538906+hf-security-analysis[bot]@users.noreply.github.com>
@SBrandeis
SBrandeis merged commit c4e748d into feat/train_encode_split Sep 15, 2026
23 of 25 checks passed
@SBrandeis
SBrandeis deleted the feat/rework-python-bindings branch September 15, 2026 15:24

@ArthurZucker ArthurZucker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One thing that we want to keep API wise are the getters like:

    #[getter]
    fn get_ids(&self) -> Vec<u32> {
        self.encoding.get_ids().to_vec()
    }

and then in python tok.encode(["hey", "heyyyyyy"]).ids.

Also, if we don't need anything else than ids. we could also have a "id_only" -> no allocation for attention mask, no encoding, no type ids -> could be faster!

For the repr i'd say let's have \n !
Interestingly we can't do tokenize anymore! That's something we'll add back in v1, but it can be as easy as just taking the vocab-decoded id (no decoder). I'll add it IMO it can be nice.

Someting missing in decode is to take list of list. Only supports numpy list, but not batch. SO either decode batch, or just support both.

  • role_to_token needs to get exposed! probably just overwrite the getter !
Image this is also fine!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's maybe show an example of how transformers does this instead since that's where it lives!

Comment on lines +8 to +9
from numpy import integer, uint32
from numpy.typing import NDArray

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

mmm numpy should not be a hard dep!!!! not sure how easy that's to do 😐

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.

3 participants