fix(dataprep): guard smart_chunk_text against stride >= chunk_size (#7126)

RawTextDataLoader.smart_chunk_text takes chunk_size and stride as its own
arguments, so a direct call with stride >= chunk_size bypasses the
constructor validation. In that case `start_idx += chunk_size - stride` is
non-positive, so start_idx never advances past the first window and the
chunking loop never terminates (hangs).

Re-add the chunk_size/stride guard at the top of smart_chunk_text so direct
callers fail fast with a clear ValueError. The constructor keeps its own
guard for the internal callers (defense in depth). Add a regression test
that calls smart_chunk_text directly with stride == chunk_size and
stride > chunk_size and asserts it raises instead of hanging.

Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
This commit is contained in:
Anas Khan 2026-07-15 07:03:54 +05:30 committed by GitHub
commit 387b2f28e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 0 deletions

View file

@ -141,6 +141,26 @@ def test_raw_text_loader():
except ValueError as e:
assert "stride" in str(e) and "chunk_size" in str(e)
# smart_chunk_text validation: called directly, chunk_size/stride are its own
# arguments and bypass the constructor guard, so it must guard itself or an
# invalid stride makes `start_idx += chunk_size - stride` non-positive and the
# chunking loop never terminates (hangs).
long_text = "This is a test file for raw text training. " * 10
valid_chunks = loader.smart_chunk_text(long_text, chunk_size = 5, stride = 2)
assert len(valid_chunks) > 0, "Valid stride should produce chunks"
try:
loader.smart_chunk_text(long_text, chunk_size = 5, stride = 5)
assert False, "Should raise ValueError for stride == chunk_size"
except ValueError as e:
assert "stride" in str(e) and "chunk_size" in str(e)
try:
loader.smart_chunk_text(long_text, chunk_size = 5, stride = 10)
assert False, "Should raise ValueError for stride > chunk_size"
except ValueError as e:
assert "stride" in str(e) and "chunk_size" in str(e)
# Preprocessor.
preprocessor = TextPreprocessor()
clean_text = preprocessor.clean_text(" messy text \n\n\n ")

View file

@ -132,6 +132,13 @@ class RawTextDataLoader:
3. Maintains context with stride overlap
4. Returns tokenized chunks directly (more efficient) or text chunks
"""
if chunk_size <= 0:
raise ValueError(f"chunk_size must be positive, got {chunk_size}")
if stride >= chunk_size:
raise ValueError(
f"stride ({stride}) must be smaller than chunk_size ({chunk_size}) to progress the chunking loop"
)
# Tokenize the whole text once for accurate token counts
tokenized = self.tokenizer(text, return_tensors = "pt", add_special_tokens = False)
tokens = tokenized["input_ids"]