Pozify / docs /coach-summary-training-report.md
tiena2cva's picture
chore: add ninja-build and build-essential to package requirements; update README and documentation to reflect changes in model configuration and local Transformers usage
afa452e
|
Raw
History Blame Contribute Delete
11.5 kB
# Coach Summary Training Report
Generated from the current Pozify codebase state on June 15, 2026.
## Summary
The coach-summary model in Pozify is a grounded JSON-to-JSON generation component, not a generic
fitness chatbot. Its job is to convert structured workout-analysis artifacts into a safe,
evidence-bounded `coach_summary.json`, then pass that output through a verifier before it is shown
in the app.
The current training stack is:
- Base model: `nvidia/NVIDIA-Nemotron-3-Nano-4B-BF16`
- Fine-tuning method: BF16 LoRA SFT on Modal
- Training target: Pozify-native structured summary generation
- Runtime fallback: deterministic conservative summary when model generation fails or verification fails
The current codebase already supports:
- dataset building from real Pozify run artifacts
- Modal stages for prepare/train/evaluate/merge/publish
- verifier-based evaluation
- merged full-model publishing
- UI metadata for provider/model/source reporting
The main deployment gap at the time of this report is not training infrastructure. The main gap is
that the published Hugging Face merged repo is still not accepted by the current Hugging Face
Inference API path used by the app, so the app falls back to rule-based summaries when that repo is
selected.
## Objective
The coach-summary model is designed to generate these grounded sections:
- `summary`
- `what_you_did`
- `what_looked_good`
- `what_changed_across_reps`
- `valid_variation_vs_issue`
- `top_fixes`
- `next_session_plan`
- `confidence_notes`
Unlike a free-form assistant, this model is instructed to:
- use only structured evidence and retrieved knowledge cards
- never invent issue labels outside `issue_markers.json`
- avoid diagnosis language
- avoid injury-prevention claims
- preserve valid variation context instead of overcorrecting it
This contract is implemented in the prompt builder and enforced again by the verifier.
## Training Data
The current SFT data is Pozify-native and built from real run artifacts under `runs/`.
### Source artifacts per example
Each SFT row is constructed from:
- `user_profile.json`
- `exercise_classification.json`
- `reps.json`
- `rep_analysis.json`
- `variation.json`
- `issue_markers.json`
- `coach_summary.json`
The dataset builder reconstructs typed contracts from those files, retrieves the same knowledge
cards used at runtime, and serializes a chat-style SFT example with:
- system prompt
- user message containing structured evidence JSON
- assistant message containing the target `coach_summary.json`
### Current local dataset size
From the checked-in data in `data/sft/`:
| File | Rows |
| --- | ---: |
| `coach_summary_train.jsonl` | 22 |
| `coach_summary_eval.jsonl` | 5 |
| `public_fitness_style.jsonl` | 854 |
The style dataset is much larger than the grounded task dataset, so the training script samples
only a small portion of style rows according to `style_weight`.
## Prompt and Grounding Design
The prompt builder creates a structured instruction block plus a structured evidence block.
### Evidence included in the prompt
- `user_profile`
- `exercise_classification`
- `variation`
- `rep_summary`
- `issue_summary`
- `priority_cues`
- `knowledge_cards`
### Core prompt rules
- Use only the evidence JSON and retrieved knowledge cards.
- Do not infer new issues absent from `issue_summary.issues`.
- Do not diagnose injuries or pathology.
- Do not claim injury prevention.
- Do not treat valid variation labels or not-issue labels as errors.
- Include exact issue or variation labels in backticks when referenced.
- Return JSON only.
This is a good fit for small-model fine-tuning because the task is narrow, repetitive, and highly
structured.
## Model and Training Setup
### Current default base model
The codebase now defaults to:
- `nvidia/NVIDIA-Nemotron-3-Nano-4B-BF16`
This is used in:
- `configs/coach_summary_lora.default.json`
- `scripts/train_coach_summary_lora.py`
- Modal training, evaluation, and merge stages in `scripts/coach_summary_modal.py`
### Default training hyperparameters
| Hyperparameter | Value |
| --- | ---: |
| Base model | `nvidia/NVIDIA-Nemotron-3-Nano-4B-BF16` |
| LoRA rank | 16 |
| LoRA alpha | 32 |
| LoRA dropout | 0.05 |
| Learning rate | 0.0002 |
| Epochs | 2 |
| Batch size per device | 1 |
| Gradient accumulation | 8 |
| Max sequence length | 2048 |
| Default style weight | 0.2 |
### Modal implementation
The full training pipeline is implemented in `scripts/coach_summary_modal.py` with these stages:
- `prepare-data`
- `train`
- `evaluate`
- `merge`
- `publish`
- `publish-merged`
- `all`
The training stage:
- loads the base model in BF16 so Nemotron-H Mamba fast kernels receive regular projection weights
- tokenizes and truncates rows explicitly before training so long JSON evidence rows cannot bypass
the sequence-length cap
- fine-tunes the LoRA adapter with the Transformers `Trainer`
- saves adapter weights and tokenizer to the Modal model volume
The merge stage:
- loads base model plus adapter
- calls `merge_and_unload()`
- writes a merged full checkpoint to `merged_model/`
## Evaluation Design
The evaluation stage is not based on generic BLEU or chat preference metrics. It uses task-specific
checks that match Pozify's production constraints.
### Reported evaluation metrics
- JSON validity rate
- verifier pass rate
- section completeness rate
- failure count and example failures
### Verifier checks
The verifier currently enforces:
- `no_issue_outside_json`
- `variation_not_overcorrected`
- `no_diagnosis`
- `no_injury_prevention_claim`
- `confidence_notes_present_when_required`
This is a strong design choice for Pozify because it measures whether the model behaves safely and
stays grounded, not just whether it sounds fluent.
## Latest Observed Training Outcome
From the latest visible Modal training logs for the full coach-summary flow:
### Training summary
| Metric | Value |
| --- | ---: |
| Train rows | 22 |
| Eval rows | 5 |
| Style rows mixed in | 4 |
| Merged train rows | 26 |
| Epochs | 2 |
| Global steps | 8 |
| Training loss | 1.0797 |
### Evaluation summary
| Metric | Value |
| --- | ---: |
| Evaluated count | 5 |
| JSON valid count | 2 |
| JSON validity rate | 0.40 |
| Verifier pass count | 0 |
| Verifier pass rate | 0.00 |
| Section completeness rate | 0.00 |
### Observed failure modes
- missing required top-level fields such as `summary`
- malformed JSON with delimiter errors
- outputs that fail schema extraction before verifier success is even possible
These numbers suggest that the current grounded task setup is correct in principle, but the dataset
is still too small and the model is not yet reliably producing the full required schema.
## Runtime Behavior in the App
At runtime the pipeline does this:
1. Generate a model summary from structured evidence.
2. Parse the model output into `coach_summary.json`.
3. Skip the verifier by default and write a `verification.json` artifact marked as disabled.
4. If verifier bypass is explicitly disabled, run the verifier.
5. If generation fails, use `fallback_initial`.
6. If generation succeeds but verification fails, use `fallback_after_verification`.
The final report stores:
- `coach_summary_provider`
- `coach_summary_model`
- `coach_summary_source`
- verifier bypass metadata
This makes the UI traceable and helps distinguish:
- cloud model output
- local model output
- conservative fallback output
## Current Deployment Status
### What works
- grounded prompt contract
- deterministic knowledge-card retrieval
- SFT dataset builder from Pozify artifacts
- Modal train/evaluate/merge/publish pipeline
- verifier integration
- fallback summary integration
- runtime metadata reporting in UI
### What is currently failing
The published merged Hugging Face repo for the fine-tuned coach model is still not accepted by the
Hugging Face inference route currently used in `HFInferenceCoachSummaryModel`.
Observed runtime failure:
- `The requested model 'build-small-hackathon/pozify-coach-summary1' is not a chat model.`
Because of that, the app falls back even when the runtime resolves the correct repo ID.
### Practical implication
The app runtime defaults to the fine-tuned coach-summary model:
- `build-small-hackathon/pozify-coach-summary1`
The deterministic fallback summary remains enabled because hosted inference can still be
unavailable, reject a model route, or return output that fails schema validation. If needed,
`nvidia/NVIDIA-Nemotron-3-Nano-4B-BF16` can still be used as an explicit base-model override.
## Assessment
### Strengths
- The task definition is well-scoped and matches the product.
- The prompt is strongly grounded on structured artifacts.
- The verifier is aligned with real product risk, not just language quality.
- The dataset builder is tightly coupled to actual runtime contracts.
- The pipeline supports both model generation and deterministic fallback.
### Weaknesses
- The grounded SFT dataset is still very small.
- Schema reliability is not yet strong enough.
- Verifier pass rate is currently too low for production dependence.
- Published merged artifacts are not yet working cleanly with the current Hugging Face inference strategy.
- Modal config reuse can accidentally preserve stale training settings if old volume artifacts are not cleaned.
## Recommendations
### Short term
1. Use `build-small-hackathon/pozify-coach-summary1` as the default runtime coach model.
2. Keep the fallback summary enabled in production.
3. Expand the grounded SFT dataset from more real runs before increasing training complexity.
4. Add stronger output-format controls or post-processing to improve JSON validity.
5. Clean or version Modal model volumes when switching base models.
### Medium term
1. Grow the Pozify-native dataset to at least 100 to 300 high-quality examples.
2. Evaluate `epochs=1` vs `epochs=2` and `style_weight=0.1` vs `0.2`.
3. Add targeted eval slices:
- no-issue cases
- valid-variation cases
- multi-issue cases
- low-confidence / low-pose-coverage cases
4. Improve inference compatibility for the merged repo or support local merged-model inference directly.
## Reproduction Commands
Build the grounded SFT dataset from run artifacts:
```bash
uv run python scripts/build_coach_summary_sft_dataset.py
```
Run the full Modal training flow:
```bash
uv run modal run scripts/coach_summary_modal.py --stage all --epochs 2 --style-weight 0.2 --repo-id build-small-hackathon/pozify-coach-summary1
```
Run the app with the default fine-tuned runtime model:
```bash
unset POZIFY_COACH_SUMMARY_MODEL
uv run python app.py
```
Or set the runtime model explicitly:
```bash
export POZIFY_COACH_SUMMARY_MODEL=build-small-hackathon/pozify-coach-summary1
uv run python app.py
```
## Conclusion
Pozify's coach-summary model training architecture is directionally strong. The core design choice
to train a grounded summary model on structured evidence, then gate it with a verifier, is the
right one for this product.
The current bottleneck is not lack of infrastructure. It is model reliability and inference
deployment maturity:
- too few grounded examples
- low schema-compliance rate
- no verifier passes in the latest visible eval
- published merged repo still not usable through the current HF inference path
The codebase is ready for the next iteration. The next high-leverage step is to improve dataset
size and output reliability while keeping the verifier and fallback architecture intact.