DELM:Data Extraction with Language Models
Project description
Data Extraction with Language Models
DELM is a Python toolkit for extracting structured data from unstructured text using language models. It provides a configurable pipeline with cost tracking, caching, and evaluation capabilities.
Features
- Supported input formats: TXT, HTML, MD, DOCX, PDF, CSV, Excel, Parquet, Feather
- Progressive schema system: simple → nested → multiple
- Multiple model providers: OpenAI, Anthropic, Google, Groq, Together AI, Fireworks AI
- Configurable processing: text splitting, relevance scoring, filtering
- Cost management: cost tracking, caching, budget limits
- Batch processing: parallel execution with checkpointing and resume
- Evaluation tools: performance metrics and cost analysis
Installation
pip install delm
Or if you would like to install from source:
# Clone the repository
git clone https://github.com/Center-for-Applied-AI/delm.git
cd delm
# Install from source
pip install -e .
Quick start
Basic usage
from pathlib import Path
from delm import DELM
# Initialize DELM from a pipeline config YAML
delm = DELM.from_yaml(
config_path="example.config.yaml",
experiment_name="my_experiment",
experiment_directory=Path("experiments"),
)
# Process data
df = delm.prep_data("data/input.txt")
results = delm.process_via_llm()
# Get results
final_df = delm.get_extraction_results()
cost_summary = delm.get_cost_summary()
Configuration files
DELM uses two configuration files:
- Pipeline configuration (
config.yaml)
llm_extraction:
provider: "openai"
name: "gpt-4o-mini"
temperature: 0.0
batch_size: 10
track_cost: true
max_budget: 50.0
data_preprocessing:
target_column: "text"
splitting:
type: "ParagraphSplit"
scoring:
type: "KeywordScorer"
keywords: ["price", "forecast", "guidance"]
schema:
spec_path: "schema_spec.yaml"
- Schema specification (
schema_spec.yaml)
schema_type: "nested"
container_name: "commodities"
variables:
- name: "commodity_type"
description: "Type of commodity mentioned"
data_type: "string"
required: true
allowed_values: ["oil", "gas", "copper", "gold"]
- name: "price_value"
description: "Price mentioned in text"
data_type: "number"
required: false
Validation notes:
validate_in_text: trueapplies to string fields only. Values must literally appear (case‑insensitive) in the source text to be kept.
Schema types
DELM supports three levels of schema complexity:
Simple schema (level 1)
Extract key-value pairs from each text chunk:
schema_type: "simple"
variables:
- name: "price"
description: "Price mentioned"
data_type: "number"
- name: "company"
description: "Company name"
data_type: "string"
Nested schema (level 2)
Extract structured objects with multiple fields:
schema_type: "nested"
container_name: "commodities"
variables:
- name: "type"
description: "Commodity type"
data_type: "string"
- name: "price"
description: "Price value"
data_type: "number"
Multiple schemas (level 3)
Extract multiple independent schemas simultaneously:
schema_type: "multiple"
commodities:
schema_type: "nested"
container_name: "commodities"
variables: [...]
companies:
schema_type: "nested"
container_name: "companies"
variables: [...]
Note: Multiple schema outputs are unwrapped. For a nested sub‑schema named books with container books, the output key is books: [...] (not books: {books: [...]}).
Supported data types
| Type | Description | Example |
|---|---|---|
string |
Text values | "Apple Inc." |
number |
Floating-point numbers | 150.5 |
integer |
Whole numbers | 2024 |
boolean |
True/False values | true |
date |
Date strings | "2025-09-15" |
[string] |
List of strings | ["oil", "gas"] |
[number] |
List of numbers | [100, 200, 300] |
[integer] |
List of integers | [1, 2, 3, 4] |
[boolean] |
List of booleans | [true, false, true] |
Advanced features
Cost summary
# Get cost summary after extraction
cost_summary = delm.get_cost_summary()
print(f"Total cost: ${cost_summary['total_cost']}")
Semantic caching
Caches API responses for identical calls to reduce repeated cost in re‑runs.
semantic_cache:
backend: "sqlite" # sqlite, lmdb, filesystem
path: ".delm_cache"
max_size_mb: 512
synchronous: "normal" # sqlite only: "normal" or "full"
Relevance filtering
data_preprocessing:
scoring:
type: "KeywordScorer"
keywords: ["price", "forecast", "guidance"]
pandas_score_filter: "delm_score >= 0.7"
If a scorer is configured but no pandas_score_filter is provided, all chunks are kept (a warning is logged).
You can also use a fuzzy keyword scorer. This requires the optional dependency rapidfuzz.
data_preprocessing:
scoring:
type: "FuzzyScorer"
keywords:
- price
- forecast
- guidance
pandas_score_filter: "delm_score >= 0.5" # example threshold for fuzzy scores
Text splitting strategies
data_preprocessing:
splitting:
type: "ParagraphSplit" # Split by paragraphs
# type: "FixedWindowSplit" # Split by sentence count
# window: 5
# stride: 2
# type: "RegexSplit" # Custom regex pattern
# pattern: "\n\n"
Post-processing
After extraction, explode the JSON column into tabular rows according to your schema.
from delm.utils.post_processing import explode_json_results
# Use the same schema used for extraction (path to the YAML/JSON or a schema object)
exploded_df = explode_json_results(
final_df,
schema=delm.config.schema.spec_path # or a loaded schema object
)
Performance and evaluation
Cost estimation
[!WARNING] Cost estimation is provided as‑is. Estimates are not guarantees and may be inaccurate. The authors and maintainers accept no liability for any losses, charges, or damages resulting from use of this feature. Use at your own risk.
Estimate total cost of your current configuration setup before running the full extraction.
from delm.utils.cost_estimation import estimate_input_token_cost, estimate_total_cost
# Estimate input token costs without API calls
input_cost = estimate_input_token_cost(
config="config.yaml",
data_source="data.csv"
)
print(f"Input token cost: ${input_cost:.2f}")
# Estimate total costs using API calls on a sample
total_cost = estimate_total_cost(
config="config.yaml",
data_source="data.csv",
sample_size=100
)
print(f"Estimated total cost: ${total_cost:.2f}")
Performance evaluation
Estimate the performance of your current configuration before running the full extraction.
from delm.utils.performance_estimation import estimate_performance
# Evaluate against human-labeled data
metrics, expected_and_extracted_df = estimate_performance(
config="config.yaml",
data_source="test_data.csv",
expected_extraction_output_df=human_labeled_df,
true_json_column="expected_json",
matching_id_column="id",
record_sample_size=50 # Optional: limit sample size
)
# Display performance metrics
for key, value in metrics.items():
precision = value.get("precision", 0)
recall = value.get("recall", 0)
f1 = value.get("f1", 0)
print(f"{key:<30} Precision: {precision:.3f} Recall: {recall:.3f} F1: {f1:.3f}")
Configuration reference
Required fields
llm_extraction.provider: LLM provider (openai, anthropic, google, etc.)llm_extraction.name: Model name (gpt-4o-mini, claude-3-sonnet, etc.)schema.spec_path: Path to schema specification file
Optional fields with defaults
llm_extraction.temperature: 0.0 (deterministic)llm_extraction.batch_size: 10 (records per batch)llm_extraction.max_workers: 1 (concurrent workers)llm_extraction.track_cost: true (cost tracking)semantic_cache.backend: "sqlite" (cache backend)
Additional LLM fields
llm_extraction.max_retries: 3 (retry attempts)llm_extraction.base_delay: 1.0 (seconds, exponential backoff base)llm_extraction.dotenv_path: null (path to “.env” for credentials)llm_extraction.model_input_cost_per_1M_tokens: null (override pricing)llm_extraction.model_output_cost_per_1M_tokens: null (override pricing)
If using providers not present in the built-in pricing DB, set both model_input_cost_per_1M_tokens and model_output_cost_per_1M_tokens, or set track_cost: false.
Data preprocessing fields
data_preprocessing.drop_target_column: falsedata_preprocessing.pandas_score_filter: null (e.g., "delm_score >= 0.7")data_preprocessing.preprocessed_data_path: null (path to “.feather” withdelm_text_chunkanddelm_chunk_id; when set, omit splitting/scoring/filter fields)
Semantic cache fields
semantic_cache.backend: "sqlite" | "lmdb" | "filesystem"semantic_cache.path: ".delm_cache"semantic_cache.max_size_mb: 512semantic_cache.synchronous: "normal" | "full" (sqlite only)
Experiment storage and logging
- Disk storage (default): checkpointing, resume, and results persisted under
delm_experiments/<experiment_name>/. - In-memory storage:
use_disk_storage=Falsefor fast prototyping (no persistence, no resume). - Logging: by default, rotating file logs under
delm_logs/<experiment_name>/whensave_file_log=True.- Tunables:
save_file_log,log_dir,console_log_level,file_log_level,override_logging. - Or call
delm.logging.configure(...)directly.
- Tunables:
Architecture
Core components
- DataProcessor: Handles loading, splitting, and scoring
- SchemaManager: Manages schema loading and validation
- ExtractionManager: Orchestrates LLM extraction
- ExperimentManager: Handles experiment state and checkpointing
- CostTracker: Monitors API costs and budgets
Strategy classes
- SplitStrategy: Text chunking (Paragraph, FixedWindow, Regex)
- RelevanceScorer: Content scoring (Keyword, Fuzzy)
- SchemaRegistry: Schema type management
Estimation functions
- estimate_input_token_cost: Estimate input token costs without API calls
- estimate_total_cost: Estimate total costs using API calls on a sample
- estimate_performance: Evaluate extraction performance against human-labeled data
File format support
| Format | Extension | Requirements |
|---|---|---|
| Text | .txt |
Built-in |
| HTML/Markdown | .html, .htm, .md |
beautifulsoup4 |
| Word Documents | .docx |
python-docx |
.pdf |
marker-pdf (OCR) |
|
| CSV | .csv |
pandas |
| Excel | .xlsx |
openpyxl |
| Parquet | .parquet |
pyarrow |
| Feather | .feather |
pyarrow |
Documentation
Local MkDocs site
- Install the documentation dependencies:
pip install mkdocs mkdocs-material mkdocstrings mkdocstrings-python - Serve the docs locally to
http://127.0.0.1:8000/:mkdocs serve - Use
mkdocs buildto generate a static site in thesite/directory.
Reference materials
- Schema Reference - Detailed schema configuration guide
- Configuration Examples - Complete configuration templates
- Schema Examples - Schema specification templates
Acknowledgments
- Built on Instructor for structured outputs
- Uses Marker for PDF processing
- Developed at the Center for Applied AI at Chicago Booth
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file delm-0.1.4.tar.gz.
File metadata
- Download URL: delm-0.1.4.tar.gz
- Upload date:
- Size: 70.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
179ec2d01f879325436b098719416ee9a6d3cd0f6a165118b922477f21df8656
|
|
| MD5 |
848539803405003e7934c843aa71d553
|
|
| BLAKE2b-256 |
c1fe7026131aaea08334f0dcd19b76aecc7a56c3c6d2ef2f7756b2f86e1ddf31
|
File details
Details for the file delm-0.1.4-py3-none-any.whl.
File metadata
- Download URL: delm-0.1.4-py3-none-any.whl
- Upload date:
- Size: 76.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
442ea908337ec48de7367e88cd9b26e48eefd7bbaf0da116543891ce23c1cdee
|
|
| MD5 |
d97e27cddbca63858e8c6ac0ba8e5f4e
|
|
| BLAKE2b-256 |
0c6b4526fdc8d12bef804693a1d274f622405124417adc3e1a7e210f0401e077
|