YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

FAIR-Coach model archive (private)

Private archive. Do not make public until dataset and model licences are verified.

Trained artefacts of the PhD thesis FAIR-Coach: diagnosis-aligned biomechanical evidence for AI exercise coaching (Monica Vahdati, University of Ottawa).

The models only work with this code version: the code defines the model classes, the evidence extraction and the input format.

Contents

Folder Content Status
dpo_adapter/ LoRA-DPO adapter that turns a fixed diagnosis into coaching feedback (base model Qwen3.8-27B) Private. Licence checks pending
diagnosis_heads/ Frozen diagnosis models mapping biomechanical evidence to 8 squat-error labels, plus two byte-identical snapshots Private. QEVD licence check pending; they depend on the Path-B classifier
pathb_stgcn/ ST-GCN classifier (correct / incorrect) behind the Path A and Path B evidence Never make public. Release reason: unverified provenance; likely includes private third-party video and CC BY-NC 4.0 data.
support_files/ Normalisation statistics, a reduced spatial-feature statistics file (mu_train and sd_train only) and the sanitised freeze manifest that the diagnosis loaders need Private

Each folder has its own README.md with SHA-256 values and limitations.

Quick start

  1. Clone the code at the matching version:

    git clone https://github.com/MonicaVahd/FAIR-Coach.git
    cd FAIR-Coach
    git checkout v0.1.0
    
  2. Install the environment as described in docs/INSTALL.md. The models were produced with Python 3.10.20, PyTorch 2.5.1+cu121, Transformers 5.17.0 and PEFT 0.20.0.

  3. Download this archive (a Hugging Face token with access to this private repository is required):

    hf auth login
    hf download MonicaVahd/fair-coach-models-private --local-dir ./fair-coach-models
    
  4. Copy the files into the code repository:

    From the archive To the code repository
    pathb_stgcn/best_stgcn.pth output/best_stgcn.pth
    diagnosis_heads/*.pt output/phase9_checkpoints/
    dpo_adapter/ (whole folder) output/phase12c_dpo_lora/
    support_files/phase7_train_normalization.json output/
    support_files/phase10f_spatial_diag_features_full8.mu_sd_only.npz output/phase10f_spatial_diag_features_full8.npz (rename it; it holds only mu_train and sd_train)
    support_files/phase10f_diag_spatial_freeze_manifest.json output/

    The diagnosis loader (analysis/live_diagnosis.py) refuses the diagnosis-aligned Concat+MLP and Reasoner v2 checkpoints if their SHA-256 differs from the freeze manifest. The reduced .npz is enough for that loader; scripts under tools/ that read other arrays from the full feature file cannot run from this archive.

  5. Run the pipeline as described in docs/USAGE.md. Datasets are not included; obtain them from their official sources (see the dataset table in the code README).

Models

dpo_adapter/: LoRA-DPO language layer

  • Purpose: verbalise a diagnosis that is already fixed, without adding unsupported claims. It never changes the diagnosis.
  • Base model: Qwen/Qwen3.8-27B (set in config.py). Files: adapter_model.safetensors (about 21 MB), adapter_config.json, tokenizer files, train_info.sanitized.json. Keep the tokenizer files next to the adapter: the code loads the tokenizer from the adapter folder.
  • Training: LoRA rank 8, alpha 16, dropout 0.05, targets q/k/v/o projections, learning rate 5e-5, DPO beta 0.1, 156 steps, 420 template-constructed preference pairs (disjoint from the 40 evaluation examples).
  • Reported result (thesis, 40 held-out examples, rule-based scoring): unsupported-claim rate 75% to 17.5%, evidence specificity 75% to 92.5%, own-label consistency 22.5% to 77.5%. The evaluation is small and template-based, and no template baseline was run.
  • Loading (mirrors feedback/dpo_feedback.py: 4-bit NF4, as in the thesis):
    import torch
    from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
    from peft import PeftModel
    
    adapter_dir = "output/phase12c_dpo_lora"
    bnb = BitsAndBytesConfig(
        load_in_4bit=True,
        bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=torch.bfloat16,
        bnb_4bit_use_double_quant=True,
    )
    tokenizer = AutoTokenizer.from_pretrained(adapter_dir)
    model = AutoModelForCausalLM.from_pretrained(
        "Qwen/Qwen3.8-27B", quantization_config=bnb,
        device_map="auto", dtype=torch.bfloat16,
    )
    model = PeftModel.from_pretrained(model, adapter_dir)
    
    The thesis code passes trust_remote_code=True when loading both the tokenizer and the base model; enable it only after reviewing the model repository. Generation in the thesis used greedy decoding (do_sample=False). A GPU is expected to be needed for a 4-bit 27B model (the code uses device_map="auto"); memory needs were not measured.

diagnosis_heads/: frozen diagnosis models

Each model outputs 8 logits; apply a sigmoid and threshold at 0.5. Label order: no_obvious_issue, shallow, knees_over_toes, back_not_straight, narrow, wide, over_90_degrees, insufficient.

File Model (class, location) Evidence input Parameters TEST micro-F1 (seed 42)
phase8_8_concat_mlp_frozen.pt Generic Concat+MLP, original fixed-epoch baseline (ConcatMLP, tools/train_concat_mlp.py) 27 generic features + mask (54) 2,024 0.2901
fine8_relations_off_frozen.pt 8-group model, relations off (RelationalDiagnosisModel, analysis/relational_diagnosis.py) generic 3,576 0.2905
fine8_relations_on_frozen.pt 8-group model, relations on (same class) generic 4,377 0.2969
reasoner_v2_frozen.pt Reasoner v2 (ReasonerV2, analysis/reasoner_v2.py) generic 3,432 0.2932
relational_reasoner_locked.pt Coarse 5-group message passing (RelationalDiagnosisModel) generic 3,513 0.2648
diag_concat_mlp_27plus10_frozen.pt Diagnosis-aligned Concat+MLP, default backend (FlexConcatMLP, analysis/live_diagnosis.py) 27 generic + 10 diagnosis-aligned features + masks (74) 2,664 0.3435
reasoner_v2_diag_spatial_frozen.pt Reasoner v2, diagnosis-aligned (ReasonerV2Diag, analysis/reasoner_v2_diag.py) 37 features 3,752 0.3322

reasoner_v2_diag_spatial_val.pt and reasoner_v2_exploratory.pt are byte-identical to their frozen counterparts.

  • Checkpoint layout: the 8.8 baseline, the three relational files and diag_concat_mlp_27plus10_frozen.pt store a wrapper dictionary with a state_dict key. The two Reasoner v2 frozen files are flat state dictionaries. The tensors were saved on cuda:0, so load with map_location="cpu" when no GPU is present.
  • Input: a RepEvidence record (schemas.py) for one validated squat repetition, encoded into the 27 generic features by analysis/reasoning_xy.py; the 10 spatial features come from spatial_features_core in tools/phase10f_spatial_diag_features.py. The 27 generic features are z-scored with phase7_train_normalization.json; the 10 spatial features use the first 10 entries of mu_train and sd_train from phase10f_spatial_diag_features_full8.npz. support_files/ holds the normalisation JSON and a reduced copy of that .npz with only mu_train and sd_train. QEVD-derived evidence files are not included.
  • Use the code loaders (analysis/live_diagnosis.py and the scripts under tools/) rather than loading the files by hand.
  • How to read the results: these are thesis results within QEVD, not independent replications. The TEST split has five participants (1,052 clips). The default model's TEST value was observed before it was designated the default, so it is not an untouched estimate. The diagnosis-aligned models add features and input dimensions compared with the generic ones, so the gain cannot be attributed to alignment alone.

pathb_stgcn/: ST-GCN behind Path A and Path B

  • File: best_stgcn.pth (12,389,290 bytes, SHA-256 04bedce9ab63032072f8be06324e2ac43f4add5b344d6f71032ef32766c70fc2), a flat state dictionary.
  • Model: ST-GCN (lib/net/st_gcn.py), built by build_stgcn_model in utils.py: 3 input channels (x, y, confidence), 2 classes (class 0 incorrect, class 1 correct), OpenPose-18 spatial graph, input shape (batch, 3, 100, 18, 1) built from COCO-17 keypoints.
  • Provenance and use: Training record not preserved; the 614 stored sequences match, by class counts, EC3D + REHAB24-6 + a private custom collection of 282 YouTube-derived sequences (indirect; not verified at sample level). Used for Path A windows and Path B repetitions in the live system.
  • Dependency: its Path-B outputs are generic evidence for every diagnosis model, so the diagnosis results cannot be reproduced without it.
  • Not recorded: the seed and held-out accuracy were not recorded, and the training script sets no seed.
  • Release reason: unverified provenance; likely includes private third-party video and CC BY-NC 4.0 data.

Intended use and limitations

  • Research and reproducibility only. This is not a medical or deployment-ready system.
  • Absolute diagnostic performance is modest (micro-F1 about 0.34), and the probabilities are poorly calibrated.
  • The grounding evaluation did not demonstrate that diagnoses depend on the intended biomechanical evidence.
  • All results are offline, squat-based and within QEVD.

Licences

  • Code: Apache-2.0 (see the GitHub repository), except the ST-GCN files under lib/net/, which keep their upstream BSD-style licence (see NOTICE).
  • Base model Qwen3.8-27B: licence to be confirmed from its official page.
  • Datasets are not redistributed here. REHAB24-6 is CC BY-NC 4.0; check the licences of QEVD, EC3D and UI-PRMD before any release.

Citation

Citation information will be added once the thesis is published.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support