Skip to content

Read training reports, evaluation charts and explanations

When you need it

Use this page to inspect a completed or failed training invocation, locate its MLflow evidence, and enable bounded evaluation charts or SHAP explanations. Start with the training walkthrough to run a project. Lifecycle decisions explain approval, rejection and rollback; this page explains the reports that support them.

What to edit

Set evaluation_charts, explainability and save_preprocessing_diagnostics under defaults or the supported named-model override in config/training.yml. The field reference lists allowed values. Generated optional report tasks and their pinned dependencies must be present: changing a setting cannot create an omitted notebook or update a deployed graph. Use project upgrades when adding those resources.

Keep workflow_contract: "3" in generated notebook parameters. It is distinct from workflow JSON config_version: 1 and companion YAML version: 1.

The command

From the generated project, using its pinned training requirements:

uv pip install -r deployment/train-requirements.txt
python src/tools/smoke.py
python src/tools/preview.py --action train
databricks bundle validate --strict -t test --profile YOUR_PROFILE
databricks bundle deploy -t test --profile YOUR_PROFILE
databricks bundle run train -t test --profile YOUR_PROFILE

Substitute your target and profile. Smoke and preview do not read source data or fit models. Preview bindings can be passed explicitly with --catalog, --input-schema, --output-schema, --metadata-schema and --resource-suffix. Do not execute explanations.py directly: the normal fit saves its report.

What you should see

Open Jobs > your run > the task > Output. Generated notebooks print STARTED, then either COMPLETED with elapsed time or FAILED with the task name, exception type, message, source file and line. Available job/run/model identifiers appear beside the start message. Failure diagnostics preserve the original exception and traceback; they do not convert a failed task to success. Inspect the failing task's inputs and saved effects before retrying.

After a successful training run (lifecycle_action=train), the final training_report starts with Where to look, one row per fitted model. Approve, reject and rollback runs show only the action result. The index links to existing evidence rather than recomputing reports:

Column What to inspect
Model / run The exact MLflow fitting run; a registered UC version where one exists. Competition losers have runs but no registered winner version.
Training data Saved table and Delta version, available source/train/holdout counts and pre-split removals; links to the underlying JSON evidence.
Preprocessing probe Saved diagnostic status and artifact, or off when confirmed by the saved config.
SHAP Saved explanation status and JSON/HTML link, or an enablement link.
Evaluation charts The saved Charts run if ready. Off when saved settings disable charts. Winner only; see the selected model for a competition candidate that was not selected. Otherwise check generate_charts > Output.
Decision threshold Saved threshold mode/values and evidence; absence is reported explicitly.

The decision, quality comparison and receipts follow this index. Single models, competition winners and model sets show the same operator blocks: Available action: approve, Available action: reject and If rollback is needed. Copy parameter values from those blocks; the operator steps explain each one. A model set ends with Decision details (JSON). Missing/unreadable evidence is unavailable, not proof that a check passed. Off is shown only when saved settings establish it. The summary uses the fitting run's saved configuration, not today's edited YAML.

Artifact links open that run's Artifacts tab; select the filename shown in the link. Threshold previews show at most ten entries and shorten long labels or values. Open decision_threshold.json for the complete saved mapping.

Chart leaves run independently and can still be running when this final report renders. Their eventual task state is in the job graph. A requested child score run starts after training_report, so it cannot have a child-run link in that report yet; open the later run_batch_scoring task. If lifecycle finalization fails, its existing exception remains authoritative and the final summary may not render. Inspect the failed task and fitting runs directly.

Other task outputs retain their labeled text or specialized reports. Notebook JSON and task values remain available for automation.

The final-report notebook (training_report.py or models_report.py) passes Databricks displayHTML to the renderer. Without it, the task prints a plain text summary and no Where to look table. The training_report task also needs the base parameter workspace_host: ${workspace.host} in resources/train.job.yml. Without it, the table renders but every link is plain text. Project upgrades show how to add both to an existing project.

Project generation writes the selected model entries in config/training.yml and optional set settings in config/inference.yml. It includes only the job notebooks of the selected graph, including optional SHAP/charts/recovery. Reinitialize a separate project when changing layout or enabling a feature whose notebook was omitted, then review and merge the required resources and files. Do not only toggle a resource flag and reference a missing notebook.

Optional evaluation charts

