opensportslib 0.2.0.dev5__tar.gz → 0.2.0.dev6__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 (183) hide show
  1. {opensportslib-0.2.0.dev5/opensportslib.egg-info → opensportslib-0.2.0.dev6}/PKG-INFO +1 -1
  2. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/apis/vqa.py +59 -25
  3. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/h5_header_distance_speed_angle.yaml +3 -3
  4. opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen3_vl_native.yaml +74 -0
  5. opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen_lora.yaml +69 -0
  6. opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen_sngar_frames.yaml +133 -0
  7. opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen_vl_native.yaml +70 -0
  8. opensportslib-0.2.0.dev6/opensportslib/configs/vqa/qwen_vl_native_awq.yaml +45 -0
  9. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/accessors.py +48 -0
  10. opensportslib-0.2.0.dev6/opensportslib/core/trainer/vqa_trainer.py +1725 -0
  11. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/datasets/vqa_dataset.py +145 -17
  12. opensportslib-0.2.0.dev6/opensportslib/models/base/qwen_vl_native.py +619 -0
  13. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/qwen_xvars.py +104 -8
  14. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/xvars_videochatgpt.py +50 -9
  15. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/builder.py +9 -1
  16. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/tools/__init__.py +3 -0
  17. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6/opensportslib.egg-info}/PKG-INFO +1 -1
  18. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib.egg-info/SOURCES.txt +10 -1
  19. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/pyproject.toml +1 -1
  20. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/conftest.py +1 -1
  21. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_task_model_api_contract.py +77 -0
  22. opensportslib-0.2.0.dev6/tests/test_vqa_api.py +595 -0
  23. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_vqa_qwen_xvars.py +79 -1
  24. opensportslib-0.2.0.dev6/tests/test_vqa_training_lora.py +1229 -0
  25. opensportslib-0.2.0.dev6/tools/convert/build_sn_vqa_2026_vqa.py +7 -0
  26. opensportslib-0.2.0.dev6/tools/convert/build_soccernet_gar_vqa.py +7 -0
  27. opensportslib-0.2.0.dev6/tools/training/vqa.py +79 -0
  28. opensportslib-0.2.0.dev5/opensportslib/core/trainer/vqa_trainer.py +0 -797
  29. opensportslib-0.2.0.dev5/tests/test_vqa_api.py +0 -240
  30. opensportslib-0.2.0.dev5/tests/test_vqa_training_lora.py +0 -563
  31. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/LICENSE +0 -0
  32. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/LICENSE-COMMERCIAL +0 -0
  33. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/MANIFEST.in +0 -0
  34. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/README.md +0 -0
  35. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/examples/quickstart/basic_classification.py +0 -0
  36. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/examples/quickstart/basic_localization.py +0 -0
  37. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/examples/quickstart/basic_vqa.py +0 -0
  38. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/__init__.py +0 -0
  39. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/apis/__init__.py +0 -0
  40. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/apis/base_task_model.py +0 -0
  41. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/apis/classification.py +0 -0
  42. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/apis/localization.py +0 -0
  43. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/cli.py +0 -0
  44. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/classification/default.yaml +0 -0
  45. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
  46. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
  47. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/classification/video.yaml +0 -0
  48. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/default.yaml +0 -0
  49. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
  50. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/default.yaml +0 -0
  51. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/h5_header_distance.yaml +0 -0
  52. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/h5_header_distance_angle.yaml +0 -0
  53. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/h5_header_distance_speed.yaml +0 -0
  54. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/h5_header_rule.yaml +0 -0
  55. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
  56. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/video_dali.yaml +0 -0
  57. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/localization/video_ocv.yaml +0 -0
  58. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/vqa/default.yaml +0 -0
  59. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/vqa/qwen.yaml +0 -0
  60. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/configs/vqa/xvars.yaml +0 -0
  61. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/__init__.py +0 -0
  62. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/__init__.py +0 -0
  63. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/conflicts.py +0 -0
  64. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/loader.py +0 -0
  65. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/migrate.py +0 -0
  66. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/migrations/__init__.py +0 -0
  67. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
  68. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/runtime_adapter.py +0 -0
  69. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/schema.py +0 -0
  70. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/schemas/__init__.py +0 -0
  71. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
  72. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
  73. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/config/validate.py +0 -0
  74. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/loss/__init__.py +0 -0
  75. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/loss/builder.py +0 -0
  76. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/loss/calf.py +0 -0
  77. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/loss/ce.py +0 -0
  78. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/loss/combine.py +0 -0
  79. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/loss/nll.py +0 -0
  80. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/optimizer/__init__.py +0 -0
  81. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/optimizer/builder.py +0 -0
  82. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/sampler/weighted_sampler.py +0 -0
  83. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/scheduler/__init__.py +0 -0
  84. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/scheduler/builder.py +0 -0
  85. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/trainer/__init__.py +0 -0
  86. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/trainer/classification_trainer.py +0 -0
  87. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/trainer/localization_trainer.py +0 -0
  88. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/checkpoint.py +0 -0
  89. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/config.py +0 -0
  90. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/config_normalize.py +0 -0
  91. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/data.py +0 -0
  92. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/ddp.py +0 -0
  93. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/default_args.py +0 -0
  94. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/hf_runtime.py +0 -0
  95. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/lightning.py +0 -0
  96. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/load_annotations.py +0 -0
  97. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/seed.py +0 -0
  98. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/video_processing.py +0 -0
  99. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/core/utils/wandb.py +0 -0
  100. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/datasets/__init__.py +0 -0
  101. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/datasets/builder.py +0 -0
  102. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/datasets/classification_dataset.py +0 -0
  103. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/datasets/localization_dataset.py +0 -0
  104. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/datasets/utils/__init__.py +0 -0
  105. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/datasets/utils/h5_tracking.py +0 -0
  106. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/datasets/utils/tracking.py +0 -0
  107. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/legacy_config/classification.yaml +0 -0
  108. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
  109. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
  110. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
  111. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/legacy_config/localization.yaml +0 -0
  112. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
  113. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
  114. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/metrics/classification_metric.py +0 -0
  115. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/metrics/localization_metric.py +0 -0
  116. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/metrics/vqa_metric.py +0 -0
  117. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/__init__.py +0 -0
  118. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/backbones/builder.py +0 -0
  119. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/contextaware.py +0 -0
  120. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/e2e.py +0 -0
  121. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/learnablepooling.py +0 -0
  122. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/rule_based.py +0 -0
  123. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/tracking.py +0 -0
  124. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/vars.py +0 -0
  125. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/video.py +0 -0
  126. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
  127. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/base/video_mae.py +0 -0
  128. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/heads/builder.py +0 -0
  129. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/neck/builder.py +0 -0
  130. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/common.py +0 -0
  131. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/impl/__init__.py +0 -0
  132. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/impl/asformer.py +0 -0
  133. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/impl/calf.py +0 -0
  134. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/impl/gsm.py +0 -0
  135. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/impl/gtad.py +0 -0
  136. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/impl/tsm.py +0 -0
  137. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/litebase.py +0 -0
  138. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/modules.py +0 -0
  139. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/shift.py +0 -0
  140. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/utils.py +0 -0
  141. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
  142. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/vqa_prompting.py +0 -0
  143. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/models/utils/xvars_clip_index.py +0 -0
  144. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/setup/setup.py +0 -0
  145. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/tools/_common.py +0 -0
  146. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/tools/hf_transfer.py +0 -0
  147. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/tools/osl_json_to_parquet.py +0 -0
  148. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib/tools/parquet_to_osl_json.py +0 -0
  149. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib.egg-info/dependency_links.txt +0 -0
  150. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib.egg-info/entry_points.txt +0 -0
  151. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib.egg-info/requires.txt +0 -0
  152. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/opensportslib.egg-info/top_level.txt +0 -0
  153. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/scripts/run_h5_header_rule_inference.py +0 -0
  154. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/setup.cfg +0 -0
  155. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_classification_dataset_paths.py +0 -0
  156. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_classification_trainer_dataloader.py +0 -0
  157. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_config_architecture.py +0 -0
  158. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_config_split_override_sync.py +0 -0
  159. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_config_utils_smoke.py +0 -0
  160. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_conversion_tools.py +0 -0
  161. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_extract_xvars_features.py +0 -0
  162. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_h5_header_rule_spotter.py +0 -0
  163. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_h5_tracking_dataset.py +0 -0
  164. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_hf_transfer_tools.py +0 -0
  165. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_localization_dali_filenames.py +0 -0
  166. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_package_smoke.py +0 -0
  167. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_pretrained_config_merge_policy.py +0 -0
  168. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_public_apis_smoke.py +0 -0
  169. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_setup_cli.py +0 -0
  170. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_subset_train_infer_integration.py +0 -0
  171. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_vqa_metrics_semantic.py +0 -0
  172. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tests/test_vqa_xvars_videochatgpt.py +0 -0
  173. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/convert/build_soccernet_gar.py +0 -0
  174. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
  175. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/convert/build_xvars_indexes.py +0 -0
  176. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/convert/extract_xvars_clip_features.py +0 -0
  177. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
  178. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
  179. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/download/download_hf_repo.py +0 -0
  180. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/download/download_osl_hf.py +0 -0
  181. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/download/upload_osl_hf.py +0 -0
  182. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/training/classification.py +0 -0
  183. {opensportslib-0.2.0.dev5 → opensportslib-0.2.0.dev6}/tools/training/localization.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensportslib
3
- Version: 0.2.0.dev5
3
+ Version: 0.2.0.dev6
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
@@ -51,6 +51,7 @@ class VQAModel(BaseTaskModel):
51
51
  return_queue=None,
52
52
  train_set=None,
53
53
  valid_set=None,
54
+ resume_from_checkpoint=None,
54
55
  use_wandb=False,
55
56
  ):
56
57
  import torch
@@ -97,14 +98,10 @@ class VQAModel(BaseTaskModel):
97
98
  train_data = build_dataset(config, train_set, None, split="train")
98
99
  valid_data = build_dataset(config, valid_set, None, split="valid")
99
100
  trainer = Trainer_VQA(config)
100
- ckpt = trainer.train(
101
- None,
102
- train_data,
103
- valid_data,
104
- rank=rank,
105
- world_size=world_size,
106
- use_wandb=use_wandb,
107
- )
101
+ train_kwargs = {"rank": rank, "world_size": world_size, "use_wandb": use_wandb}
102
+ if resume_from_checkpoint is not None:
103
+ train_kwargs["resume_from_checkpoint"] = resume_from_checkpoint
104
+ ckpt = trainer.train(None, train_data, valid_data, **train_kwargs)
108
105
  if rank == 0 and return_queue is not None:
109
106
  return_queue.put(ckpt)
110
107
  finally:
@@ -139,37 +136,73 @@ class VQAModel(BaseTaskModel):
139
136
  train_set: str | None = None,
140
137
  valid_set: str | None = None,
141
138
  weights: str | None = None,
139
+ resume_from_checkpoint: str | None = None,
140
+ use_ddp: bool | None = None,
142
141
  use_wandb: bool = True,
143
142
  **kwargs,
144
143
  ) -> str | None:
145
144
  del kwargs
145
+
146
+ self.config = resolve_config_omega(self.config, weights=weights)
147
+ execution = get_train_execution(self.config)
148
+ backend = str(execution.get("training_backend", "placeholder")).lower()
149
+ vqa_backend = get_vqa_backend(self.config)
150
+ if vqa_backend == "qwen_xvars_infer" and backend != "qwen_xvars_lora":
151
+ raise ValueError(
152
+ "The 'qwen_xvars_infer' backend requires TRAIN.execution.training_backend='qwen_xvars_lora' for train()."
153
+ )
154
+ if vqa_backend == "qwen_vl_native_infer" and backend != "qwen_vl_native_lora":
155
+ raise ValueError(
156
+ "The 'qwen_vl_native_infer' backend requires TRAIN.execution.training_backend='qwen_vl_native_lora' for train()."
157
+ )
146
158
  import torch
147
159
  import torch.multiprocessing as mp
148
160
 
149
- self.config = resolve_config_omega(self.config, weights=weights)
150
- if get_vqa_backend(self.config) == "qwen_xvars_infer":
151
- raise ValueError("The 'qwen_xvars_infer' backend is inference-only and does not support train().")
152
161
  train_set = self._resolve_split_path("train", train_set)
153
162
  valid_set = self._resolve_split_path("valid", valid_set)
154
- execution = get_train_execution(self.config)
155
- backend = str(execution.get("training_backend", "placeholder")).lower()
156
- if backend == "xvars_videochatgpt_lora":
157
- world_size = torch.cuda.device_count() or get_system_gpu_count(self.config)
163
+ if backend in {"xvars_videochatgpt_lora", "qwen_xvars_lora", "qwen_vl_native_lora"}:
158
164
  requested_gpus = get_system_gpu_count(self.config)
