Long-file input coverage and aggregation experiments
A long file may exceed an encoder's input limit, or lose its tail through max_chunks
or first aggregation. Preflight reports what the configured input pipeline can see;
the comparison workflow then scores the same pair using declared existing strategies.
Start offline
python -m pip install -e ".[chunking]"
python examples/experiments/robustness_and_long_files.py \
--output-dir benchmark_outputs/experiments
matheel experiments long-files \
benchmark_outputs/experiments/left.py benchmark_outputs/experiments/right.py \
--config benchmark_outputs/experiments/long_file_runs.json \
--output-dir benchmark_outputs/long_files
The default runs compare the existing static_hash backend with no chunking, then
character-tokenizer Chonkie chunks aggregated by mean, elementwise max, or first.
A fifth run caps mean aggregation at two chunks. These use no trained-model downloads.
static_hash has no transformer input limit and ignores max_token_length.
These are existing embedding-aggregation choices. max takes the maximum of each
vector coordinate; it does not select the highest-scoring pair of source chunks.
The multi-vector backend has its own late-interaction behavior and ignores the
single-vector chunk_aggregation control.
Preflight without loading a model
matheel experiments preflight solution.py --output benchmark_outputs/preflight.json
For another declared pipeline, pass a JSON object of scorer options:
{
"vector_backend": "sentence_transformers",
"model_name": "sentence-transformers/all-MiniLM-L6-v2",
"max_token_length": 256,
"chunking_method": "chonkie_token",
"chunk_size": 128,
"chunk_overlap": 16,
"max_chunks": 4,
"chunker_options": {"tokenizer": "character"},
"chunk_aggregation": "mean"
}
matheel experiments preflight solution.py --options-file input_options.json \
--output benchmark_outputs/preflight.json
Without --inspect-model, preflight does not load models or contact a model hub.
It reports actual UTF-8 bytes, lines, chunk selection and source alignment. Transformer
token counts and truncation coverage remain unknown. A byte or line count is not a
substitute for the model's tokenizer.
Measure the real tokenizer's truncation
--inspect-model explicitly loads the configured model and tokenizer. It may download
weights unless they are already cached; use HF_HUB_OFFLINE=1 and
TRANSFORMERS_OFFLINE=1 to require cached weights.
HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 \
matheel experiments preflight solution.py --options-file input_options.json \
--inspect-model --output benchmark_outputs/tokenizer_preflight.json
The Python API also accepts an already loaded model or tokenizer:
from matheel.long_files import preflight_long_file
report = preflight_long_file(
source_text, options=input_options, model=loaded_model,
)
With compatible fast-tokenizer offsets, preflight applies the tokenizer's actual
truncation operation. This accounts for special tokens, prompt boundaries and left
or right truncation. The effective input limit is the minimum of the requested cap
and the detected model/tokenizer caps. Query and document limits can be inspected
separately with is_query=True or False.
The model's default prompt is recorded when available. For another wrapper-specific
query/document prefix, pass the exact prefix through the Python API. Preflight cannot
infer arbitrary encoder prompts or additional text normalization. A tokenizer that
supports counting but lacks offsets records count-only evidence; retained source
tokens and bytes are unknown when that input exceeds the cap.
An already truncating Rust tokenizer may not expose an uncapped counting operation;
preflight records that limitation as unknown coverage without mutating it or preventing
the configured scorer from running.
Interpret coverage
The JSON records original and prepared source hashes/byte/line counts, generated and selected chunks, omitted chunks, effective chunks, per-chunk input/retained token counts, and truncation evidence.
selected_chunk_coverage measures the union of chunk-aligned prepared-source bytes;
overlap is not double-counted. Chunk-to-source substring alignment is marked as an
estimate when source is repeated or rewritten. Unmatched generated chunk text yields
unknown coverage. Whitespace trimmed by the existing input preparation is recorded in
the separate original/prepared counts.
effective_model_input_coverage additionally accounts for truncation and first
aggregation. For transformer offsets it counts source bytes spanned by retained tokens,
so whitespace without token offsets is excluded. It measures visible input, not which
tokens influenced a final vector or whether a comparison is semantically correct.
Compare declared configurations
matheel experiments long-files accepts a normal comparison-suite runs JSON file.
It records every configuration, full source text/hashes, implementation hashes,
preflight evidence and score in long_files.json, plus long_files_scores.csv.
Semantic runs inspect their configured model before scoring by default;
--no-inspect-models retains byte/line diagnostics without the extra inspection load.
Failed scorers retain null scores and errors, and make the CLI exit nonzero.
Lexical and code-only scorers use the full prepared source; chunking and vector limits do not apply to those components. Preflight states this when such configurations are compared. Changing a chunk size or aggregation defines an exploratory configuration: it does not modify the frozen plagiarism-v1 256-token protocol or its published scores.
Choose a configuration using measured coverage
The 0.7.1 configuration guidance experiment uses one real Python pair selected by a predeclared byte-count rule. It compares the same pinned cached MiniLM model at a 256-token cap with raw input, 512-character chunks/64-character overlap aggregated by mean, max or first, and mean capped at two chunks. A full-source Winnowing score supplies a lexical comparison. The pair's existing label is retained in its dataset; this one-pair experiment does not estimate classification or retrieval quality.
Read each score next to the input-coverage report. Raw input can omit the tail
when the tokenizer limit is exceeded. Unlimited mean/max aggregation can preserve
more input while changing the representation and score. first still encodes
selected chunks but uses only the first chunk in the final vector, so its extra
work does not provide final-vector tail coverage. max_chunks=2 is an explicit
input budget, with measured omissions rather than a claim of complete coverage.
Character chunk sizes are reproducible input boundaries, not model-token counts. The real tokenizer's per-chunk retained-token measurements determine whether a 512-character chunk itself truncates. Choose chunking and aggregation before evaluating the intended workload, check effective coverage, and compare detection metrics on that workload separately. Full input visibility alone does not make a semantic representation accurate, and these controlled comparisons do not select a universal aggregation strategy.
For the recorded pair, raw MiniLM truncated both files and tokenizer offsets
mapped 30.8%/30.1% of their prepared bytes into retained inputs. Unlimited mean/max
chunks had zero truncated chunks and selected all prepared bytes; their mapped
spans were 78.2%/75.9%, with whitespace outside token offsets excluded from the
calculation. first used mapped spans of 15.0%/16.5% despite encoding six/five
chunks. Its similarity (0.9186) exceeded raw input's (0.9014), illustrating why
a higher similarity score cannot select an aggregation strategy without
evaluation metrics. Full per-run coverage and scores are in the linked evidence.