[ReID part 1] Standalone ReIDModel, architectures, and gallery eval#480
Open
AlexBodner wants to merge 38 commits into
Open
[ReID part 1] Standalone ReIDModel, architectures, and gallery eval#480AlexBodner wants to merge 38 commits into
AlexBodner wants to merge 38 commits into
Conversation
AlexBodner
force-pushed
the
feat/core/reid
branch
from
June 29, 2026 14:27
40f6c3e to
4372c3a
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a ReID (appearance) subsystem to Trackers and integrates it into BoT-SORT and ByteTrack association so tracks can be maintained/recovered using appearance embeddings in addition to IoU.
Changes:
- Introduces a
trackers.core.reidpackage: OSNet clean-room backbone, model loading (hf://+ local), preprocessing, feature bank (EMA), similarity + fusion utilities, and offline eval (CMC/mAP/mINP). - Extends
BoTSORTTrackerandByteTrackTrackerto optionally use aReIDModelfor first-stage association (and BoT-SORT lost-track appearance recovery), with per-track EMA feature banks. - Adds tests for ReID model/config/loader behavior and fusion helpers, plus docs + notebooks demonstrating evaluation and webcam usage.
Reviewed changes
Copilot reviewed 28 out of 31 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Adds locked dependency metadata for the new reid extra. |
| pyproject.toml | Introduces a reid optional-dependency extra (torch/torchvision/timm/hf hub). |
| src/trackers/init.py | Exposes ReIDModel at the package top level. |
| src/trackers/core/reid/init.py | Public ReID API surface (ReIDModel, eval helpers, similarity, etc.). |
| src/trackers/core/reid/model.py | ReID model wrapper: device selection, feature extraction, save/load entrypoints. |
| src/trackers/core/reid/feature_bank.py | Per-track EMA embedding storage. |
| src/trackers/core/reid/distance.py | Cosine similarity matrix computation for tracks × detections. |
| src/trackers/core/reid/extraction.py | Convenience wrapper to embed detection boxes from a frame. |
| src/trackers/core/reid/fusion_methods.py | Shared IoU/appearance fusion helpers (masking + weighted blend). |
| src/trackers/core/reid/models/init.py | Exposes registry/preprocessing/loader utilities. |
| src/trackers/core/reid/models/loaders.py | HF/local weights resolution + state-dict loading/reporting. |
| src/trackers/core/reid/models/preprocessing.py | Torchvision preprocessing pipeline config + serialization. |
| src/trackers/core/reid/models/registry.py | Alias/model-card registry + reid_config.json (de)serialization. |
| src/trackers/core/reid/architectures/init.py | Architecture builder for OSNet variants and timm: backbones. |
| src/trackers/core/reid/architectures/osnet.py | OSNet backbone implementation (adapted, licensed). |
| src/trackers/core/reid/eval/init.py | Public eval API exports. |
| src/trackers/core/reid/eval/datasets.py | Market-1501/MSMT17 dataset split loaders/parsers. |
| src/trackers/core/reid/eval/evaluator.py | End-to-end embedding extraction + metric computation pipeline. |
| src/trackers/core/reid/eval/metrics.py | Retrieval metric computation (CMC/mAP/mINP). |
| src/trackers/core/botsort/tracklet.py | Adds optional per-track FeatureBank. |
| src/trackers/core/botsort/tracker.py | Integrates ReID into BoT-SORT (gated-min fusion + lost recovery). |
| src/trackers/core/bytetrack/tracklet.py | Adds optional per-track FeatureBank. |
| src/trackers/core/bytetrack/tracker.py | Integrates ReID into ByteTrack first-stage association (weighted fusion). |
| tests/core/test_reid_fusion.py | Unit tests for fusion helpers + BoT-SORT gated-min behavior. |
| tests/core/reid/test_reid.py | Tests for preprocessing, registry/config, loaders, and model smoke/roundtrip. |
| tests/core/reid/init.py | Initializes the ReID test package. |
| docs/trackers/botsort.md | Documents new BoT-SORT ReID parameters and behavior. |
| notebooks/webcam_reid_demo.py | End-to-end demo script for webcam tracking with BoT-SORT + ReID. |
| notebooks/eval_reid.ipynb | ReID evaluation notebook for Market-1501/MSMT17. |
| .gitignore | Ignores local rfcs/ directory. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
2 tasks
cursor
Bot
force-pushed
the
feat/core/reid
branch
from
July 15, 2026 13:51
6625885 to
d567e99
Compare
Introduce the optional trackers[reid] stack with OSNet and FastReID SBS backbones, FeatureBank, Market-1501/MSMT17 evaluation, and lazy imports so base trackers stay torch-free. Tracker association wiring is deferred. Co-authored-by: Alexander Bodner <AlexBodner@users.noreply.github.com>
Match changelog style, narrow the public ReID exports, clarify docs as standalone embeddings/eval, and fix the eval notebook install pin. Co-authored-by: Alexander Bodner <AlexBodner@users.noreply.github.com>
Skip ReID src/tests during collection when optional deps are missing so integration CI (dev group only) no longer errors on doctest imports. Also apply pre-commit formatting fixes. Co-authored-by: Alexander Bodner <AlexBodner@users.noreply.github.com>
Keep FeatureBank/eval tests always runnable without trackers[reid]. Move model/architecture/loader coverage to test_reid_model.py, which CI runs with --extra reid instead of importorskip guards. Co-authored-by: Alexander Bodner <AlexBodner@users.noreply.github.com>
Allow DEFAULT_MODEL strict loads by building backbone-only OSNet when num_classes=0, and drop unused package exports / Reid* aliases. Co-authored-by: Cursor <cursoragent@cursor.com>
AlexBodner
force-pushed
the
feat/core/reid
branch
from
July 15, 2026 14:40
0b61cce to
6158f70
Compare
Drop the separate _lazy helper in favor of package __getattr__, merge distance/extraction into appearance.py, and rename protocols to encoder. Co-authored-by: Cursor <cursoragent@cursor.com>
Default local pytest skips integration and slow; main CI runs slow ReID weight smokes while still excluding dataset integration. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep part 1 focused on OSNet, timm backbones, and gallery eval; FastReID MOT17 SBS moves with association wiring in the follow-up. Co-authored-by: Cursor <cursoragent@cursor.com>
7 tasks
Drop part-2 scaffolding, make architecture-only loads offline, trim the public surface, and remove the unused slow-test policy. Co-authored-by: Cursor <cursoragent@cursor.com>
Integration CI collects only under tests/, and heavy ReID model tests use importorskip so missing trackers[reid] no longer needs a custom collect hook. Co-authored-by: Cursor <cursoragent@cursor.com>
Collect only the integration modules in CI/docs so heavy ReID tests are never imported when trackers[reid] is not installed. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the subprocess import guards and the dedicated CI step; optional ReID loading stays as implementation, without dedicated tests for it. Co-authored-by: Cursor <cursoragent@cursor.com>
Normalize with an eps floor like torch, raise on non-finite or shape mismatch instead of quietly ignoring bad inputs. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop silent NaN→zero and dim-mismatch→zero paths; require finite matrices and matching feature dims so association failures surface immediately. Co-authored-by: Cursor <cursoragent@cursor.com>
Explain architectures vs curated ModelCard aliases on the API page and in module docstrings so registry.py is not mistaken for the backbone factory. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the loading diagram and “common confusion” note with plain load paths and a short how-to for registering a new backbone. Co-authored-by: Cursor <cursoragent@cursor.com>
Extract query/gallery embeddings independently in ReIDEvaluator, document --extra reid for local pytest, and cover partial embedding reuse in tests. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep release notes out of this branch until the feature is ready to ship. Co-authored-by: Cursor <cursoragent@cursor.com>
Assert hand-computed Rank-1, mAP, and mINP for a one-query gallery that drops the same-(pid, camid) junk entry before scoring. Co-authored-by: Cursor <cursoragent@cursor.com>
Normalize detection rows in appearance_similarity, require max_rank >= 10, validate provided embedding lengths, and stop model importing appearance's private helper. Co-authored-by: Cursor <cursoragent@cursor.com>
Cosine association already normalizes both sides; store raw EMA features and emit raw embeddings unless normalize_embeddings / normalize is opted in. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep each docstring focused on what that API does, not where L2 lives elsewhere. Co-authored-by: Cursor <cursoragent@cursor.com>
FeatureBank only stores EMA features; cosine L2 belongs with appearance_similarity. Co-authored-by: Cursor <cursoragent@cursor.com>
Prefer plain backticks like SORT/ByteTrack instead of :class:/:meth: markup. Co-authored-by: Cursor <cursoragent@cursor.com>
Short Google-style summaries, plain backticks, fuller Returns/Raises/Notes, and a leaner API page without ownership essays. Co-authored-by: Cursor <cursoragent@cursor.com>
Match eval/IO Raises style for Market-1501 and MSMT17 entry points. Co-authored-by: Cursor <cursoragent@cursor.com>
Use Sequence[str] and normalize=False so stubs structurally match the protocol. Co-authored-by: Cursor <cursoragent@cursor.com>
Comment on lines
+131
to
+134
| resolved_arch = architecture if architecture is not None else card.architecture | ||
| resolved_weights = card.weights | ||
| resolved_preprocessing = preprocessing if preprocessing is not None else card.preprocessing | ||
| resolved_warning = card.domain_warning |
Comment on lines
+263
to
+265
| img = PILImage.open(p).convert("RGB") | ||
| crop = self._preprocessing.resize_crop(np.asarray(img)) | ||
| tensors.append(self._transforms(PILImage.fromarray(crop))) |
Comment on lines
+58
to
+60
| if not os.path.exists(source): | ||
| raise FileNotFoundError(f"Weights file not found: {source}") | ||
| return source |
Keep part 1 scoped to the model and gallery-eval stack. FeatureBank, appearance similarity, and ReIDEncoder belong with tracker wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace ReIDPathEncoder with one encoder interface that covers frame and path embedding. Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Standalone ReID foundation for Trackers — model loading, OSNet /
timm:architectures, and gallery evaluation. Tracker association utilities and BoT-SORT wiring land in #501.ReIDModelwith curated OSNet alias andsave_pretrained/from_pretrainedtimm:backbonesReIDEvaluator(CMC / mAP / mINP)ReIDPathEncoderpip install 'trackers[reid]'Intentionally not in this PR (deferred to #501):
FeatureBank,appearance_similarity,ReIDEncoder, and BoT-SORT association.Benchmarks
Same-domain OSNet x1.0 eval from
notebooks/eval_reid.ipynb, compared to the torchreid model zoo (zoo numbers are euclidean).Euclidean matches the published protocol within ~0.5 pp. Cosine is our default association distance and is a different protocol (typically a bit higher).
Type of Change
Testing
Test details:
tests/core/reid/test_reid.py(gallery eval only; notrackers[reid]required)tests/core/reid/test_reid_model.py(needsuv sync --group dev --extra reid)--extra reidand runspytest -m "not integration"tests/core/test_tracker_integration.pyandtests/eval/test_integration.pyChecklist
Additional Context
Follow-up: #501 adds shared tracker association utilities under
trackers.core.reid, wires BoT-SORT, FastReID SBS, CLI, and demos on top of this branch.