fix(analyzer): fix GLiNER multi-instance entity leakage and simplify config#2181
Draft
kalra-mohit wants to merge 1 commit into
Draft
Conversation
Closed
4 tasks
…config (data-privacy-stack#1760) Consolidates and builds on two other open PRs against this issue, crediting both explicitly: - Auto-derives a unique recognizer name from class_name + model_name when name is omitted on a class_name: GLiNERRecognizer YAML entry, so multiple instances no longer each require an explicit unique name. Approach credited to data-privacy-stack#2018 (ynachiket). - Adds an include_requested_entities_as_labels option (default true) to GLiNERRecognizer. When multiple instances are configured with different entity_mapping/threshold values, GLiNER's ad-hoc-label support previously let a requested entity type "leak" into an instance that wasn't configured for it, evaluated against the wrong threshold. Setting this to false per-instance closes the leak by restricting that instance to only ever request labels it's configured for. Design credited to data-privacy-stack#2154 (ultramancode), reproducing hexsm's original report. - Updates the GLiNER sample docs and recognizer_registry_provider.md to document both, replacing the earlier docs-only PR's caveat about the leakage bug with the actual fix. Closes data-privacy-stack#1760 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kalra-mohit
force-pushed
the
feat/gliner-multi-instance-consolidated
branch
from
July 21, 2026 23:04
c9249fc to
56e4e4c
Compare
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.
Summary
Consolidates two other open approaches to this issue into one working, documented, tested fix, crediting both explicitly:
class_name: GLiNERRecognizerYAML entry no longer requires an explicit uniquename— when omitted, one is derived automatically fromclass_name+model_name.include_requested_entities_as_labelsoption (defaulttrue, preserving existing behavior). GLiNER's ad-hoc-label support previously let a globally-requested entity type "leak" into aGLiNERRecognizerinstance that wasn't configured for it, evaluated against the wrong instance's threshold, when multiple instances are configured with differententity_mapping/thresholdvalues. Setting this tofalseper-instance closes the leak by restricting GLiNER's label input to only that instance's own configured entities.gliner.md,recognizer_registry_provider.md) to document both, replacing an earlier docs-only PR's (docs(analyzer): document and test configuring multiple GLiNERRecognizer instances via YAML #2180, mine) caveat about the leakage bug with the actual fix.Closes #1760
Why consolidated rather than three separate PRs
Posted on the issue thread before starting this work: three open PRs (#2018, #2154, #2180) were addressing complementary but separate slices of the same underlying problem. Rather than have maintainers review and merge three overlapping PRs, this folds the auto-naming behavior and the leakage fix together with the docs so a user configuring multiple
GLiNERRecognizerinstances gets working, documented, isolated behavior in one PR. Happy to split this back up, defer to #2018/#2154 directly, or adjust scope however maintainers prefer — flagged this intent on the issue first specifically to get out ahead of that.Root cause (verified against current source, not assumed)
In
GLiNERRecognizer.analyze(),__create_input_labels()appends every globally-requested entity type as an ad-hoc GLiNER label by default. Combined with the result filter (if entities and presidio_entity not in entities: continue), which checks against the global requested-entity list rather than this instance's ownentity_mapping, an instance configured only for e.g.ADDRESScan still return anORGANIZATIONresult ifORGANIZATIONwas requested elsewhere in the sameanalyze()call — evaluated against theADDRESSinstance's threshold, not the (possibly stricter) threshold configured forORGANIZATIONelsewhere.flowchart TD A["YAML: 2x class_name: GLiNERRecognizer\nentries, different entity_mapping/threshold"] --> B["Loader: name auto-derived\nfrom class_name + model_name"] B --> C1["Instance A: entity_mapping={Address: ADDRESS}\nthreshold=0.65"] B --> C2["Instance B: entity_mapping={Organization: ORGANIZATION}\nthreshold=0.80"] D["analyze(entities=[ADDRESS, ORGANIZATION, PRODUCT])"] --> C1 D --> C2 C1 -. "include_requested_entities_as_labels=True (old default):\nORGANIZATION leaks in as ad-hoc label,\nreturned at Instance A's 0.65 threshold" .-> BUG["Wrong threshold applied"] C1 -- "include_requested_entities_as_labels=False:\nonly ever sends [Address] as labels" --> FIXED["Leak closed"]Test plan
include_requested_entities_as_labels=Falseprevents the leakRecognizerRegistryProviderwith two full YAML-style configs, verifying both instances load with correct distinct names, thresholds, and the leakage flag appliedtest_gliner_recognizer.py,test_yaml_recognizer_models.py,test_recognizer_registry_provider.py,test_recognizers_loader_utils.py) — 152 passed, 0 failedruff checkclean on both changed source files