vit-curator 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vit_curator-0.3.1/.gitignore +52 -0
- vit_curator-0.3.1/LICENSE +21 -0
- vit_curator-0.3.1/PKG-INFO +178 -0
- vit_curator-0.3.1/README.md +129 -0
- vit_curator-0.3.1/pyproject.toml +90 -0
- vit_curator-0.3.1/src/vit_curator/__init__.py +6 -0
- vit_curator-0.3.1/src/vit_curator/cli.py +1459 -0
- vit_curator-0.3.1/src/vit_curator/config.py +267 -0
- vit_curator-0.3.1/src/vit_curator/ingest/__init__.py +30 -0
- vit_curator-0.3.1/src/vit_curator/ingest/archive.py +81 -0
- vit_curator-0.3.1/src/vit_curator/ingest/fsops.py +57 -0
- vit_curator-0.3.1/src/vit_curator/ingest/pipeline.py +478 -0
- vit_curator-0.3.1/src/vit_curator/ingest/sorters.py +58 -0
- vit_curator-0.3.1/src/vit_curator/ingest/state.py +70 -0
- vit_curator-0.3.1/src/vit_curator/ingest/urls.py +70 -0
- vit_curator-0.3.1/src/vit_curator/label/__init__.py +25 -0
- vit_curator-0.3.1/src/vit_curator/label/client.py +212 -0
- vit_curator-0.3.1/src/vit_curator/label/dispatcher.py +354 -0
- vit_curator-0.3.1/src/vit_curator/label/metrics.py +448 -0
- vit_curator-0.3.1/src/vit_curator/label/prompt.py +164 -0
- vit_curator-0.3.1/src/vit_curator/label/scheduler.py +170 -0
- vit_curator-0.3.1/src/vit_curator/label/schemas.py +56 -0
- vit_curator-0.3.1/src/vit_curator/label/store.py +375 -0
- vit_curator-0.3.1/src/vit_curator/langgraph_pipeline.py +249 -0
- vit_curator-0.3.1/src/vit_curator/post/__init__.py +53 -0
- vit_curator-0.3.1/src/vit_curator/post/chunk.py +240 -0
- vit_curator-0.3.1/src/vit_curator/post/embed.py +214 -0
- vit_curator-0.3.1/src/vit_curator/post/enrich.py +541 -0
- vit_curator-0.3.1/src/vit_curator/post/knowledge_graph.py +500 -0
- vit_curator-0.3.1/src/vit_curator/post/layout_graph.py +282 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/__init__.py +41 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/bucket.py +84 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/decode.py +298 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/dedupe.py +217 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/derivatives.py +971 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/perceptual_dedupe.py +338 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/scan.py +160 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/transform.py +278 -0
- vit_curator-0.3.1/src/vit_curator/preprocess/writer_queue.py +292 -0
- vit_curator-0.3.1/src/vit_curator/shared/__init__.py +3 -0
- vit_curator-0.3.1/src/vit_curator/shared/checkpoint.py +43 -0
- vit_curator-0.3.1/src/vit_curator/shared/db.py +498 -0
- vit_curator-0.3.1/src/vit_curator/shared/errors.py +130 -0
- vit_curator-0.3.1/src/vit_curator/shared/hashing.py +61 -0
- vit_curator-0.3.1/src/vit_curator/shared/progress.py +62 -0
- vit_curator-0.3.1/src/vit_curator/shared/signals.py +81 -0
- vit_curator-0.3.1/src/vit_curator/shared/state.py +74 -0
- vit_curator-0.3.1/src/vit_curator/train/__init__.py +34 -0
- vit_curator-0.3.1/src/vit_curator/train/data.py +168 -0
- vit_curator-0.3.1/src/vit_curator/train/evaluate.py +283 -0
- vit_curator-0.3.1/src/vit_curator/train/export.py +184 -0
- vit_curator-0.3.1/src/vit_curator/train/models.py +104 -0
- vit_curator-0.3.1/src/vit_curator/train/predict.py +216 -0
- vit_curator-0.3.1/src/vit_curator/train/train.py +182 -0
- vit_curator-0.3.1/src/vit_curator/tui/__init__.py +45 -0
- vit_curator-0.3.1/src/vit_curator/tui/app.py +490 -0
- vit_curator-0.3.1/src/vit_curator/tui/screens.py +346 -0
- vit_curator-0.3.1/src/vit_curator/tui/themes.py +101 -0
- vit_curator-0.3.1/src/vit_curator/tui/widgets.py +446 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
*.egg
|
|
11
|
+
.installed.cfg
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
ENV/
|
|
18
|
+
|
|
19
|
+
# Test / tooling caches
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
.pyright_cache/
|
|
24
|
+
.coverage
|
|
25
|
+
.coverage.*
|
|
26
|
+
htmlcov/
|
|
27
|
+
.tox/
|
|
28
|
+
.cache
|
|
29
|
+
|
|
30
|
+
# uv
|
|
31
|
+
uv.lock.local
|
|
32
|
+
|
|
33
|
+
# OS / editor
|
|
34
|
+
.DS_Store
|
|
35
|
+
Thumbs.db
|
|
36
|
+
.idea/
|
|
37
|
+
.vscode/
|
|
38
|
+
*.swp
|
|
39
|
+
*.swo
|
|
40
|
+
*~
|
|
41
|
+
|
|
42
|
+
# Build / hatch artifacts
|
|
43
|
+
/src/*.egg-info/
|
|
44
|
+
|
|
45
|
+
# Pipeline runtime data (created by CLI runs)
|
|
46
|
+
var/
|
|
47
|
+
index.duckdb
|
|
48
|
+
*.duckdb
|
|
49
|
+
*.duckdb.wal
|
|
50
|
+
|
|
51
|
+
# Benchmark artifacts
|
|
52
|
+
bench_output/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jakob Charles
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vit-curator
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: End-to-end ML curation pipeline: image ingest, preprocess, VLM label, train/predict, and RAG-style chunk/embed/enrich — single CLI, single DuckDB.
|
|
5
|
+
Author: Jakob Charles
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Requires-Dist: duckdb>=1.0.0
|
|
10
|
+
Requires-Dist: fastai>=2.7.0
|
|
11
|
+
Requires-Dist: httpx>=0.27.0
|
|
12
|
+
Requires-Dist: networkx>=3.2
|
|
13
|
+
Requires-Dist: numpy>=1.26.0
|
|
14
|
+
Requires-Dist: orjson>=3.10.0
|
|
15
|
+
Requires-Dist: pillow>=10.0.0
|
|
16
|
+
Requires-Dist: psutil>=7.2.1
|
|
17
|
+
Requires-Dist: pydantic>=2.7.0
|
|
18
|
+
Requires-Dist: requests>=2.31.0
|
|
19
|
+
Requires-Dist: rich>=13.7.0
|
|
20
|
+
Requires-Dist: torch>=2.0.0
|
|
21
|
+
Requires-Dist: torchvision>=0.16.0
|
|
22
|
+
Requires-Dist: typer>=0.12.0
|
|
23
|
+
Requires-Dist: xxhash>=3.4.1
|
|
24
|
+
Provides-Extra: dali
|
|
25
|
+
Requires-Dist: nvidia-dali-cuda120; extra == 'dali'
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pyright>=1.1.380; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: ruff>=0.6.0; extra == 'dev'
|
|
30
|
+
Provides-Extra: embed
|
|
31
|
+
Requires-Dist: sentence-transformers>=2.2.0; extra == 'embed'
|
|
32
|
+
Provides-Extra: label
|
|
33
|
+
Requires-Dist: nvidia-ml-py>=12.0.0; extra == 'label'
|
|
34
|
+
Provides-Extra: langgraph
|
|
35
|
+
Requires-Dist: langgraph-checkpoint-sqlite>=2.0.0; extra == 'langgraph'
|
|
36
|
+
Requires-Dist: langgraph>=0.2.0; extra == 'langgraph'
|
|
37
|
+
Provides-Extra: train
|
|
38
|
+
Requires-Dist: fastai>=2.7.0; extra == 'train'
|
|
39
|
+
Requires-Dist: ipython>=8.0.0; extra == 'train'
|
|
40
|
+
Requires-Dist: onnx>=1.14.0; extra == 'train'
|
|
41
|
+
Requires-Dist: scikit-learn>=1.3.0; extra == 'train'
|
|
42
|
+
Requires-Dist: torch>=2.0.0; extra == 'train'
|
|
43
|
+
Requires-Dist: torchvision>=0.16.0; extra == 'train'
|
|
44
|
+
Provides-Extra: tui
|
|
45
|
+
Requires-Dist: textual>=0.47.0; extra == 'tui'
|
|
46
|
+
Provides-Extra: vips
|
|
47
|
+
Requires-Dist: pyvips>=2.2.0; extra == 'vips'
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# ViT-Curator
|
|
51
|
+
|
|
52
|
+
> End-to-end ML curation pipeline: image ingest → preprocess → VLM label →
|
|
53
|
+
> train/predict → chunk/embed/enrich, plus a live TUI dashboard.
|
|
54
|
+
> Single CLI, single DuckDB.
|
|
55
|
+
|
|
56
|
+
[](https://github.com/Veedubin/vit-curator/actions/workflows/ci.yml)
|
|
57
|
+
[](https://www.python.org/downloads/)
|
|
58
|
+
[](LICENSE)
|
|
59
|
+
[](https://docs.astral.sh/ruff/)
|
|
60
|
+
|
|
61
|
+
## What it does
|
|
62
|
+
|
|
63
|
+
ViT-Curator is a single command-line tool that turns a giant pile of messy
|
|
64
|
+
images into a deduplicated, labeled, searchable knowledge base — and lets
|
|
65
|
+
you train a custom model to auto-label new images.
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
download/unzip
|
|
69
|
+
→ scan → hash → dedupe → crop/deskew → resize to N presets
|
|
70
|
+
→ VLM (Qwen3-VL) labels every image
|
|
71
|
+
→ train a fastai ViT/ResNet on the labels
|
|
72
|
+
→ predict on new images at low cost
|
|
73
|
+
→ chunk / embed / enrich the captions + text
|
|
74
|
+
→ Textual TUI watches it all run
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Everything lives in **one DuckDB file** — `files`, derivatives, labels,
|
|
78
|
+
runs, predictions, trained models, chunks, embeddings, and enrichments
|
|
79
|
+
all share a single schema with an additive-migration framework.
|
|
80
|
+
|
|
81
|
+
## Installation
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
uv sync # Core dependencies
|
|
85
|
+
uv sync --extra train # + FastAI training
|
|
86
|
+
uv sync --extra label # + nvidia-ml-py for GPU monitoring
|
|
87
|
+
uv sync --extra tui # + Textual dashboard
|
|
88
|
+
uv sync --extra dali # + NVIDIA DALI for GPU decode
|
|
89
|
+
uv sync --extra embed # + sentence-transformers for embeddings
|
|
90
|
+
uv sync --extra dev # + pytest, ruff, pyright
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The CLI entry point is `vit-curator` (alias `up`).
|
|
94
|
+
|
|
95
|
+
## Usage
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Run directly via uv (recommended — no venv activation needed)
|
|
99
|
+
|
|
100
|
+
# 0. Ingest: download URLs, extract archives, sort into a directory layout
|
|
101
|
+
vit-curator ingest --dest /data --download urls.txt
|
|
102
|
+
|
|
103
|
+
# 1-2. Preprocess: scan, hash, dedupe, decode, generate per-preset derivatives
|
|
104
|
+
vit-curator preprocess --src /data/sorted --out /data \
|
|
105
|
+
--presets "vit-train-256=256,thumb-64=64"
|
|
106
|
+
|
|
107
|
+
# 1.5. Near-duplicate detection (phash)
|
|
108
|
+
vit-curator perceptual-dedupe --src /data/sorted --threshold 8
|
|
109
|
+
|
|
110
|
+
# 3. VLM labeling against a running vLLM server
|
|
111
|
+
vit-curator label --db /data/index.duckdb --server-url http://localhost:8000
|
|
112
|
+
|
|
113
|
+
# 4-6. Train, evaluate, predict, export
|
|
114
|
+
vit-curator train --db /data/index.duckdb --run-id <uuid>
|
|
115
|
+
vit-curator evaluate --db /data/index.duckdb --run-id <uuid> --model model.pkl
|
|
116
|
+
vit-curator predict --db /data/index.duckdb --model model.pkl --target-run-id <uuid>
|
|
117
|
+
vit-curator export-model --model model.pkl --formats onnx,torchscript
|
|
118
|
+
|
|
119
|
+
# 7. Post-processing (RAG)
|
|
120
|
+
vit-curator chunk --db /data/index.duckdb --source predictions --run-id <uuid>
|
|
121
|
+
vit-curator embed --db /data/index.duckdb --model sentence-transformers/all-MiniLM-L6-v2
|
|
122
|
+
vit-curator enrich --db /data/index.duckdb --server-url http://localhost:9001
|
|
123
|
+
|
|
124
|
+
# Live Textual TUI dashboard
|
|
125
|
+
vit-curator dashboard --db /data/index.duckdb
|
|
126
|
+
|
|
127
|
+
# YAML config-driven full chain
|
|
128
|
+
vit-curator run-all --config pipeline.yaml --dry-run
|
|
129
|
+
vit-curator run-all --config pipeline.yaml --stages preprocess,train
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Real-world jobs it's good for
|
|
133
|
+
|
|
134
|
+
- **E-commerce cataloging** at scale (dedupe, crop, deskew, auto-tag, train a custom classifier).
|
|
135
|
+
- **Document / archive digitization** with skew correction + semantic search over the OCR'd text.
|
|
136
|
+
- **Dataset curation** before a vision-model fine-tune.
|
|
137
|
+
- **Reverse image search** / near-duplicate detection for a content platform.
|
|
138
|
+
- **RAG from a visual corpus** — turn a museum or archive into a queryable knowledge base.
|
|
139
|
+
|
|
140
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full feature list.
|
|
141
|
+
|
|
142
|
+
## Architecture
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
src/vit_curator/
|
|
146
|
+
├── cli.py # Typer entrypoint — every stage as a subcommand
|
|
147
|
+
├── config.py # Frozen dataclasses for all stage configs
|
|
148
|
+
├── shared/ # DB schema, hashing, errors, progress, signals
|
|
149
|
+
├── ingest/ # Stage 0: download / unarchive / sort
|
|
150
|
+
├── preprocess/ # Stages 1-2: scan, hash, dedupe, decode, derivatives, crop/deskew, perceptual dedupe
|
|
151
|
+
├── label/ # Stage 3: VLM dispatcher + metrics + scheduler
|
|
152
|
+
├── train/ # Stages 4-6: train, evaluate, predict, export
|
|
153
|
+
├── post/ # Stage 7: chunk, embed, enrich
|
|
154
|
+
└── tui/ # Textual dashboard (5 screens, GPU meter, latency histogram)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Development
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
uv sync --extra dev
|
|
161
|
+
uv run ruff check .
|
|
162
|
+
uv run pytest -m "not torch and not fastai and not dali and not nvidia and not slow"
|
|
163
|
+
uv run python scripts/benchmark.py # smoke benchmark of all 4 core stages
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The default test deselection skips tests that need optional heavy stacks
|
|
167
|
+
(torch, fastai, DALI, nvidia-ml-py). To run those locally:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
VIT_CURATOR_TEST_TORCH=1 uv run pytest
|
|
171
|
+
VIT_CURATOR_TEST_FASTAI=1 uv run pytest
|
|
172
|
+
VIT_CURATOR_TEST_DALI=1 uv run pytest
|
|
173
|
+
VIT_CURATOR_TEST_NVIDIA=1 uv run pytest
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# ViT-Curator
|
|
2
|
+
|
|
3
|
+
> End-to-end ML curation pipeline: image ingest → preprocess → VLM label →
|
|
4
|
+
> train/predict → chunk/embed/enrich, plus a live TUI dashboard.
|
|
5
|
+
> Single CLI, single DuckDB.
|
|
6
|
+
|
|
7
|
+
[](https://github.com/Veedubin/vit-curator/actions/workflows/ci.yml)
|
|
8
|
+
[](https://www.python.org/downloads/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://docs.astral.sh/ruff/)
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
ViT-Curator is a single command-line tool that turns a giant pile of messy
|
|
15
|
+
images into a deduplicated, labeled, searchable knowledge base — and lets
|
|
16
|
+
you train a custom model to auto-label new images.
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
download/unzip
|
|
20
|
+
→ scan → hash → dedupe → crop/deskew → resize to N presets
|
|
21
|
+
→ VLM (Qwen3-VL) labels every image
|
|
22
|
+
→ train a fastai ViT/ResNet on the labels
|
|
23
|
+
→ predict on new images at low cost
|
|
24
|
+
→ chunk / embed / enrich the captions + text
|
|
25
|
+
→ Textual TUI watches it all run
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Everything lives in **one DuckDB file** — `files`, derivatives, labels,
|
|
29
|
+
runs, predictions, trained models, chunks, embeddings, and enrichments
|
|
30
|
+
all share a single schema with an additive-migration framework.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
uv sync # Core dependencies
|
|
36
|
+
uv sync --extra train # + FastAI training
|
|
37
|
+
uv sync --extra label # + nvidia-ml-py for GPU monitoring
|
|
38
|
+
uv sync --extra tui # + Textual dashboard
|
|
39
|
+
uv sync --extra dali # + NVIDIA DALI for GPU decode
|
|
40
|
+
uv sync --extra embed # + sentence-transformers for embeddings
|
|
41
|
+
uv sync --extra dev # + pytest, ruff, pyright
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The CLI entry point is `vit-curator` (alias `up`).
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Run directly via uv (recommended — no venv activation needed)
|
|
50
|
+
|
|
51
|
+
# 0. Ingest: download URLs, extract archives, sort into a directory layout
|
|
52
|
+
vit-curator ingest --dest /data --download urls.txt
|
|
53
|
+
|
|
54
|
+
# 1-2. Preprocess: scan, hash, dedupe, decode, generate per-preset derivatives
|
|
55
|
+
vit-curator preprocess --src /data/sorted --out /data \
|
|
56
|
+
--presets "vit-train-256=256,thumb-64=64"
|
|
57
|
+
|
|
58
|
+
# 1.5. Near-duplicate detection (phash)
|
|
59
|
+
vit-curator perceptual-dedupe --src /data/sorted --threshold 8
|
|
60
|
+
|
|
61
|
+
# 3. VLM labeling against a running vLLM server
|
|
62
|
+
vit-curator label --db /data/index.duckdb --server-url http://localhost:8000
|
|
63
|
+
|
|
64
|
+
# 4-6. Train, evaluate, predict, export
|
|
65
|
+
vit-curator train --db /data/index.duckdb --run-id <uuid>
|
|
66
|
+
vit-curator evaluate --db /data/index.duckdb --run-id <uuid> --model model.pkl
|
|
67
|
+
vit-curator predict --db /data/index.duckdb --model model.pkl --target-run-id <uuid>
|
|
68
|
+
vit-curator export-model --model model.pkl --formats onnx,torchscript
|
|
69
|
+
|
|
70
|
+
# 7. Post-processing (RAG)
|
|
71
|
+
vit-curator chunk --db /data/index.duckdb --source predictions --run-id <uuid>
|
|
72
|
+
vit-curator embed --db /data/index.duckdb --model sentence-transformers/all-MiniLM-L6-v2
|
|
73
|
+
vit-curator enrich --db /data/index.duckdb --server-url http://localhost:9001
|
|
74
|
+
|
|
75
|
+
# Live Textual TUI dashboard
|
|
76
|
+
vit-curator dashboard --db /data/index.duckdb
|
|
77
|
+
|
|
78
|
+
# YAML config-driven full chain
|
|
79
|
+
vit-curator run-all --config pipeline.yaml --dry-run
|
|
80
|
+
vit-curator run-all --config pipeline.yaml --stages preprocess,train
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Real-world jobs it's good for
|
|
84
|
+
|
|
85
|
+
- **E-commerce cataloging** at scale (dedupe, crop, deskew, auto-tag, train a custom classifier).
|
|
86
|
+
- **Document / archive digitization** with skew correction + semantic search over the OCR'd text.
|
|
87
|
+
- **Dataset curation** before a vision-model fine-tune.
|
|
88
|
+
- **Reverse image search** / near-duplicate detection for a content platform.
|
|
89
|
+
- **RAG from a visual corpus** — turn a museum or archive into a queryable knowledge base.
|
|
90
|
+
|
|
91
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full feature list.
|
|
92
|
+
|
|
93
|
+
## Architecture
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
src/vit_curator/
|
|
97
|
+
├── cli.py # Typer entrypoint — every stage as a subcommand
|
|
98
|
+
├── config.py # Frozen dataclasses for all stage configs
|
|
99
|
+
├── shared/ # DB schema, hashing, errors, progress, signals
|
|
100
|
+
├── ingest/ # Stage 0: download / unarchive / sort
|
|
101
|
+
├── preprocess/ # Stages 1-2: scan, hash, dedupe, decode, derivatives, crop/deskew, perceptual dedupe
|
|
102
|
+
├── label/ # Stage 3: VLM dispatcher + metrics + scheduler
|
|
103
|
+
├── train/ # Stages 4-6: train, evaluate, predict, export
|
|
104
|
+
├── post/ # Stage 7: chunk, embed, enrich
|
|
105
|
+
└── tui/ # Textual dashboard (5 screens, GPU meter, latency histogram)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Development
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
uv sync --extra dev
|
|
112
|
+
uv run ruff check .
|
|
113
|
+
uv run pytest -m "not torch and not fastai and not dali and not nvidia and not slow"
|
|
114
|
+
uv run python scripts/benchmark.py # smoke benchmark of all 4 core stages
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The default test deselection skips tests that need optional heavy stacks
|
|
118
|
+
(torch, fastai, DALI, nvidia-ml-py). To run those locally:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
VIT_CURATOR_TEST_TORCH=1 uv run pytest
|
|
122
|
+
VIT_CURATOR_TEST_FASTAI=1 uv run pytest
|
|
123
|
+
VIT_CURATOR_TEST_DALI=1 uv run pytest
|
|
124
|
+
VIT_CURATOR_TEST_NVIDIA=1 uv run pytest
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "vit-curator"
|
|
3
|
+
version = "0.3.1"
|
|
4
|
+
description = "End-to-end ML curation pipeline: image ingest, preprocess, VLM label, train/predict, and RAG-style chunk/embed/enrich — single CLI, single DuckDB."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = {text = "MIT"}
|
|
8
|
+
authors = [{name = "Jakob Charles"}]
|
|
9
|
+
dependencies = [
|
|
10
|
+
"duckdb>=1.0.0",
|
|
11
|
+
"rich>=13.7.0",
|
|
12
|
+
"typer>=0.12.0",
|
|
13
|
+
"xxhash>=3.4.1",
|
|
14
|
+
"pillow>=10.0.0",
|
|
15
|
+
"requests>=2.31.0",
|
|
16
|
+
"httpx>=0.27.0",
|
|
17
|
+
"orjson>=3.10.0",
|
|
18
|
+
"pydantic>=2.7.0",
|
|
19
|
+
"psutil>=7.2.1",
|
|
20
|
+
"numpy>=1.26.0",
|
|
21
|
+
"torch>=2.0.0",
|
|
22
|
+
"torchvision>=0.16.0",
|
|
23
|
+
"fastai>=2.7.0",
|
|
24
|
+
"networkx>=3.2",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
dali = ["nvidia-dali-cuda120"]
|
|
29
|
+
vips = ["pyvips>=2.2.0"]
|
|
30
|
+
train = ["fastai>=2.7.0", "torch>=2.0.0", "torchvision>=0.16.0", "scikit-learn>=1.3.0", "onnx>=1.14.0", "ipython>=8.0.0"]
|
|
31
|
+
label = ["nvidia-ml-py>=12.0.0"]
|
|
32
|
+
tui = ["textual>=0.47.0"]
|
|
33
|
+
embed = ["sentence-transformers>=2.2.0"]
|
|
34
|
+
langgraph = ["langgraph>=0.2.0", "langgraph-checkpoint-sqlite>=2.0.0"]
|
|
35
|
+
dev = ["pytest>=8.0.0", "ruff>=0.6.0", "pyright>=1.1.380"]
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
vit-curator = "vit_curator.cli:app"
|
|
39
|
+
up = "vit_curator.cli:app"
|
|
40
|
+
|
|
41
|
+
[build-system]
|
|
42
|
+
requires = ["hatchling>=1.21.0"]
|
|
43
|
+
build-backend = "hatchling.build"
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["src/vit_curator"]
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.sdist]
|
|
49
|
+
include = [
|
|
50
|
+
"src/vit_curator",
|
|
51
|
+
"configs",
|
|
52
|
+
"README.md",
|
|
53
|
+
"LICENSE",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[tool.ruff]
|
|
57
|
+
line-length = 100
|
|
58
|
+
target-version = "py311"
|
|
59
|
+
|
|
60
|
+
[tool.ruff.lint]
|
|
61
|
+
select = ["E", "F", "I", "B", "UP", "SIM", "PL", "RUF"]
|
|
62
|
+
ignore = ["PLR0913", "PLR2004", "PLR0912", "PLR0915", "B008"]
|
|
63
|
+
|
|
64
|
+
[tool.ruff.lint.per-file-ignores]
|
|
65
|
+
"tests/**/*.py" = ["PLC0415"]
|
|
66
|
+
|
|
67
|
+
[tool.pyright]
|
|
68
|
+
typeCheckingMode = "basic"
|
|
69
|
+
pythonVersion = "3.11"
|
|
70
|
+
venvPath = "."
|
|
71
|
+
venv = ".venv"
|
|
72
|
+
reportMissingImports = "warning"
|
|
73
|
+
reportMissingTypeStubs = "warning"
|
|
74
|
+
|
|
75
|
+
[tool.pytest.ini_options]
|
|
76
|
+
testpaths = ["tests"]
|
|
77
|
+
markers = [
|
|
78
|
+
"torch: tests requiring torch (deselect with '-m \"not torch\"')",
|
|
79
|
+
"fastai: tests requiring fastai (deselect with '-m \"not fastai\"')",
|
|
80
|
+
"dali: tests requiring nvidia-dali (deselect with '-m \"not dali\"')",
|
|
81
|
+
"vips: tests requiring pyvips/libvips (deselect with '-m \"not vips\"')",
|
|
82
|
+
"nvidia: tests requiring nvidia GPU (deselect with '-m \"not nvidia\"')",
|
|
83
|
+
"slow: slow-running tests (deselect with '-m \"not slow\"')",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[dependency-groups]
|
|
87
|
+
dev = [
|
|
88
|
+
"pyright>=1.1.409",
|
|
89
|
+
"pytest>=9.0.3",
|
|
90
|
+
]
|