Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ccaa8cc
docs(changelog): consolidate the 0.6.0 release section with highlight…
davidamacey Oct 16, 2026
b7fd93c
chore(release): bump version to 0.6.0
davidamacey Oct 16, 2026
81d904f
docs(release): add the 0.6.0 release notes and refresh status docs fo…
davidamacey Oct 16, 2026
6220004
docs(release): name only the current release in docs and rename the 0…
davidamacey Oct 16, 2026
e957146
feat(bench): add scale_run driver for 100k ingest benchmarks
davidamacey Oct 15, 2026
2e469a2
feat(datasets): add pinned Open Images train benchmark fetcher
davidamacey Oct 15, 2026
3a9042a
feat(bench): scale_run manifest source and Open Images pin checksum
davidamacey Oct 15, 2026
429a777
docs(changelog): note the scale benchmark driver and Open Images fetcher
davidamacey Oct 16, 2026
3ab646b
docs(performance): add the 10k and 100k scale ladder results
davidamacey Oct 16, 2026
d6d5f4e
docs(release): record the scale ladder in the 0.6.0 notes
davidamacey Oct 16, 2026
07cb77f
fix(ingest): charge a GPU-decoded photo its encoded size at the admis…
davidamacey Oct 16, 2026
c229272
perf(ingest): read a batch's source files in parallel off the event loop
davidamacey Oct 16, 2026
3852686
docs(storage): write-path investigation, NVMe recommendation, OP_OPEN…
davidamacey Oct 16, 2026
af357f0
Merge branch 'perf/ingest-write-path' into release/0.6.0
davidamacey Oct 16, 2026
9c8ff20
docs(performance): record the 20 MP re-check after the admission and …
davidamacey Oct 16, 2026
ced6ec2
docs(release): add the large-photo ingest result to the 0.6.0 highlights
davidamacey Oct 16, 2026
965bc00
docs(screenshots): refresh for 0.6.0
davidamacey Oct 16, 2026
facadef
fix(release): scale_run uses the shared API prefix helper; allow the …
davidamacey Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 121 additions & 9 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ where things live, and the commands and rules that matter.

Before making design decisions or judgment calls, read
[`docs/VISION_AND_GOALS.md`](docs/VISION_AND_GOALS.md): what OpenProcessor is
for, the v0.5.0 feature scope, and the standards the code is held to (no dead
for, the v0.6.0 feature scope, and the standards the code is held to (no dead
code, no compatibility shims, fail-closed isolation, class identity by name
never index, review depth matched to real risk).

Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,27 @@ README is the overview, the install and a first result.
- **Dataset import, combine, export, train, promote.** YOLO, COCO and
OpenProcessor-export layouts; merge up to eight projects; bake-off model
comparison; promotion back into Triton.
- **Selective VLM assist.** `POST /assist/runs` sends a crop, a box, a
selection, a cluster, a sub-cluster or a filter to the VLM, whole or as a
representative sample, and proposes a cluster label you apply explicitly
(see [Selective VLM and segmenter assist](docs-site/docs/guides/selective-assist.mdx)).
A project calls no VLM until it activates one.
- **Bulk ingest.** A folder, a manifest or an S3 bucket runs as a background
job with a preview first; ingest can also be detection-only.
- **Class identity by name.** Import, combine, export, train, promote and
model sharing map classes by name, never by index.
- **The lock rule.** A human-set or import-validated label or box, and
anything in the frozen test holdout, is never overwritten by an automated
writer.

**What's new in 0.6.0.** Faster ingest (images decoded once, uint8 inputs to
Triton, an FP16 embedding engine, GPU decode for large photos, multi-GPU
embedding, batched writes; numbers in [`docs/PERFORMANCE.md`](docs/PERFORMANCE.md)),
assist runs, bulk and S3 ingest, and a cleaned-up codebase. Upgrading from 0.5.0:
read the upgrade notes in [`CHANGELOG.md`](CHANGELOG.md) (new projects start
with the VLM off, `CROPWRIGHT_*` env names are now `OP_CROPWRIGHT_*`, the
evaluator has its own `evaluator` profile).

