opensportslib 0.2.0.dev2__py3-none-any.whl → 0.2.0.dev3__py3-none-any.whl

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/cli.py CHANGED
@@ -11,8 +11,8 @@ def main(argv: Optional[list[str]] = None) -> int:
11
11
  parser.add_argument("command", choices=["setup"])
12
12
  parser.add_argument("--pyg", action="store_true")
13
13
  parser.add_argument("--dali", action="store_true")
14
- parser.add_argument("--xvars", action="store_true")
15
- parser.add_argument("--qwen", action="store_true")
14
+ parser.add_argument("--vqa_xvars", action="store_true")
15
+ parser.add_argument("--vqa_qwen", action="store_true")
16
16
 
17
17
  args = parser.parse_args(argv)
18
18
 
@@ -20,8 +20,8 @@ def main(argv: Optional[list[str]] = None) -> int:
20
20
  setup(
21
21
  pyg=args.pyg,
22
22
  dali=args.dali,
23
- xvars=args.xvars,
24
- qwen=args.qwen
23
+ vqa_xvars=args.vqa_xvars,
24
+ vqa_qwen=args.vqa_qwen
25
25
  )
26
26
  return 0
27
27
 
@@ -1,95 +1,8 @@
1
- TASK: VQA
2
- VERSION: 2
3
-
4
1
  SYSTEM:
5
2
  paths:
6
- log_dir: ./logs
7
3
  save_dir: ./checkpoints_vqa_qwen
8
- work_dir: ./checkpoints_vqa_qwen
9
- device: cuda
10
- gpu:
11
- count: 1
12
- id: 0
13
- reproducibility:
14
- use_seed: true
15
- seed: 42
16
-
17
- DATA:
18
- common:
19
- dataset_name: OSL-XFoul
20
- data_root: /home/vorajv/dataset/OSL-XFoul
21
- feature_index: /home/vorajv/dataset/OSL-XFoul/feature_index.json
22
- prediction_index: /home/vorajv/dataset/OSL-XFoul/prediction_index.json
23
- runtime:
24
- loader_backend: opencv
25
- splits:
26
- train:
27
- annotation_path: /home/vorajv/dataset/OSL-XFoul/train.json
28
- source_path: /home/vorajv/dataset/OSL-XFoul
29
- dataloader:
30
- batch_size: 1
31
- shuffle: true
32
- num_workers: 0
33
- pin_memory: false
34
- mp_context: spawn
35
- persistent_workers: false
36
- valid:
37
- annotation_path: /home/vorajv/dataset/OSL-XFoul/valid.json
38
- source_path: /home/vorajv/dataset/OSL-XFoul
39
- dataloader:
40
- batch_size: 1
41
- shuffle: false
42
- num_workers: 0
43
- pin_memory: false
44
- mp_context: spawn
45
- persistent_workers: false
46
- test:
47
- annotation_path: /home/vorajv/dataset/OSL-XFoul/test.json
48
- source_path: /home/vorajv/dataset/OSL-XFoul
49
- dataloader:
50
- batch_size: 1
51
- shuffle: false
52
- num_workers: 0
53
- pin_memory: false
54
- mp_context: spawn
55
- persistent_workers: false
56
- inputs:
57
- video:
58
- modality: video
59
- representation: raw
60
- source:
61
- format: mp4
62
- sampling:
63
- num_frames: 100
64
- input_fps: 25
65
- target_fps: 17
66
- start_frame: 63
67
- end_frame: 87
68
- transform: {}
69
- augmentations: {}
70
- params: {}
71
- question:
72
- modality: text
73
- representation: raw
74
- source:
75
- format: json
76
- sampling: {}
77
- transform: {}
78
- augmentations: {}
79
- params: {}
80
4
 
81
5
  MODEL:
82
- runtime:
83
- dtype: fp16
84
- device: auto
85
- compile: false
86
- freeze: false
87
- load:
88
- checkpoint_path: null
89
- pretrained: false
90
- strict: true
91
- map_location: null
92
- format: auto
93
6
  components:
94
7
  video_encoder:
95
8
  kind: encoder
@@ -114,83 +27,19 @@ MODEL:
114
27
  kind: decoder
115
28
  source:
116
29
  provider: huggingface
117
- # Qwen/Qwen2.5-7B-Instruct or Qwen/Qwen3.5-9B-Base
30
+ # Supported models: Qwen/Qwen2.5-7B-Instruct or Qwen/Qwen3.5-9B-Base
118
31
  name: Qwen/Qwen3.5-9B-Base
