05786ce9eb
* refactor: enable mypy strict checking for rfdetr.datasets.transforms * refactor: parameterize remaining bare ndarray annotations
413 lines
18 KiB
TOML
413 lines
18 KiB
TOML
[build-system]
|
|
requires = ["setuptools>=42", "wheel"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "rfdetr"
|
|
version = "1.10.0.dev"
|
|
description = "RF-DETR"
|
|
readme = "README.md"
|
|
authors = [
|
|
{name = "Roboflow, Inc", email = "develop@roboflow.com"}
|
|
]
|
|
license = {text = "Apache License 2.0"}
|
|
requires-python = ">=3.10"
|
|
classifiers = [
|
|
"Development Status :: 4 - Beta",
|
|
"Intended Audience :: Developers",
|
|
"Intended Audience :: Education",
|
|
"Intended Audience :: Science/Research",
|
|
"License :: OSI Approved :: Apache Software License",
|
|
"Programming Language :: Python :: 3",
|
|
"Programming Language :: Python :: 3.10",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: 3.13",
|
|
"Programming Language :: Python :: 3 :: Only",
|
|
"Topic :: Software Development",
|
|
"Topic :: Scientific/Engineering",
|
|
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
"Typing :: Typed",
|
|
"Operating System :: POSIX",
|
|
"Operating System :: Unix",
|
|
"Operating System :: MacOS"
|
|
]
|
|
keywords = ["machine-learning", "deep-learning", "vision", "ML", "DL", "AI", "DETR", "RF-DETR", "Roboflow"]
|
|
|
|
dependencies = [
|
|
"requests", # weight download from remote URLs
|
|
"numpy", # array conversion throughout inference, evaluation, export, and visualization
|
|
"torch>=2.2.0", # core tensor ops and model forward pass
|
|
"torchvision>=0.17.0", # image transforms and ops (aligned with torch>=2.2.0)
|
|
"tqdm", # progress bars during weight download
|
|
"transformers>=5.1.0,<6.0.0", # DINOv2 backbone loading
|
|
"pydantic>=2.0,<3", # ModelConfig / TrainConfig validation
|
|
"supervision>=0.29.0", # inference output (Detections, Masks)
|
|
"pyDeprecate>=0.9,<0.10", # deprecation warnings for legacy APIs; >=0.6 for deprecated_class
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
lora = [
|
|
"peft", # LoRA backbone fine-tuning
|
|
]
|
|
train = [
|
|
"peft", # LoRA backbone fine-tuning (available during training)
|
|
"pytorch_lightning>=2.6,<3,!=2.6.2,!=2.6.3", # Keep exclusions; see issue #1016 / related advisory for why 2.6.2 and 2.6.3 are blocked
|
|
"torchmetrics[detection]>=1.8.2,<1.9.0", # one-pass COCO adapter validates the TorchMetrics 1.8 private backend contract; re-verify _validate_private_contract() (src/rfdetr/training/coco_map.py) against 1.9+ before widening this pin
|
|
"faster-coco-eval>=1.7.2",
|
|
"pycocotools",
|
|
"scipy",
|
|
"roboflow",
|
|
"rf100vl",
|
|
]
|
|
augment = [
|
|
"albumentations>=1.4.24,<3.0.0", # optional custom CPU augmentations
|
|
"kornia>=0.7,<1", # optional GPU-side augmentation
|
|
]
|
|
onnx = [
|
|
"onnx>=1.16.0,<2.0",
|
|
"onnxsim>=0.7.0", # 0.7.0 ships wheels for cp310/311/312-abi3 (3.10-3.13) on linux x86_64+aarch64, win_amd64 and macOS arm64. The old <0.6.0 pin resolved to 0.5.0, which lacks cp311/cp313/aarch64 wheels, so pip built onnxsim's bundled onnxruntime/onnx from source and the install hung (#749).
|
|
"onnx_graphsurgeon",
|
|
# onnxruntime dropped cp310 wheels after 1.23.2; 1.24.0+ ship cp311-cp314 only. Unpinned,
|
|
# a 3.10 resolve picks the newest release and then fails at install with "no source
|
|
# distribution or wheel for the current platform". Remove the split when the project's
|
|
# requires-python floor moves past 3.10.
|
|
"onnxruntime<1.24; python_version < '3.11'",
|
|
"onnxruntime; python_version >= '3.11'",
|
|
"polygraphy",
|
|
]
|
|
tensorrt = [
|
|
"onnxruntime-gpu",
|
|
"tensorrt>=8.6.1",
|
|
"polygraphy",
|
|
]
|
|
# pycuda is only used by async TRTInference in rfdetr.export.benchmark. It ships as an sdist
|
|
# and builds against the CUDA toolkit dev headers (cuda.h), which a GPU driver alone does not
|
|
# provide. Keep it out of the base [tensorrt] extra so the ONNX->engine parity path (polygraphy
|
|
# TrtRunner, no pycuda) installs on a driver-only runner; async benchmarking opts into it here.
|
|
tensorrt-bench = [
|
|
"pycuda>=2024.1",
|
|
]
|
|
tflite = [
|
|
# TFLite conversion routes every export through the ONNX pipeline first (export_onnx's
|
|
# graph optimization/simplification), so these are needed here directly rather than via
|
|
# the separate [onnx] extra — onnxruntime is NOT included: it's only for running ONNX
|
|
# inference, never touched by the TFLite export path.
|
|
"onnx>=1.20.0,<2.0; python_version >= '3.12' and python_version < '3.13'",
|
|
"onnxsim>=0.7.0; python_version >= '3.12' and python_version < '3.13'", # 0.7.0 ships a cp312 abi3 wheel; the old <0.6.0 pin resolved to 0.5.0 whose wheels don't cover every platform, so pip built from source and hung (#749).
|
|
"onnx_graphsurgeon; python_version >= '3.12' and python_version < '3.13'",
|
|
"polygraphy; python_version >= '3.12' and python_version < '3.13'",
|
|
"onnx2tf>=2.4.0,<3.0.0; python_version >= '3.12' and python_version < '3.13'",
|
|
"flatbuffers>=23.5.26; python_version >= '3.12' and python_version < '3.13'",
|
|
"tf-keras>=2.16.0; python_version >= '3.12' and python_version < '3.13'",
|
|
"tensorflow>=2.16.0; python_version >= '3.12' and python_version < '3.13'",
|
|
]
|
|
executorch = [
|
|
# torch.export -> .pte, XNNPACK CPU delegate; validated on 1.3.1.
|
|
# executorch publishes cp310-cp313 wheels only (1.3.1 is current) and has no sdist, so a
|
|
# 3.14 install fails on wheel availability rather than resolution. The marker keeps the
|
|
# extra installable-but-empty on 3.14, matching how [tflite] is gated to 3.12. Drop the
|
|
# `python_version < '3.14'` marker once executorch ships cp314 wheels.
|
|
"executorch>=1.3,<2.0; python_version < '3.14'",
|
|
]
|
|
coreml = [
|
|
# torch.export (ExportedProgram) support added in coremltools 8.0 (see
|
|
# src/rfdetr/export/_coreml/torch_ops.py, op_coverage.py for the private-API surface this pin
|
|
# guards — coremltools._TORCH_OPS_REGISTRY internals can rename across minors).
|
|
"coremltools>=8.0,<10.0",
|
|
# torch>=2.12 sharply raises the rate of a CoreML/eager numeric-parity divergence on real-image
|
|
# input (coremltools 9.0): bisected 2026-07-28 on RFDETRNano with random-init weights —
|
|
# torch<2.12 failed ~1/6 repeat runs, torch>=2.12.0 failed ~6/7 (up to ~1.0 abs diff on raw
|
|
# query outputs; tests/export/test_coreml_export.py::TestCoreMLEndToEnd::
|
|
# test_outputs_match_pytorch_supervision_image[detection]). Same decomposed op set both sides —
|
|
# looks like a coremltools MIL lowering regression exposed by torch 2.12's export graph, not a
|
|
# missing/renamed op. This pin reduces the failure rate, it does not eliminate it — the
|
|
# underlying instability (random/untrained-weight activations pushing some op toward
|
|
# overflow/nan during MIL conversion; see the divide-by-zero/overflow RuntimeWarnings logged
|
|
# during convert) is present at some low rate on torch<2.12 too. Raise this cap once the root
|
|
# cause is understood/fixed upstream; don't treat it as a guaranteed-deterministic fix.
|
|
"torch<2.12",
|
|
]
|
|
loggers = [
|
|
"tensorboard>=2.13.0",
|
|
"protobuf>=3.20.0", # Cap <4.0.0 removed — tensorflow>=2.16.0 (required by [tflite]) needs protobuf>=3.20.3 and is incompatible with <4.0.0 (see #1041)
|
|
"wandb",
|
|
"mlflow",
|
|
"clearml",
|
|
]
|
|
visual = [
|
|
"matplotlib",
|
|
"pandas",
|
|
"seaborn",
|
|
]
|
|
cli = ["jsonargparse[signatures]>=4.27.7"]
|
|
plus = ["rfdetr_plus>=1.0.1, <2.0.0"]
|
|
# XLA backend for TPU training AND hardware-free XLA validation on CPU/GPU PJRT.
|
|
# torch_xla is built on top of torch (NOT mutually exclusive — it requires torch present) and its
|
|
# _XLAC extension is ABI-locked to ONE torch minor (a mismatch surfaces as an `undefined symbol`
|
|
# ImportError on `import torch_xla`). torch_xla does not hard-pin torch in requires_dist, and PEP 508
|
|
# cannot express "equal minor", so we pin BOTH to the current known-good pair (2.9) — bump the two
|
|
# together when a newer torch_xla ships. Wheels are Linux x86_64 only (py3.10-3.13) -> sys_platform
|
|
# marker keeps macOS/Windows installs of this extra a no-op. The bare wheel runs the CPU PJRT plugin
|
|
# (PJRT_DEVICE=CPU) with no libtpu; real TPU adds torch_xla[tpu] (libtpu), GPU PJRT needs the separate
|
|
# CUDA plugin wheel. Used by ci-tests-xla.yml to exercise @pytest.mark.xla paths.
|
|
xla = [
|
|
"torch==2.9.*; sys_platform == 'linux'",
|
|
"torch_xla==2.9.*; sys_platform == 'linux'",
|
|
]
|
|
|
|
[dependency-groups]
|
|
# TODO: Temporary: GPU runner only has CUDA 12.8 driver (12080); torch>=2.11 requires a newer driver.
|
|
# Remove this group and the --group ci-gpu-pin references in CI once the driver is updated.
|
|
# Does not affect users installing rfdetr from PyPI.
|
|
ci-gpu-pin = [
|
|
"torch<2.11",
|
|
"torchvision<0.26",
|
|
]
|
|
|
|
# TODO: Temporary: executorch==1.3.1's prebuilt wheel is compiled against ~torch-2.12.x's C10 ABI
|
|
# (executorch itself only floors torch>=2.12.0a0, no ceiling). torch>=2.13.0 removed/changed a C10
|
|
# symbol the wheel links, breaking executorch.runtime at dlopen (undefined symbol). Empirically
|
|
# validated: torch==2.12.1 + executorch==1.3.1 imports executorch.runtime cleanly; torch==2.13.0
|
|
# does not. Remove this group and the --group ci-executorch-pin reference in CI once executorch
|
|
# ships a release compatible with newer torch. Does not affect users installing rfdetr from PyPI —
|
|
# see rfdetr.export._executorch.converter._check_executorch_available(require_runtime=True) for the
|
|
# equivalent runtime guidance surfaced to end users who hit this.
|
|
ci-executorch-pin = [
|
|
"torch<2.13",
|
|
]
|
|
|
|
build = [
|
|
"twine>=5.1.1",
|
|
"wheel>=0.40",
|
|
"build>=0.10"
|
|
]
|
|
|
|
tests = [
|
|
"pytest>=7.2,<10",
|
|
"pytest-cov>=4,<8",
|
|
"pytest-xdist>=3.6,<4",
|
|
"pytest-rerunfailures>=10,<15",
|
|
"pytest-timeout>=2,<3",
|
|
"pytest-doctestplus>=1.2,<2",
|
|
"pandas", # imported directly by tests/training/test_metrics_csv.py to read CSVLogger output
|
|
"tomli>=2.0; python_version < '3.11'",
|
|
]
|
|
|
|
typing = [
|
|
# Keep this pin aligned with the local mypy hook in .pre-commit-config.yaml.
|
|
"mypy==1.19.1",
|
|
# mypy 1.19.x can crash while processing NumPy 2.4 symbols in strict mode.
|
|
"numpy<2.4",
|
|
"types-PyYAML",
|
|
"types-requests",
|
|
"types-tqdm",
|
|
]
|
|
|
|
docs = [
|
|
"mkdocs-material[imaging]>=9.7",
|
|
"mkdocstrings>=0.25.2,<0.30.0",
|
|
"mkdocstrings-python>=1.10.9",
|
|
"mike>=2.0.0",
|
|
"mkdocs-jupyter>=0.24.3",
|
|
"mkdocs-git-committers-plugin-2>=2.4.1",
|
|
"mkdocs-git-revision-date-localized-plugin>=1.2.4",
|
|
"tomli>=2.0; python_version < '3.11'",
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://github.com/roboflow/rf-detr"
|
|
|
|
[project.scripts]
|
|
rfdetr = "rfdetr.cli:main"
|
|
|
|
[tool.uv]
|
|
# onnx2tf>=2.4.0 pins numpy==1.26.4 (exact). Its dependency ml-dtypes==0.5.1 in turn requires
|
|
# numpy>=2.1.0 on python_full_version>='3.13' — contradicting the numpy==1.26.4 pin on 3.13.
|
|
# tflite deps carry python_version>='3.12' and <'3.13' markers because onnx2tf's numpy pin
|
|
# cannot be satisfied on 3.13 via any available release; when onnx2tf relaxes the exact pin,
|
|
# remove the <'3.13' upper bound from the tflite deps AND from the override below.
|
|
override-dependencies = [
|
|
"ml-dtypes==0.5.1; python_version >= '3.12' and python_version < '3.13'",
|
|
]
|
|
|
|
# ci-gpu-pin (torch<2.11, GPU-driver constraint) and the executorch extra (torch>=2.12.0a0,
|
|
# from executorch's own metadata) are unsatisfiable together -- no CI job combines them, but
|
|
# `uv sync --all-groups` and a plain `uv lock` need to know that so the universal resolver
|
|
# forks the two instead of failing to find one lockfile that satisfies both at once.
|
|
#
|
|
# coreml (torch<2.12, see coreml extra comment) and executorch (torch>=2.12.0a0) are likewise
|
|
# unsatisfiable together -- no CI job combines them either, same fork rationale.
|
|
conflicts = [
|
|
[
|
|
{ group = "ci-gpu-pin" },
|
|
{ extra = "executorch" },
|
|
],
|
|
[
|
|
{ extra = "coreml" },
|
|
{ extra = "executorch" },
|
|
],
|
|
# executorch and tflite extras are unsatisfiable together; declare a conflict so `uv lock` / `uv sync --all-groups` can fork.
|
|
[
|
|
{ extra = "executorch" },
|
|
{ extra = "tflite" },
|
|
],
|
|
# xla (torch==2.9.*, pinned to torch_xla's companion release) and executorch
|
|
# (torch>=2.12.0a0) are likewise unsatisfiable together -- same fork rationale.
|
|
[
|
|
{ extra = "executorch" },
|
|
{ extra = "xla" },
|
|
],
|
|
]
|
|
|
|
|
|
[tool.setuptools.packages.find]
|
|
where = ["src"]
|
|
include = ["rfdetr*"]
|
|
|
|
[tool.setuptools]
|
|
include-package-data = false
|
|
|
|
[tool.setuptools.package-data]
|
|
rfdetr = ["py.typed", "models/backbone/dinov2_configs/*.json"]
|
|
|
|
[tool.ruff]
|
|
fix = true
|
|
line-length = 120
|
|
target-version = "py310"
|
|
|
|
[tool.ruff.lint]
|
|
select = [
|
|
"E", # pycodestyle errors
|
|
"W", # pycodestyle warnings
|
|
"F", # pyflakes
|
|
"I", # isort
|
|
"N", # pep8-naming: lowercase variables (N806) and arguments (N803)
|
|
]
|
|
extend-select = [
|
|
"RUF100", # yesqa
|
|
]
|
|
ignore = [
|
|
"E722", # todo: Do not use bare `except`
|
|
]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"notebooks/*.py" = ["E402"] # cell-local imports are intentional in percent-format scripts
|
|
"docs/cookbooks/*.ipynb" = [
|
|
"E402", # cell-local imports are intentional in percent-format scripts
|
|
"E501", # jupytext notebook — markdown prose lines are intentionally unwrapped
|
|
]
|
|
"docs/cookbooks/*.py" = [
|
|
"E402", # cell-local imports are intentional in percent-format scripts
|
|
"E501", # .py mirror of jupytext notebook — markdown prose lines are intentionally unwrapped
|
|
]
|
|
|
|
[tool.docformatter]
|
|
wrap-summaries = 120
|
|
wrap-descriptions = 120
|
|
|
|
[tool.pytest.ini_options]
|
|
addopts = [
|
|
"-v", # verbose output
|
|
"--color=yes", # colored output
|
|
"--doctest-plus", # run doctests from all modules (pytest-doctestplus)
|
|
]
|
|
# Doctest collection is intentionally enabled across tests/ (no doctest_norecursedirs exclusion) so
|
|
# helper-function doctests in test modules run. This previously blanket-excluded tests/* because
|
|
# doctestplus walking every test module's attributes after the TF/ai_edge_litert stack is imported by
|
|
# the tflite export tests grows unittest.mock.call's cached child-mock graph unboundedly — observed
|
|
# 38 GB RSS and a silent SIGKILL during collection. If that recurs, reintroduce
|
|
# `doctest_norecursedirs = ["tests/*"]` or scope it to `tests/export/test_tflite_inference.py`.
|
|
pythonpath = ["src", "."]
|
|
markers = [
|
|
"gpu: tests that require GPU or are slow on CPU",
|
|
"xla: tests that require an XLA device or torch_xla runtime (TPU, or CPU/GPU PJRT)",
|
|
"tpu: tests that require real TPU hardware (libtpu/MXU); not runnable on CPU/GPU PJRT",
|
|
"coco17: tests that require COCO 2017 images or annotations",
|
|
# `flaky` is provided by pytest-rerunfailures; registered here too for clarity and to stay
|
|
# safe under --strict-markers (used by tests/benchmarks/test_training_*.py).
|
|
"flaky: tests that may fail due to nondeterminism and are retried via pytest-rerunfailures",
|
|
"e2e_executorch: ExecuTorch end-to-end export + numerical parity (opt-in)",
|
|
"e2e_coreml: CoreML end-to-end convert + numerical parity (structured and photo inputs; opt-in)",
|
|
"e2e_tensorrt: TensorRT end-to-end ONNX->engine build + parity (GPU, opt-in)",
|
|
"e2e_roboflow: live deploy_to_roboflow() upload + train-status validation (issue #1116); requires ROBOFLOW_API_KEY (opt-in)",
|
|
]
|
|
filterwarnings = [
|
|
# pytest-xdist workers close their channel before teardown completes;
|
|
# this is a known false-positive that does not affect test results.
|
|
"ignore::pluggy.PluggyTeardownRaisedWarning",
|
|
# Many tests instantiate ModelConfig variants with `pretrain_weights=None`
|
|
# to skip downloads. The pretrain-compat warning is intentional UX for
|
|
# end users; silence it globally for the test suite and re-enable it
|
|
# explicitly in the dedicated tests via `warnings.catch_warnings` plus
|
|
# `warnings.simplefilter("always")`.
|
|
# NOTE: expressed as a message regex (not as
|
|
# ``ignore::rfdetr.config.PretrainWeightsCompatibilityWarning``) because a
|
|
# class-path filter forces pytest to import ``rfdetr.config`` at
|
|
# config-parse time — before ``pytest-cov`` starts tracing — which makes
|
|
# the module's top-level statements appear uncovered.
|
|
"ignore:.*was instantiated with pretrain_weights=None:UserWarning",
|
|
"ignore:.*was instantiated with overrides that differ from the variant:UserWarning",
|
|
]
|
|
|
|
[tool.codespell]
|
|
skip = "*.pth"
|
|
ignore-words-list = "ane"
|
|
|
|
[tool.mypy]
|
|
python_version = "3.10"
|
|
ignore_missing_imports = false
|
|
explicit_package_bases = true
|
|
strict = true
|
|
mypy_path = "src"
|
|
exclude = [
|
|
"^docs/(hooks|scripts)/",
|
|
]
|
|
overrides = [
|
|
{ module = [
|
|
"tests.*",
|
|
"einops", "einops.*",
|
|
"matplotlib", "matplotlib.*",
|
|
"pandas", "pandas.*",
|
|
"seaborn", "seaborn.*",
|
|
], ignore_errors = true },
|
|
{ module = [
|
|
"torchvision", "torchvision.*",
|
|
"pycocotools", "pycocotools.*",
|
|
"timm", "timm.*",
|
|
"einops", "einops.*",
|
|
"deprecate", "deprecate.*",
|
|
"faster_coco_eval", "faster_coco_eval.*",
|
|
"matplotlib", "matplotlib.*",
|
|
"pandas", "pandas.*",
|
|
"requests", "requests.*",
|
|
"seaborn", "seaborn.*",
|
|
"tqdm", "tqdm.*",
|
|
"kornia", "kornia.*",
|
|
"albumentations", "albumentations.*",
|
|
"onnx", "onnx.*",
|
|
"onnx2tf", "onnx2tf.*",
|
|
"onnx_graphsurgeon", "onnx_graphsurgeon.*",
|
|
"onnxruntime", "onnxruntime.*",
|
|
"onnxsim", "onnxsim.*",
|
|
"polygraphy", "polygraphy.*",
|
|
"tensorrt", "tensorrt.*",
|
|
"pycuda", "pycuda.*",
|
|
"jsonargparse", "jsonargparse.*",
|
|
"tflite_runtime", "tflite_runtime.*",
|
|
"tensorflow", "tensorflow.*",
|
|
"executorch", "executorch.*",
|
|
"coremltools", "coremltools.*",
|
|
"roboflow", "roboflow.*",
|
|
"rfdetr_plus", "rfdetr_plus.*",
|
|
], ignore_missing_imports = true },
|
|
# Optional-import None assignments in console.py: type: ignore[assignment, misc] is needed when
|
|
# rich IS installed (full-venv mypy sees the assignment error) but flagged as unused by the
|
|
# pre-commit hook (which runs mypy with --ignore-missing-imports so rich types are unresolved).
|
|
{ module = ["rfdetr.utilities.console"], warn_unused_ignores = false },
|
|
# Modules with pre-existing type errors — ignored until incrementally fixed.
|
|
{ module = [
|
|
"rfdetr.datasets.coco",
|
|
], ignore_errors = true },
|
|
]
|