opensportslib 0.3.0__tar.gz → 0.3.0.dev1__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.
- {opensportslib-0.3.0/opensportslib.egg-info → opensportslib-0.3.0.dev1}/PKG-INFO +21 -5
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/README.md +19 -4
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/apis/classification.py +12 -1
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/apis/localization.py +103 -5
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/apis/vqa.py +59 -25
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/default.yaml +1 -1
- opensportslib-0.3.0.dev1/opensportslib/configs/localization/h5_header_distance.yaml +93 -0
- opensportslib-0.3.0.dev1/opensportslib/configs/localization/h5_header_distance_angle.yaml +93 -0
- opensportslib-0.3.0.dev1/opensportslib/configs/localization/h5_header_distance_speed.yaml +93 -0
- opensportslib-0.3.0.dev1/opensportslib/configs/localization/h5_header_distance_speed_angle.yaml +93 -0
- opensportslib-0.3.0.dev1/opensportslib/configs/localization/h5_header_rule.yaml +99 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/vqa/default.yaml +1 -1
- opensportslib-0.3.0.dev1/opensportslib/configs/vqa/qwen3_vl_native.yaml +81 -0
- opensportslib-0.3.0.dev1/opensportslib/configs/vqa/qwen_lora.yaml +69 -0
- opensportslib-0.3.0.dev1/opensportslib/configs/vqa/qwen_sngar_frames.yaml +133 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/accessors.py +96 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/trainer/classification_trainer.py +12 -2
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/trainer/localization_trainer.py +10 -1
- opensportslib-0.3.0.dev1/opensportslib/core/trainer/vqa_trainer.py +1726 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/load_annotations.py +9 -1
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/datasets/classification_dataset.py +160 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/datasets/localization_dataset.py +8 -0
- opensportslib-0.3.0.dev1/opensportslib/datasets/utils/h5_tracking.py +338 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/datasets/vqa_dataset.py +145 -17
- opensportslib-0.3.0.dev1/opensportslib/models/base/qwen_vl_native.py +620 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/qwen_xvars.py +108 -11
- opensportslib-0.3.0.dev1/opensportslib/models/base/rule_based.py +579 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/xvars_videochatgpt.py +57 -15
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/builder.py +16 -3
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/tools/__init__.py +3 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1/opensportslib.egg-info}/PKG-INFO +21 -5
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib.egg-info/SOURCES.txt +19 -1
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib.egg-info/requires.txt +1 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/pyproject.toml +2 -2
- opensportslib-0.3.0.dev1/scripts/run_h5_header_rule_inference.py +65 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/conftest.py +1 -1
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_config_architecture.py +14 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_config_utils_smoke.py +37 -1
- opensportslib-0.3.0.dev1/tests/test_h5_header_rule_spotter.py +540 -0
- opensportslib-0.3.0.dev1/tests/test_h5_tracking_dataset.py +196 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_task_model_api_contract.py +77 -0
- opensportslib-0.3.0.dev1/tests/test_vqa_api.py +595 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_vqa_qwen_xvars.py +79 -1
- opensportslib-0.3.0.dev1/tests/test_vqa_training_lora.py +1229 -0
- opensportslib-0.3.0.dev1/tools/convert/build_sn_vqa_2026_vqa.py +7 -0
- opensportslib-0.3.0.dev1/tools/convert/build_soccernet_gar_vqa.py +7 -0
- opensportslib-0.3.0.dev1/tools/training/vqa.py +79 -0
- opensportslib-0.3.0.dev1/tools/upload/upload_model_hf.py +223 -0
- opensportslib-0.3.0/opensportslib/core/trainer/vqa_trainer.py +0 -797
- opensportslib-0.3.0/tests/test_vqa_api.py +0 -240
- opensportslib-0.3.0/tests/test_vqa_training_lora.py +0 -563
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/LICENSE +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/LICENSE-COMMERCIAL +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/MANIFEST.in +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/examples/quickstart/basic_classification.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/examples/quickstart/basic_localization.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/examples/quickstart/basic_vqa.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/apis/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/apis/base_task_model.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/cli.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/classification/default.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/classification/video.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/localization/default.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/localization/video_dali.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/localization/video_ocv.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/vqa/qwen.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/configs/vqa/xvars.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/conflicts.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/loader.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/migrate.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/migrations/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/runtime_adapter.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/schema.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/schemas/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/config/validate.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/loss/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/loss/builder.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/loss/calf.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/loss/ce.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/loss/combine.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/loss/nll.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/optimizer/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/optimizer/builder.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/sampler/weighted_sampler.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/scheduler/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/scheduler/builder.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/trainer/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/checkpoint.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/config.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/config_normalize.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/data.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/ddp.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/default_args.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/hf_runtime.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/lightning.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/seed.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/video_processing.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/core/utils/wandb.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/datasets/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/datasets/builder.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/datasets/utils/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/datasets/utils/tracking.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/legacy_config/classification.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/legacy_config/localization.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/metrics/classification_metric.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/metrics/localization_metric.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/metrics/vqa_metric.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/backbones/builder.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/contextaware.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/e2e.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/learnablepooling.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/tracking.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/vars.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/video.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/base/video_mae.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/heads/builder.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/neck/builder.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/common.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/impl/__init__.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/impl/asformer.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/impl/calf.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/impl/gsm.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/impl/gtad.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/impl/tsm.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/litebase.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/modules.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/shift.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/utils.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/vqa_prompting.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/models/utils/xvars_clip_index.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/setup/setup.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/tools/_common.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/tools/hf_transfer.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/tools/osl_json_to_parquet.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib/tools/parquet_to_osl_json.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib.egg-info/dependency_links.txt +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib.egg-info/entry_points.txt +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/opensportslib.egg-info/top_level.txt +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/setup.cfg +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_classification_dataset_paths.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_classification_trainer_dataloader.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_config_split_override_sync.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_conversion_tools.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_extract_xvars_features.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_hf_transfer_tools.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_localization_dali_filenames.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_package_smoke.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_pretrained_config_merge_policy.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_public_apis_smoke.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_setup_cli.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_subset_train_infer_integration.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_vqa_metrics_semantic.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tests/test_vqa_xvars_videochatgpt.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/convert/build_soccernet_gar.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/convert/build_xvars_indexes.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/convert/extract_xvars_clip_features.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/download/download_hf_repo.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/download/download_osl_hf.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/download/upload_osl_hf.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/training/classification.py +0 -0
- {opensportslib-0.3.0 → opensportslib-0.3.0.dev1}/tools/training/localization.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensportslib
|
|
3
|
-
Version: 0.3.0
|
|
3
|
+
Version: 0.3.0.dev1
|
|
4
4
|
Summary: OpenSportsLib is the professional library, designed for advanced video understanding in sports. It provides state-of-the-art tools for action recognition, spotting, retrieval, and captioning, making it ideal for researchers, analysts, and developers working with sports video data.
|
|
5
5
|
Author: Jeet Vora
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -26,6 +26,7 @@ Requires-Dist: tabulate
|
|
|
26
26
|
Requires-Dist: pytorch-lightning
|
|
27
27
|
Requires-Dist: pandas
|
|
28
28
|
Requires-Dist: pyarrow
|
|
29
|
+
Requires-Dist: h5py==3.16.0
|
|
29
30
|
Requires-Dist: huggingface_hub
|
|
30
31
|
Requires-Dist: easydict
|
|
31
32
|
Provides-Extra: test
|
|
@@ -316,10 +317,25 @@ single_prediction = my_model.infer(
|
|
|
316
317
|
```
|
|
317
318
|
|
|
318
319
|
Use `opensportslib/configs/vqa/xvars.yaml` with `opensportslib setup --vqa_xvars`
|
|
319
|
-
for the X-VARS
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
320
|
+
for the X-VARS backend. OpenSportsLib supports three VQA options:
|
|
321
|
+
|
|
322
|
+
- `opensportslib/configs/vqa/xvars.yaml`
|
|
323
|
+
Original X-VARS / Video-ChatGPT path.
|
|
324
|
+
- CLIP features + Qwen
|
|
325
|
+
Use `opensportslib/configs/vqa/qwen.yaml` for inference and
|
|
326
|
+
`opensportslib/configs/vqa/qwen_lora.yaml` for LoRA training.
|
|
327
|
+
- `opensportslib/configs/vqa/qwen3_vl_native.yaml`
|
|
328
|
+
Full end-to-end native QwenVL path. This is the single canonical QwenVL
|
|
329
|
+
config; change `MODEL.components.llm_decoder.params.repo_id` to switch model
|
|
330
|
+
IDs.
|
|
331
|
+
|
|
332
|
+
Use `opensportslib setup --vqa_qwen` for both the CLIP+Qwen and native QwenVL
|
|
333
|
+
paths. The CLIP+Qwen configs support `Qwen/Qwen2.5-7B-Instruct` and
|
|
334
|
+
`Qwen/Qwen3.5-9B-Base`. The native QwenVL config defaults to
|
|
335
|
+
`Qwen/Qwen3-VL-8B-Instruct` and supports:
|
|
336
|
+
|
|
337
|
+
- `Qwen/Qwen3-VL-8B-Instruct`
|
|
338
|
+
- `Qwen/Qwen2.5-VL-7B-Instruct`
|
|
323
339
|
|
|
324
340
|
For X-VARS, `feature_source: indexed_or_raw_clip` prefers indexed CLIP features
|
|
325
341
|
when available and falls back to extracting CLIP features from raw video during
|
|
@@ -281,10 +281,25 @@ single_prediction = my_model.infer(
|
|
|
281
281
|
```
|
|
282
282
|
|
|
283
283
|
Use `opensportslib/configs/vqa/xvars.yaml` with `opensportslib setup --vqa_xvars`
|
|
284
|
-
for the X-VARS
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
284
|
+
for the X-VARS backend. OpenSportsLib supports three VQA options:
|
|
285
|
+
|
|
286
|
+
- `opensportslib/configs/vqa/xvars.yaml`
|
|
287
|
+
Original X-VARS / Video-ChatGPT path.
|
|
288
|
+
- CLIP features + Qwen
|
|
289
|
+
Use `opensportslib/configs/vqa/qwen.yaml` for inference and
|
|
290
|
+
`opensportslib/configs/vqa/qwen_lora.yaml` for LoRA training.
|
|
291
|
+
- `opensportslib/configs/vqa/qwen3_vl_native.yaml`
|
|
292
|
+
Full end-to-end native QwenVL path. This is the single canonical QwenVL
|
|
293
|
+
config; change `MODEL.components.llm_decoder.params.repo_id` to switch model
|
|
294
|
+
IDs.
|
|
295
|
+
|
|
296
|
+
Use `opensportslib setup --vqa_qwen` for both the CLIP+Qwen and native QwenVL
|
|
297
|
+
paths. The CLIP+Qwen configs support `Qwen/Qwen2.5-7B-Instruct` and
|
|
298
|
+
`Qwen/Qwen3.5-9B-Base`. The native QwenVL config defaults to
|
|
299
|
+
`Qwen/Qwen3-VL-8B-Instruct` and supports:
|
|
300
|
+
|
|
301
|
+
- `Qwen/Qwen3-VL-8B-Instruct`
|
|
302
|
+
- `Qwen/Qwen2.5-VL-7B-Instruct`
|
|
288
303
|
|
|
289
304
|
For X-VARS, `feature_source: indexed_or_raw_clip` prefers indexed CLIP features
|
|
290
305
|
when available and falls back to extracting CLIP features from raw video during
|
|
@@ -17,6 +17,17 @@ from opensportslib.core.config.accessors import (
|
|
|
17
17
|
)
|
|
18
18
|
from opensportslib.core.utils.config import expand
|
|
19
19
|
|
|
20
|
+
|
|
21
|
+
def _is_tracking_graph_modality(modality):
|
|
22
|
+
return str(modality).lower() in {
|
|
23
|
+
"tracking",
|
|
24
|
+
"tracking_parquet",
|
|
25
|
+
"tracking_h5",
|
|
26
|
+
"player_centroids_h5",
|
|
27
|
+
"player_joints_h5",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
20
31
|
class ClassificationModel(BaseTaskModel):
|
|
21
32
|
"""Top-level task wrapper for classification."""
|
|
22
33
|
|
|
@@ -100,7 +111,7 @@ class ClassificationModel(BaseTaskModel):
|
|
|
100
111
|
trainer.model = model
|
|
101
112
|
|
|
102
113
|
modality = get_data_modality(config)
|
|
103
|
-
use_tracking_collate = modality
|
|
114
|
+
use_tracking_collate = _is_tracking_graph_modality(modality)
|
|
104
115
|
logging.info(
|
|
105
116
|
"Worker setup | mode=%s | modality=%s | tracking_collate=%s",
|
|
106
117
|
mode,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
3
|
import time
|
|
4
|
+
from types import SimpleNamespace
|
|
4
5
|
|
|
5
6
|
from opensportslib.apis.base_task_model import BaseTaskModel
|
|
6
7
|
from opensportslib.core.config.accessors import (
|
|
@@ -14,6 +15,8 @@ from opensportslib.core.config.accessors import (
|
|
|
14
15
|
get_split_annotation_path,
|
|
15
16
|
get_split_cfg,
|
|
16
17
|
set_split_annotation_path,
|
|
18
|
+
set_loader_backend,
|
|
19
|
+
get_model_family,
|
|
17
20
|
)
|
|
18
21
|
from opensportslib.core.utils.config import expand
|
|
19
22
|
|
|
@@ -21,6 +24,17 @@ from opensportslib.core.utils.config import expand
|
|
|
21
24
|
class LocalizationModel(BaseTaskModel):
|
|
22
25
|
"""Top-level task wrapper for localization / spotting."""
|
|
23
26
|
|
|
27
|
+
_HF_BACKEND_SPLIT_TYPES = {
|
|
28
|
+
"dali": {
|
|
29
|
+
"VideoGameWithOpencv": "VideoGameWithDali",
|
|
30
|
+
"VideoGameWithOpencvVideo": "VideoGameWithDaliVideo",
|
|
31
|
+
},
|
|
32
|
+
"opencv": {
|
|
33
|
+
"VideoGameWithDali": "VideoGameWithOpencv",
|
|
34
|
+
"VideoGameWithDaliVideo": "VideoGameWithOpencvVideo",
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
# def __init__(self, config=None, weights=None):
|
|
25
39
|
# super().__init__(config=config, weights=None)
|
|
26
40
|
# if weights is not None:
|
|
@@ -61,6 +75,82 @@ class LocalizationModel(BaseTaskModel):
|
|
|
61
75
|
device,
|
|
62
76
|
)
|
|
63
77
|
|
|
78
|
+
@staticmethod
|
|
79
|
+
def _device_type(device) -> str:
|
|
80
|
+
device_type = getattr(device, "type", device)
|
|
81
|
+
return str(device_type).split(":", 1)[0].lower()
|
|
82
|
+
|
|
83
|
+
@staticmethod
|
|
84
|
+
def _is_hf_repo_weights(weights: str | None) -> bool:
|
|
85
|
+
if not weights:
|
|
86
|
+
return False
|
|
87
|
+
from opensportslib.core.utils.config import is_local_path
|
|
88
|
+
|
|
89
|
+
return not is_local_path(weights)
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def _iter_split_items(splits):
|
|
93
|
+
if splits is None:
|
|
94
|
+
return []
|
|
95
|
+
if isinstance(splits, dict):
|
|
96
|
+
return list(splits.items())
|
|
97
|
+
return list(vars(splits).items())
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def _ensure_namespace(parent, attr: str):
|
|
101
|
+
current = getattr(parent, attr, None)
|
|
102
|
+
if current is None:
|
|
103
|
+
current = SimpleNamespace()
|
|
104
|
+
setattr(parent, attr, current)
|
|
105
|
+
return current
|
|
106
|
+
|
|
107
|
+
def _normalize_opencv_dataloader(self, split_name: str, split_cfg) -> None:
|
|
108
|
+
dataloader = getattr(split_cfg, "dataloader", None)
|
|
109
|
+
if dataloader is None:
|
|
110
|
+
dataloader = SimpleNamespace()
|
|
111
|
+
setattr(split_cfg, "dataloader", dataloader)
|
|
112
|
+
|
|
113
|
+
if getattr(dataloader, "batch_size", None) is None:
|
|
114
|
+
dataloader.batch_size = 1
|
|
115
|
+
if getattr(dataloader, "shuffle", None) is None:
|
|
116
|
+
dataloader.shuffle = split_name == "train"
|
|
117
|
+
if getattr(dataloader, "num_workers", None) is None:
|
|
118
|
+
dataloader.num_workers = 0
|
|
119
|
+
if getattr(dataloader, "pin_memory", None) is None:
|
|
120
|
+
dataloader.pin_memory = False
|
|
121
|
+
|
|
122
|
+
def _adapt_hf_backend_for_device(self, weights: str | None) -> None:
|
|
123
|
+
if not self._is_hf_repo_weights(weights):
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
from opensportslib.core.utils.config import select_device
|
|
127
|
+
|
|
128
|
+
device = select_device(self.config.SYSTEM)
|
|
129
|
+
backend = "dali" if self._device_type(device) == "cuda" else "opencv"
|
|
130
|
+
current_backend = get_loader_backend(self.config)
|
|
131
|
+
set_loader_backend(self.config, backend)
|
|
132
|
+
|
|
133
|
+
common = getattr(getattr(self.config, "DATA", None), "common", None)
|
|
134
|
+
if common is None:
|
|
135
|
+
return
|
|
136
|
+
splits = self._ensure_namespace(common, "splits")
|
|
137
|
+
remap = self._HF_BACKEND_SPLIT_TYPES[backend]
|
|
138
|
+
|
|
139
|
+
for split_name, split_cfg in self._iter_split_items(splits):
|
|
140
|
+
split_type = getattr(split_cfg, "type", None)
|
|
141
|
+
if split_type in remap:
|
|
142
|
+
setattr(split_cfg, "type", remap[split_type])
|
|
143
|
+
if backend == "opencv":
|
|
144
|
+
self._normalize_opencv_dataloader(split_name, split_cfg)
|
|
145
|
+
|
|
146
|
+
if current_backend != backend:
|
|
147
|
+
logging.info(
|
|
148
|
+
"HF localization runtime backend override: %s -> %s for weights=%s",
|
|
149
|
+
current_backend,
|
|
150
|
+
backend,
|
|
151
|
+
weights,
|
|
152
|
+
)
|
|
153
|
+
|
|
64
154
|
def load_weights(
|
|
65
155
|
self,
|
|
66
156
|
weights: str | None = None,
|
|
@@ -79,6 +169,7 @@ class LocalizationModel(BaseTaskModel):
|
|
|
79
169
|
if weights is None:
|
|
80
170
|
raise ValueError("`weights` must be provided to load_weights().")
|
|
81
171
|
|
|
172
|
+
self._adapt_hf_backend_for_device(weights)
|
|
82
173
|
device = select_device(self.config.SYSTEM)
|
|
83
174
|
self._gate_multi_gpu_by_device(device)
|
|
84
175
|
if self.model is None:
|
|
@@ -170,6 +261,11 @@ class LocalizationModel(BaseTaskModel):
|
|
|
170
261
|
|
|
171
262
|
del kwargs
|
|
172
263
|
|
|
264
|
+
if str(get_model_family(self.config)).lower() == "rulebased":
|
|
265
|
+
raise NotImplementedError(
|
|
266
|
+
"RuleBased localization models are inference-only; call infer() instead of train()."
|
|
267
|
+
)
|
|
268
|
+
|
|
173
269
|
train_set = self._resolve_split_path("train", train_set)
|
|
174
270
|
valid_set = self._resolve_split_path("valid", valid_set)
|
|
175
271
|
self._set_split_path("train", train_set)
|
|
@@ -177,8 +273,10 @@ class LocalizationModel(BaseTaskModel):
|
|
|
177
273
|
# E2E validation mAP uses the `valid_data_frames` split; keep it in sync
|
|
178
274
|
# with explicit valid annotation overrides.
|
|
179
275
|
self._set_split_path("valid_data_frames", valid_set)
|
|
180
|
-
|
|
276
|
+
|
|
181
277
|
self.config = resolve_config_omega(self.config, weights=weights)
|
|
278
|
+
effective_weights = weights if weights is not None else self.last_loaded_weights
|
|
279
|
+
self._adapt_hf_backend_for_device(effective_weights)
|
|
182
280
|
check_config(self.config, split="train")
|
|
183
281
|
init_wandb(
|
|
184
282
|
self.config_path,
|
|
@@ -190,8 +288,6 @@ class LocalizationModel(BaseTaskModel):
|
|
|
190
288
|
logging.info("Configuration:")
|
|
191
289
|
logging.info(self.config)
|
|
192
290
|
|
|
193
|
-
effective_weights = weights if weights is not None else self.last_loaded_weights
|
|
194
|
-
|
|
195
291
|
def set_seed(seed):
|
|
196
292
|
random.seed(seed)
|
|
197
293
|
np.random.seed(seed)
|
|
@@ -292,6 +388,8 @@ class LocalizationModel(BaseTaskModel):
|
|
|
292
388
|
self._set_split_path("test", test_set)
|
|
293
389
|
|
|
294
390
|
self.config = resolve_config_omega(self.config, weights=weights)
|
|
391
|
+
effective_weights = weights if weights is not None else self.last_loaded_weights
|
|
392
|
+
self._adapt_hf_backend_for_device(effective_weights)
|
|
295
393
|
check_config(self.config, split="test")
|
|
296
394
|
self.config.infer_split = whether_infer_split(get_split_cfg(self.config, "test"))
|
|
297
395
|
|
|
@@ -307,8 +405,6 @@ class LocalizationModel(BaseTaskModel):
|
|
|
307
405
|
|
|
308
406
|
start = time.time()
|
|
309
407
|
|
|
310
|
-
effective_weights = weights if weights is not None else self.last_loaded_weights
|
|
311
|
-
|
|
312
408
|
if effective_weights is not None:
|
|
313
409
|
if self.model is None or self.last_loaded_weights != effective_weights:
|
|
314
410
|
self.load_weights(weights=effective_weights)
|
|
@@ -362,6 +458,8 @@ class LocalizationModel(BaseTaskModel):
|
|
|
362
458
|
test_set = self._resolve_split_path("test", test_set)
|
|
363
459
|
self._set_split_path("test", test_set)
|
|
364
460
|
self.config = resolve_config_omega(self.config, weights=weights)
|
|
461
|
+
effective_weights = weights if weights is not None else self.last_loaded_weights
|
|
462
|
+
self._adapt_hf_backend_for_device(effective_weights)
|
|
365
463
|
check_config(self.config, split="test")
|
|
366
464
|
self.config.infer_split = whether_infer_split(get_split_cfg(self.config, "test"))
|
|
367
465
|
|
|
@@ -51,6 +51,7 @@ class VQAModel(BaseTaskModel):
|
|
|
51
51
|
return_queue=None,
|
|
52
52
|
train_set=None,
|
|
53
53
|
valid_set=None,
|
|
54
|
+
resume_from_checkpoint=None,
|
|
54
55
|
use_wandb=False,
|
|
55
56
|
):
|
|
56
57
|
import torch
|
|
@@ -97,14 +98,10 @@ class VQAModel(BaseTaskModel):
|
|
|
97
98
|
train_data = build_dataset(config, train_set, None, split="train")
|
|
98
99
|
valid_data = build_dataset(config, valid_set, None, split="valid")
|
|
99
100
|
trainer = Trainer_VQA(config)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
rank=rank,
|
|
105
|
-
world_size=world_size,
|
|
106
|
-
use_wandb=use_wandb,
|
|
107
|
-
)
|
|
101
|
+
train_kwargs = {"rank": rank, "world_size": world_size, "use_wandb": use_wandb}
|
|
102
|
+
if resume_from_checkpoint is not None:
|
|
103
|
+
train_kwargs["resume_from_checkpoint"] = resume_from_checkpoint
|
|
104
|
+
ckpt = trainer.train(None, train_data, valid_data, **train_kwargs)
|
|
108
105
|
if rank == 0 and return_queue is not None:
|
|
109
106
|
return_queue.put(ckpt)
|
|
110
107
|
finally:
|
|
@@ -139,37 +136,73 @@ class VQAModel(BaseTaskModel):
|
|
|
139
136
|
train_set: str | None = None,
|
|
140
137
|
valid_set: str | None = None,
|
|
141
138
|
weights: str | None = None,
|
|
139
|
+
resume_from_checkpoint: str | None = None,
|
|
140
|
+
use_ddp: bool | None = None,
|
|
142
141
|
use_wandb: bool = True,
|
|
143
142
|
**kwargs,
|
|
144
143
|
) -> str | None:
|
|
145
144
|
del kwargs
|
|
145
|
+
|
|
146
|
+
self.config = resolve_config_omega(self.config, weights=weights)
|
|
147
|
+
execution = get_train_execution(self.config)
|
|
148
|
+
backend = str(execution.get("training_backend", "placeholder")).lower()
|
|
149
|
+
vqa_backend = get_vqa_backend(self.config)
|
|
150
|
+
if vqa_backend == "qwen_xvars_infer" and backend != "qwen_xvars_lora":
|
|
151
|
+
raise ValueError(
|
|
152
|
+
"The 'qwen_xvars_infer' backend requires TRAIN.execution.training_backend='qwen_xvars_lora' for train()."
|
|
153
|
+
)
|
|
154
|
+
if vqa_backend == "qwen_vl_native_infer" and backend != "qwen_vl_native_lora":
|
|
155
|
+
raise ValueError(
|
|
156
|
+
"The 'qwen_vl_native_infer' backend requires TRAIN.execution.training_backend='qwen_vl_native_lora' for train()."
|
|
157
|
+
)
|
|
146
158
|
import torch
|
|
147
159
|
import torch.multiprocessing as mp
|
|
148
160
|
|
|
149
|
-
self.config = resolve_config_omega(self.config, weights=weights)
|
|
150
|
-
if get_vqa_backend(self.config) == "qwen_xvars_infer":
|
|
151
|
-
raise ValueError("The 'qwen_xvars_infer' backend is inference-only and does not support train().")
|
|
152
161
|
train_set = self._resolve_split_path("train", train_set)
|
|
153
162
|
valid_set = self._resolve_split_path("valid", valid_set)
|
|
154
|
-
|
|
155
|
-
backend = str(execution.get("training_backend", "placeholder")).lower()
|
|
156
|
-
if backend == "xvars_videochatgpt_lora":
|
|
157
|
-
world_size = torch.cuda.device_count() or get_system_gpu_count(self.config)
|
|
163
|
+
if backend in {"xvars_videochatgpt_lora", "qwen_xvars_lora", "qwen_vl_native_lora"}:
|
|
158
164
|
requested_gpus = get_system_gpu_count(self.config)
|
|
159
|
-
|
|
165
|
+
available_gpus = int(torch.cuda.device_count() or 0)
|
|
166
|
+
if requested_gpus > 0:
|
|
167
|
+
world_size = min(available_gpus, int(requested_gpus)) if available_gpus > 0 else int(requested_gpus)
|
|
168
|
+
else:
|
|
169
|
+
world_size = available_gpus
|
|
170
|
+
effective_world_size = max(int(world_size), 1)
|
|
171
|
+
if use_ddp is None:
|
|
172
|
+
launch_ddp = effective_world_size > 1
|
|
173
|
+
else:
|
|
174
|
+
launch_ddp = bool(use_ddp) and effective_world_size > 1
|
|
175
|
+
if requested_gpus > 0 and available_gpus > 0 and requested_gpus != available_gpus:
|
|
176
|
+
logging.info(
|
|
177
|
+
"VQA train GPU selection | requested=%s | available=%s | launching=%s",
|
|
178
|
+
requested_gpus,
|
|
179
|
+
available_gpus,
|
|
180
|
+
effective_world_size if launch_ddp else 1,
|
|
181
|
+
)
|
|
160
182
|
logging.info(
|
|
161
|
-
"VQA train launch | mode=%s | world_size=%s",
|
|
162
|
-
"ddp" if
|
|
163
|
-
|
|
183
|
+
"VQA train launch | mode=%s | requested_gpus=%s | available_gpus=%s | world_size=%s",
|
|
184
|
+
"ddp" if launch_ddp else "single",
|
|
185
|
+
requested_gpus,
|
|
186
|
+
available_gpus,
|
|
187
|
+
effective_world_size if launch_ddp else 1,
|
|
164
188
|
)
|
|
165
189
|
|
|
166
190
|
ctx = mp.get_context("spawn")
|
|
167
191
|
queue = ctx.SimpleQueue()
|
|
168
|
-
if
|
|
192
|
+
if launch_ddp:
|
|
169
193
|
mp.spawn(
|
|
170
194
|
VQAModel._worker_ddp,
|
|
171
|
-
args=(
|
|
172
|
-
|
|
195
|
+
args=(
|
|
196
|
+
effective_world_size,
|
|
197
|
+
self.config_path,
|
|
198
|
+
self.config,
|
|
199
|
+
queue,
|
|
200
|
+
train_set,
|
|
201
|
+
valid_set,
|
|
202
|
+
resume_from_checkpoint,
|
|
203
|
+
use_wandb,
|
|
204
|
+
),
|
|
205
|
+
nprocs=effective_world_size,
|
|
173
206
|
)
|
|
174
207
|
else:
|
|
175
208
|
VQAModel._worker_ddp(
|
|
@@ -180,6 +213,7 @@ class VQAModel(BaseTaskModel):
|
|
|
180
213
|
return_queue=queue,
|
|
181
214
|
train_set=train_set,
|
|
182
215
|
valid_set=valid_set,
|
|
216
|
+
resume_from_checkpoint=resume_from_checkpoint,
|
|
183
217
|
use_wandb=use_wandb,
|
|
184
218
|
)
|
|
185
219
|
ckpt = queue.get()
|
|
@@ -189,7 +223,7 @@ class VQAModel(BaseTaskModel):
|
|
|
189
223
|
|
|
190
224
|
raise ValueError(
|
|
191
225
|
f"Unsupported VQA training backend '{backend}'. "
|
|
192
|
-
"Only 'xvars_videochatgpt_lora'
|
|
226
|
+
"Only 'xvars_videochatgpt_lora' and 'qwen_xvars_lora' are supported."
|
|
193
227
|
)
|
|
194
228
|
|
|
195
229
|
def infer(
|
|
@@ -216,8 +250,6 @@ class VQAModel(BaseTaskModel):
|
|
|
216
250
|
self.config = resolve_config_omega(self.config, weights=weights)
|
|
217
251
|
backend = get_vqa_backend(self.config)
|
|
218
252
|
effective_weights = weights if weights is not None else self.last_loaded_weights
|
|
219
|
-
if backend == "qwen_xvars_infer" and effective_weights is not None:
|
|
220
|
-
raise ValueError("The 'qwen_xvars_infer' backend does not support adapter weights for infer().")
|
|
221
253
|
_set_model_checkpoint_path(self.config, effective_weights)
|
|
222
254
|
self.trainer = Trainer_VQA(self.config)
|
|
223
255
|
if effective_weights is not None:
|
|
@@ -237,6 +269,8 @@ class VQAModel(BaseTaskModel):
|
|
|
237
269
|
"question": str(question).strip(),
|
|
238
270
|
"references": [],
|
|
239
271
|
"video_path": resolved_video_path,
|
|
272
|
+
"frame_paths": [],
|
|
273
|
+
"video_frames": [],
|
|
240
274
|
"video_spatio_temporal_features": None,
|
|
241
275
|
"prior_prediction_text": "",
|
|
242
276
|
"labels": {},
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
TASK: localization
|
|
2
|
+
VERSION: 2
|
|
3
|
+
|
|
4
|
+
SYSTEM:
|
|
5
|
+
paths:
|
|
6
|
+
work_dir: ./outputs/header_spotting_distance
|
|
7
|
+
device: cpu
|
|
8
|
+
gpu:
|
|
9
|
+
count: 0
|
|
10
|
+
|
|
11
|
+
DATA:
|
|
12
|
+
common:
|
|
13
|
+
dataset_name: h5_headers
|
|
14
|
+
data_root: ./data
|
|
15
|
+
classes:
|
|
16
|
+
- header
|
|
17
|
+
splits:
|
|
18
|
+
test:
|
|
19
|
+
type: H5OSLJsonSpotting
|
|
20
|
+
annotation_path: ./data/h5.json
|
|
21
|
+
source_path: ./data
|
|
22
|
+
dataloader:
|
|
23
|
+
batch_size: 1
|
|
24
|
+
shuffle: false
|
|
25
|
+
num_workers: 0
|
|
26
|
+
pin_memory: false
|
|
27
|
+
inputs:
|
|
28
|
+
tracking:
|
|
29
|
+
modality: player_joints_h5
|
|
30
|
+
representation: raw
|
|
31
|
+
source:
|
|
32
|
+
format: h5
|
|
33
|
+
sampling: {}
|
|
34
|
+
transform: {}
|
|
35
|
+
augmentations: {}
|
|
36
|
+
params: {}
|
|
37
|
+
|
|
38
|
+
MODEL:
|
|
39
|
+
metadata:
|
|
40
|
+
family: RuleBased
|
|
41
|
+
runner:
|
|
42
|
+
type: runner_h5_header_rule
|
|
43
|
+
components:
|
|
44
|
+
rule:
|
|
45
|
+
kind: algorithm
|
|
46
|
+
source:
|
|
47
|
+
provider: opensportslib
|
|
48
|
+
registry: rule_based
|
|
49
|
+
name: h5_header_distance
|
|
50
|
+
params:
|
|
51
|
+
label: header
|
|
52
|
+
head_name: action
|
|
53
|
+
distance_threshold_m: 0.5
|
|
54
|
+
min_confidence: 0.5
|
|
55
|
+
confidence_mode: linear_inverse_distance
|
|
56
|
+
confidence_power: 1.0
|
|
57
|
+
nms_window_ms: 1000
|
|
58
|
+
nms_scope: sample
|
|
59
|
+
ball_tolerance_ms: 60
|
|
60
|
+
chunk_size: 100000
|
|
61
|
+
head_joints: [nose, neck, l_eye, r_eye, l_ear, r_ear]
|
|
62
|
+
required_input_type: player_joints_h5
|
|
63
|
+
ball_path_field: ball_path
|
|
64
|
+
timestamp_field: timestamp_utc
|
|
65
|
+
output_task: action_spotting
|
|
66
|
+
include_diagnostics: true
|
|
67
|
+
position_ms_origin: joint_h5_start
|
|
68
|
+
metadata_start_field: start_utc
|
|
69
|
+
metadata_end_field: end_utc
|
|
70
|
+
ball_coordinate_fields: [x, y, z]
|
|
71
|
+
joint_coordinate_suffixes: [x, y, z]
|
|
72
|
+
identity_fields: [player_id, jersey_number, team_id, is_home]
|
|
73
|
+
invalid_coordinate_values: [-200.0]
|
|
74
|
+
sideline_filter_enabled: true
|
|
75
|
+
pitch_half_width_m: 50.0
|
|
76
|
+
sideline_exclusion_m: 1.0
|
|
77
|
+
sideline_reference: ball_y
|
|
78
|
+
trajectory_filter_enabled: false
|
|
79
|
+
trajectory_change_mode: either_angle_or_speed
|
|
80
|
+
trajectory_pre_window_ms: 200
|
|
81
|
+
trajectory_post_window_ms: 200
|
|
82
|
+
trajectory_min_angle_deg: 25.0
|
|
83
|
+
trajectory_min_speed_delta_ratio: 0.25
|
|
84
|
+
trajectory_min_vector_norm_m: 0.05
|
|
85
|
+
trajectory_use_xy_only: false
|
|
86
|
+
confidence_output_key: confidence_score
|
|
87
|
+
topology: []
|
|
88
|
+
|
|
89
|
+
TRAIN:
|
|
90
|
+
trainer:
|
|
91
|
+
type: trainer_rule_based
|
|
92
|
+
execution:
|
|
93
|
+
enabled: false
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
TASK: localization
|
|
2
|
+
VERSION: 2
|
|
3
|
+
|
|
4
|
+
SYSTEM:
|
|
5
|
+
paths:
|
|
6
|
+
work_dir: ./outputs/header_spotting_distance_angle
|
|
7
|
+
device: cpu
|
|
8
|
+
gpu:
|
|
9
|
+
count: 0
|
|
10
|
+
|
|
11
|
+
DATA:
|
|
12
|
+
common:
|
|
13
|
+
dataset_name: h5_headers
|
|
14
|
+
data_root: ./data
|
|
15
|
+
classes:
|
|
16
|
+
- header
|
|
17
|
+
splits:
|
|
18
|
+
test:
|
|
19
|
+
type: H5OSLJsonSpotting
|
|
20
|
+
annotation_path: ./data/h5.json
|
|
21
|
+
source_path: ./data
|
|
22
|
+
dataloader:
|
|
23
|
+
batch_size: 1
|
|
24
|
+
shuffle: false
|
|
25
|
+
num_workers: 0
|
|
26
|
+
pin_memory: false
|
|
27
|
+
inputs:
|
|
28
|
+
tracking:
|
|
29
|
+
modality: player_joints_h5
|
|
30
|
+
representation: raw
|
|
31
|
+
source:
|
|
32
|
+
format: h5
|
|
33
|
+
sampling: {}
|
|
34
|
+
transform: {}
|
|
35
|
+
augmentations: {}
|
|
36
|
+
params: {}
|
|
37
|
+
|
|
38
|
+
MODEL:
|
|
39
|
+
metadata:
|
|
40
|
+
family: RuleBased
|
|
41
|
+
runner:
|
|
42
|
+
type: runner_h5_header_rule
|
|
43
|
+
components:
|
|
44
|
+
rule:
|
|
45
|
+
kind: algorithm
|
|
46
|
+
source:
|
|
47
|
+
provider: opensportslib
|
|
48
|
+
registry: rule_based
|
|
49
|
+
name: h5_header_distance_angle
|
|
50
|
+
params:
|
|
51
|
+
label: header
|
|
52
|
+
head_name: action
|
|
53
|
+
distance_threshold_m: 0.5
|
|
54
|
+
min_confidence: 0.5
|
|
55
|
+
confidence_mode: linear_inverse_distance
|
|
56
|
+
confidence_power: 1.0
|
|
57
|
+
nms_window_ms: 1000
|
|
58
|
+
nms_scope: sample
|
|
59
|
+
ball_tolerance_ms: 60
|
|
60
|
+
chunk_size: 100000
|
|
61
|
+
head_joints: [nose, neck, l_eye, r_eye, l_ear, r_ear]
|
|
62
|
+
required_input_type: player_joints_h5
|
|
63
|
+
ball_path_field: ball_path
|
|
64
|
+
timestamp_field: timestamp_utc
|
|
65
|
+
output_task: action_spotting
|
|
66
|
+
include_diagnostics: true
|
|
67
|
+
position_ms_origin: joint_h5_start
|
|
68
|
+
metadata_start_field: start_utc
|
|
69
|
+
metadata_end_field: end_utc
|
|
70
|
+
ball_coordinate_fields: [x, y, z]
|
|
71
|
+
joint_coordinate_suffixes: [x, y, z]
|
|
72
|
+
identity_fields: [player_id, jersey_number, team_id, is_home]
|
|
73
|
+
invalid_coordinate_values: [-200.0]
|
|
74
|
+
sideline_filter_enabled: true
|
|
75
|
+
pitch_half_width_m: 50.0
|
|
76
|
+
sideline_exclusion_m: 1.0
|
|
77
|
+
sideline_reference: ball_y
|
|
78
|
+
trajectory_filter_enabled: true
|
|
79
|
+
trajectory_change_mode: angle
|
|
80
|
+
trajectory_pre_window_ms: 200
|
|
81
|
+
trajectory_post_window_ms: 200
|
|
82
|
+
trajectory_min_angle_deg: 25.0
|
|
83
|
+
trajectory_min_speed_delta_ratio: 0.25
|
|
84
|
+
trajectory_min_vector_norm_m: 0.05
|
|
85
|
+
trajectory_use_xy_only: false
|
|
86
|
+
confidence_output_key: confidence_score
|
|
87
|
+
topology: []
|
|
88
|
+
|
|
89
|
+
TRAIN:
|
|
90
|
+
trainer:
|
|
91
|
+
type: trainer_rule_based
|
|
92
|
+
execution:
|
|
93
|
+
enabled: false
|