[MarkdownTableSerializer] Chunk overflow with landscape tables in non-landscape mode
Author: mathewmeconryCreated May 11, 2026Updated Sep 13, 2026
Labelsbug
Bug
When we convert and chunk the attached PDF (the original is much bigger, but this is enough to trigger the bug) with the HybridChunker and a limit of 8192 tokens per chunk, the resulting chunk is bigger than 8192 because of the prefix. I believe that the root issue is the table in the wrong orientation, which causes the "table headers" to be repeated multiple times with the MarkdownTableSerializer enabled:
Tabelle 2: Muster der Wahrnehmung in Entscheidungssituationen\n\n| Typ 4: »Abweichendes »breite Problemstreu- | Typ 4: »Abweichendes Verhalten der Kinder« »breite Problemstreu- | Typ 4: »Abweichendes Verhalten der Kinder« »breite Problemstreu- | Typ 4: »Abweichendes Verhalten der Kinder« »breite Problemstreu- | »Abweichendes Verhalten der Kinder« »breite Problemstreu- | »Abweichendes Verhalten der Kinder« »problematische Verhal- »breite Problemstreu- | »Abweichendes Verhalten der Kinder« »problematische Verhal- »besondere Problemlagen | Verhalten der Kinder« »problematische Verhal- »besondere Problemlagen | »problematische Verhal- tensweisen des Kindes »besondere Problemlagen | »problematische Verhal- tensweisen des Kindes »besondere Problemlagen | »problematische Verhal- tensweisen des Kindes »besondere Problemlagen | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- | »problematische Verhal- | Verhalten der Kinder« »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes | »problematische Verhal- tensweisen des Kindes vor allem mit Gesetzes- | »problematische Verhal- tensweisen des Kindes vor allem mit Gesetzes- | »problematische Verhal- tensweisen des Kindes vor allem mit Gesetzes- »besondere Problemlagen Drogenabhängigkeit, [...] | »problematische Verhal- tensweisen des Kindes vor allem mit Gesetzes- »besondere Problemlagen Drogenabhängigkeit, [...] | »problematische Verhal- tensweisen des Kindes vor allem mit Gesetzes- »besondere Problemlagen Drogenabhängigkeit, [...] | »problematische Verhal- tensweisen des Kindes vor allem mit Gesetzes- »besondere Problemlagen Drogenabhängigkeit, [...] | »problematische Verhal- tensweisen des Kindes vor allem mit Gesetzes- »besondere Problemlagen Drogenabhängigkeit, [...] |
PDF:
f2552dc4-ad0d-4086-bc3c-cb4cfc2a8aa5.pdf
Steps to reproduce
- Download the PDF
- Run the following script
import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import (
ThreadedPdfPipelineOptions,
TableStructureV2Options,
TableFormerMode,
EasyOcrOptions,
)
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.accelerator_options import AcceleratorDevice, AcceleratorOptions
from docling_core.transforms.chunker.hybrid_chunker import HybridChunker
from docling_core.transforms.chunker.tokenizer.openai import OpenAITokenizer
from docling_core.transforms.serializer.markdown import (
MarkdownParams,
MarkdownTableSerializer,
)
from docling_core.transforms.chunker.hierarchical_chunker import (
ChunkingDocSerializer,
ChunkingSerializerProvider,
)
import tiktoken
log.info("Starting bug reproduction script...")
log.info("Configuring document converter with CPU acceleration...")
pdf_pipline_options = ThreadedPdfPipelineOptions(
accelerator_options=AcceleratorOptions(
device=AcceleratorDevice.CPU
), # Use CPU acceleration
threads=4,
max_concurrent_results=4,
ocr_batch_size=4, # default 4
layout_batch_size=4, # default 4
table_batch_size=4, # currently not using GPU batching
ocr_options=EasyOcrOptions(
lang=[
"en",
"de",
"fr",
"es",
"it",
"pt",
], # Add more languages as needed
),
)
pdf_pipline_options.enable_remote_services = True
pdf_pipline_options.allow_external_plugins = True
pdf_pipline_options.do_ocr = True
pdf_pipline_options.do_table_structure = True
pdf_pipline_options.do_code_enrichment = False
pdf_pipline_options.do_formula_enrichment = False
pdf_pipline_options.do_chart_extraction = False
pdf_pipline_options.table_structure_options = TableStructureV2Options(
do_cell_matching=True, mode=TableFormerMode.ACCURATE
)
doc_converter = DocumentConverter(
allowed_formats=[
InputFormat.PDF,
# Plain Text formats
InputFormat.HTML,
InputFormat.MD,
InputFormat.CSV,
# Office formats
InputFormat.DOCX,
InputFormat.XLSX,
InputFormat.PPTX,
],
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pdf_pipline_options)
},
)
log.info("Document converter configured. Starting conversion of test document...")
conv_result = doc_converter.convert(
"./f2552dc4-ad0d-4086-bc3c-cb4cfc2a8aa5.pdf"
)
tokenizer = OpenAITokenizer(
tokenizer=tiktoken.encoding_for_model("text-embedding-3-small"),
max_tokens=8192,
)
log.info("Document conversion completed. Starting chunking of converted document...")
class SerializerProvider(ChunkingSerializerProvider):
def get_serializer(self, doc):
return ChunkingDocSerializer(
doc=doc,
table_serializer=MarkdownTableSerializer(),
)
chunker = HybridChunker(
tokenizer=tokenizer,
max_tokens=8192,
repeat_table_headers=True,
merge_peers=True,
serializer_provider=SerializerProvider(),
)
chunk_iter = chunker.chunk(dl_doc=conv_result.document)
for i, chunk in enumerate(chunk_iter):
log.debug(f"Chunk {i}: {chunk}")
enriched_text = chunker.contextualize(chunk=chunk)
if tokenizer.count_tokens(enriched_text) > 8192:
log.warning(f"Chunk {i} exceeds token limit after contextualization: {tokenizer.count_tokens(enriched_text)} tokens")
Output
WARNING:__main__:Chunk 4 exceeds token limit after contextualization: 8241 tokens
WARNING:__main__:Chunk 9 exceeds token limit after contextualization: 8193 tokens
Docling version
"docling=2.91.0", "docling-core[chunking-openai]=2.74.1",
Python version
Python 3.12.13
Source: docling-project/docling