DQM-ML V2 Project Overview
This page is for developers who want to understand how DQM-ML is structured and how to work with the codebase. For a general introduction to what DQM-ML does, check out the Home page.
See also:
Concepts for definitions of Metric, Batch Metric, Data Selection, Processor, and related terminology used throughout this page.
For the full developer guide, see Developer Guide.
Package Architecture
The project is organized as a Python monorepo using uv workspace.
Directory Structure
dqm-ml-workspace/
├── packages/
│ ├── dqm-ml-core/ # Core API & standard metrics
│ ├── dqm-ml-job/ # Pipeline orchestration & data loaders
│ ├── dqm-ml-images/ # Image feature extraction
│ ├── dqm-ml-pytorch/ # PyTorch-based metrics (Domain Gap)
│ └── dqm-ml/ # CLI wrapper & entry point
├── tests/ # Test suite
├── docs/ # Documentation
└── examples/ # Example configurations
Here's how the packages relate to each other:
flowchart TB
job[dqm-ml-job\nOrchestration] --> core[dqm-ml-core\nCore API]
images[dqm-ml-images\nVisual Features] --> core
pytorch[dqm-ml-pytorch\nPyTorch Metrics] --> core
cli[dqm-ml\nCLI Wrapper] --> job
cli --> core
cli --> images
cli --> pytorch
What Each Package Does
| Package | Purpose |
|---|---|
| dqm-ml-core | Defines the base Processor class and three interfaces: MetricsProcessor, FeaturesProcessor, GapProcessor. Provides core metrics (Completeness, Representativeness, Diversity). |
| dqm-ml-job | Handles the data pipeline: loading data, processing batches, and writing results. Think of it as the "engine room." |
| dqm-ml-images | Extracts visual features from images (luminosity, contrast, blur, entropy) - useful for checking image dataset quality. |
| dqm-ml-pytorch | Provides GapProcessor (Domain Gap) and FeaturesProcessor (Image Embeddings) - metrics that need PyTorch. |
| dqm-ml | The CLI entry point - what you use from the command line to run jobs. |
Key Technologies
DQM-ML uses these tools to be fast and reliable:
- uv: Fast Python package manager and workspace orchestrator
- PyArrow: Efficient batch processing and memory-efficient data handling
- nox: Task runner for testing, linting, and documentation
- mkdocs-material: The beautiful documentation you're reading now
Building and Running
Here's how to get started with development:
Setup
Running the CLI
The main entry point is the dqm-ml CLI:
# List available metrics and data loaders
uv run dqm-ml list
# Execute a pipeline from a configuration file
uv run dqm-ml process -p config.yaml
Testing and Quality Checks
We maintain high code quality with automated checks:
# Run all tests, linting, and type checking
uv run nox
# Run specific checks
uv run nox -s test # Run tests
uv run nox -s lint # Check code style
uv run nox -s type_check # Type checking
uv run nox -s docs # Build documentation
Developing New Metrics
If you want to add a new metric (awesome!), here's how it works:
Three Processor Interfaces
DQM-ML V2 defines three distinct processor interfaces, each with its own base class:
| Interface | Base Class | Purpose |
|---|---|---|
| Metrics | MetricsProcessor |
Compute aggregated metric scores from data (Completeness, Representativeness, Diversity) |
| Features | FeaturesProcessor |
Extract feature columns from data (Visual Features, Embeddings) |
| Gap | GapProcessor |
Compute pairwise distances between selections (Domain Gap) |
All three inherit from a common Processor base class which provides:
- __init__, _check_failure_rate, _check_image_fail_fast, needed_columns(), reset()
MetricsProcessor
Extends Processor. Implement:
- generated_metrics() → list[str] — output metric names
- select_columns(batch, prev_features) → dict[str, pa.Array] — select columns (optional, default in base)
- compute_batch_metric(features) → dict[str, pa.Array] — batch statistics
- compute(batch_metrics) → dict[str, Any] — final scores
FeaturesProcessor
Extends Processor. Implement:
- generated_features() → list[str] — output feature column names
- compute_features(batch, prev_features) → dict[str, pa.Array] — new feature columns
- needed_columns() → list[str] — input columns needed (optional, default: input_columns)
GapProcessor
Extends Processor. Implement:
- select_features(batch, prev_features) → dict[str, pa.Array] — retrieve embeddings
- compute_batch_metric(features) → dict[str, pa.Array] — batch statistics
- compute(batch_metrics) → dict[str, Any] — final scores
- compute_delta(source, target) → dict[str, Any] — pairwise distances
Data Loading Pattern
Data loaders work in two tiers:
DataLoader: Factory that discovers what Data Selections are availableDataSelection: Handles iterating through a specific Data Selection in Batches
Coding Standards
We keep the codebase consistent with these tools:
- Linting: ruff - Line length is 120 characters
- Type Checking: mypy - Strict mode enabled
- Formatting:
ruff format- Consistent code style - Testing: pytest with 300-second timeout per test