X-VARS Setup and Artifact Flow¶
Date: July 6, 2026
Canonical dataset: /home/vorajv/dataset/OSL-XFoul
Canonical config: /home/vorajv/opensportslib/opensportslib/configs/vqa/xvars.yaml
X-VARS reference root: /home/vorajv/X-VARS/X-VARS
This page is the source of truth for using the OpenSportsLib vqa-xvars
backend. It covers the required weights, how to download them, how to extract
X-VARS CLIP features, how to build the feature and prediction indexes, and how
those artifacts map into the OpenSportsLib VQA config.
X-VARS setup¶
The X-VARS-specific part is the setup:
- downloading the X-VARS visual and decoder weights
- optionally pre-extracting CLIP feature pickles
- building
feature_index.jsonandprediction_index.json
When feature_source: indexed_or_raw_clip is used, X-VARS infer() prefers
indexed features when available and can fall back to extracting CLIP features
from raw video on the fly. Pre-extracted features remain the preferred path for
speed, parity, and reproducibility.
Required Artifacts¶
The X-VARS backend relies on four artifact groups:
14_model.pth.tarThis is the strict X-VARS visual encoder checkpoint used for feature extraction and for the visual encoder weight path in the config.base_model_videoChatGPTThis is the decoder backbone used by the X-VARS backend. It must be a directory-style Hugging Face model bundle, not a single checkpoint file.feature_index.jsonMaps OSL sample ids to extractedPRE_CLIP_feature_clip_{1,2,3}.pklfiles.prediction_index.jsonMaps OSL sample ids to referee-prior fields derived from OSL labels.
Download Weights¶
The local X-VARS repo points to a shared Google Drive folder for the upstream artifacts:
- Shared drive folder:
https://drive.google.com/drive/folders/1UbMAQVFrTB-DtEFUSmv8tBXuurrBfMUJ?usp=sharing - X-VARS training reference:
/home/vorajv/X-VARS/X-VARS/training.md - X-VARS demo reference:
/home/vorajv/X-VARS/X-VARS/demo.md
Download these artifacts from that drive:
14_model.pth.tarbase_model_videoChatGPT
If base_model_videoChatGPT is downloaded as a zip archive, extract it so the
final result is a directory containing files such as:
config.jsonmodel-00001-of-00003.safetensorsmodel.safetensors.index.json- tokenizer files
Recommended Local Layout¶
The OpenSportsLib X-VARS config currently expects the following local layout:
/home/vorajv/X-VARS/weights/
├── 14_model.pth.tar
└── base_model_videoChatGPT/
├── config.json
├── model-00001-of-00003.safetensors
├── model-00002-of-00003.safetensors
├── model-00003-of-00003.safetensors
├── model.safetensors.index.json
└── tokenizer files...
Use your own local paths if needed, but then update the config accordingly.
How These Paths Map Into xvars.yaml¶
The canonical X-VARS config is:
opensportslib/configs/vqa/xvars.yaml
These fields consume the X-VARS artifacts:
MODEL.components.video_encoder.load.weights_pathPoints to14_model.pth.tarMODEL.components.llm_decoder.params.repo_idPoints to thebase_model_videoChatGPTdirectoryDATA.common.feature_indexPoints tofeature_index.jsonDATA.common.prediction_indexPoints toprediction_index.json
In the current local config, those values are:
DATA:
common:
feature_index: /home/vorajv/dataset/OSL-XFoul/feature_index.json
prediction_index: /home/vorajv/dataset/OSL-XFoul/prediction_index.json
MODEL:
components:
video_encoder:
load:
weights_path: /home/vorajv/X-VARS/weights/14_model.pth.tar
llm_decoder:
params:
repo_id: /home/vorajv/X-VARS/weights/base_model_videoChatGPT
Artifact Flow¶
The artifact pipeline is:
- Download
14_model.pth.tarandbase_model_videoChatGPT - Use
14_model.pth.tarwithtools/convert/extract_xvars_clip_features.pyto createPRE_CLIP_feature_clip_{1,2,3}.pkl - Use
tools/convert/build_xvars_indexes.pyto build: feature_index.jsonprediction_index.json- Point
opensportslib/configs/vqa/xvars.yamlat those paths - Run
infer()ortrain()with the X-VARS backend
base_model_videoChatGPT is used by the decoder backbone. It is not consumed by
the feature extraction or index builder scripts.
Step 1: Extract X-VARS CLIP Features¶
OpenSportsLib provides:
tools/convert/extract_xvars_clip_features.py
This script writes:
PRE_CLIP_feature_clip_1.pklPRE_CLIP_feature_clip_2.pklPRE_CLIP_feature_clip_3.pkl
under split and sample-id directories.
CLI arguments¶
--dataset-rootRoot path containing split JSON files and dataset media--dataset-output-rootRoot path where extracted feature pickle files are written--splitsSplits to process, defaults totrain valid test--modestrict_xvarsorclip_compat--vision-modelVision backbone, defaults toopenai/clip-vit-large-patch14--weights-pathRequired forstrict_xvars; path to14_model.pth.tar--start-frameStrict X-VARS crop start frame--end-frameStrict X-VARS crop end frame--target-fpsStrict X-VARS target fps after crop--source-fpsStrict X-VARS source fps used for resampling--max-framesMaximum frames for extraction--max-samplesLimit samples for smoke testing,0means all--overwriteRewrite feature files if they already exist
Strict X-VARS example with current local paths¶
python tools/convert/extract_xvars_clip_features.py \
--mode strict_xvars \
--weights-path /home/vorajv/X-VARS/weights/14_model.pth.tar \
--dataset-root /home/vorajv/dataset/OSL-XFoul \
--dataset-output-root /home/vorajv/dataset/OSL-XFoul \
--splits train valid test \
--start-frame 63 \
--end-frame 87 \
--target-fps 17 \
--source-fps 25
Generic placeholder example¶
python tools/convert/extract_xvars_clip_features.py \
--mode strict_xvars \
--weights-path /path/to/14_model.pth.tar \
--dataset-root /path/to/OSL-XFoul \
--dataset-output-root /path/to/OSL-XFoul \
--splits train valid test
Output contract¶
strict_xvarsmust produce features with shape300 x 1024clip_compatmust produce features with shape356 x 1024
Step 2: Build feature_index.json and prediction_index.json¶
OpenSportsLib provides:
tools/convert/build_xvars_indexes.py
This script reads the OSL annotations and extracted feature pickle layout and writes:
feature_index.jsonprediction_index.json
What each index contains¶
feature_index.jsonMapsidto one or morefeature_pathspointing atPRE_CLIP_feature_clip_{1,2,3}.pklprediction_index.jsonMapsidto referee prior fields like action, offence, and severity derived from the OSL labels
CLI arguments¶
--dataset-rootRoot path containing train/valid/test JSON files--features-rootRoot path where the extracted feature pickle files live--output-dirDirectory wherefeature_index.jsonandprediction_index.jsonare written--emit-expected-pathsBootstrap mode that writes expected feature paths even when the.pklfiles do not exist yet
Example with current local paths¶
python tools/convert/build_xvars_indexes.py \
--dataset-root /home/vorajv/dataset/OSL-XFoul \
--features-root /home/vorajv/dataset/OSL-XFoul \
--output-dir /home/vorajv/dataset/OSL-XFoul
Generic placeholder example¶
python tools/convert/build_xvars_indexes.py \
--dataset-root /path/to/OSL-XFoul \
--features-root /path/to/OSL-XFoul \
--output-dir /path/to/OSL-XFoul
Bootstrap mode example¶
python tools/convert/build_xvars_indexes.py \
--dataset-root /path/to/OSL-XFoul \
--features-root /path/to/OSL-XFoul \
--output-dir /path/to/OSL-XFoul \
--emit-expected-paths
Without --emit-expected-paths, the script exits with an error if some samples
have no feature pickle files.
Inference Behavior¶
For X-VARS specifically:
feature_source: indexed_or_raw_clipprefers indexed CLIP features when they are available throughfeature_index.json- if indexed features are missing,
infer()can extract CLIP features from raw video on the fly - pre-extracted indexed features are still recommended for reproducible parity and faster runtime
Upstream-style Prediction Export¶
For X-VARS-style export rows, use: