461bf6fd40
CI / lint (3.11) (push) Has been cancelled
CI / lint (3.12) (push) Has been cancelled
CI / lint (3.13) (push) Has been cancelled
CI / shellcheck (push) Has been cancelled
CI / shfmt (push) Has been cancelled
CI / setup (3.11) (push) Has been cancelled
CI / setup (3.12) (push) Has been cancelled
CI / setup (3.13) (push) Has been cancelled
CI / check-licenses (3.12) (push) Has been cancelled
CI / test_unit (3.11) (push) Has been cancelled
CI / test_unit (3.12) (push) Has been cancelled
CI / test_unit (3.13) (push) Has been cancelled
CI / test_unit_no_extras (3.11) (push) Has been cancelled
CI / test_unit_no_extras (3.12) (push) Has been cancelled
CI / test_json_to_html (3.12) (push) Has been cancelled
CI / test_unit_no_extras (3.13) (push) Has been cancelled
CI / test_unit_dependency_extras (csv, 3.12, --extra csv) (push) Has been cancelled
CI / test_unit_dependency_extras (xlsx, 3.11, --extra xlsx) (push) Has been cancelled
CI / test_unit_dependency_extras (xlsx, 3.12, --extra xlsx) (push) Has been cancelled
CI / test_unit_dependency_extras (csv, 3.11, --extra csv) (push) Has been cancelled
CI / test_unit_dependency_extras (csv, 3.13, --extra csv) (push) Has been cancelled
CI / test_unit_dependency_extras (docx, 3.11, --extra docx) (push) Has been cancelled
CI / test_unit_dependency_extras (docx, 3.12, --extra docx) (push) Has been cancelled
CI / test_unit_dependency_extras (docx, 3.13, --extra docx) (push) Has been cancelled
CI / test_unit_dependency_extras (markdown, 3.11, --extra md) (push) Has been cancelled
CI / test_unit_dependency_extras (markdown, 3.12, --extra md) (push) Has been cancelled
CI / test_unit_dependency_extras (markdown, 3.13, --extra md) (push) Has been cancelled
CI / test_unit_dependency_extras (odt, 3.11, --extra odt) (push) Has been cancelled
CI / test_unit_dependency_extras (odt, 3.12, --extra odt) (push) Has been cancelled
CI / test_unit_dependency_extras (odt, 3.13, --extra odt) (push) Has been cancelled
CI / test_unit_dependency_extras (pdf-image, 3.11, --extra pdf --extra image --extra paddleocr) (push) Has been cancelled
CI / test_unit_dependency_extras (pdf-image, 3.12, --extra pdf --extra image --extra paddleocr) (push) Has been cancelled
CI / test_unit_dependency_extras (pdf-image, 3.13, --extra pdf --extra image --extra paddleocr) (push) Has been cancelled
CI / test_unit_dependency_extras (pptx, 3.11, --extra pptx) (push) Has been cancelled
CI / test_unit_dependency_extras (pptx, 3.12, --extra pptx) (push) Has been cancelled
CI / test_unit_dependency_extras (pptx, 3.13, --extra pptx) (push) Has been cancelled
CI / test_unit_dependency_extras (pypandoc, 3.11, --extra epub --extra org --extra rtf --extra rst) (push) Has been cancelled
CI / test_unit_dependency_extras (pypandoc, 3.12, --extra epub --extra org --extra rtf --extra rst) (push) Has been cancelled
CI / test_unit_dependency_extras (pypandoc, 3.13, --extra epub --extra org --extra rtf --extra rst) (push) Has been cancelled
Build And Push Docker Image / set-short-sha (push) Has been cancelled
Partition Benchmark / setup (push) Has been cancelled
Partition Benchmark / Measure and compare partition() runtime (push) Has been cancelled
CI / test_unit_dependency_extras (xlsx, 3.13, --extra xlsx) (push) Has been cancelled
CI / test_ingest_src (3.12) (push) Has been cancelled
CI / test_json_to_markdown (3.12) (push) Has been cancelled
CI / changelog (push) Has been cancelled
CI / test_dockerfile (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Build And Push Docker Image / build-images (linux/amd64, opensource-linux-8core) (push) Has been cancelled
Build And Push Docker Image / build-images (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Build And Push Docker Image / publish-images (push) Has been cancelled
99 lines
3.7 KiB
Python
99 lines
3.7 KiB
Python
from copy import deepcopy
|
|
from typing import Callable, List, Optional
|
|
|
|
from transformers import PreTrainedTokenizer
|
|
|
|
from unstructured.documents.elements import Element, NarrativeText, Text
|
|
|
|
|
|
def stage_for_transformers(
|
|
elements: List[Text],
|
|
tokenizer: PreTrainedTokenizer,
|
|
**chunk_kwargs,
|
|
) -> List[Element]:
|
|
"""Stages text elements for transformers pipelines by chunking them into sections that can
|
|
fit into the attention window for the model associated with the tokenizer."""
|
|
chunked_elements: List[Element] = []
|
|
for element in elements:
|
|
# NOTE(robinson) - Only chunk potentially lengthy text. Shorter text (like titles)
|
|
# should already fit into the attention window just fine.
|
|
if isinstance(element, (NarrativeText, Text)):
|
|
chunked_text = chunk_by_attention_window(element.text, tokenizer, **chunk_kwargs)
|
|
for chunk in chunked_text:
|
|
_chunk_element = deepcopy(element)
|
|
_chunk_element.text = chunk
|
|
chunked_elements.append(_chunk_element)
|
|
else:
|
|
chunked_elements.append(element)
|
|
|
|
return chunked_elements
|
|
|
|
|
|
def chunk_by_attention_window(
|
|
text: str,
|
|
tokenizer: PreTrainedTokenizer,
|
|
buffer: int = 2,
|
|
max_input_size: Optional[int] = None,
|
|
split_function: Callable[[str], List[str]] = lambda text: text.split(" "),
|
|
chunk_separator: str = " ",
|
|
) -> List[str]:
|
|
"""Splits a string of text into chunks that will fit into a model's attention
|
|
window.
|
|
|
|
Parameters
|
|
----------
|
|
text: The raw input text for the model
|
|
tokenizer: The transformers tokenizer for the model
|
|
buffer: Indicates the number of tokens to leave as a buffer for the attention window. This
|
|
is to account for special tokens like [CLS] that can appear at the beginning or
|
|
end of an input sequence.
|
|
max_input_size: The size of the attention window for the model. If not specified, will
|
|
use the model_max_length attribute on the tokenizer object.
|
|
split_function: The function used to split the text into chunks to consider for adding to the
|
|
attention window.
|
|
chunk_separator: The string used to concat adjacent chunks when reconstructing the text
|
|
"""
|
|
max_input_size = tokenizer.model_max_length if max_input_size is None else max_input_size
|
|
if buffer < 0 or buffer >= max_input_size:
|
|
raise ValueError(
|
|
f"buffer is set to {buffer}. Must be greater than zero and smaller than "
|
|
f"max_input_size, which is {max_input_size}.",
|
|
)
|
|
|
|
max_chunk_size = max_input_size - buffer
|
|
|
|
split_text: List[str] = split_function(text)
|
|
num_splits = len(split_text)
|
|
|
|
chunks: List[str] = []
|
|
chunk_text = ""
|
|
chunk_size = 0
|
|
|
|
for i, segment in enumerate(split_text):
|
|
tokens = tokenizer.tokenize(segment)
|
|
num_tokens = len(tokens)
|
|
if num_tokens > max_chunk_size:
|
|
raise ValueError(
|
|
f"The number of tokens in the segment is {num_tokens}. "
|
|
f"The maximum number of tokens is {max_chunk_size}. "
|
|
"Consider using a different split_function to reduce the size "
|
|
"of the segments under consideration. The text that caused the "
|
|
f"error is: \n\n{segment}",
|
|
)
|
|
|
|
if chunk_size + num_tokens > max_chunk_size:
|
|
chunks.append(chunk_text + chunk_separator.strip())
|
|
chunk_text = ""
|
|
chunk_size = 0
|
|
|
|
# NOTE(robinson) - To avoid the separator appearing at the beginning of the string
|
|
if chunk_size > 0:
|
|
chunk_text += chunk_separator
|
|
chunk_text += segment
|
|
chunk_size += num_tokens
|
|
|
|
if i == (num_splits - 1) and len(chunk_text) > 0:
|
|
chunks.append(chunk_text)
|
|
|
|
return chunks
|