opensportslib 0.2.0.dev6__tar.gz → 0.2.0.dev7__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.2.0.dev6/opensportslib.egg-info → opensportslib-0.2.0.dev7}/PKG-INFO +21 -6
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/README.md +19 -4
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/localization.py +97 -5
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/default.yaml +1 -1
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/default.yaml +1 -1
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen3_vl_native.yaml +8 -1
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/accessors.py +38 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/vqa_trainer.py +12 -11
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/qwen_vl_native.py +2 -1
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/qwen_xvars.py +4 -3
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/xvars_videochatgpt.py +7 -6
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7/opensportslib.egg-info}/PKG-INFO +21 -6
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/SOURCES.txt +2 -3
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/requires.txt +1 -1
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/pyproject.toml +2 -2
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_config_architecture.py +14 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_config_utils_smoke.py +37 -1
- opensportslib-0.2.0.dev7/tools/upload/upload_model_hf.py +223 -0
- opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen_vl_native.yaml +0 -70
- opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen_vl_native_awq.yaml +0 -45
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/LICENSE +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/LICENSE-COMMERCIAL +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/MANIFEST.in +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/examples/quickstart/basic_classification.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/examples/quickstart/basic_localization.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/examples/quickstart/basic_vqa.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/base_task_model.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/classification.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/vqa.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/cli.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/classification/default.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/classification/video.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/default.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_distance.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_distance_angle.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_distance_speed.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_distance_speed_angle.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_rule.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/video_dali.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/video_ocv.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen_lora.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen_sngar_frames.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/xvars.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/conflicts.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/loader.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/migrate.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/migrations/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/runtime_adapter.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/schema.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/schemas/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/validate.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/builder.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/calf.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/ce.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/combine.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/nll.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/optimizer/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/optimizer/builder.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/sampler/weighted_sampler.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/scheduler/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/scheduler/builder.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/classification_trainer.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/localization_trainer.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/checkpoint.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/config.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/config_normalize.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/data.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/ddp.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/default_args.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/hf_runtime.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/lightning.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/load_annotations.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/seed.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/video_processing.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/wandb.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/builder.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/classification_dataset.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/localization_dataset.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/utils/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/utils/h5_tracking.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/utils/tracking.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/vqa_dataset.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/classification.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/localization.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/metrics/classification_metric.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/metrics/localization_metric.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/metrics/vqa_metric.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/backbones/builder.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/contextaware.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/e2e.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/learnablepooling.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/rule_based.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/tracking.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/vars.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/video.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/video_mae.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/builder.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/heads/builder.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/neck/builder.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/common.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/asformer.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/calf.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/gsm.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/gtad.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/tsm.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/litebase.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/modules.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/shift.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/utils.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/vqa_prompting.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/xvars_clip_index.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/setup/setup.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/__init__.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/_common.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/hf_transfer.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/osl_json_to_parquet.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/parquet_to_osl_json.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/dependency_links.txt +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/entry_points.txt +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/top_level.txt +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/scripts/run_h5_header_rule_inference.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/setup.cfg +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/conftest.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_classification_dataset_paths.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_classification_trainer_dataloader.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_config_split_override_sync.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_conversion_tools.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_extract_xvars_features.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_h5_header_rule_spotter.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_h5_tracking_dataset.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_hf_transfer_tools.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_localization_dali_filenames.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_package_smoke.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_pretrained_config_merge_policy.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_public_apis_smoke.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_setup_cli.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_subset_train_infer_integration.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_task_model_api_contract.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_api.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_metrics_semantic.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_qwen_xvars.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_training_lora.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_xvars_videochatgpt.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_sn_vqa_2026_vqa.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_soccernet_gar.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_soccernet_gar_vqa.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_xvars_indexes.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/extract_xvars_clip_features.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/download/download_hf_repo.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/download/download_osl_hf.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/download/upload_osl_hf.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/training/classification.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/training/localization.py +0 -0
- {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/training/vqa.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensportslib
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev7
|
|
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,7 +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
|
|
29
|
+
Requires-Dist: h5py==3.16.0
|
|
30
30
|
Requires-Dist: huggingface_hub
|
|
31
31
|
Requires-Dist: easydict
|
|
32
32
|
Provides-Extra: test
|
|
@@ -317,10 +317,25 @@ single_prediction = my_model.infer(
|
|
|
317
317
|
```
|
|
318
318
|
|
|
319
319
|
Use `opensportslib/configs/vqa/xvars.yaml` with `opensportslib setup --vqa_xvars`
|
|
320
|
-
for the X-VARS
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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`
|
|
324
339
|
|
|
325
340
|
For X-VARS, `feature_source: indexed_or_raw_clip` prefers indexed CLIP features
|
|
326
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
|
|
@@ -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,7 @@ 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,
|
|
17
19
|
get_model_family,
|
|
18
20
|
)
|
|
19
21
|
from opensportslib.core.utils.config import expand
|
|
@@ -22,6 +24,17 @@ from opensportslib.core.utils.config import expand
|
|
|
22
24
|
class LocalizationModel(BaseTaskModel):
|
|
23
25
|
"""Top-level task wrapper for localization / spotting."""
|
|
24
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
|
+
|
|
25
38
|
# def __init__(self, config=None, weights=None):
|
|
26
39
|
# super().__init__(config=config, weights=None)
|
|
27
40
|
# if weights is not None:
|
|
@@ -62,6 +75,82 @@ class LocalizationModel(BaseTaskModel):
|
|
|
62
75
|
device,
|
|
63
76
|
)
|
|
64
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
|
+
|
|
65
154
|
def load_weights(
|
|
66
155
|
self,
|
|
67
156
|
weights: str | None = None,
|
|
@@ -80,6 +169,7 @@ class LocalizationModel(BaseTaskModel):
|
|
|
80
169
|
if weights is None:
|
|
81
170
|
raise ValueError("`weights` must be provided to load_weights().")
|
|
82
171
|
|
|
172
|
+
self._adapt_hf_backend_for_device(weights)
|
|
83
173
|
device = select_device(self.config.SYSTEM)
|
|
84
174
|
self._gate_multi_gpu_by_device(device)
|
|
85
175
|
if self.model is None:
|
|
@@ -183,8 +273,10 @@ class LocalizationModel(BaseTaskModel):
|
|
|
183
273
|
# E2E validation mAP uses the `valid_data_frames` split; keep it in sync
|
|
184
274
|
# with explicit valid annotation overrides.
|
|
185
275
|
self._set_split_path("valid_data_frames", valid_set)
|
|
186
|
-
|
|
276
|
+
|
|
187
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)
|
|
188
280
|
check_config(self.config, split="train")
|
|
189
281
|
init_wandb(
|
|
190
282
|
self.config_path,
|
|
@@ -196,8 +288,6 @@ class LocalizationModel(BaseTaskModel):
|
|
|
196
288
|
logging.info("Configuration:")
|
|
197
289
|
logging.info(self.config)
|
|
198
290
|
|
|
199
|
-
effective_weights = weights if weights is not None else self.last_loaded_weights
|
|
200
|
-
|
|
201
291
|
def set_seed(seed):
|
|
202
292
|
random.seed(seed)
|
|
203
293
|
np.random.seed(seed)
|
|
@@ -298,6 +388,8 @@ class LocalizationModel(BaseTaskModel):
|
|
|
298
388
|
self._set_split_path("test", test_set)
|
|
299
389
|
|
|
300
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)
|
|
301
393
|
check_config(self.config, split="test")
|
|
302
394
|
self.config.infer_split = whether_infer_split(get_split_cfg(self.config, "test"))
|
|
303
395
|
|
|
@@ -313,8 +405,6 @@ class LocalizationModel(BaseTaskModel):
|
|
|
313
405
|
|
|
314
406
|
start = time.time()
|
|
315
407
|
|
|
316
|
-
effective_weights = weights if weights is not None else self.last_loaded_weights
|
|
317
|
-
|
|
318
408
|
if effective_weights is not None:
|
|
319
409
|
if self.model is None or self.last_loaded_weights != effective_weights:
|
|
320
410
|
self.load_weights(weights=effective_weights)
|
|
@@ -368,6 +458,8 @@ class LocalizationModel(BaseTaskModel):
|
|
|
368
458
|
test_set = self._resolve_split_path("test", test_set)
|
|
369
459
|
self._set_split_path("test", test_set)
|
|
370
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)
|
|
371
463
|
check_config(self.config, split="test")
|
|
372
464
|
self.config.infer_split = whether_infer_split(get_split_cfg(self.config, "test"))
|
|
373
465
|
|
{opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen3_vl_native.yaml
RENAMED
|
@@ -25,8 +25,15 @@ MODEL:
|
|
|
25
25
|
kind: decoder
|
|
26
26
|
source:
|
|
27
27
|
provider: huggingface
|
|
28
|
-
|
|
28
|
+
# Canonical end-to-end QwenVL config.
|
|
29
|
+
# Swap this model ID if you want another supported QwenVL checkpoint.
|
|
30
|
+
# - Qwen/Qwen3-VL-8B-Instruct
|
|
31
|
+
# - Qwen/Qwen2.5-VL-7B-Instruct
|
|
32
|
+
name: Qwen/Qwen3-VL-8B-Instruct
|
|
29
33
|
params:
|
|
34
|
+
# Supported examples:
|
|
35
|
+
# - Qwen/Qwen3-VL-8B-Instruct
|
|
36
|
+
# - Qwen/Qwen2.5-VL-7B-Instruct
|
|
30
37
|
repo_id: Qwen/Qwen3-VL-8B-Instruct
|
|
31
38
|
overrides: {}
|
|
32
39
|
metadata:
|
{opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/accessors.py
RENAMED
|
@@ -68,6 +68,20 @@ def get_loader_backend(cfg: Any) -> str:
|
|
|
68
68
|
return str(backend).lower()
|
|
69
69
|
|
|
70
70
|
|
|
71
|
+
def set_loader_backend(cfg: Any, backend: str) -> None:
|
|
72
|
+
data = getattr(cfg, "DATA", None)
|
|
73
|
+
if data is None:
|
|
74
|
+
data = SimpleNamespace()
|
|
75
|
+
setattr(cfg, "DATA", data)
|
|
76
|
+
|
|
77
|
+
common = _ensure_child(data, "common")
|
|
78
|
+
runtime = _ensure_child(common, "runtime")
|
|
79
|
+
if isinstance(runtime, dict):
|
|
80
|
+
runtime["loader_backend"] = str(backend).lower()
|
|
81
|
+
else:
|
|
82
|
+
setattr(runtime, "loader_backend", str(backend).lower())
|
|
83
|
+
|
|
84
|
+
|
|
71
85
|
def get_system_path(cfg: Any, key: str, default: str | None = None) -> str | None:
|
|
72
86
|
system = _as_dict(getattr(cfg, "SYSTEM", None))
|
|
73
87
|
paths = _as_dict(system.get("paths"))
|
|
@@ -351,6 +365,30 @@ def get_train_execution(cfg: Any) -> dict[str, Any]:
|
|
|
351
365
|
return _as_dict(train.get("execution"))
|
|
352
366
|
|
|
353
367
|
|
|
368
|
+
def get_hf_prefer_cuda(cfg: Any, hf_cfg: dict[str, Any] | None = None) -> bool:
|
|
369
|
+
"""Resolve whether HF-backed runtimes should prefer CUDA.
|
|
370
|
+
|
|
371
|
+
Precedence:
|
|
372
|
+
1. explicit TRAIN.execution.hf.prefer_cuda
|
|
373
|
+
2. SYSTEM.device mapping:
|
|
374
|
+
- cpu -> False
|
|
375
|
+
- cuda/gpu -> True
|
|
376
|
+
- auto/unset -> True
|
|
377
|
+
"""
|
|
378
|
+
hf_cfg = _as_dict(hf_cfg) if hf_cfg is not None else _as_dict(get_train_execution(cfg).get("hf"))
|
|
379
|
+
explicit = hf_cfg.get("prefer_cuda")
|
|
380
|
+
if explicit is not None:
|
|
381
|
+
return bool(explicit)
|
|
382
|
+
|
|
383
|
+
system = _as_dict(getattr(cfg, "SYSTEM", None))
|
|
384
|
+
mode = str(system.get("device", "auto")).strip().lower()
|
|
385
|
+
if mode == "cpu":
|
|
386
|
+
return False
|
|
387
|
+
if mode in {"cuda", "gpu"}:
|
|
388
|
+
return True
|
|
389
|
+
return True
|
|
390
|
+
|
|
391
|
+
|
|
354
392
|
def get_hf_cuda_device_index(cfg: Any, hf_cfg: dict[str, Any] | None = None) -> int | None:
|
|
355
393
|
"""Resolve the CUDA device index used by HuggingFace runtime helpers."""
|
|
356
394
|
if os.environ.get("CUDA_VISIBLE_DEVICES"):
|
{opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/vqa_trainer.py
RENAMED
|
@@ -17,24 +17,25 @@ import torch
|
|
|
17
17
|
from tqdm.auto import tqdm
|
|
18
18
|
|
|
19
19
|
from opensportslib.core.config.accessors import (
|
|
20
|
-
get_xvars_train_model_id,
|
|
21
|
-
get_xvars_train_tokenizer_id,
|
|
22
|
-
get_xvars_train_video_token_len,
|
|
23
20
|
get_hf_cuda_device_index,
|
|
24
|
-
|
|
25
|
-
get_vqa_decoder_model_id,
|
|
26
|
-
is_xvars_videochatgpt_backend,
|
|
21
|
+
get_hf_prefer_cuda,
|
|
27
22
|
get_model_runtime_dtype,
|
|
28
23
|
get_split_dataloader_cfg,
|
|
29
24
|
get_system_path,
|
|
30
25
|
get_train_epochs,
|
|
31
26
|
get_train_execution,
|
|
32
27
|
get_train_optimizer,
|
|
28
|
+
get_vqa_backend,
|
|
29
|
+
get_vqa_decoder_model_id,
|
|
33
30
|
get_vqa_eval_profile_cfg,
|
|
34
31
|
get_vqa_generation_cfg,
|
|
35
32
|
get_vqa_mm_hidden_size,
|
|
36
33
|
get_vqa_native_visual_cfg,
|
|
37
34
|
get_vqa_prompt_video_token_len,
|
|
35
|
+
get_xvars_train_model_id,
|
|
36
|
+
get_xvars_train_tokenizer_id,
|
|
37
|
+
get_xvars_train_video_token_len,
|
|
38
|
+
is_xvars_videochatgpt_backend,
|
|
38
39
|
)
|
|
39
40
|
from opensportslib.core.utils.config import save_config
|
|
40
41
|
from opensportslib.core.utils.hf_runtime import (
|
|
@@ -952,7 +953,7 @@ class VQAXVarsVideoChatGPTLoraTrainer:
|
|
|
952
953
|
cuda_device_index = get_hf_cuda_device_index(self.config, hf_cfg)
|
|
953
954
|
if bnb_config is not None:
|
|
954
955
|
model_kwargs["quantization_config"] = bnb_config
|
|
955
|
-
if
|
|
956
|
+
if get_hf_prefer_cuda(self.config, hf_cfg) and torch.cuda.is_available():
|
|
956
957
|
if cuda_device_index is not None:
|
|
957
958
|
torch.cuda.set_device(cuda_device_index)
|
|
958
959
|
model_kwargs["device_map"] = {"": cuda_device_index}
|
|
@@ -1033,7 +1034,7 @@ class VQAXVarsVideoChatGPTLoraTrainer:
|
|
|
1033
1034
|
"report_to": ["wandb"] if use_wandb else [],
|
|
1034
1035
|
"remove_unused_columns": False,
|
|
1035
1036
|
"disable_tqdm": bool(sft_cfg.get("disable_tqdm", True)),
|
|
1036
|
-
"use_cpu": not
|
|
1037
|
+
"use_cpu": not get_hf_prefer_cuda(self.config, hf_cfg),
|
|
1037
1038
|
"fp16": fp16,
|
|
1038
1039
|
"bf16": bf16,
|
|
1039
1040
|
"gradient_checkpointing": bool(sft_cfg.get("gradient_checkpointing", False)),
|
|
@@ -1186,7 +1187,7 @@ class VQAQwenXVarsLoraTrainer:
|
|
|
1186
1187
|
cuda_device_index = get_hf_cuda_device_index(self.config, hf_cfg)
|
|
1187
1188
|
if bnb_config is not None:
|
|
1188
1189
|
model_kwargs["quantization_config"] = bnb_config
|
|
1189
|
-
if
|
|
1190
|
+
if get_hf_prefer_cuda(self.config, hf_cfg) and torch.cuda.is_available():
|
|
1190
1191
|
if cuda_device_index is not None:
|
|
1191
1192
|
torch.cuda.set_device(cuda_device_index)
|
|
1192
1193
|
model_kwargs["device_map"] = {"": cuda_device_index}
|
|
@@ -1261,7 +1262,7 @@ class VQAQwenXVarsLoraTrainer:
|
|
|
1261
1262
|
"report_to": ["wandb"] if use_wandb else [],
|
|
1262
1263
|
"remove_unused_columns": False,
|
|
1263
1264
|
"disable_tqdm": bool(sft_cfg.get("disable_tqdm", True)),
|
|
1264
|
-
"use_cpu": not
|
|
1265
|
+
"use_cpu": not get_hf_prefer_cuda(self.config, hf_cfg),
|
|
1265
1266
|
"fp16": fp16,
|
|
1266
1267
|
"bf16": bf16,
|
|
1267
1268
|
"gradient_checkpointing": bool(sft_cfg.get("gradient_checkpointing", False)),
|
|
@@ -1491,7 +1492,7 @@ class VQAQwenVLNativeLoraTrainer:
|
|
|
1491
1492
|
"report_to": ["wandb"] if use_wandb else [],
|
|
1492
1493
|
"remove_unused_columns": False,
|
|
1493
1494
|
"disable_tqdm": bool(sft_cfg.get("disable_tqdm", True)),
|
|
1494
|
-
"use_cpu": not
|
|
1495
|
+
"use_cpu": not get_hf_prefer_cuda(self.config, hf_cfg),
|
|
1495
1496
|
"fp16": fp16,
|
|
1496
1497
|
"bf16": bf16,
|
|
1497
1498
|
"gradient_checkpointing": bool(sft_cfg.get("gradient_checkpointing", False)),
|
{opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/qwen_vl_native.py
RENAMED
|
@@ -13,6 +13,7 @@ import torch.nn as nn
|
|
|
13
13
|
|
|
14
14
|
from opensportslib.core.config.accessors import (
|
|
15
15
|
get_hf_cuda_device_index,
|
|
16
|
+
get_hf_prefer_cuda,
|
|
16
17
|
get_model_load,
|
|
17
18
|
get_train_execution,
|
|
18
19
|
get_vqa_generation_cfg,
|
|
@@ -248,7 +249,7 @@ class QwenVLNativeModel(nn.Module):
|
|
|
248
249
|
hf_cfg = _as_dict(exec_cfg.get("hf"))
|
|
249
250
|
quant_cfg = _as_dict(exec_cfg.get("quantization"))
|
|
250
251
|
local_files_only = bool(hf_cfg.get("local_files_only", False))
|
|
251
|
-
prefer_cuda =
|
|
252
|
+
prefer_cuda = get_hf_prefer_cuda(config, hf_cfg)
|
|
252
253
|
cuda_device_index = get_hf_cuda_device_index(config, hf_cfg)
|
|
253
254
|
use_cuda = prefer_cuda and torch.cuda.is_available()
|
|
254
255
|
if use_cuda and cuda_device_index is not None:
|
{opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/qwen_xvars.py
RENAMED
|
@@ -13,6 +13,7 @@ from opensportslib.core.config.accessors import (
|
|
|
13
13
|
get_component_load_by_kind,
|
|
14
14
|
get_component_params_by_kind,
|
|
15
15
|
get_hf_cuda_device_index,
|
|
16
|
+
get_hf_prefer_cuda,
|
|
16
17
|
get_model_load,
|
|
17
18
|
get_model_runtime_dtype,
|
|
18
19
|
get_train_execution,
|
|
@@ -363,7 +364,7 @@ class QwenXVarsModel(nn.Module):
|
|
|
363
364
|
)
|
|
364
365
|
|
|
365
366
|
local_files_only = bool(hf_cfg.get("local_files_only", False))
|
|
366
|
-
prefer_cuda =
|
|
367
|
+
prefer_cuda = get_hf_prefer_cuda(config, hf_cfg)
|
|
367
368
|
cuda_device_index = get_hf_cuda_device_index(config, hf_cfg)
|
|
368
369
|
mm_hidden_size = int(projector_params.get("input_dim") or get_vqa_mm_hidden_size(config, default=1024))
|
|
369
370
|
use_cuda = prefer_cuda and torch.cuda.is_available()
|
|
@@ -481,7 +482,7 @@ class QwenXVarsModel(nn.Module):
|
|
|
481
482
|
self.raw_extractor = XVarsStrictRawVideoFeatureExtractor(
|
|
482
483
|
weights_path=self.vision_weights_path,
|
|
483
484
|
vision_tower=self.vision_tower_name,
|
|
484
|
-
prefer_cuda=
|
|
485
|
+
prefer_cuda=get_hf_prefer_cuda(config, hf_cfg),
|
|
485
486
|
start_frame=self.strict_sampling_cfg.get("start_frame"),
|
|
486
487
|
end_frame=self.strict_sampling_cfg.get("end_frame"),
|
|
487
488
|
input_fps=self.strict_sampling_cfg.get("input_fps"),
|
|
@@ -491,7 +492,7 @@ class QwenXVarsModel(nn.Module):
|
|
|
491
492
|
else:
|
|
492
493
|
self.raw_extractor = XVarsRawVideoFeatureExtractor(
|
|
493
494
|
vision_tower=self.vision_tower_name,
|
|
494
|
-
prefer_cuda=
|
|
495
|
+
prefer_cuda=get_hf_prefer_cuda(config, hf_cfg),
|
|
495
496
|
)
|
|
496
497
|
if isinstance(self.raw_extractor, XVarsStrictRawVideoFeatureExtractor):
|
|
497
498
|
features, classifier_prior = self.raw_extractor.extract_with_prior(video_path)
|
|
@@ -19,16 +19,17 @@ import torch.nn as nn
|
|
|
19
19
|
from opensportslib.core.config.accessors import (
|
|
20
20
|
get_component_load_by_kind,
|
|
21
21
|
get_component_params_by_kind,
|
|
22
|
-
get_hf_cuda_device_index,
|
|
23
22
|
get_data_sampling,
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
get_hf_cuda_device_index,
|
|
24
|
+
get_hf_prefer_cuda,
|
|
26
25
|
get_model_load,
|
|
27
26
|
get_model_runtime_dtype,
|
|
28
27
|
get_train_execution,
|
|
29
28
|
get_vqa_feature_source,
|
|
30
29
|
get_vqa_mm_hidden_size,
|
|
31
30
|
get_vqa_xvars_feature_mode,
|
|
31
|
+
get_xvars_infer_tokenizer_id,
|
|
32
|
+
get_xvars_infer_video_token_len,
|
|
32
33
|
)
|
|
33
34
|
from opensportslib.core.utils.hf_runtime import (
|
|
34
35
|
VIDEO_SPECIAL_TOKENS,
|
|
@@ -856,7 +857,7 @@ class XVarsVideoChatGPTModel(nn.Module):
|
|
|
856
857
|
)
|
|
857
858
|
|
|
858
859
|
local_files_only = bool(hf_cfg.get("local_files_only", False))
|
|
859
|
-
prefer_cuda =
|
|
860
|
+
prefer_cuda = get_hf_prefer_cuda(config, hf_cfg)
|
|
860
861
|
cuda_device_index = get_hf_cuda_device_index(config, hf_cfg)
|
|
861
862
|
adapter_path = get_model_load(config).get("checkpoint_path")
|
|
862
863
|
projection_path = xvars_cfg.get("projection_path")
|
|
@@ -998,7 +999,7 @@ class XVarsVideoChatGPTModel(nn.Module):
|
|
|
998
999
|
self.raw_extractor = XVarsStrictRawVideoFeatureExtractor(
|
|
999
1000
|
weights_path=self.vision_weights_path,
|
|
1000
1001
|
vision_tower=self.vision_tower_name,
|
|
1001
|
-
prefer_cuda=
|
|
1002
|
+
prefer_cuda=get_hf_prefer_cuda(self.config, hf_cfg),
|
|
1002
1003
|
start_frame=self.strict_sampling_cfg.get("start_frame"),
|
|
1003
1004
|
end_frame=self.strict_sampling_cfg.get("end_frame"),
|
|
1004
1005
|
input_fps=self.strict_sampling_cfg.get("input_fps"),
|
|
@@ -1008,7 +1009,7 @@ class XVarsVideoChatGPTModel(nn.Module):
|
|
|
1008
1009
|
else:
|
|
1009
1010
|
self.raw_extractor = XVarsRawVideoFeatureExtractor(
|
|
1010
1011
|
vision_tower=self.vision_tower_name,
|
|
1011
|
-
prefer_cuda=
|
|
1012
|
+
prefer_cuda=get_hf_prefer_cuda(self.config, hf_cfg),
|
|
1012
1013
|
)
|
|
1013
1014
|
if isinstance(self.raw_extractor, XVarsStrictRawVideoFeatureExtractor):
|
|
1014
1015
|
logger.info("USING STRICT XVARS EXTRACTOR")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensportslib
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev7
|
|
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,7 +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
|
|
29
|
+
Requires-Dist: h5py==3.16.0
|
|
30
30
|
Requires-Dist: huggingface_hub
|
|
31
31
|
Requires-Dist: easydict
|
|
32
32
|
Provides-Extra: test
|
|
@@ -317,10 +317,25 @@ single_prediction = my_model.infer(
|
|
|
317
317
|
```
|
|
318
318
|
|
|
319
319
|
Use `opensportslib/configs/vqa/xvars.yaml` with `opensportslib setup --vqa_xvars`
|
|
320
|
-
for the X-VARS
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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`
|
|
324
339
|
|
|
325
340
|
For X-VARS, `feature_source: indexed_or_raw_clip` prefers indexed CLIP features
|
|
326
341
|
when available and falls back to extracting CLIP features from raw video during
|
|
@@ -39,8 +39,6 @@ opensportslib/configs/vqa/qwen.yaml
|
|
|
39
39
|
opensportslib/configs/vqa/qwen3_vl_native.yaml
|
|
40
40
|
opensportslib/configs/vqa/qwen_lora.yaml
|
|
41
41
|
opensportslib/configs/vqa/qwen_sngar_frames.yaml
|
|
42
|
-
opensportslib/configs/vqa/qwen_vl_native.yaml
|
|
43
|
-
opensportslib/configs/vqa/qwen_vl_native_awq.yaml
|
|
44
42
|
opensportslib/configs/vqa/xvars.yaml
|
|
45
43
|
opensportslib/core/__init__.py
|
|
46
44
|
opensportslib/core/config/__init__.py
|
|
@@ -175,4 +173,5 @@ tools/download/download_osl_hf.py
|
|
|
175
173
|
tools/download/upload_osl_hf.py
|
|
176
174
|
tools/training/classification.py
|
|
177
175
|
tools/training/localization.py
|
|
178
|
-
tools/training/vqa.py
|
|
176
|
+
tools/training/vqa.py
|
|
177
|
+
tools/upload/upload_model_hf.py
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "opensportslib"
|
|
7
|
-
version = "0.2.0.
|
|
7
|
+
version = "0.2.0.dev7"
|
|
8
8
|
description = "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."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
11
|
-
dependencies = [ "SoccerNet", "av", "decord; platform_system != 'Darwin' and platform_machine != 'arm64' and platform_machine != 'aarch64'", "evaluate", "scikit-learn", "torch", "torchvision", "transformers==4.57.3", "tokenizers==0.22.1", "accelerate", "wandb", "opencv-python", "omegaconf", "timm", "seaborn", "tabulate", "pytorch-lightning", "pandas", "pyarrow", "h5py", "huggingface_hub", "easydict",]
|
|
11
|
+
dependencies = [ "SoccerNet", "av", "decord; platform_system != 'Darwin' and platform_machine != 'arm64' and platform_machine != 'aarch64'", "evaluate", "scikit-learn", "torch", "torchvision", "transformers==4.57.3", "tokenizers==0.22.1", "accelerate", "wandb", "opencv-python", "omegaconf", "timm", "seaborn", "tabulate", "pytorch-lightning", "pandas", "pyarrow", "h5py==3.16.0", "huggingface_hub", "easydict",]
|
|
12
12
|
[[project.authors]]
|
|
13
13
|
name = "Jeet Vora"
|
|
14
14
|
|
|
@@ -112,6 +112,20 @@ def test_vqa_qwen_experiment_composes_all_layers():
|
|
|
112
112
|
assert cfg["TRAIN"]["execution"]["hf"]["offload_folder"] == "./hf_offload_qwen"
|
|
113
113
|
|
|
114
114
|
|
|
115
|
+
def test_vqa_qwen_vl_native_experiment_composes_all_layers():
|
|
116
|
+
cfg = load_config("opensportslib/configs/vqa/qwen3_vl_native.yaml", as_namespace=False)
|
|
117
|
+
|
|
118
|
+
assert cfg["VERSION"] == 2
|
|
119
|
+
assert cfg["TASK"] == "vqa"
|
|
120
|
+
assert cfg["SYSTEM"]["paths"]["log_dir"] == "./logs"
|
|
121
|
+
assert cfg["SYSTEM"]["paths"]["save_dir"] == "./checkpoints_vqa_qwen3_vl_native"
|
|
122
|
+
assert cfg["SYSTEM"]["paths"]["work_dir"] == "./checkpoints_vqa_qwen3_vl_native"
|
|
123
|
+
assert cfg["DATA"]["common"]["runtime"]["loader_backend"] == "opencv"
|
|
124
|
+
assert cfg["MODEL"]["metadata"]["backend"] == "qwen_vl_native_infer"
|
|
125
|
+
assert cfg["MODEL"]["components"]["llm_decoder"]["source"]["name"] == "Qwen/Qwen3-VL-8B-Instruct"
|
|
126
|
+
assert cfg["TRAIN"]["execution"]["training_backend"] == "qwen_vl_native_lora"
|
|
127
|
+
|
|
128
|
+
|
|
115
129
|
def test_validation_accepts_canonical_schema():
|
|
116
130
|
canonical = load_config(
|
|
117
131
|
"opensportslib/configs/localization/default.yaml",
|