119
32
  params:
120
- # Qwen/Qwen2.5-7B-Instruct or Qwen/Qwen3.5-9B-Base
33
+ # Supported models: Qwen/Qwen2.5-7B-Instruct or Qwen/Qwen3.5-9B-Base
121
34
  repo_id: Qwen/Qwen3.5-9B-Base
122
35
  overrides: {}
123
- topology:
124
- - from: video_encoder
125
- to: mm_projector
126
- - from: mm_projector
127
- to: llm_decoder
128
36
  metadata:
129
37
  backend: qwen_xvars_infer
130
38
 
131
- IO:
132
- inputs:
133
- video: video_encoder
134
- question: llm_decoder
135
- outputs:
136
- answer_text: llm_decoder
137
- explanation_text: llm_decoder
138
-
139
39
  TRAIN:
140
- trainer:
141
- type: vqa
142
-
143
- epochs: 3
144
-
145
- criterion:
146
- type: CrossEntropyLoss
147
-
148
- optimizer:
149
- type: AdamW
150
- lr: 0.0002
151
- weight_decay: 0.001
152
-
153
- scheduler:
154
- type: constant
155
-
156
40
  execution:
157
- enabled: true
158
- training_backend: xvars_videochatgpt_lora
159
- feature_backend: xvars_clip
160
- view_sampling_policy: random_train_deterministic_eval
161
- acc_grad_iter: 8
162
- log_interval: 1
163
- dry_run: false
164
-
165
- xvars:
166
- feature_mode: strict_xvars
167
- projection_path: null
168
-
169
41
  prompt:
170
- style: detailed
171
42
  system_prompt: You are a football video assistant. Answer the VQA question using the provided video context and referee priors.
172
- include_priors: true
173
- prediction_prior_adapter: xvars_referee
174
- prior_fields: [action, offence, contact, bodypart]
175
- video_token_len: 300
176
-
177
- generation:
178
- max_new_tokens: 128
179
- temperature: 0.0
180
-
181
- eval_profile:
182
- metric_set: [exact_match, contains_match, token_f1, referee_semantic]
183
- aggregation: mean
184
- exclusions: []
185
-
186
- sft:
187
- max_seq_length: 480
188
- include_video_tokens: true
189
- disable_tqdm: false
190
- reference_mode: all
191
- append_eos_token: true
192
- gradient_checkpointing: true
193
- save_strategy: epoch
194
43
 
195
44
  hf:
196
45
  tokenizer_id: ${MODEL.components.llm_decoder.params.repo_id}
@@ -198,31 +47,3 @@ TRAIN:
198
47
  local_files_only: false
199
48
  device_map: auto
200
49
  offload_folder: ./hf_offload_qwen
201
-
202
- lora:
203
- r: 16
204
- alpha: 32
205
- dropout: 0.05
206
- bias: none
207
- prepare_kbit: true
208
- target_modules: [mm_projector, upsample_features, up_proj, down_proj, gate_proj, k_proj, q_proj, v_proj, o_proj]
209
- exclude_modules: '^base_lm\.model\.mm_projector$'
210
-
211
- quantization:
212
- enabled: false
213
- load_in_4bit: true
214
- bnb_4bit_quant_type: nf4
215
- compute_dtype: float16
216
- bnb_4bit_use_double_quant: true
217
-
218
- checkpoint:
219
- save_adapter: true
220
- merge_and_save: false
221
-
222
- selection:
223
- monitor: loss
224
- mode: min
225
-
226
- checkpoint:
227
- save_every: 1
228
- save_best: true
@@ -18,7 +18,7 @@ from .migrate import migrate_config
18
18
  from .runtime_adapter import maybe_namespace, namespace_to_plain_dict
19
19
 
20
20
  _YAML_SUFFIXES = {".yaml", ".yml"}
21
- _TASK_DIRS = {"classification", "localization"}
21
+ _TASK_DIRS = {"classification", "localization", "vqa"}
22
22
  _INTERPOLATION_RE = re.compile(r"\$\{([^}]+)\}")
23
23
 
24
24
 
@@ -183,12 +183,12 @@ def verify():
183
183
  else:
184
184
  print("Running on CPU")
185
185
 
186
- def setup(dali=False, pyg=False, xvars=False, qwen=False):
186
+ def setup(dali=False, pyg=False, vqa_xvars=False, vqa_qwen=False):
187
187
  install_torch()
188
188
  install_extras(dali=dali, pyg=pyg)