159
- use_ddp = world_size > 1 and int(requested_gpus) > 1
165
+ available_gpus = int(torch.cuda.device_count() or 0)
166
+ if requested_gpus > 0:
167
+ world_size = min(available_gpus, int(requested_gpus)) if available_gpus > 0 else int(requested_gpus)
168
+ else:
169
+ world_size = available_gpus
170
+ effective_world_size = max(int(world_size), 1)
171
+ if use_ddp is None:
172
+ launch_ddp = effective_world_size > 1
173
+ else:
174
+ launch_ddp = bool(use_ddp) and effective_world_size > 1
175
+ if requested_gpus > 0 and available_gpus > 0 and requested_gpus != available_gpus:
176
+ logging.info(
177
+ "VQA train GPU selection | requested=%s | available=%s | launching=%s",
178
+ requested_gpus,
179
+ available_gpus,
180
+ effective_world_size if launch_ddp else 1,
181
+ )
160
182
  logging.info(
161
- "VQA train launch | mode=%s | world_size=%s",
162
- "ddp" if use_ddp else "single",
163
- world_size if use_ddp else 1,
183
+ "VQA train launch | mode=%s | requested_gpus=%s | available_gpus=%s | world_size=%s",
184
+ "ddp" if launch_ddp else "single",
185
+ requested_gpus,
186
+ available_gpus,
187
+ effective_world_size if launch_ddp else 1,
164
188
  )
165
189
 
166
190
  ctx = mp.get_context("spawn")
167
191
  queue = ctx.SimpleQueue()
168
- if use_ddp:
192
+ if launch_ddp:
169
193
  mp.spawn(
170
194
  VQAModel._worker_ddp,
171
- args=(world_size, self.config_path, self.config, queue, train_set, valid_set, use_wandb),
172
- nprocs=world_size,
195
+ args=(
196
+ effective_world_size,
197
+ self.config_path,
198
+ self.config,
199
+ queue,
200
+ train_set,
201
+ valid_set,
202
+ resume_from_checkpoint,
203
+ use_wandb,
204
+ ),
205
+ nprocs=effective_world_size,
173
206
  )
174
207
  else:
175
208
  VQAModel._worker_ddp(
@@ -180,6 +213,7 @@ class VQAModel(BaseTaskModel):
180
213
  return_queue=queue,
181
214
  train_set=train_set,
182
215
  valid_set=valid_set,
216
+ resume_from_checkpoint=resume_from_checkpoint,
183
217
  use_wandb=use_wandb,
184
218
  )
185
219
  ckpt = queue.get()
@@ -189,7 +223,7 @@ class VQAModel(BaseTaskModel):
189
223
 
190
224
  raise ValueError(
191
225
  f"Unsupported VQA training backend '{backend}'. "
192
- "Only 'xvars_videochatgpt_lora' is supported."
226
+ "Only 'xvars_videochatgpt_lora' and 'qwen_xvars_lora' are supported."
193
227
  )
194
228
 
