Seamless training UX: configurable persisted splits, full hyperparameter/augmentation control, rich metric visualization, one-click evaluation#18
Merged
Conversation
…h, richer metrics capture
…sisted splits UI, rich metrics + native plots, one-click eval - Frontend: grouped config-driven hyperparameter/augmentation form, SplitPanel with ratio/seed/stratify + per-class breakdown, multi-panel run-detail charts (loss/mAP/PR/LR), summary tiles, native plot gallery, Run Evaluation button - Backend: split GET/POST endpoints + ?split= asset filter, metric-key normalization, summary/plots/split in metrics_json, plot streaming endpoint, run detail exposes artifacts - Tests: split_service unit coverage; specs/training-ux docs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The training flow worked end-to-end but had four seams that made it neither fully controllable nor truly intuitive:
train_taskhardcoded a round-robin split (split = "val" if i % 5 == 4 else "train") and never held out a test set, while evaluation readasset.meta_data.split. So the "test set" you'd evaluate on was never actually unseen during training, and nothing was persisted to visualize.metrics/mAP50(B),train/box_loss,val/box_loss,lr/pg0— but the frontend looked for clean keys (mAP50,box_loss), so most lines never rendered, and losses + mAP were crushed onto one shared 0–1 axis. Native Ultralytics plots (PR curve, confusion matrix, results grid) were discarded.What changed
Backend
services/split_service.py: deterministic, seeded, optionally class-stratified split assignment persisted into the existingasset.meta_data.split; hash-based fallback so runs are always reproducible.jobs/tasks/training.py: honors the persisted split and holds out test assets entirely;ULTRALYTICS_TRAIN_ARGSallow-list forwards every tunable knob withplots=True;_normalize_metricsmaps Ultralytics keys → clean charted keys; persists{epochs, split, summary, plots}inmetrics_jsonand uploads plot PNGs to MinIO.GET/POST /api/datasets/{id}/versions/{vid}/split,?split=filter on the asset list,/runs/{id}/metricsnow returnssummary/plots/split(+ presigned plot URLs),/runs/{id}/plots/{name}stream; run detail exposesartifacts.services/storage.py:put_bytes/get_byteshelpers.Frontend
SplitPanelwith ratio/seed/stratify controls, a stacked split bar, and per-class-per-split breakdown; the split is persisted on launch so training trains on exactly what you see.Notes
asset.meta_data,experiment_runs.metrics_json/artifacts).Verification
ruff/black/isortclean on all changed backend files.tests/unit/test_split_service.py(ratios, determinism, slice-sum, persistence, reproducibility), plus existing asset and training-service suites.tscandprettierclean on the three changed frontend files. (The 9 remainingtscerrors are pre-existing onmaininupload.tsx/projects/[projectId]/index.tsxand are unrelated to this PR.)specs/training-ux/.https://claude.ai/code/session_01DWbceFZLMEB9F76zTJNhrp
Generated by Claude Code