The whole curation surface is in
[`contracts/openapi/curation.json`](contracts/openapi/curation.json); the
guides are under [`docs-site/docs/guides/`](docs-site/docs/guides/).
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.5.0
0.6.0
22 changes: 11 additions & 11 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ x-gateway-wrap: &gateway_wrap |

services:
triton-server:
image: ${OP_TRITON_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-triton:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_TRITON_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-triton:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-triton
logging: *default-logging
restart: always
Expand Down Expand Up @@ -139,7 +139,7 @@ services:
- triton_net

api:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-api
logging: *default-logging
restart: always
Expand Down Expand Up @@ -331,7 +331,7 @@ services:
cropwright:
profiles: ['cropwright']
# OP_CROPWRIGHT_IMAGE (a full reference, e.g. a digest pin) wins over the OP_IMAGE_TAG default.
image: ${OP_CROPWRIGHT_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/cropwright:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_CROPWRIGHT_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/cropwright:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-cropwright
# Soft scheduling floor for the static-file nginx, not a cap.
mem_reservation: 64m
Expand Down Expand Up @@ -399,7 +399,7 @@ services:
# ===================================================================

curation-detection-worker:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-detection-worker
logging: *default-logging
mem_reservation: 1g
Expand Down Expand Up @@ -465,7 +465,7 @@ services:
- triton_net

curation-vlm-worker:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-vlm-worker
logging: *default-logging
mem_reservation: 512m
Expand Down Expand Up @@ -504,7 +504,7 @@ services:
- triton_net

curation-auto-label-worker:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-auto-label-worker
logging: *default-logging
# deploy form, not mem_reservation: Compose rejects the two together, and
Expand Down Expand Up @@ -573,7 +573,7 @@ services:
- triton_net

curation-cluster-refresh:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-cluster-refresh
logging: *default-logging
mem_reservation: 1g
Expand Down Expand Up @@ -610,7 +610,7 @@ services:
# profile, so `--profile curation up -d` does not reserve a GPU for it.
# `docker compose run --rm curation-evaluator`.
curation-evaluator:
image: ${OP_EVALUATOR_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-evaluator:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_EVALUATOR_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-evaluator:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-evaluator
logging: *default-logging
profiles:
Expand Down Expand Up @@ -652,7 +652,7 @@ services:
# OP_SEGMENTER_URL=http://segmenter:8000 \
# docker compose --profile curation --profile segmenter up -d
segmenter:
image: ${OP_SEGMENTER_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-segmenter:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_SEGMENTER_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-segmenter:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-segmenter
logging: *default-logging
profiles:
Expand Down Expand Up @@ -721,7 +721,7 @@ services:
# ===================================================================

curation-trainer:
image: ${OP_TRAINER_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-trainer:${OP_IMAGE_TAG:-0.5.0}}
image: ${OP_TRAINER_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-trainer:${OP_IMAGE_TAG:-0.6.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-trainer
logging: *default-logging
profiles:
Expand Down Expand Up @@ -1102,7 +1102,7 @@ services:
soft: 65536
hard: 65536
volumes:
- opensearch_data:/usr/share/opensearch/data
- ${OP_OPENSEARCH_DATA:-opensearch_data}:/usr/share/opensearch/data
ports:
- "${OP_BIND_ADDRESS:-127.0.0.1}:${OPENSEARCH_PORT:-4607}:9200" # REST API
healthcheck:
Expand Down
11 changes: 7 additions & 4 deletions docs-site/docs/about/vision-and-goals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The pipeline, end to end: ingest, detection, region stage (one or many boxes per
embedding and clustering, human and AI review, import of labeled datasets, export,
training, bake-off, and promotion back into serving.

## What v0.5.0 delivers
## What v0.6.0 delivers

- Isolated projects, each with its own indexes, directories and class registry.
- Editable prompt packs and region profiles, versioned and revertible.
Expand All @@ -31,6 +31,8 @@ training, bake-off, and promotion back into serving.
- Dataset import (YOLO, COCO, OpenProcessor exports) and project combine, with classes
mapped by name.
- A one-line installer.
- Assist runs: send a crop, a selection, a cluster or a filter to the VLM and apply the proposed label explicitly.
- Bulk ingest from a folder, a manifest or S3, with a preview, and measured ingest speed-ups (decode once, uint8 inputs, FP16 embeddings, GPU decode, multi-GPU embedding).
- Documentation for every feature, and a public, reproducible cars-and-wheels example.

## Standards the code is held to
Expand All @@ -44,10 +46,11 @@ training, bake-off, and promotion back into serving.
operation.
- Work is merged in waves, each with its own gate.

## Not in v0.5.0
## Not in v0.6.0

Deep GPU and Triton pipeline optimization (issue #40), benchmarks, a technical white
paper and more domain showcases are planned after the release.
The full zero-copy GPU pipeline (issue #40), the 1M-image scale step, request-driven
processing plans, faces and OCR on resident crops, a technical white paper and more
domain showcases are planned for the next release and after.

## More detail

Expand Down
2 changes: 1 addition & 1 deletion docs-site/docs/api-reference/curation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: Curation routes
# Curation routes

:::info[Experimental]
The curation subsystem is experimental in v0.5.0. It is real and tested,
The curation subsystem is experimental in v0.6.0. It is real and tested,
but backward compatibility across releases is not guaranteed until it
graduates. It ships opt-in behind the `curation` compose profile.
:::
Expand Down
2 changes: 1 addition & 1 deletion docs-site/docs/getting-started/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The curation subsystem is **domain-agnostic**: nothing about "what an item
or a region of interest is" is hardcoded. It is **bring-your-own-model**:
you supply the item detector, and optionally a VLM, a region detector and
training data. It ships **opt-in** behind the `curation` compose profile and,
like the rest of the API, has **no authentication**. v0.5.0 keeps no
like the rest of the API, has **no authentication**. v0.6.0 keeps no
compatibility shims: a renamed environment variable is rejected at startup,
not translated.

Expand Down
2 changes: 1 addition & 1 deletion docs-site/docs/getting-started/quick-start.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ both `triton` and `opensearch` report `"ok": true`:
```json
{
"status": "ready",
"version": "0.5.0",
"version": "0.6.0",
"api_version": "v1",
"services": {
"triton": {"ok": true, "detail": "is_server_live OK", ...},
Expand Down
2 changes: 2 additions & 0 deletions docs-site/docs/guides/ingest-large-folder.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ Measured rates, all on an RTX A6000, from
| 12 to 24 MP photos, `/ingest/batch`, CPU decode, detect and embed | 27.0 images/s | Decode once and the GPU decode |
| The same photos with GPU decode | 35.0 images/s | Decode once and the GPU decode |
| The same photos, GPU decode, detect only | 44.0 images/s | Decode once and the GPU decode |
| 100,000 public Open Images (up to 0.7 MP), one A6000, stopped and resumed once | 35.96 images/s | Scale ladder: 10k and 100k |
| 100,000 camera-original 20 MP JPEGs on a NAS, one A6000, stopped and resumed once | 21.00 images/s | Scale ladder: 10k and 100k |

Host CPU per photo at bulk was 1.12 s on the CPU path and 0.34 s with GPU decode.

Expand Down
77 changes: 77 additions & 0 deletions docs-site/docs/operations/storage.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
sidebar_position: 10
title: Storage and sizing
---

# Storage and sizing

**Put the OpenSearch data directory on local NVMe.** Do not put it on a network share (NFS, SMB, a NAS
volume), and keep it off the disk that holds your source images when that disk is shared. OpenSearch
syncs its transaction log on every bulk request, flushes segments and merges them in the background;
those are many small synced writes, which a local SSD absorbs and a network share does not under load.

## What was measured

One OpenSearch 3.6.0 node (2 GB heap, the project's index bodies and Lucene HNSW fields, random
1024-dimension vectors in documents shaped like real crop and image documents, 60,000 crop documents
plus 9,375 image documents per run, 4 bulk writers of 1,000 documents), data on local NVMe against
data on the NAS array (md RAID6, ext4), same host and same moment. Raw files:
`docs/benchmarks/write_path_*.json`; method and every number: `docs/design/ingest_write_path_investigation.md`.

| Case | NVMe | NAS |
|---|---:|---:|
| Documents per second, nothing else running (4 writers) | 3,199 | 2,631 |
| Documents per second, 8 writers | 5,334 | 3,542 |
| Flush time per run (node counter) | 3.4 s | 14.8 s |
| Same run while two readers stream source photos from the same NAS (167 MB/s) | 2,511 docs/s, bulk p95 2.6 s | 1,106 docs/s, bulk p95 14.7 s, flush 26 s |

Alone, the NAS costs about 18 percent of write speed. Sharing the array with the image reads
costs 2.3 times, and the slowest bulk request grows from 2.6 to 14.7 seconds. A 100,000-image
run at 36 images per second needs about 200 documents per second, so OpenSearch on a NAS keeps up
with ingest; the damage is the tail (stalls during merges and while other jobs use the array), and
every other consumer of that array pays for the merge traffic.

## Sizing

| Quantity | Measured |
|---|---:|
| Index size per 100,000 small images (about 0.7 MP, 4.9 crops each) | 8.9 GiB (about 91 KB per image) |
| Index size per 100,000 camera photos (20 MP, 2.4 crops each) | 4.4 GiB (about 47 KB per image) |
| Index bytes per crop | about 19.5 KB |
| Segments after a 100,000-image run (before any merge) | 128 to 159 |

Plan for about 20 KB per crop plus the same again for merge headroom: a million small images is
about 90 GiB of index and needs about 180 GiB free. Merges rewrite data many times over (one
real index merged 68 GB in total to hold a few GB), so free space is a hard requirement, not a
comfort.

## Moving the data directory to NVMe

`OP_OPENSEARCH_DATA` in `.env` is either a Docker volume name (the default, `opensearch_data`) or
an absolute host path. To move an existing deployment:

```bash
./openprocessor stop # or: make down
sudo mkdir -p /srv/opensearch-data
sudo docker run --rm -v <project>_opensearch_data:/from -v /srv/opensearch-data:/to \
alpine sh -c 'cp -a /from/. /to/' # <project> is COMPOSE_PROJECT_NAME
sudo chown -R 1000:1000 /srv/opensearch-data # OpenSearch runs as uid 1000
echo 'OP_OPENSEARCH_DATA=/srv/opensearch-data' >> .env
./openprocessor start
curl -s localhost:4607/_cluster/health # green, then check the document counts
```

Keep the old volume until the counts match, then remove it.

## Ingest settings that depend on where the files are

- `OP_INGEST_READ_THREADS` (default 8): threads per API worker that read a batch's source files in
parallel. One read after another from a share ran at 155 MB/s; 16 in parallel at 700 MB/s.
- `OP_INGEST_INFLIGHT_MB` (default 1024): decoded megabytes one worker holds. Photos the GPU
decode takes are counted by their encoded size, so a 16-photo request of 20 MP no longer fills
the whole budget.

Index-level levers that were tried and are not recommended for bulk runs on this index type
(`refresh_interval` -1 or 30 s were 28 percent slower, because the HNSW graph is then built in
one large flush; `translog.durability: async` gained 3 to 12 percent and gives up the crash
guarantee) are in the investigation file.
4 changes: 2 additions & 2 deletions docs-site/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs-site/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openprocessor-docs",
"version": "0.5.0",
"version": "0.6.0",
"private": true,
"license": "AGPL-3.0-or-later",
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions docs-site/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const sidebars: SidebarsConfig = {
'operations/training-and-promote',
'operations/monitoring',
'operations/release-acceptance',
'operations/storage',
'operations/upgrade-and-backup',
],
},
Expand Down
25 changes: 11 additions & 14 deletions docs-site/src/data/roadmap.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,25 @@
"note": "Hand-maintained, not derived from an issue tracker. 'Shipped' means it is on main today; 'Planned' items are design work that has not landed and may change after measurement. Update this file when scope actually changes; never describe work that isn't planned.",
"releases": [
{
"version": "v0.5.0",
"headline": "The monorepo release: backend and Cropwright in one repository, label confirmation, one-port gateway",
"version": "v0.6.0",
"headline": "Faster ingest and assist runs: selective VLM labeling, bulk ingest, measured GPU pipeline steps",
"stage": "shipped",
"summary": "The Triton-backed core API and the opt-in /curation active-learning subsystem, now released together with the Cropwright frontend (frontend/) from one repository and one docs site. Adds label confirmation (VLM scope policy, detector class kept beside VLM labels, accuracy audit, audit-gated auto-promote), the gateway, and a refreshed dependency set.",
"summary": "The measured first half of the Triton throughput plan (decode once, uint8 inputs, FP16 PE image encoder, GPU decode, multi-GPU embedding, coalesced writes) plus assist runs, bulk and S3 ingest, detection-only ingest and a repository cleanup. Numbers are in docs/PERFORMANCE.md.",
"items": [
"Backend and the Cropwright web UI in one repository, built and pinned together; one docs site",
"Label confirmation: per-project VLM scope policy, the detector's own class kept beside VLM labels, a detector_disagreements review tab, an accuracy audit with Wilson 95% intervals, and an audit gate on auto-promote",
"Optional detector hint for VLM prompt packs (detector_hint_min_confidence_pct, off by default; +7.8 points overall accuracy on a COCO oracle)",
"Gateway: Grafana, Prometheus, OpenSearch Dashboards and MLflow on sub-paths of the single Cropwright port (OP_GATEWAY_SUBPATHS)",
"Breaking: the compose service yolo-api is now api; the unread ocr_det_* region profile fields are removed",
"/curation: 266 method routes in the generated OpenAPI contract",
"Refreshed dependencies: FastAPI 0.143 and Pydantic 2.14, SvelteKit 3 and TypeScript 6, MLflow 3.17, PyTorch 2.14.1 segmenter base, Playwright 1.63",
"Opt-in compose profiles: curation, segmenter, vlm, training, monitoring, benchmark, cropwright"
"Assist runs (/assist/runs): send a crop, box, selection, cluster, sub-cluster or filter to the VLM; cluster label proposals applied explicitly",
"Prompt-pack attributes replace the hard-coded make and model; a project calls no VLM until one is activated",
"Bulk ingest of a folder, manifest or S3 with a preview; detection-only ingest",
"Ingest speed-ups: decode once, uint8 inputs, FP16 PE image encoder, GPU decode, data-parallel PE encoding, coalesced writes, Lucene vector engine for new projects",
"Breaking: CROPWRIGHT_* env names are OP_CROPWRIGHT_*; /vlm/label_cluster and /vlm/verify_regions are replaced by /assist/runs; the evaluator has its own compose profile",
"Repository cleanup: guards, dead code removed, large files split, one typed env module, one docs source of truth"
]
},
{
"version": "Next",
"version": "v0.7.0",
"headline": "Triton throughput: keep images on the GPU",
"stage": "next",
"summary": "A measured, wave-by-wave optimization plan for the inference and ingest pipeline. The goal is to decode each image once on the GPU and keep it resident across the models that need it, with every change behind a flag, a parity gate against today's outputs, and a p50/p99 benchmark gate. None of this has shipped.",
"summary": "The rest of the measured optimization plan: keep each decoded image resident on the GPU across the models that need it, with every change behind a flag, a parity gate against today's outputs and a p50/p99 benchmark gate. The 1M-image scale step is a goal here, not a claim. None of this has shipped.",
"items": [
"CPU-side fixes first: decode once, stop blocking the event loop, shorter Triton queue delays",
"Smaller model outputs (end2end secondary detector, in-graph OCR argmax) and a GPU-resident OCR BLS",
"GPU JPEG decode (DALI or nvJPEG, chosen by bake-off) and static Triton ensembles for /detect and /embed",
"A GPU-resident curation ingest pipeline (BLS) that cuts crops and embeddings from the full-resolution frame",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs-site/static/img/screenshots/cropwright/classes-1600.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs-site/static/img/screenshots/cropwright/dashboard-1600.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs-site/static/img/screenshots/cropwright/review-1600.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading