---
title: "Parsing PDFs, slides, HTML - sanely"
newsletter: "MLOps Community"
date: 2025-10-07
source: https://aaif.live/newsletters/mlopscommunity/2025-10-07-parsing-pdfs-slides-html-sanely
---

# Parsing PDFs, slides, HTML - sanely

*A closer look at Unstructured.io’s 0.18 update and what it changes for RAG pipelines.*

*MLOps Community — Agentic AI Foundation, 2025-10-07*

If you’re worried you’ll be next in an acqui-hire [https://techcrunch.com/2025/10/03/with-its-latest-acqui-hire-openai-is-doubling-down-on-personalized-consumer-ai/] list, it’s worth bookmarking our job board [https://jobs.mlops.community/].

## by

UNSTRUCTURED.IO: LLM-READY DOCUMENT ETL WITHOUT REWRITING YOUR STACK

by Stephen Oladele [https://www.linkedin.com/in/stephenoladele/]

Since its first commit in 2022, Unstructured [https://docs.unstructured.io/welcome] grew from a PDF splitter into a modular ETL stack for unstructured content:

 1. OSS extraction library (unstructured)
 2. ML add-ons (unstructured-inference)
 3. Scalable pipelines (unstructured-ingest)
 4. Serverless/hosted Partition and Chunking API

That mix is why it shows up in so many production RAG stacks today. Version 0.18 OSS series (summer 2025)introduced faster PDF partitioning and improved chunking API for RAG pipelines.


⏩ TL;DR

 * Use Unstructured when you need reliable, typed elements from heterogeneous docs (PDFs, slides, HTML) and want sane chunking and table/image handling.
 * Run fast for text-heavy digital PDFs; switch to hi_res (layout models) for scans/mixed layouts; use the API for strategies like vlm and extra chunking options.
 * Watch for heavier deps/perf with hi_res, table extraction flags, and API-only features.
 * ⭐ Verdict: 4.4/5 (the most pragmatic doc ETL for LLMs; not magic, but battle-tested.)


WHAT IS UNSTRUCTURED?

An open-source ETL framework [https://github.com/Unstructured-IO/unstructured] that:

 1. Loads documents from 40+ sources [https://docs.unstructured.io/open-source/ingestion/source-connectors/overview] (filesystem, S3, GMail, Jira, …).
 2. Partitions each file into logical elements (Title, NarrativeText, Table, ListItem, PageBreak).
 3. Enriches with layout ML (table boundaries, header detection, image OCR).
 4. Spits out JSON, Markdown, HTML, or Arrow, with coordinates, page numbers, languages, SHA hashes.

The same API powers:

 * Python SDK (from unstructured.partition.pdf import partition_pdf(...))
 * CLI (unstructured-ingest --strategy hi_res --recursive s3://bucket …)
 * Cloud SaaS/Docker micro-service (POST /general/v0/general)


KEY FEATURES OF UNSTRUCTURED

Here are all the core parts of Unstructured:


HOW UNSTRUCTURED WORKS (UNDER THE HOOD)

Partition → Elements → Chunk → Embed


You call a partition_* function (or the API). It returns a list of typed elements (e.g., Title, NarrativeText, Table) with metadata (page, coords, text_as_html for tables, etc.). You then chunk those elements (e.g., “by_title”) and embed the chunks.

Extraction strategies

 * fast: fastest, fewer heavy dependencies; good for bulk/simple docs.
 * hi_res: uses unstructured-inference layout models (Detectron2) for higher fidelity on PDFs/slides; better table/figure handling (needs OS deps).
 * vlm: uses a vision-language model for image-heavy docs or screenshots.

Tables and images

 * Turn on infer_table_structure (and for PDFs, pdf_infer_table_structure) to preserve tables (HTML in metadata.text_as_html).
 * There’s a guided “Extract tables as HTML” and “Extract images and tables” how-to in docs.

Chunking

 * Core chunkers combine neighboring elements with size limits; by_title respects section boundaries (and never mixes a Table with other text). API adds extra strategies and parameters (combine_under_n_chars, multipage_sections, by_similarity).


QUICK SPIN-UP (TWO WAYS)


A) ONE-LINE API (DOCKER OR HOSTED)

Shell # Local API (example) docker pull downloads.unstructured.io/unstructured-io/unstructured-api:latest # Run locally docker run -p 8000:8000 -d --rm --name unstructured-api \ downloads.unstructured.io/unstructured-io/unstructured-api:latest # Send a PDF → get elements + chunks, hi-res + tables HTML preserved curl -X POST "http://localhost:8000/general/v0/general" \ -H "Content-Type: multipart/form-data" \ -F "files=@sample.pdf" \ -F "strategy=hi_res" \ -F "chunking_strategy=by_title" \ -F "combine_under_n_chars=500" \ -F "multipage_sections=true" \ -F "include_orig_elements=true"

Why this way? Fewer OS deps; newest chunking features are first-class in the API.

B) Local Python (OSS): digital PDF, keep it fast

Python # pip install "unstructured[pdf]" from unstructured.partition.pdf import partition_pdf elements = partition_pdf( filename="report.pdf", strategy="fast", # try fast first; faster on simple PDFs extract_images=False ) # elements is a list of typed blocks: Title, NarrativeText, ListItem, Table, ...

Unstructured’s docs recommend [https://docs.unstructured.io/api-reference/partition/speed-up-large-files-batches] trying fast on simple PDFs before reaching for hi_res to reduce processing time.

C) Local Python (scanned or mixed layout PDF, include tables)

Python # pip install "unstructured[pdf-inference]" # brings layout/ocr deps from unstructured.partition.pdf import partition_pdf elements = partition_pdf( filename="financials_scanned.pdf", strategy="hi_res", # layout models (Detectron2/YOLOX) infer_table_structure=True, # include HTML table structure extract_images=True )

(Note: hi_res needs OS deps like poppler, tesseract, libmagic, libreoffice per README.)

Connectors for Real Pipelines

Need to pull from SaaS or clouds and push to a lake/vector DB? Unstructured Ingest ships many source [https://docs.unstructured.io/open-source/ingestion/source-connectors/overview] and destination connectors [https://docs.unstructured.io/open-source/ingestion/destination-connectors/overview] (S3/GCS/Azure, Confluence, Notion, Salesforce, Airtable, Slack, SharePoint, etc.), and can call the API directly (--partition-by-api).

Example (Airtable → API → JSON):

Shell # deps pip install "unstructured-ingest[airtable]" # run local API in another shell if you want to avoid hosted keys: # docker run -p 8000:8000 -d --rm --name unstructured-api \ # downloads.unstructured.io/unstructured-io/unstructured-api:latest unstructured-ingest \ airtable \ --personal-access-token "$AIRTABLE_PAT" \ --list-of-paths "appr9nKeXLAtg6bgn/tblZ8uT1GY7NLbWit" \ --output-dir ./local-out \ --num-processes 2 \ --reprocess \ --partition-by-api \ --partition-endpoint "http://localhost:8000/general/v0/general"


WHY MLOPS ENGINEERS SHOULD CARE

 1. 
    Better recall with fewer hallucinations: Element-aware chunking [https://docs.unstructured.io/open-source/core-functionality/chunking] maintains the section semantics and table structure, resulting in retrieval units that are cleaner than those produced by blind text splits.
 2. Switchable fidelity: fast for throughput; hi_res when layout matters (scientific PDFs, slide decks).
 3. Production dataplane: Use the API [https://docs.unstructured.io/open-source/ingestion/overview] to avoid wrestling with OS deps and to access advanced chunking controls.
 4. End-to-end ingestion: Connectors [https://docs.unstructured.io/open-source/ingestion/source-connectors/overview] + chunking + metadata pave a straight path to embeddings and vector stores.
 5. API extras. The hosted API exposes chunking modes [https://docs.unstructured.io/api-reference/api-services/chunking] and strategies beyond OSS defaults (e.g., vlm).


GOTCHAS AND CAVEATS (READ THIS BEFORE YOU ROLL OUT)

 1. hi_res is heavier. Layout inference improves accuracy on tables/figures but increases runtime and system deps; try fast first on digital PDFs.
 2. Tables aren’t “just there.” On PDFs [https://docs.unstructured.io/examplecode/codesamples/apioss/table-extraction-from-pdf] you’ll want strategy="hi_res" and skip_infer_table_types=False to populate text_as_html on Table elements. (The older pdf_infer_table_structure is deprecated.)
 3. API-only capabilities exist. Some strategies (e.g., vlm) and chunking options are exposed in the Serverless API [https://docs.unstructured.io/api-reference/partition/partitioning] rather than the OSS path.
 4. OCR languages and agents. For non-English scans, pass languages=[...] (API [https://docs.unstructured.io/api-reference/general/summary]) or set the OCR agent in OSS; you’ll need language packs.
 5. Large-file performance. Unstructured’s docs include concrete tuning tips [https://docs.unstructured.io/open-source/how-to/speed-up-large-files-batches] for big PDFs/batches; read them before you queue a 2k-page corpus.


SANITY-CHECK SCENARIOS

 * RAG for financial filings (scanned + tables). Use strategy="hi_res" with skip_infer_table_types=False; chunk by title/semantics; consider API if you want vlm for image-heavy pages.
 * Policy docs/handbooks (digital PDFs). Run fast, chunk by titles/sections. Faster, fewer deps, usually enough fidelity.
 * SharePoint/Confluence crawl. Use unstructured-ingest [https://docs.unstructured.io/open-source/ingestion/ingest-cli]; start local, then flip --partition-by-api for scale without changing code.

Community Pulse

https://mlops-community.slack.com/archives/C015J2Y9RLM/p1734196244184519?thread_ts=1734152489.432569&cid=C015J2Y9RLM

Thread link [https://mlops-community.slack.com/archives/C015J2Y9RLM/p1734196244184519?thread_ts=1734152489.432569&cid=C015J2Y9RLM]


REAL-WORLD USE CASE: AGENTIC SAFETY RED-TEAM

 1. Ingest 10 k annual reports (PDF) from S3 nightly.
 2. Hi-Res partition with table inference → JSON → DuckDB.
 3. Chunk + embed with OpenAI Ada-3.
 4. Query via LangChain retriever in chatbot.
 5. Outcome: 40% reduction in hallucinated KPIs vs. plain pdfminer pipeline.


HOW UNSTRUCTURED STACKS UP (2025)

➡️ Third-party rows are directional; choose based on vendor posture, compliance, and TCO.

Final Verdict: 4.4/5 “Pragmatic, Proven, and Worth the Slot in Your Stack”

Rating: ⭐⭐⭐⭐☆ (4.4/5)

✅ Ship it if…

 * Your corpus spans scans + digital PDFs + HTML/Office, and you need typed elements (esp. tables, images).
 * You want one ETL that can run locally now and API later (same JSON shape).
 * You need connectors to move content at scale without writing crawlers.

❌ Hold off if…

 * Your docs are all digital PDFs with simple text and a basic text extractor suffices.
 * You can’t accept heavier deps/runtime for hi_res, and no API usage is allowed.
 * You already standardized on a single cloud OCR like LlamaParse [https://developers.llamaindex.ai/python/framework/llama_cloud/llama_parse/]/Llama Cloud [https://cloud.llamaindex.ai/] that meets all needs and don’t need OSS flexibility.

Bottom line: For teams serious about production RAG/agents over messy docs, Unstructured gives you a cohesive OSS toolbox (from one-liners to a full ETL) with the right escape hatches for fidelity and scale.

📌 Resources to Learn More

 * Docs & Quick-starts: https://docs.unstructured.io/welcome
 * GitHub core library: https://github.com/Unstructured-IO/unstructured
 * Ingest connectors: https://github.com/Unstructured-IO/unstructured-ingest
 * Chunking best practices blog: https://unstructured.io/blog/chunking-for-rag-best-practices
 * Example notebooks: https://github.com/Unstructured-IO/notebooks

Interested in partnering with us? Get in touch: partners@mlops.community

Thanks for reading. See you in Slack [https://go.mlops.community/slack], YouTube [https://www.youtube.com/channel/UCG6qpjVnBTTT8wLGBygANOQ?view_as=subscriber], and podcast [https://home.mlops.community/public/content/] land. Oh yeah, and we are also on X [https://twitter.com/mlopscommunity] and LinkedIn [https://go.mlops.community/linkedin].

---
Source: https://aaif.live/newsletters/mlopscommunity/2025-10-07-parsing-pdfs-slides-html-sanely