189
- if xvars:
189
+ if vqa_xvars:
190
190
  install_xvars_dependencies(XVARS_DEPENDENCY_PINS)
191
- if qwen:
191
+ if vqa_qwen:
192
192
  install_xvars_dependencies(QWEN_DEPENDENCY_PINS)
193
193
  verify()
194
194
 
@@ -202,9 +202,9 @@ if __name__ == "__main__":
202
202
  parser = argparse.ArgumentParser()
203
203
  parser.add_argument("--dali", action="store_true")
204
204
  parser.add_argument("--pyg", action="store_true")
205
- parser.add_argument("--xvars", action="store_true")
206
- parser.add_argument("--qwen", action="store_true")
205
+ parser.add_argument("--vqa_xvars", action="store_true")
206
+ parser.add_argument("--vqa_qwen", action="store_true")
207
207
 
208
208
  args = parser.parse_args()
209
209
 
210
- setup(dali=args.dali, pyg=args.pyg, xvars=args.xvars, qwen=args.qwen)
210
+ setup(dali=args.dali, pyg=args.pyg, vqa_xvars=args.vqa_xvars, vqa_qwen=args.vqa_qwen)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensportslib
3
- Version: 0.2.0.dev2
3
+ Version: 0.2.0.dev3
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
@@ -93,13 +93,26 @@ opensportslib setup --pyg
93
93
 
94
94
  # Optional: install for DALI support
95
95
  opensportslib setup --dali
96
- ```
96
+
97
+ # Optional: install the X-VARS-compatible VQA dependency profile
98
+ opensportslib setup --vqa_xvars
99
+
100
+ # Optional: install the Qwen-compatible VQA dependency profile
101
+ opensportslib setup --vqa_qwen
102
+ ```
97
103
  ---
98
104
 
99
105
  **Note:**
100
106
  Run `opensportslib setup` to automatically configure dependencies.
101
107
  If issues occur, manually install compatible versions of `torch`, `torchvision`, and related libraries according to your CUDA version or system compatibility.
102
108
 
109
+ For VQA, use exactly one backend-specific dependency profile:
110
+
111
+ - `--vqa_xvars` installs the X-VARS-compatible Hugging Face stack from `XVARS_DEPENDENCY_PINS`
112
+ - `--vqa_qwen` installs the Qwen-compatible Hugging Face stack from `QWEN_DEPENDENCY_PINS`
113
+
114
+ The `vqa_qwen` config supports `Qwen/Qwen2.5-7B-Instruct` and `Qwen/Qwen3.5-9B-Base`.
115
+
103
116
  ---
104
117
 
105
118
  ## Data and pretrained models
