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.
Files changed (181) hide show
  1. {opensportslib-0.2.0.dev6/opensportslib.egg-info → opensportslib-0.2.0.dev7}/PKG-INFO +21 -6
  2. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/README.md +19 -4
  3. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/localization.py +97 -5
  4. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/default.yaml +1 -1
  5. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/default.yaml +1 -1
  6. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen3_vl_native.yaml +8 -1
  7. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/accessors.py +38 -0
  8. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/vqa_trainer.py +12 -11
  9. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/qwen_vl_native.py +2 -1
  10. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/qwen_xvars.py +4 -3
  11. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/xvars_videochatgpt.py +7 -6
  12. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7/opensportslib.egg-info}/PKG-INFO +21 -6
  13. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/SOURCES.txt +2 -3
  14. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/requires.txt +1 -1
  15. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/pyproject.toml +2 -2
  16. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_config_architecture.py +14 -0
  17. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_config_utils_smoke.py +37 -1
  18. opensportslib-0.2.0.dev7/tools/upload/upload_model_hf.py +223 -0
  19. opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen_vl_native.yaml +0 -70
  20. opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen_vl_native_awq.yaml +0 -45
  21. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/LICENSE +0 -0
  22. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/LICENSE-COMMERCIAL +0 -0
  23. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/MANIFEST.in +0 -0
  24. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/examples/quickstart/basic_classification.py +0 -0
  25. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/examples/quickstart/basic_localization.py +0 -0
  26. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/examples/quickstart/basic_vqa.py +0 -0
  27. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/__init__.py +0 -0
  28. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/__init__.py +0 -0
  29. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/base_task_model.py +0 -0
  30. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/classification.py +0 -0
  31. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/apis/vqa.py +0 -0
  32. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/cli.py +0 -0
  33. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/classification/default.yaml +0 -0
  34. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
  35. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
  36. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/classification/video.yaml +0 -0
  37. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
  38. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/default.yaml +0 -0
  39. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_distance.yaml +0 -0
  40. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_distance_angle.yaml +0 -0
  41. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_distance_speed.yaml +0 -0
  42. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_distance_speed_angle.yaml +0 -0
  43. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/h5_header_rule.yaml +0 -0
  44. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
  45. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/video_dali.yaml +0 -0
  46. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/localization/video_ocv.yaml +0 -0
  47. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen.yaml +0 -0
  48. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen_lora.yaml +0 -0
  49. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/qwen_sngar_frames.yaml +0 -0
  50. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/configs/vqa/xvars.yaml +0 -0
  51. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/__init__.py +0 -0
  52. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/__init__.py +0 -0
  53. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/conflicts.py +0 -0
  54. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/loader.py +0 -0
  55. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/migrate.py +0 -0
  56. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/migrations/__init__.py +0 -0
  57. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
  58. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/runtime_adapter.py +0 -0
  59. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/schema.py +0 -0
  60. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/schemas/__init__.py +0 -0
  61. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
  62. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
  63. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/config/validate.py +0 -0
  64. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/__init__.py +0 -0
  65. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/builder.py +0 -0
  66. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/calf.py +0 -0
  67. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/ce.py +0 -0
  68. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/combine.py +0 -0
  69. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/loss/nll.py +0 -0
  70. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/optimizer/__init__.py +0 -0
  71. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/optimizer/builder.py +0 -0
  72. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/sampler/weighted_sampler.py +0 -0
  73. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/scheduler/__init__.py +0 -0
  74. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/scheduler/builder.py +0 -0
  75. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/__init__.py +0 -0
  76. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/classification_trainer.py +0 -0
  77. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/trainer/localization_trainer.py +0 -0
  78. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/checkpoint.py +0 -0
  79. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/config.py +0 -0
  80. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/config_normalize.py +0 -0
  81. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/data.py +0 -0
  82. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/ddp.py +0 -0
  83. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/default_args.py +0 -0
  84. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/hf_runtime.py +0 -0
  85. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/lightning.py +0 -0
  86. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/load_annotations.py +0 -0
  87. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/seed.py +0 -0
  88. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/video_processing.py +0 -0
  89. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/core/utils/wandb.py +0 -0
  90. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/__init__.py +0 -0
  91. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/builder.py +0 -0
  92. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/classification_dataset.py +0 -0
  93. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/localization_dataset.py +0 -0
  94. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/utils/__init__.py +0 -0
  95. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/utils/h5_tracking.py +0 -0
  96. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/utils/tracking.py +0 -0
  97. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/datasets/vqa_dataset.py +0 -0
  98. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/classification.yaml +0 -0
  99. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
  100. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
  101. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
  102. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/localization.yaml +0 -0
  103. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
  104. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
  105. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/metrics/classification_metric.py +0 -0
  106. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/metrics/localization_metric.py +0 -0
  107. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/metrics/vqa_metric.py +0 -0
  108. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/__init__.py +0 -0
  109. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/backbones/builder.py +0 -0
  110. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/contextaware.py +0 -0
  111. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/e2e.py +0 -0
  112. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/learnablepooling.py +0 -0
  113. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/rule_based.py +0 -0
  114. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/tracking.py +0 -0
  115. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/vars.py +0 -0
  116. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/video.py +0 -0
  117. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
  118. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/base/video_mae.py +0 -0
  119. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/builder.py +0 -0
  120. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/heads/builder.py +0 -0
  121. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/neck/builder.py +0 -0
  122. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/common.py +0 -0
  123. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/__init__.py +0 -0
  124. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/asformer.py +0 -0
  125. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/calf.py +0 -0
  126. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/gsm.py +0 -0
  127. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/gtad.py +0 -0
  128. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/impl/tsm.py +0 -0
  129. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/litebase.py +0 -0
  130. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/modules.py +0 -0
  131. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/shift.py +0 -0
  132. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/utils.py +0 -0
  133. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
  134. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/vqa_prompting.py +0 -0
  135. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/models/utils/xvars_clip_index.py +0 -0
  136. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/setup/setup.py +0 -0
  137. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/__init__.py +0 -0
  138. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/_common.py +0 -0
  139. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/hf_transfer.py +0 -0
  140. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/osl_json_to_parquet.py +0 -0
  141. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib/tools/parquet_to_osl_json.py +0 -0
  142. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/dependency_links.txt +0 -0
  143. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/entry_points.txt +0 -0
  144. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/opensportslib.egg-info/top_level.txt +0 -0
  145. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/scripts/run_h5_header_rule_inference.py +0 -0
  146. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/setup.cfg +0 -0
  147. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/conftest.py +0 -0
  148. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_classification_dataset_paths.py +0 -0
  149. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_classification_trainer_dataloader.py +0 -0
  150. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_config_split_override_sync.py +0 -0
  151. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_conversion_tools.py +0 -0
  152. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_extract_xvars_features.py +0 -0
  153. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_h5_header_rule_spotter.py +0 -0
  154. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_h5_tracking_dataset.py +0 -0
  155. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_hf_transfer_tools.py +0 -0
  156. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_localization_dali_filenames.py +0 -0
  157. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_package_smoke.py +0 -0
  158. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_pretrained_config_merge_policy.py +0 -0
  159. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_public_apis_smoke.py +0 -0
  160. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_setup_cli.py +0 -0
  161. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_subset_train_infer_integration.py +0 -0
  162. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_task_model_api_contract.py +0 -0
  163. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_api.py +0 -0
  164. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_metrics_semantic.py +0 -0
  165. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_qwen_xvars.py +0 -0
  166. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_training_lora.py +0 -0
  167. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tests/test_vqa_xvars_videochatgpt.py +0 -0
  168. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_sn_vqa_2026_vqa.py +0 -0
  169. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_soccernet_gar.py +0 -0
  170. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
  171. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_soccernet_gar_vqa.py +0 -0
  172. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/build_xvars_indexes.py +0 -0
  173. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/extract_xvars_clip_features.py +0 -0
  174. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
  175. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
  176. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/download/download_hf_repo.py +0 -0
  177. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/download/download_osl_hf.py +0 -0
  178. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/download/upload_osl_hf.py +0 -0
  179. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/training/classification.py +0 -0
  180. {opensportslib-0.2.0.dev6 → opensportslib-0.2.0.dev7}/tools/training/localization.py +0 -0
  181. {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.dev6
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-compatible backend, or `opensportslib/configs/vqa/qwen.yaml` with
321
- `opensportslib setup --vqa_qwen` for the Qwen-compatible backend. The Qwen
322
- backend currently supports `Qwen/Qwen2.5-7B-Instruct` and
323
- `Qwen/Qwen3.5-9B-Base`.
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-compatible backend, or `opensportslib/configs/vqa/qwen.yaml` with
285
- `opensportslib setup --vqa_qwen` for the Qwen-compatible backend. The Qwen
286
- backend currently supports `Qwen/Qwen2.5-7B-Instruct` and
287
- `Qwen/Qwen3.5-9B-Base`.
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
 
@@ -2,7 +2,7 @@ SYSTEM:
2
2
  paths:
3
3
  log_dir: ./logs
4
4
  save_dir: ./checkpoints
5
- device: cuda
5
+ device: auto
6
6
  gpu:
7
7
  id: 0
8
8
  reproducibility:
@@ -5,7 +5,7 @@ SYSTEM:
5
5
  paths:
6
6
  save_dir: ./checkpoints_vqa
7
7
  work_dir: ${SYSTEM.paths.save_dir}
8
- device: cuda
8
+ device: auto
9
9
  gpu:
10
10
  count: 1
11
11
  id: 0
@@ -25,8 +25,15 @@ MODEL:
25
25
  kind: decoder
26
26
  source:
27
27
  provider: huggingface
28
- name: Qwen/Qwen3-VL-8B-Instruct
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:
@@ -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"):
@@ -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
- get_vqa_backend,
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 bool(hf_cfg.get("prefer_cuda", True)) and torch.cuda.is_available():
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 bool(hf_cfg.get("prefer_cuda", True)),
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 bool(hf_cfg.get("prefer_cuda", True)) and torch.cuda.is_available():
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 bool(hf_cfg.get("prefer_cuda", True)),
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 bool(hf_cfg.get("prefer_cuda", True)),
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)),
@@ -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 = bool(hf_cfg.get("prefer_cuda", True))
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:
@@ -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 = bool(hf_cfg.get("prefer_cuda", True))
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=bool(hf_cfg.get("prefer_cuda", True)),
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=bool(hf_cfg.get("prefer_cuda", True)),
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
- get_xvars_infer_tokenizer_id,
25
- get_xvars_infer_video_token_len,
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 = bool(hf_cfg.get("prefer_cuda", True))
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=bool(hf_cfg.get("prefer_cuda", True)),
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=bool(hf_cfg.get("prefer_cuda", True)),
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.dev6
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-compatible backend, or `opensportslib/configs/vqa/qwen.yaml` with
321
- `opensportslib setup --vqa_qwen` for the Qwen-compatible backend. The Qwen
322
- backend currently supports `Qwen/Qwen2.5-7B-Instruct` and
323
- `Qwen/Qwen3.5-9B-Base`.
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
@@ -16,7 +16,7 @@ tabulate
16
16
  pytorch-lightning
17
17
  pandas
18
18
  pyarrow
19
- h5py
19
+ h5py==3.16.0
20
20
  huggingface_hub
21
21
  easydict
22
22
 
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "opensportslib"
7
- version = "0.2.0.dev6"
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",