Skip to content

Fix index misalignment in char_wb ngram padding - #8429

Open
adityaanikam wants to merge 9 commits into
NVIDIA:mainfrom
adityaanikam:tfidf-char-wb-ngram-fix-8416
Open

Fix index misalignment in char_wb ngram padding#8429
adityaanikam wants to merge 9 commits into
NVIDIA:mainfrom
adityaanikam:tfidf-char-wb-ngram-fix-8416

Conversation

@adityaanikam

Copy link
Copy Markdown

Fixes #8416

Root cause

get_char_ngrams() pads each token with self.delimiter on both sides before generating character ngrams:

padding = Series(self.delimiter).repeat(len(tokens))

@adityaanikam
adityaanikam requested a review from a team as a code owner July 31, 2026 15:20
@adityaanikam
adityaanikam requested a review from jcrist July 31, 2026 15:20
@copy-pr-bot

copy-pr-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the Cython / Python Cython or Python issue label Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1740ef06-05f0-40fb-8b59-945a5f18d611

📥 Commits

Reviewing files that changed from the base of the PR and between 9eb9f3f and dd84c4f.

📒 Files selected for processing (1)
  • python/cuml/tests/test_text_feature_extraction.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • python/cuml/tests/test_text_feature_extraction.py

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.


📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Improved character n-gram processing to maintain correct positional alignment across documents, including documents with no extracted tokens.
    • Ensured per-document token counts remain aligned with generated n-gram data, improving consistency for text feature extraction results.

Walkthrough

The vectorizer now preserves document alignment for character n-grams, including documents with zero tokens. Related test annotations now reference the NVIDIA/cuml repository.

Changes

Character n-gram alignment fix

Layer / File(s) Summary
Character n-gram alignment fix
python/cuml/cuml/feature_extraction/_vectorizers.py, python/cuml/tests/test_text_feature_extraction.py
The vectorizer resets indexes before concatenation and reindexes n-gram counts across all documents with zero counts for documents without tokens. Test skip and xfail annotations use updated issue URLs.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to dd84c

This change corrects char_wb n-gram document alignment and adds parity coverage for the reported multi-character range. No unresolved merge-blocking risk is identified.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The URL updates in test_text_feature_extraction.py are unrelated to the char_wb padding fix and the requirements in issue #8416. Remove the unrelated issue URL changes, or document a clear reason that they are required for this pull request.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary fix for index misalignment in char_wb n-gram padding.
Description check ✅ Passed The description addresses issue #8416 and identifies the char_wb padding logic in get_char_ngrams().
Linked Issues check ✅ Passed The changes reset token and padding indexes and preserve zero-token documents, which addresses the duplicate-index failure and the char_wb multi-character n-gram behavior required by issue #8416.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
python/cuml/cuml/feature_extraction/_vectorizers.py (1)

216-224: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add an enabled char_wb Tfidf regression test.

In python/cuml/tests/test_text_feature_extraction.py, test TfidfVectorizer.fit_transform(analyzer="char_wb", ngram_range=(2, 6)). Compare the sparse output and feature names with scikit-learn using get_feature_names_out().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cuml/cuml/feature_extraction/_vectorizers.py` around lines 216 - 224,
Add an enabled regression test in test_text_feature_extraction.py covering
TfidfVectorizer with analyzer="char_wb" and ngram_range=(2, 6). Fit and
transform the same input with cuML and scikit-learn, then compare sparse outputs
and feature names using get_feature_names_out().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@python/cuml/cuml/feature_extraction/_vectorizers.py`:
- Around line 216-224: Add an enabled regression test in
test_text_feature_extraction.py covering TfidfVectorizer with analyzer="char_wb"
and ngram_range=(2, 6). Fit and transform the same input with cuML and
scikit-learn, then compare sparse outputs and feature names using
get_feature_names_out().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 80ca255e-7d3d-41f0-ab51-594df4f04c33

📥 Commits

Reviewing files that changed from the base of the PR and between 74f5ffa and 3edfa37.

📒 Files selected for processing (1)
  • python/cuml/cuml/feature_extraction/_vectorizers.py

@csadorf

csadorf commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

@divyegala Can you review this, please?

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

Thank you for the contribution! Could you please add a test?

@adityaanikam
adityaanikam requested a review from a team as a code owner August 19, 2026 09:00
@adityaanikam

adityaanikam commented Aug 19, 2026

Copy link
Copy Markdown
Author

Added test_tfidf_vectorizer_char_wb_ngrams — compares cuML's TfidfVectorizer(analyzer="char_wb", ngram_range=(2, 6)) against scikit-learn's on the existing DOCS fixture (13 documents, mixed lengths, includes empty docs), checking both the output matrix and feature names via get_feature_names_out(). That corpus mix is what actually exercises the bug, since the misalignment only showed up once documents had varying token counts. Also rebased onto latest main to pick up the get_feature_names_out() API change from #8480.
This also needs bug + non-breaking labels for the Label Checker I don't have permission to add them myself.

@divyegala divyegala added bug Something isn't working non-breaking Non-breaking change labels Aug 19, 2026

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

Thank you, LGTM!

@divyegala

Copy link
Copy Markdown
Contributor

/ok to test 36f9500

@divyegala

Copy link
Copy Markdown
Contributor

/merge

@divyegala

Copy link
Copy Markdown
Contributor

Hi @adityaanikam , could you please run pre-commit and push up a new commit?

@adityaanikam

Copy link
Copy Markdown
Author

Hi @adityaanikam , could you please run pre-commit and push up a new commit?

done

@divyegala

Copy link
Copy Markdown
Contributor

/ok to test 41a6044

CI on this PR failed test_tfidf_vectorizer_char_wb_ngrams with KeyError: boolean label can not be used without a boolean index, in get_ngrams' ngram_count[not_empty_docs] filter. That test's DOCS fixture includes two empty-string documents, and this is the first char_wb test to include one.

get_char_ngrams' char_wb branch computes ngram_count via doc_id_df.groupby("doc_id", sort=True).sum(). A document that tokenizes to zero tokens never contributes a row to doc_id_df, so its doc_id is entirely absent from the groupby result's index, rather than present with a count of 0. token_count, computed separately via str_series.str.token_count(), still has an entry for every document. The two indices then disagree, and get_ngrams' later not_empty_docs boolean mask, built from token_count's full index, no longer aligns with ngram_count's shorter one.

Reindexed ngram_count onto token_count's index with fill_value=0 right after the groupby, restoring the same index for both that the other two branches (char, ngram_size == 1) already get for free since their ngram_count is arithmetic directly on token_count.

This bug predates this PR and is unrelated to the padding order change in get_char_ngrams; it was only ever latent because no earlier char_wb test included a document with zero tokens. The regression test already added in this PR (test_tfidf_vectorizer_char_wb_ngrams) exercises it directly, so no additional test is needed. Could not run this locally, cuml requires an NVIDIA GPU and CUDA runtime; verified the fix by tracing the exact index mismatch against the failing job's log and reasoning through cudf.Series.reindex semantics, and am relying on CI to confirm.
@jcrist

jcrist commented Sep 3, 2026

Copy link
Copy Markdown
Member

/merge

@jcrist

jcrist commented Sep 3, 2026

Copy link
Copy Markdown
Member

/ok to test dd84c4f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Cython / Python Cython or Python issue non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] TfidfVectorizer with char_wb analyzer and ngrams fails

6 participants