Detailed Bundle initialization asks evaluation_charts_enabled (default: false). Choosing true adds a separate generate_charts task after model evaluation, plus matplotlib==3.10.0 in the training environment. Charts do not retrain models.

Layout Images and destination
Single Saved model diagnostics in a Charts child of its training run
Competition CV leaderboard and selected model diagnostics share a Charts child of the parent training run; final holdout is never used to rank candidates
Model set Each component has its own Charts child; a separate Charts child of the set parent contains the overview

Regression includes actual versus predicted, residuals and error distribution. Classification includes raw/normalized confusion matrices and per-class metrics; ROC/PR and calibration require model probabilities. Tree models expose native feature importance; linear models expose signed coefficients when available. Saved CV folds, tuning trials and training loss are plotted only when present. Full-holdout metric summaries use existing scalar values and separate metric scales.

Open the Charts tab using the links printed by generate_charts. Images are indexed in dedicated Charts child runs with no training parameters, so MLflow's image-grid header does not repeat the long parameter list. The original training run retains all parameters, metrics and model artifacts. Its skyulf.charts.run_id tag links to the latest successful chart run.

MLflow can automatically create image cards from logged image keys. If a card is missing from your saved layout, choose Add chart -> Image grid and select a key such as single_actual_vs_predicted or competition_leaderboard. The task output is plain text: created image keys grouped under their MLflow Charts links. Sample counts, skipped diagnostics and charts_run_id remain in evaluation_charts/report.json on the parent training run. Component reports keep the source run_id and the separate chart destination_run_id.

config/training.yml > defaults controls the saved sample and display budgets:

evaluation_charts:
  enabled: true
  max_rows: 2000
  max_features: 20
  max_classes: 20

Enabling charts saves a deterministic bounded sample of actual heldout predictions, probabilities and labels in the evaluated model's MLflow artifacts, subject to the experiment's access and retention policies. Raw features and record keys are excluded. Sampling happens after full-holdout evaluation, preserving temporal feature context. Maximums are 10,000 rows, 50 displayed features and 50 classes; each sample has a 16 MiB budget. Pairwise coefficient outputs are capped at 20 boundaries. Sample diagnostics are labelled with their row count; full-holdout scalar metrics are never overwritten. Missing classes or unavailable model capabilities are reported explicitly.

If the saved output includes scoring_status, prediction diagnostics plot only rows marked predicted. Excluded rows remain in the original uniform sample; their null predictions are not turned into zeros. Each component report records sample_scored_rows, sample_excluded_rows and sample_excluded_by_reason. Chart captions and task output show how many sampled rows were accepted or excluded. These are sample counts, not the full holdout's exclusion counts. Fewer than two predicted sample rows skip prediction diagnostics; available model and training evidence charts can still be shown. Sampling, saved labels and evaluation metrics are unchanged, and malformed predictions still raise an error.

The task is an independent leaf with no retries. A chart failure can mark the overall job failed but does not undo model decisions or repeat training. Inspect the chart task and skyulf.charts.status; do not repair an old lifecycle invocation. Setting enabled to false disables an already deployed chart task. Adding charts to a project generated without them also requires adding the generated task and Matplotlib dependency, then redeploying; the flag alone cannot change a job graph.

Optional SHAP explanations

Quick setup leaves SHAP off and skips its questions. Detailed setup can add the config, pinned dependencies and separate shap_model/shap_<name> leaves. The SHAP explanation guide shows how to add those files to an existing project, where reports are saved and how to read them. Computation uses bounded training inputs during fit; the leaf displays the saved report without retraining. Unavailable or disabled SHAP does not replace the model's evaluation metrics.

Training graph and notebook files

Each train_<name> performs a real fit and retains its split, preprocessing, model, CV and tuning information. Its shap_<name> task is a separate leaf: it displays that exact run's saved report and has no outgoing dependencies. SHAP computation still happens during the fit; the leaf does not retrain the model. Unavailable explanations show their saved reason. A report-task failure is visible in the job but does not prevent model selection or set assembly.

SHAP tasks display saved explanation charts. Training, scoring and monitoring report tasks also render readable summaries where available. Structured JSON and saved artifacts retain the machine-readable results; task values and downstream job handoffs use those results, not the HTML presentation.

Each diagram starts after initialize_run and choose_action select training. The single-model main path is:

flowchart LR
    A["load_data"] --> B["prepare_dataset"]
    B --> C["train_and_tune"]
    C --> D["validate_model"]
    D --> E["register_model"]
    E --> F["evaluate_model"]
    F --> G["model_decision"]
    G --> H["training_report"]

The competition shares the prepared dataset and fans out into named fits. Selection uses training-side CV, adopts the fitted winner without retraining and retains loser runs without registering them:

flowchart LR
    A["load_data"] --> B["prepare_dataset"]
    B --> C["train_name: each candidate"]
    C --> D["select_best_model"]
    D --> E["register_model"]
    E --> F["evaluate_model"]
    F --> G["model_decision"]
    G --> H["training_report"]

The multi-target model set has separate source/split/fit work inside each branch. It packages every pinned component, checks the saved quality policies and applies one set-level decision. The model set guide explains the set:

flowchart LR
    C["train_name: each target"] --> D["register_model_set"]
    D --> E["evaluate_model_set"]
    E --> F["model_decision"]
    F --> G["training_report"]

train_name represents each concrete train_<name> key in the generated graph. These diagrams show the training paths, not every condition or optional leaf. Manual approve/reject/rollback skip fitting and use model_decision. training_report uses ALL_DONE to attempt finalization even after a failure; that does not make the failed invocation successful. Optional SHAP leaves depend only on their own fitting task; chart generation is another independent branch. After a successful final report, the verified scoring handoff can start the separate score job. Model-set aliases belong to the set, while components remain pinned.

The graph uses meaningful model names; notebook implementation is shared:

File in src/jobs Responsibility
initialize_run.py Pin single/competition source, recipes and champion
initialize_models.py Pin every multi-model recipe, source version and set baseline
load_data.py, prepare_dataset.py Load and split the shared single/competition dataset
train_and_tune.py Fit a single model
train_model.py Fit the named competition candidate or multi-model branch
shap_report.py Display one training task's saved SHAP report
select_best_model.py Select the complete competition's winner from training-side CV
validate_model.py Verify the single fitted candidate before registration
register_model.py, evaluate_model.py, model_decision.py Existing single-model registration and alias controls
register_model_set.py Package the complete set and nominate its challenger
evaluate_model_set.py Evaluate every component against its quality policy and pinned champion
model_set_decision.py Apply set promotion policy or an explicit approve/reject/rollback action
training_report.py, models_report.py Final single/competition or multi-model status
score.py, score_models.py Saved single-model or model-set scoring

Changing parameters or a recipe keeps the graph unchanged. After adding, removing or renaming entries in config/training.yml > models, run:

python src/tools/refresh_training_graph.py
databricks bundle validate --strict --target test
databricks bundle deploy --target test

The refresh script preserves schedules, compute and operator settings. A changed model list with an old deployed graph is rejected before any model is trained. Tasks can run concurrently when compute permits; each task's row/byte/search limits still apply separately. Existing serialized job admission, frozen receipts and no-repair/no-retry rules remain in effect.

Training parameters in MLflow

After training, open the model's MLflow experiment run and select Parameters. Competition candidates and multi-target branches each record their own settings:

Parameter Meaning
tuning_strategy, tuning_model_type Search strategy and selected model family
tuning_requested_metric, tuning_metric Requested objective and resolved scorer
tuning_requested_trials, tuning_trials Configured trial budget and actual Core trial count
tuning_random_state, tuning_timeout, tuning_n_jobs Search seed, timeout and workers
tuning_strategy_params, tuning_search_space Strategy controls and effective search space
tuning_best_params.<name> Each parameter selected by the final search

Large parameter previews point to the complete tuning.json artifact. Existing cv_* parameters remain alongside these fields; tuning_best_score is a metric. With nested CV, Parameters shows the final search on all training rows; individual outer-fold selections remain in tuning.json.

Fixed and tuned models also expose their fitted configuration in Parameters:

Parameter Meaning
model_type, model_params.<name> Model family and actual constructor settings, including defaults and tuned values
ensemble.base_models, ensemble.strategy Ordered member names and voting/stacking strategy
ensemble.voting, ensemble.weights Applicable voting type and weights in member order
ensemble.final_estimator, ensemble.cv Stacking meta-model and its internal folds, separate from workflow CV
split_strategy, split_test_size, split_random_state, split_stratify Active random holdout controls, separate from CV and tuning seeds
split_start, split_holdout_start, split_cutoff, split_event_column Temporal holdout boundaries and clock column; inactive random controls are omitted
preprocessing_recipe, pre_split_recipe Selected recipe or declared builder default; inline means no project recipe metadata
preprocessing_steps, pre_split_steps Ordered step names for each phase