195
229
  def infer(
@@ -216,8 +250,6 @@ class VQAModel(BaseTaskModel):
216
250
  self.config = resolve_config_omega(self.config, weights=weights)
217
251
  backend = get_vqa_backend(self.config)
218
252
  effective_weights = weights if weights is not None else self.last_loaded_weights
219
- if backend == "qwen_xvars_infer" and effective_weights is not None:
220
- raise ValueError("The 'qwen_xvars_infer' backend does not support adapter weights for infer().")
221
253
  _set_model_checkpoint_path(self.config, effective_weights)
222
254
  self.trainer = Trainer_VQA(self.config)
223
255
  if effective_weights is not None:
@@ -237,6 +269,8 @@ class VQAModel(BaseTaskModel):
237
269
  "question": str(question).strip(),
238
270
  "references": [],
239
271
  "video_path": resolved_video_path,
272
+ "frame_paths": [],
273
+ "video_frames": [],
240
274
  "video_spatio_temporal_features": None,
241
275
  "prior_prediction_text": "",
242
276
  "labels": {},
@@ -11,14 +11,14 @@ SYSTEM:
11
11
  DATA:
12
12
  common:
13
13
  dataset_name: h5_headers
14
- data_root: ./data
14
+ data_root: /home/vorajv/dataset/silvio-h5/
15
15
  classes:
16
16
  - header
17
17
  splits:
18
18
  test:
19
19
  type: H5OSLJsonSpotting
20
- annotation_path: ./data/h5.json
21
- source_path: ./data
20
+ annotation_path: /home/vorajv/dataset/silvio-h5/h5_tiny.json
21
+ source_path: /home/vorajv/dataset/silvio-h5/
22
22
  dataloader:
23
23
  batch_size: 1
24
24
  shuffle: false
@@ -0,0 +1,74 @@
1
+ SYSTEM:
2
+ paths:
3
+ save_dir: ./checkpoints_vqa_qwen3_vl_native
4
+ gpu:
5
+ count: 4
6
+ id: null
7
+
8
+ MODEL:
9
+ topology: []
10
+ components:
11
+ video_encoder:
12
+ kind: encoder
13
+ source:
14
+ provider: opensportslib
15
+ name: qwen_vl_native
16
+ params:
17
+ feature_source: raw_video
18
+ native_vl:
19
+ visual_input_mode: frames
20
+ num_frames: 8
21
+ min_pixels: 50176 # 28*28*64
22
+ max_pixels: 401408 # 28*28*512
23
+ overrides: {}
24
+ llm_decoder:
25
+ kind: decoder
26
+ source:
27
+ provider: huggingface
28
+ name: Qwen/Qwen3-VL-8B-Instruct
29
+ params:
30
+ repo_id: Qwen/Qwen3-VL-8B-Instruct
31
+ overrides: {}
32
+ metadata:
33
+ backend: qwen_vl_native_infer
34
+
35
+ TRAIN:
36
+ optimizer:
37
+ type: adamw_torch
38
+ lr: 0.0002
39
+ weight_decay: 0.001
40
+ execution:
41
+ acc_grad_iter: 4
42
+ training_backend: qwen_vl_native_lora
43
+ prompt:
44
+ system_prompt: You are a football video assistant. Answer the VQA question using the provided visual evidence and referee priors.
45
+ native_vl:
46
+ visual_input_mode: frames
47
+ num_frames: 8
48
+ min_pixels: 50176 # 28*28*64
49
+ max_pixels: 401408 # 28*28*512
50
+ hf:
51
+ tokenizer_id: ${MODEL.components.llm_decoder.params.repo_id}
52
+ prefer_cuda: true
53
+ local_files_only: false
54
+ device_map: null
55
+ sft:
56
+ per_device_train_batch_size: 1
57
+ per_device_eval_batch_size: 1
58
+ max_seq_length: 1024
59
+ max_grad_norm: 1.0
60
+ memory_cache_rows: 0
61
+ gradient_checkpointing: true
62
+ ddp_find_unused_parameters: false
63
+ ddp_broadcast_buffers: false
64
+ resume_optimizer_state: false
65
+ cache_tokenized_rows: false
66
+ disable_tqdm: false
67
+ save_strategy: epoch
68
+ # save_steps: 100
69
+ # save_total_limit: 3
70
+ evaluation_strategy: "no"
71
+ lora:
72
+ prepare_kbit: false
73
+ quantization:
74
+ enabled: false
@@ -0,0 +1,69 @@
1
+ SYSTEM:
2
+ paths:
3
+ save_dir: ./checkpoints_vqa_qwen_lora
4
+ gpu:
5
+ count: 4
6
+
7
+ MODEL:
8
+ components:
9
+ video_encoder:
10
+ kind: encoder
11
+ source:
12
+ provider: opensportslib
13
+ name: xvars_clip_features
14
+ load:
15
+ weights_path: /home/vorajv/X-VARS/weights/14_model.pth.tar
16
+ params:
17
+ feature_source: indexed_or_raw_clip
18
+ vision_tower: openai/clip-vit-large-patch14
19
+ feature_dim: 1024
20
+ overrides: {}
21
+ mm_projector:
22
+ kind: projector
23
+ source:
24
+ provider: opensportslib
25
+ params:
26
+ input_dim: 1024
27
+ overrides: {}
28
+ llm_decoder:
29
+ kind: decoder
30
+ source:
31
+ provider: huggingface
32
+ name: Qwen/Qwen3.5-9B-Base
33
+ params:
34
+ repo_id: Qwen/Qwen3.5-9B-Base
35
+ overrides: {}
36
+ metadata:
37
+ backend: qwen_xvars_infer
38
+
39
+ TRAIN:
40
+ execution:
41
+ training_backend: qwen_xvars_lora
42
+ prompt:
43
+ system_prompt: You are a football video assistant. Answer the VQA question using the provided video context and referee priors.
44
+ hf:
45
+ tokenizer_id: ${MODEL.components.llm_decoder.params.repo_id}
46
+ prefer_cuda: true
47
+ local_files_only: false
48
+ sft:
49
+ per_device_train_batch_size: 1
50
+ per_device_eval_batch_size: 1
51
+ gradient_accumulation_steps: 8
52
+ max_seq_length: 480
53
+ gradient_checkpointing: true
54
+ disable_tqdm: true
55
+ save_strategy: epoch
56
+ evaluation_strategy: "no"
57
+ lora:
58
+ r: 16
59
+ alpha: 32
60
+ dropout: 0.05
61
+ bias: none
62
+ prepare_kbit: false
63
+ target_modules: [q_proj, v_proj, k_proj, o_proj]
64
+ quantization:
65
+ enabled: false
66
+ load_in_4bit: true
67
+ bnb_4bit_quant_type: nf4
68
+ compute_dtype: float16
69
+ bnb_4bit_use_double_quant: true
@@ -0,0 +1,133 @@
1
+ SYSTEM:
2
+ paths:
3
+ save_dir: ./checkpoints_vqa_qwen_sngar_frames
4
+ gpu:
5
+ count: 4
6
+ id: null
7
+
8
+ DATA:
9
+ common:
10
+ dataset_name: sngar-frames-vqa
11
+ data_root: /home/vorajv/dataset/sngar-frames
12
+ splits:
13
+ test:
14
+ annotation_path: ${DATA.common.data_root}/test.json
15
+ source_path: ${DATA.common.data_root}
16
+ dataloader:
17
+ batch_size: 1
18
+ shuffle: false
19
+ num_workers: 0
20
+ pin_memory: false
21
+ inputs:
22
+ video:
23
+ modality: frames_npy
24
+ representation: frames_npy
25
+ source:
26
+ format: npy
27
+ sampling:
28
+ num_frames: 16
29
+ transform: {}
30
+ augmentations: {}
31
+ params: {}
32
+ question:
33
+ modality: text
34
+ representation: raw
35
+ source:
36
+ format: json
37
+ sampling: {}
38
+ transform: {}
39
+ augmentations: {}
40
+ params: {}
41
+
42
+ MODEL:
43
+ topology: []
44
+ components:
45
+ video_encoder:
46
+ kind: encoder
47
+ source:
48
+ provider: opensportslib
49
+ name: qwen_vl_native
50
+ params:
51
+ feature_source: raw_video
52
+ native_vl:
53
+ visual_input_mode: frames
54
+ num_frames: 8
55
+ min_pixels: 50176 # 28*28*64
56
+ max_pixels: 401408 # 28*28*512
57
+ overrides: {}
58
+ llm_decoder:
59
+ kind: decoder
60
+ source:
61
+ provider: huggingface
62
+ name: Qwen/Qwen3-VL-8B-Instruct
63
+ params:
64
+ repo_id: Qwen/Qwen3-VL-8B-Instruct
65
+ overrides: {}
66
+ metadata:
67
+ backend: qwen_vl_native_infer
68
+
69
+ TRAIN:
70
+ optimizer:
71
+ hf_optim: adamw_torch
72
+ execution:
73
+ acc_grad_iter: 4
74
+ training_backend: qwen_vl_native_lora
75
+ prompt:
76
+ include_priors: false
77
+ system_prompt: >-
78
+ You are a soccer action classifier for short soccer clips.
79
+ Your task is to choose exactly one label from this closed set:
80
+ PASS, HEADER, HIGH PASS, OUT, CROSS, THROW IN, SHOT,
81
+ PLAYER SUCCESSFUL TACKLE, FREE KICK, GOAL.
82
+ Use these label meanings:
83
+ PASS = a standard grounded or short pass between teammates.
84
+ HEADER = the ball is intentionally played with the head.
85
+ HIGH PASS = a lofted or aerial pass to a teammate that is not mainly a cross.
86
+ OUT = the ball goes out of play.
87
+ CROSS = the ball is delivered from a wide area into the box or a dangerous central area.
88
+ THROW IN = play is restarted with a throw-in from the sideline.
89
+ SHOT = a player attempts to score.
90
+ PLAYER SUCCESSFUL TACKLE = a defender successfully wins or disrupts possession with a tackle.
91
+ FREE KICK = play is restarted with a free kick.
92
+ GOAL = the ball enters the goal and a goal is scored.
93
+ Decision rules:
94
+ Prefer the main action visible in the clip.
95
+ Choose the closest valid label if the clip is ambiguous.
96
+ Do not output any words other than the single label.
97
+ Do not explain.
98
+ Do not output a sentence.
99
+ Do not output punctuation.
100
+ Do not output 'The' or any extra text.
101
+ generation:
102
+ max_new_tokens: 3
103
+ temperature: 0.0
104
+ repetition_penalty: 1.0
105
+ no_repeat_ngram_size: 2
106
+ native_vl:
107
+ visual_input_mode: frames
108
+ num_frames: 8
109
+ min_pixels: 50176 # 28*28*64
110
+ max_pixels: 401408 # 28*28*512
111
+ hf:
112
+ tokenizer_id: ${MODEL.components.llm_decoder.params.repo_id}
113
+ prefer_cuda: true
114
+ local_files_only: false
115
+ device_map: auto
116
+ offload_folder: ./hf_offload_qwen
117
+ sft:
118
+ per_device_train_batch_size: 1
119
+ per_device_eval_batch_size: 1
120
+ max_seq_length: 1024
121
+ max_grad_norm: 1.0
122
+ gradient_checkpointing: true
123
+ ddp_find_unused_parameters: false
124
+ ddp_broadcast_buffers: false
125
+ resume_optimizer_state: false
126
+ cache_tokenized_rows: false
127
+ disable_tqdm: false
128
+ save_strategy: epoch
129
+ evaluation_strategy: "no"
130
+ lora:
131
+ prepare_kbit: false
132
+ quantization:
133
+ enabled: false
@@ -0,0 +1,70 @@
1
+ SYSTEM:
2
+ paths:
3
+ save_dir: ./checkpoints_vqa_qwen_vl_native
4
+ gpu:
5
+ count: 4
6
+ id: null
7
+
8
+ MODEL:
9
+ topology: []
10
+ components:
11
+ video_encoder:
12
+ kind: encoder
13
+ source:
14
+ provider: opensportslib
15
+ name: qwen_vl_native
16
+ params:
17
+ feature_source: raw_video
18
+ native_vl:
19
+ visual_input_mode: frames
20
+ num_frames: 8
21
+ min_pixels: 50176 # 28*28*64
22
+ max_pixels: 401408 # 28*28*512
23
+ overrides: {}
24
+ llm_decoder:
25
+ kind: decoder
26
+ source:
27
+ provider: huggingface
28
+ name: Qwen/Qwen2.5-VL-7B-Instruct
29
+ params:
30
+ repo_id: Qwen/Qwen2.5-VL-7B-Instruct
31
+ overrides: {}
32
+ metadata:
33
+ backend: qwen_vl_native_infer
34
+
35
+ TRAIN:
36
+ optimizer:
37
+ type: adamw_torch
38
+ lr: 0.0002
39
+ weight_decay: 0.001
40
+ execution:
41
+ acc_grad_iter: 4
42
+ training_backend: qwen_vl_native_lora
43
+ prompt:
44
+ system_prompt: You are a football video assistant. Answer the VQA question using the provided visual evidence and referee priors.
45
+ native_vl:
46
+ visual_input_mode: frames
47
+ num_frames: 8
48
+ min_pixels: 50176 # 28*28*64
49
+ max_pixels: 401408 # 28*28*512
50
+ hf:
51
+ tokenizer_id: ${MODEL.components.llm_decoder.params.repo_id}
52
+ prefer_cuda: true
53
+ local_files_only: false
54
+ device_map: null
55
+ sft:
56
+ per_device_train_batch_size: 1
57
+ per_device_eval_batch_size: 1
58
+ max_seq_length: 1024
59
+ memory_cache_rows: 0
60
+ gradient_checkpointing: true
61
+ ddp_find_unused_parameters: false
62
+ resume_optimizer_state: false
63
+ cache_tokenized_rows: false
64
+ disable_tqdm: false
65
+ save_strategy: epoch
66
+ evaluation_strategy: "no"
67
+ lora:
68
+ prepare_kbit: false
69
+ quantization:
70
+ enabled: false
@@ -0,0 +1,45 @@
1
+ SYSTEM:
2
+ paths:
3
+ save_dir: ./checkpoints_vqa_qwen_vl_native_awq
4
+
5
+ MODEL:
6
+ topology: []
7
+ components:
8
+ video_encoder:
9
+ kind: encoder
10
+ source:
11
+ provider: opensportslib
12
+ name: qwen_vl_native
13
+ params:
14
+ feature_source: raw_video
15
+ native_vl:
16
+ visual_input_mode: frames
17
+ num_frames: 8
18
+ min_pixels: 200704
19
+ max_pixels: 1003520
20
+ overrides: {}
21
+ llm_decoder:
22
+ kind: decoder
23
+ source:
24
+ provider: huggingface
25
+ name: Qwen/Qwen2.5-VL-7B-Instruct-AWQ
26
+ params:
27
+ repo_id: Qwen/Qwen2.5-VL-7B-Instruct-AWQ
28
+ overrides: {}
29
+ metadata:
30
+ backend: qwen_vl_native_infer
31
+
32
+ TRAIN:
33
+ execution:
34
+ prompt:
35
+ system_prompt: You are a football video assistant. Answer the VQA question using the provided visual evidence and referee priors.
36
+ native_vl:
37
+ visual_input_mode: frames
38
+ num_frames: 8
39
+ min_pixels: 200704
40
+ max_pixels: 1003520
41
+ hf:
42
+ tokenizer_id: ${MODEL.components.llm_decoder.params.repo_id}
43
+ prefer_cuda: true
44
+ local_files_only: false
45
+ device_map: auto
@@ -466,6 +466,10 @@ def is_xvars_videochatgpt_backend(cfg: Any) -> bool:
466
466
  return get_vqa_backend(cfg) == "xvars_videochatgpt"
467
467
 
468
468
 
469
+ def is_qwen_vl_native_backend(cfg: Any) -> bool:
470
+ return get_vqa_backend(cfg) == "qwen_vl_native_infer"
471
+
472
+
469
473
  def normalize_xvars_feature_mode(mode: Any, default: str = "strict_xvars") -> str:
470
474
  value = str(mode or "").strip().lower()
471
475
  if not value:
@@ -612,6 +616,50 @@ def get_vqa_mm_hidden_size(cfg: Any, default: int = 1024) -> int:
612
616
  return int(default)
613
617
 
614
618
 
619
+ def get_vqa_native_visual_cfg(cfg: Any) -> dict[str, Any]:
620
+ execution = get_train_execution(cfg)
621
+ native_cfg = _as_dict(execution.get("native_vl"))
622
+ if native_cfg:
623
+ return native_cfg
624
+
625
+ encoder_params = get_component_params_by_kind(cfg, "encoder")
626
+ return _as_dict(encoder_params.get("native_vl"))
627
+
628
+
629
+ def get_vqa_native_visual_input_mode(cfg: Any, default: str = "frames") -> str:
630
+ native_cfg = get_vqa_native_visual_cfg(cfg)
631
+ mode = str(native_cfg.get("visual_input_mode", default) or default).strip().lower()
632
+ if mode not in {"frames", "video_with_frames_fallback"}:
633
+ raise ValueError(
634
+ f"Unsupported native VL visual_input_mode '{mode}'. "
635
+ "Expected 'frames' or 'video_with_frames_fallback'."
636
+ )
637
+ return mode
638
+
639
+
640
+ def get_vqa_native_num_frames(cfg: Any, default: int = 8) -> int:
641
+ native_cfg = get_vqa_native_visual_cfg(cfg)
642
+ if native_cfg.get("num_frames") is not None:
643
+ return max(1, int(native_cfg["num_frames"]))
644
+
645
+ sampling = get_data_sampling(cfg)
646
+ if sampling.get("num_frames") is not None:
647
+ return max(1, int(sampling["num_frames"]))
648
+ return int(default)
649
+
650
+
651
+ def get_vqa_native_min_pixels(cfg: Any) -> int | None:
652
+ native_cfg = get_vqa_native_visual_cfg(cfg)
653
+ value = native_cfg.get("min_pixels")
654
+ return int(value) if value is not None else None
655
+
656
+
657
+ def get_vqa_native_max_pixels(cfg: Any) -> int | None:
658
+ native_cfg = get_vqa_native_visual_cfg(cfg)
659
+ value = native_cfg.get("max_pixels")
660
+ return int(value) if value is not None else None
661
+
662
+
615
663
  def get_model_runtime_dtype(cfg: Any, default: str = "fp32") -> str:
616
664
  runtime = get_model_runtime(cfg)
617
665
  dtype = runtime.get("dtype", default)