@@ -287,7 +300,7 @@ metrics_from_file = my_model.evaluate(
287
300
  from opensportslib.apis import VQAModel
288
301
 
289
302
  my_model = VQAModel(
290
- config="/path/to/vqa.yaml",
303
+ config="opensportslib/configs/vqa/qwen.yaml",
291
304
  weights=None, # optional: path or Hugging Face model ID
292
305
  )
293
306
 
@@ -300,13 +313,20 @@ single_prediction = my_model.infer(
300
313
  video_path="/path/to/video.mp4",
301
314
  question="What card would you give? Why?",
302
315
  )
303
-
304
- metrics = my_model.evaluate(
305
- test_set="/path/to/test_annotations.json",
306
- predictions=predictions,
307
- )
308
316
  ```
309
317
 
318
+ Use `opensportslib/configs/vqa/xvars.yaml` with `opensportslib setup --vqa_xvars`
319
+ for the X-VARS-compatible backend, or `opensportslib/configs/vqa/qwen.yaml` with
320
+ `opensportslib setup --vqa_qwen` for the Qwen-compatible backend. The Qwen
321
+ backend currently supports `Qwen/Qwen2.5-7B-Instruct` and
322
+ `Qwen/Qwen3.5-9B-Base`.
323
+
324
+ For X-VARS, `feature_source: indexed_or_raw_clip` prefers indexed CLIP features
325
+ when available and falls back to extracting CLIP features from raw video during
326
+ `infer()`. Pre-extracted features remain the preferred path for parity, speed,
327
+ and reproducibility. See [docs/xvars_integration_phases.md](docs/xvars_integration_phases.md)
328
+ for the full X-VARS setup workflow.
329
+
310
330
 
311
331
  ---
312
332
 
@@ -414,6 +434,12 @@ opensportslib setup --pyg
414
434
 
415
435
  # Optional: install for DALI support
416
436
  opensportslib setup --dali
437
+
438
+ # Optional: install the X-VARS-compatible VQA dependency profile
439
+ opensportslib setup --vqa_xvars
440
+
441
+ # Optional: install the Qwen-compatible VQA dependency profile
442
+ opensportslib setup --vqa_qwen
417
443
  ```
418
444
 
419
445
  ### Git workflow
@@ -1,7 +1,7 @@
1
1
  examples/quickstart/basic_classification.py,sha256=byefVwdVS6yHuHOSBRHB3czrm5ya4ZpIM_qI72UTpv4,1048
2
2
  examples/quickstart/basic_localization.py,sha256=ZTwVIBFcIuIcctW9OJNHctpsIKAgtVsRzn2HxmYYLaY,1049
3
3
  opensportslib/__init__.py,sha256=yl-0Zd38CgUGwn-ZUpT_rbaJx1nMwUPjod5U1TcAL7U,619
4
- opensportslib/cli.py,sha256=SGKdn7ntt4d7U1GslWIUMLYbNiDAMo1cdMxtWW2s3n0,805
4
+ opensportslib/cli.py,sha256=45tA92cctPQuruJACAm4TqEbdFwLp-AEknvsOgszxUM,829
5
5
  opensportslib/apis/__init__.py,sha256=4PCdg5owC2HWoTnPYiTl140ddz1rxipexoOmxHKL2yE,460
6
6
  opensportslib/apis/base_task_model.py,sha256=SZJCwzaagjBwozleOfaVJSjI0T94EgyhVBY9qz4JYFk,4807
7
7
  opensportslib/apis/classification.py,sha256=LfwnfnMdQiipqZymGpEPc0lPL64oXilL_eT45ueMkBA,11282
@@ -17,13 +17,12 @@ opensportslib/configs/localization/default.yaml,sha256=CCsR1ewdVn5aBTo6nBPkBnwCt
17
17
  opensportslib/configs/localization/netvladpp_resnetpca512.yaml,sha256=i-bB-LGekwdha761xuBjIs_6LJpTmQ2MH6Vusc1WSXI,3169
18
18
  opensportslib/configs/localization/video_dali.yaml,sha256=GhbqlNLJNY3U2Vwd1TOBtO--yRNpk0wbt8xFoxTibbg,2802
19
19
  opensportslib/configs/localization/video_ocv.yaml,sha256=sbUpACassaVK6ND4ChogiK9DfMvJisPM9SUpSh8olvg,3055
20
- opensportslib/configs/vqa/qwen.yaml,sha256=KgFWQlk52Stb1O8k79yGTQuvMnMnTwylTbfhMLVcZ9Q,5294
21
- opensportslib/configs/vqa/xvars_lora.yaml,sha256=zl2SYCxj9zGCBLrxPD-yEc6rb0soPLyzBpdG2zbPnEg,6465
20
+ opensportslib/configs/vqa/qwen.yaml,sha256=yQ7RSCa3JKN3POrgZWjfYdsG_BsQeo0oDekojUe1jqg,1318
22
21
  opensportslib/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
22
  opensportslib/core/config/__init__.py,sha256=joSTWPBuLQDSFQIbAVpmOyeFLTxhIZRR_-K4DgEK8MM,635
24
23
  opensportslib/core/config/accessors.py,sha256=I6oi2lhqr9HChci90iHV3SnJAw6ykxeTLUVoecS-xhk,19613
25
24
  opensportslib/core/config/conflicts.py,sha256=cs28TIoA5w3GlQ3QTXD4AqEQL22nHxKPCS7eR-L20wI,4835
26
- opensportslib/core/config/loader.py,sha256=k7C8IslU0WymzP71dnQ4MiXeViunyR_zYCZ6mhUrF_Q,5654
25
+ opensportslib/core/config/loader.py,sha256=IvOyA7Bc5_OEMXidiAywS9kUqepY2DR3Bf_hRuHSGVM,5661
27
26
  opensportslib/core/config/migrate.py,sha256=C2RFBjMl3uve2D1lIgVxnKMUjovtxxMBZKRG6h-Aot4,817
28
27
  opensportslib/core/config/runtime_adapter.py,sha256=IIw4_1tV2-cuySypxlqEYzF_wpJjETihnUsJs22kvg8,2018
29
28
  opensportslib/core/config/schema.py,sha256=up-GvHD1eaNfhnJ9ifQ97S3_-UeMHW5V3DpjBF4_0TA,1931
@@ -106,18 +105,18 @@ opensportslib/models/utils/impl/calf.py,sha256=L_BBthf4EGGhCWZnRKjKAUUs2cqzVFnBr
106
105
  opensportslib/models/utils/impl/gsm.py,sha256=eD48Dqhp1t2Qw74rkKZKZt415fs3fdUTufdRoYik540,5389
107
106
  opensportslib/models/utils/impl/gtad.py,sha256=QXae-tZj1Leyx501OYQuBKntHW7Rf0ggxVomxtV7Si4,16928
108
107
  opensportslib/models/utils/impl/tsm.py,sha256=URU1PB48jVvpeokCT3MNX8xUo7bi2jiidt3BRzIhVSY,5180
109
- opensportslib/setup/setup.py,sha256=UBXzuDKG0gmsygPfWIhnRIrsKx4S738zkxJ5vsaHVlM,6090
108
+ opensportslib/setup/setup.py,sha256=PSzHmSR5eND0WqisklhSSMhfWOxHwD7OVlV7MliG_Fg,6130
110
109
  opensportslib/tools/__init__.py,sha256=F_Oc8401Tmuwlc30lbEQOWdrTvfClNhrIlxwkGJ-dNE,1615
111
110
  opensportslib/tools/_common.py,sha256=CNSADAK8odNS0xUd2tNExoukrgKEbfNNwGbwIF5JJZU,675
112
111
  opensportslib/tools/hf_transfer.py,sha256=wkVJc0iyJojJSV6XBAPtPVQ58NbrGNoEZG5c3-bkMEE,31275
113
112
  opensportslib/tools/osl_json_to_parquet.py,sha256=VsEy7KF7x6PA5GPdiAFDgYlyfW9Cey-SvnOiRca2s74,15132
114
113
  opensportslib/tools/parquet_to_osl_json.py,sha256=CcD4oYF8HTwJnANr81PerJXLRqTc6BZ6mVsKu7YNJw0,9259
115
- opensportslib-0.2.0.dev2.dist-info/licenses/LICENSE,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
116
- opensportslib-0.2.0.dev2.dist-info/licenses/LICENSE-COMMERCIAL,sha256=dg9GjCyCFMcfDJPkZ-IFDDt3Z5x_IdTY3YY-yOC1Eo0,163
114
+ opensportslib-0.2.0.dev3.dist-info/licenses/LICENSE,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
115
+ opensportslib-0.2.0.dev3.dist-info/licenses/LICENSE-COMMERCIAL,sha256=dg9GjCyCFMcfDJPkZ-IFDDt3Z5x_IdTY3YY-yOC1Eo0,163
117
116
  tests/conftest.py,sha256=M10-WTFqwR8n4GvaHh2uDzeknxOWSwCoWslpHA4VQ3I,26806
118
117
  tests/test_classification_dataset_paths.py,sha256=UMKj52WcWIayPAYVm7ZAmsF2W9yiYecEJ_F7lzmejEs,3636
119
118
  tests/test_classification_trainer_dataloader.py,sha256=T-1ukT7UOjnoAG-9zD4oLHijTRy7qD_vAlMFmavU5oI,5118
120
- tests/test_config_architecture.py,sha256=4xth4qcmquv5-8HUlrqFY42kcgnqcf8xwRmYVz6iveU,5367
119
+ tests/test_config_architecture.py,sha256=VltPXXmlrSv_pa4klMSKWaZz09uADUFIHozOgt-paZE,6775
121
120
  tests/test_config_split_override_sync.py,sha256=GdpzlVkGzX_Uac6KEFZPviXAtt_ATV1ERwAicNvIk4E,1635
122
121
  tests/test_config_utils_smoke.py,sha256=03fNAkICbqbDkugzxHPsRd4lXhxqBRCYeWKMreYcxOU,2590
123
122
  tests/test_conversion_tools.py,sha256=Kg20dC1w3kygrl6VIW1dKZW25bBPb2Ha9DLmYqik2HY,9059
@@ -143,8 +142,8 @@ tools/download/download_osl_hf.py,sha256=4dd-Yei2g_lp7NKom8FQlR99PQkQO3DZpAyKmdY
143
142
  tools/download/upload_osl_hf.py,sha256=YO-1uqxs-_6wdEdVYrJ7nqelpRDUOYsEmZW5HhpseiI,5777
144
143
  tools/training/classification.py,sha256=cSMIMNfP08McYUOt17ONo4WVKjAmLDl20WYOidYjJ8k,1277
145
144
  tools/training/localization.py,sha256=UC7liIEF_BrVtN8lnLZ5DOGEqSuwB_rNQgjoN_xEKuI,1271
146
- opensportslib-0.2.0.dev2.dist-info/METADATA,sha256=GBfvHYucQAwggy2SHt84KH2-dZ5Gk2Qyhk7cpOaMPuU,11552
147
- opensportslib-0.2.0.dev2.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
148
- opensportslib-0.2.0.dev2.dist-info/entry_points.txt,sha256=8haQLjVcah3IRKrlsyeecr0cUB5eXH9UPgJ_DDdT4Zk,57
149
- opensportslib-0.2.0.dev2.dist-info/top_level.txt,sha256=IJ6LnztNOeuEKQTiMTPPokBJr9ZxUCEIvbCjlPwUVEs,35
150
- opensportslib-0.2.0.dev2.dist-info/RECORD,,
145
+ opensportslib-0.2.0.dev3.dist-info/METADATA,sha256=4xf0tx6TSpzdV9FmI2saESQd7DUmSLqe6ByoC7Fr7Rg,12875
146
+ opensportslib-0.2.0.dev3.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
147
+ opensportslib-0.2.0.dev3.dist-info/entry_points.txt,sha256=8haQLjVcah3IRKrlsyeecr0cUB5eXH9UPgJ_DDdT4Zk,57
148
+ opensportslib-0.2.0.dev3.dist-info/top_level.txt,sha256=IJ6LnztNOeuEKQTiMTPPokBJr9ZxUCEIvbCjlPwUVEs,35
149
+ opensportslib-0.2.0.dev3.dist-info/RECORD,,
@@ -1,7 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
3
  import pytest
4
- import yaml
5
4
 
6
5
  from opensportslib.core.config import load_config, migrate_config, validate_config
7
6
  from opensportslib.core.config.accessors import (
@@ -25,16 +24,19 @@ def test_public_config_api_is_canonical_first():
25
24
  def test_legacy_inputs_route_through_migration(tmp_path):
26
25
  config_path = tmp_path / "legacy.yaml"
27
26
  config_path.write_text(
28
- yaml.safe_dump(
29
- {
30
- "DATA": {
31
- "data_dir": str(tmp_path / "data"),
32
- "annotations": {"train": str(tmp_path / "train.json")},
33
- },
34
- "MODEL": {"backbone": {"type": "smoke_backbone"}},
35
- "SYSTEM": {"save_dir": str(tmp_path / "ckpt")},
36
- },
37
- sort_keys=False,
27
+ "\n".join(
28
+ [
29
+ "DATA:",
30
+ f" data_dir: {tmp_path / 'data'}",
31
+ " annotations:",
32
+ f" train: {tmp_path / 'train.json'}",
33
+ "MODEL:",
34
+ " backbone:",
35
+ " type: smoke_backbone",
36
+ "SYSTEM:",
37
+ f" save_dir: {tmp_path / 'ckpt'}",
38
+ "",
39
+ ]
38
40
  ),
39
41
  encoding="utf-8",
40
42
  )
@@ -83,6 +85,33 @@ def test_localization_experiment_composes_all_layers():
83
85
  assert cfg["MODEL"]["components"]["video_encoder"]["source"]["name"] == "rny008_gsm"
84
86
 
85
87
 
88
+ def test_vqa_xvars_experiment_composes_all_layers():
89
+ cfg = load_config("opensportslib/configs/vqa/xvars.yaml", as_namespace=False)
90
+
91
+ assert cfg["VERSION"] == 2
92
+ assert cfg["TASK"] == "vqa"
93
+ assert cfg["SYSTEM"]["paths"]["log_dir"] == "./logs"
94
+ assert cfg["SYSTEM"]["paths"]["save_dir"] == "./checkpoints_vqa_lora"
95
+ assert cfg["SYSTEM"]["paths"]["work_dir"] == "./checkpoints_vqa_lora"
96
+ assert cfg["DATA"]["common"]["runtime"]["loader_backend"] == "opencv"
97
+ assert cfg["MODEL"]["metadata"]["backend"] == "xvars_videochatgpt"
98
+ assert cfg["TRAIN"]["execution"]["hf"]["tokenizer_id"] == "/home/vorajv/X-VARS/weights/base_model_videoChatGPT"
99
+
100
+
101
+ def test_vqa_qwen_experiment_composes_all_layers():
102
+ cfg = load_config("opensportslib/configs/vqa/qwen.yaml", as_namespace=False)
103
+
104
+ assert cfg["VERSION"] == 2
105
+ assert cfg["TASK"] == "vqa"
106
+ assert cfg["SYSTEM"]["paths"]["log_dir"] == "./logs"
107
+ assert cfg["SYSTEM"]["paths"]["save_dir"] == "./checkpoints_vqa_qwen"
108
+ assert cfg["SYSTEM"]["paths"]["work_dir"] == "./checkpoints_vqa_qwen"
109
+ assert cfg["DATA"]["common"]["runtime"]["loader_backend"] == "opencv"
110
+ assert cfg["MODEL"]["metadata"]["backend"] == "qwen_xvars_infer"
111
+ assert cfg["MODEL"]["components"]["llm_decoder"]["source"]["name"] == "Qwen/Qwen3.5-9B-Base"
112
+ assert cfg["TRAIN"]["execution"]["hf"]["offload_folder"] == "./hf_offload_qwen"
113
+
114
+
86
115
  def test_validation_accepts_canonical_schema():
87
116
  canonical = load_config(
88
117
  "opensportslib/configs/localization/default.yaml",
@@ -1,243 +0,0 @@
1
- TASK: VQA
2
- VERSION: 2
3
-
4
- SYSTEM:
5
- paths:
6
- log_dir: ./logs
7
- save_dir: ./checkpoints_vqa_lora
8
- work_dir: ./checkpoints_vqa_lora
9
- device: cuda
10
- gpu:
11
- count: 4
12
- id: 0
13
- reproducibility:
14
- use_seed: true
15
- seed: 42
16
-
17
- DATA:
18
- common:
19
- dataset_name: OSL-XFoul
20
- data_root: /home/vorajv/dataset/OSL-XFoul
21
- feature_index: /home/vorajv/dataset/OSL-XFoul/feature_index.json
22
- prediction_index: /home/vorajv/dataset/OSL-XFoul/prediction_index.json
23
- runtime:
24
- loader_backend: opencv
25
- splits:
26
- train:
27
- annotation_path: /home/vorajv/dataset/OSL-XFoul/train.json
28
- source_path: /home/vorajv/dataset/OSL-XFoul
29
- dataloader:
30
- batch_size: 1
31
- shuffle: true
32
- num_workers: 0
33
- pin_memory: false
34
- mp_context: spawn
35
- persistent_workers: false
36
- valid:
37
- annotation_path: /home/vorajv/dataset/OSL-XFoul/valid.json
38
- source_path: /home/vorajv/dataset/OSL-XFoul
39
- dataloader:
40
- batch_size: 1
41
- shuffle: false
42
- num_workers: 0
43
- pin_memory: false
44
- mp_context: spawn
45
- persistent_workers: false
46
- test:
47
- annotation_path: /home/vorajv/dataset/OSL-XFoul/test.json
48
- source_path: /home/vorajv/dataset/OSL-XFoul
49
- dataloader:
50
- batch_size: 1
51
- shuffle: false
52
- num_workers: 0
53
- pin_memory: false
54
- mp_context: spawn
55
- persistent_workers: false
56
- inputs:
57
- video:
58
- modality: video
59
- representation: raw
60
- source:
61
- format: mp4
62
- sampling:
63
- num_frames: 100
64
- input_fps: 25
65
- target_fps: 17
66
- start_frame: 63
67
- end_frame: 87
68
- transform: {}
69
- augmentations: {}
70
- params: {}
71
- question:
72
- modality: text
73
- representation: raw
74
- source:
75
- format: json
76
- sampling: {}
77
- transform: {}
78
- augmentations: {}
79
- params: {}
80
-
81
- MODEL:
82
- runtime:
83
- dtype: fp16
84
- device: auto
85
- compile: false
86
- freeze: false
87
- load:
88
- checkpoint_path: null
89
- pretrained: false
90
- strict: true
91
- map_location: null
92
- format: auto
93
- components:
94
- video_encoder:
95
- kind: encoder
96
- source:
97
- provider: opensportslib
98
- # XVARS-trained classifier weights to load into that architecture
99
- load:
100
- weights_path: /home/vorajv/X-VARS/weights/14_model.pth.tar
101
- params:
102
- # CLIP architecture and image processor to instantiate.
103
- feature_source: indexed_or_raw_clip
104
- vision_tower: openai/clip-vit-large-patch14
105
- feature_dim: 1024
106
- overrides: {}
107
- mm_projector:
108
- kind: projector
109
- source:
110
- provider: opensportslib
111
- params:
112
- input_dim: 1024
113
- overrides: {}
114
- llm_decoder:
115
- kind: decoder
116
- source:
117
- provider: opensportslib
118
- params:
119
- repo_id: /home/vorajv/X-VARS/weights/base_model_videoChatGPT
120
- overrides: {}
121
- topology:
122
- - from: video_encoder
123
- to: mm_projector
124
- - from: mm_projector
125
- to: llm_decoder
126
- metadata:
127
- backend: xvars_videochatgpt
128
-
129
- IO:
130
- inputs:
131
- video: video_encoder
132
- question: llm_decoder
133
- outputs:
134
- answer_text: llm_decoder
135
- explanation_text: llm_decoder
136
-
137
- TRAIN:
138
- trainer:
139
- type: vqa
140
-
141
- epochs: 3
142
-
143
- criterion:
144
- type: CrossEntropyLoss
145
-
146
- optimizer:
147
- type: AdamW
148
- lr: 0.0002
149
- weight_decay: 0.001
150
-
151
- scheduler:
152
- type: constant
153
-
154
- execution:
155
- enabled: true
156
- training_backend: xvars_videochatgpt_lora
157
- feature_backend: xvars_clip
158
- view_sampling_policy: random_train_deterministic_eval
159
- acc_grad_iter: 8
160
- log_interval: 1
161
- dry_run: false
162
-
163
- xvars:
164
- feature_mode: strict_xvars
165
- # Optional: path to a separate mm_projector checkpoint.
166
- # null means use the projector already embedded in base_model_videoChatGPT.
167
- projection_path: null
168
-
169
- prompt:
170
- style: detailed
171
- system_prompt: You are Video-ChatGPT, a large vision-language assistant. You are able to understand the video content that the user provides, and assist the user with a variety of tasks using natural language.Follow the instructions carefully and explain your answers in detail based on the provided video.
172
- include_priors: true
173
- prediction_prior_adapter: xvars_referee
174
- prior_fields: [action, offence, contact, bodypart]
175
- video_token_len: 300
176
-
177
- generation:
178
- max_new_tokens: 128
179
- temperature: 0.0
180
-
181
- # Optional XFoul-only generated-answer smoke test.
182
- # During LoRA training, this runs generation on one known training sample and
183
- # checks that the answer still contains referee-domain terms and avoids known
184
- # code-like failure strings. Disable or replace these values for non-XFoul data.
185
- generated_validation:
186
- enabled: true
187
- sample_id: action_0
188
- every_steps: 25
189
- max_new_tokens: 128
190
- require_relevance: true
191
- required_terms: [foul, card, challenge, spa, dogso, advantage]
192
- forbidden_terms: [get_children, django, httpclient, "```python", "```php"]
193
-
194
- # OpenSportsLib-native VQA evaluation config. This does not correspond to
195
- # an upstream X-VARS benchmark scorer.
196
- eval_profile:
197
- metric_set: [exact_match, contains_match, token_f1, referee_semantic]
198
- aggregation: mean
199
- exclusions: []
200
-
201
- sft:
202
- max_seq_length: 480
203
- include_video_tokens: true
204
- disable_tqdm: false
205
- reference_mode: all
206
- append_eos_token: true
207
- gradient_checkpointing: true
208
- save_strategy: "epoch"
209
-
210
- hf:
211
- tokenizer_id: ${MODEL.components.llm_decoder.params.repo_id}
212
-
213
- lora:
214
- r: 16
215
- alpha: 32
216
- dropout: 0.05
217
- bias: none
218
- prepare_kbit: true
219
- target_modules: [mm_projector, upsample_features, up_proj, down_proj, gate_proj, k_proj, q_proj, v_proj, o_proj]
220
- exclude_modules: '^base_lm\.model\.mm_projector$'
221
-
222
- quantization:
223
- enabled: false
224
- load_in_4bit: true
225
- bnb_4bit_quant_type: nf4
226
- compute_dtype: float16
227
- bnb_4bit_use_double_quant: true
228
-
229
- # LoRA adapter save policy:
230
- # save_adapter: true saves the LoRA adapter artifacts.
231
- # merge_and_save: false keeps the base model and adapter separate.
232
- # If you set merge_and_save: true, it would export a merged model for standalone inference.
233
- checkpoint:
234
- save_adapter: true
235
- merge_and_save: false
236
-
237
- selection:
238
- monitor: loss
239
- mode: min
240
-
241
- checkpoint:
242
- save_every: 1
243
- save_best: true