training_parameters.json retains complete summaries when a preview exceeds the display limit. Non-JSON constructor objects are described by type; their nested constructor settings are separate entries, and the fitted artifact retains the actual objects. builder_default means the builder has no named recipe default; none means that optional builder is absent. Previously saved artifacts without recipe metadata still work.

Task outputs and saved input evidence

The train job has one active run, with queued training and operator actions:

Task Purpose
initialize_run Validate settings and pin source version, recipe and expected champion
choose_action Select training or an explicit approve/reject/rollback action
load_data Read the bounded pinned source and save its verified dataset
prepare_dataset Apply fixed cleanup and eligibility rules, then save training/holdout partitions
train_and_tune Fit preprocessing inside training folds, run configured CV/tuning, and save the fitted pipeline
validate_model Verify the single fitted candidate
select_best_model Show the competition leaderboard and selected winner
register_model Check heldout evaluation before registering and nominating the candidate
evaluate_model Compare the registered candidate with the pinned champion on the same holdout
model_decision Apply promotion policy or execute an explicit approve/reject/rollback action
training_report Finalize the run and publish verified results and next actions
register_monitor Enroll the activated model, competition winner or model-set components before scoring
scoring_requested Check whether scoring was requested
run_batch_scoring Invoke the existing score job

The separate score job has the score task. With CDF expiry recovery enabled, recovery_needed routes recognized expiry to recover_predictions, and scoring_report shows the actual scoring or recovery result. Open training_report for metrics, the decision and ready-to-copy next_actions. Search details are in train_and_tune; champion comparison is in evaluate_model. Score results are in the child or independent score run. Manual actions skip data and training and use model_decision directly. Finalization can run after failure; that does not imply a successful result.

The score job's monitor_model task invokes the separate monitoring job after its preparation checks succeed. In that monitoring job, monitor_model measures enrolled models, monitoring_report displays saved drift and performance evidence, and evaluate_retraining applies the configured retraining guards. These are monitoring operations, not fitting tasks in the train graph.

prepare_dataset applies only fixed transformations and filters. Learned preprocessing and feature engineering stay inside train_and_tune so each CV fold learns from its own training rows. With tuning disabled, that task fits the configured model directly. With training_layout=model_competition, each named candidate is fitted and select_best_model verifies the complete shared-CV leaderboard before the winner reaches registration. Other candidates remain inspectable MLflow runs without registered versions.

Bounded source and split datasets are saved as Parquet artifacts under the MLflow run's lifecycle/data/. Downstream training verifies their saved digests and preserves split membership without rereading the source. These artifacts contain training data: apply the experiment's access and retention policy. Registration and approval retain their source/evidence replay checks.

Preprocessing diagnostics

With defaults.save_preprocessing_diagnostics: true, each fitting run saves preprocessing_probe.json; the fitting task's Output (train_and_tune or train_<name>) shows the result. The preprocessing diagnostics guide explains the check and every status.

Common errors and fixes

Symptom Check and fix
A report task/notebook is missing Regenerate the selected optional capability separately, review its notebooks/dependencies/resources, and redeploy the matching graph.
SHAP says unavailable Read the saved reason; check transformed feature width, supported model and installed pinned dependencies. max_features does not select columns.
An evaluation chart is absent Inspect evaluation_charts/report.json; unavailable probabilities, missing classes or absent CV/tuning history can legitimately skip a chart.
A chart task failed after a model decision Inspect skyulf.charts.status; the independent leaf does not undo decisions. Do not repair an old lifecycle invocation to recreate charts.
Training report ran after another task failed Finalization reports the failure; a completed report does not establish a successful training run.
Large MLflow parameter value is truncated Read training_parameters.json or tuning.json for the complete saved value.
Preprocessing reports requires_context Supply the actual groups/history through the supported inference contract; the sample probe cannot certify worker or endpoint execution.

Reports describe the exact saved run and installed Core version. A local preview or the examples on this page do not establish cloud execution or model quality.