fix: resolve current model metadata deterministically - #2632
Conversation
|
/azp run |
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
Hey Rana Singh (@ranadeepsingh) 👋! We use semantic commit messages to streamline the release process. Examples of commit messages with semantic prefixes:
To test your commit locally, please follow our guild on building from source. |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This PR fixes non-deterministic scored-model metadata resolution in the core metrics pipeline, preventing ComputeModelStatistics from selecting stale model metadata across repeated training/evaluation within the same DataFrame lineage (as reported in #1697).
Changes:
- Make
MetricUtils.getSchemaInfodeterministically enumerate, de-duplicate, and sort scored-model metadata candidates, filtering to complete (label + valid kind + prediction) candidates and rejecting ambiguity with guidance. - Add early, actionable column validation in
ComputeModelStatisticsto avoid constructing Spark expressions with unresolved/null columns, while keeping classification score resolution lazy for score-irrelevant metrics. - Add targeted regression tests covering stale metadata scenarios, explicit override precedence, deterministic ambiguity rejection, and improved error cases.
Show a summary per file
| File | Description |
|---|---|
| core/src/main/scala/com/microsoft/azure/synapse/ml/core/metrics/MetricUtils.scala | Deterministic scored-model candidate discovery/selection and improved ambiguity/missing-metadata handling. |
| core/src/main/scala/com/microsoft/azure/synapse/ml/train/ComputeModelStatistics.scala | Validates resolved label/prediction/score columns up-front with actionable errors; keeps score validation lazy for non-score metrics. |
| core/src/test/scala/com/microsoft/azure/synapse/ml/train/VerifyComputeModelStatistics.scala | Adds focused tests for stale lineage metadata, explicit overrides, deterministic ambiguity failure, and score-column validation behavior. |
Review details
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
## Summary Make the missing-metadata error mention the all-metrics restriction only when evaluationMetric is actually unresolved, and cover the explicit-metric/missing-label case. ## Prompting Intent Address the actionable PR review comment without expanding issue microsoft#1697 scope, then re-run the focused JDK 11 test, compile, and style validation. ## Linked Sources - GitHub issue: microsoft#1697 - Pull request: microsoft#2632 - Review comment: microsoft#2632 (comment) ## Rationale Conditioning the hint on the unresolved setting avoids telling users to change a metric that is already explicit while preserving guidance when the default all-metrics mode is genuinely ambiguous. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2632 +/- ##
==========================================
+ Coverage 88.60% 88.63% +0.03%
==========================================
Files 331 331
Lines 18531 18556 +25
Branches 1752 1740 -12
==========================================
+ Hits 16419 16447 +28
+ Misses 2112 2109 -3
🚀 New features to boost your workflow:
|
|
CI follow-up for latest SHA
I did not delete shared Azure Search indexes to make the PR green. Diagnostic logs and the local JDK 11 validation evidence are retained in the requested issue artifact directory. |
Prevent ComputeModelStatistics from selecting orphaned model metadata left in dataframe lineage. Resolve complete scored-model candidates deterministically, honor explicit label and metric intent, reject genuine ambiguity, and report actionable missing-column errors. Fix GitHub issue microsoft#1697 end to end while keeping the change focused and backward compatible. Reproduce repeated regression/classification training, preserve explicit column settings, cover ambiguous and missing metadata, and validate both classification and regression paths with JDK 11. - GitHub issue: microsoft#1697 Enumerating complete label-plus-prediction metadata sets avoids relying on schema or metadata-map order and naturally excludes stale label-only entries. Explicit label and evaluation settings constrain selection without guessing. Ambiguous complete candidates fail with guidance rather than silently choosing a model, while generic Spark models retain the explicit-column fallback. Score validation remains lazy for metrics that do not consume scores to preserve existing behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary Make the missing-metadata error mention the all-metrics restriction only when evaluationMetric is actually unresolved, and cover the explicit-metric/missing-label case. ## Prompting Intent Address the actionable PR review comment without expanding issue microsoft#1697 scope, then re-run the focused JDK 11 test, compile, and style validation. ## Linked Sources - GitHub issue: microsoft#1697 - Pull request: microsoft#2632 - Review comment: microsoft#2632 (comment) ## Rationale Conditioning the hint on the unresolved setting avoids telling users to change a metric that is already explicit while preserving guidance when the default all-metrics mode is genuinely ambiguous. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary Make scored-model discovery deterministic for duplicate, conflicting, incomplete, and reordered metadata; preserve fully explicit evaluation settings; validate columns with Spark case-sensitivity semantics; and retain parameters across copy, pipeline, and serialization paths. ## Prompting Intent Make GitHub PR microsoft#2632 merge-ready after the microsoft#2635 metric changes by auditing metadata resolution, schema propagation, API compatibility, classification/regression behavior, pipeline serialization, code generation, determinism, concurrency safety, and performance, with robust end-to-end and negative tests. ## Linked Sources - GitHub issue: microsoft#1697 - Pull request: microsoft#2632 - Interacting pull request: microsoft#2635 - Review comment: microsoft#2632 (comment) ## Rationale A one-pass immutable metadata index removes schema-order dependence and avoids repeated model-by-model scans. Equivalent metadata is collapsed by semantic signature, conflicting required or score roles fail deterministically, orphaned entries remain ignorable, and complete explicit settings bypass unrelated metadata only when no metadata-derived column is needed. Package-scoped role lookup preserves the existing public API while preventing first-column selection, and defaultCopy preserves uid and params without changing the copy signature. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary Add merged PR microsoft#2635 as a release-compatibility prerequisite so the metadata-resolution patch applies and compiles cleanly on the Spark 4.1 branch. ## Prompting Intent Account for merged PR microsoft#2635 while making PR microsoft#2632 merge-ready, including an exact release-branch replay and Spark 4.1 test compilation rather than relying only on the master build. ## Linked Sources - Pull request: microsoft#2632 - Prerequisite pull request: microsoft#2635 - GitHub issue: microsoft#1697 ## Rationale PR microsoft#2635 changed ComputeModelStatistics and its tests after Spark 4.1 diverged, so the PR-only patch conflicts without that baseline. Replaying the merged commit after the existing scoped test prerequisite matches the pipeline's prerequisite mechanism, keeps the feature patch focused, and was verified by an exact JDK 17 Spark 4.1 test:compile replay. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5cdf9ed to
dc55c79
Compare
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
## Summary Teach release compatibility replay to include an add-only scoped baseline when a later unscoped prerequisite modifies that path, validate the scoped blob against the dependent commit's parent, and reset the release checkout before applying patches. ## Prompting Intent Resolve the concrete Spark 4.1 Azure failure for PR microsoft#2632 without weakening prerequisite validation. The merged microsoft#2635 prerequisite depends on test files added by the existing scoped microsoft#2507 prerequisite even though those files are not directly changed by the PR. ## Linked Sources - Pull request: microsoft#2632 - Failed Azure build: https://msdata.visualstudio.com/b9b2accc-2d1c-45b3-9d24-0eb5d78cc47f/_build/results?buildId=231383144 - Dependent prerequisite: microsoft#2635 - Scoped baseline prerequisite: microsoft#2507 ## Rationale The existing replay selected scoped prerequisites only by direct PR-path overlap, so microsoft#2635 was applied before its add-only test baseline and failed. Looking ahead only to later unscoped prerequisites preserves normal skip behavior for unrelated paths while replaying true dependencies in config order. Comparing the scoped blob to the first dependent prerequisite parent retains exact-baseline validation, and a hard reset removes checkout/index drift before three-way application. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
core/src/main/scala/com/microsoft/azure/synapse/ml/core/metrics/MetricUtils.scala:196
- The ambiguity error suggests only setting
labelColandevaluationMetric, but callers may already have both set and still hit this when multiple candidates share the same label/kind (e.g., differing prediction/raw columns). The message should also guide users toward specifying columns explicitly (or clearing stale metadata) so the next action is clear.
throw new IllegalArgumentException(
"Ambiguous scored-model metadata. Multiple complete candidates match: " +
candidates.map(_.description).mkString("[", ", ", "]. ") +
"Set labelCol and evaluationMetric to select one candidate; remove stale score metadata if needed.")
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
## Summary Resolve configured label columns using Spark case-sensitivity semantics across model and per-instance statistics, improve ambiguous metadata guidance, and remove non-portable Bash negative array indexing from release replay. ## Prompting Intent Address every final Copilot review comment on PR microsoft#2632 while preserving deterministic metadata selection, schema propagation, compatibility, and Spark 4.1 replay behavior. ## Linked Sources - Pull request: microsoft#2632 - GitHub issue: microsoft#1697 - Case-resolution review: microsoft#2632 (comment) - Bash-portability review: microsoft#2632 (comment) - Interacting pull request: microsoft#2635 ## Rationale A package-scoped overload preserves the existing public JVM API while letting runtime callers apply the active Spark resolver semantics. Normalizing only a unique case-insensitive schema match avoids inventing precedence when case-colliding columns exist. Explicit selection state in the replay loop is portable across supported Bash versions and clearer than inspecting the last array element. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
The suppressed Copilot observation in review 4945931887 is also addressed by 0564a2b: ambiguous metadata guidance now recommends explicit scoredLabelsCol/scoresCol selection when labelCol and evaluationMetric are insufficient, or removal of stale metadata. |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
## Summary Resolve configured label columns using Spark case-sensitivity semantics across model and per-instance statistics, use the default Spark session when transformSchema has no active session, improve ambiguous metadata guidance, and remove non-portable Bash negative array indexing from release replay. ## Prompting Intent Address every final Copilot review comment on PR microsoft#2632 while preserving deterministic metadata selection, schema propagation, compatibility, and Spark 4.1 replay behavior. ## Linked Sources - Pull request: microsoft#2632 - GitHub issue: microsoft#1697 - Case-resolution review: microsoft#2632 (comment) - Bash-portability review: microsoft#2632 (comment) - Default-session review: microsoft#2632 (comment) - Interacting pull request: microsoft#2635 ## Rationale A package-scoped overload preserves the existing public JVM API while letting runtime callers apply Spark resolver semantics. Normalizing only a unique case-insensitive schema match avoids inventing precedence when case-colliding columns exist. transformSchema prefers the active session but falls back to the default session so its resolver matches runtime configuration whenever Spark context is available. Explicit replay selection state is portable across supported Bash versions and clearer than inspecting the last array element. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0564a2b to
49dcd37
Compare
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Review details
Suppressed comments (1)
pipeline.yaml:1219
- Same as above:
LATER_PARENT=$(git rev-parse ...)runs underset -eand can terminate the release-compat job with an unstructured git error if a later prerequisite is invalid. Wrap thisrev-parsein anif ! ...; thenwith a##vso[task.logissue type=error]message so failures are actionable and consistent.
LATER_PREREQUISITE="${CONFIGURED_PREREQUISITES[$later_index]}"
LATER_PARENT=$(git rev-parse "$LATER_PREREQUISITE^1")
- Files reviewed: 7/7 changed files
- Comments generated: 2
- Review effort level: Lite
## Summary Resolve configured labels using Spark case-sensitivity semantics in metadata-backed and fully explicit evaluation, use the default Spark session when transformSchema has no active session, improve ambiguity guidance, and harden release replay portability and dependent-prerequisite diagnostics. ## Prompting Intent Address every Copilot review comment on PR microsoft#2632 while preserving deterministic metadata selection, schema propagation, API compatibility, and Spark 4.1 replay behavior with end-to-end negative coverage. ## Linked Sources - Pull request: microsoft#2632 - GitHub issue: microsoft#1697 - Case-resolution review: microsoft#2632 (comment) - Bash-portability review: microsoft#2632 (comment) - Default-session review: microsoft#2632 (comment) - Explicit-schema review: microsoft#2632 (comment) - Replay-diagnostics review: microsoft#2632 (comment) - Interacting pull request: microsoft#2635 ## Rationale A package-scoped resolver preserves the existing public API while applying identical unique case-insensitive matching in metadata-backed and explicit paths. transformSchema prefers the active session and falls back to the default session so schema inference follows runtime configuration whenever Spark context exists. Explicit replay selection avoids Bash negative-index compatibility issues, and guarded parent resolution yields deterministic Azure errors for root or invalid dependent prerequisites; parameterized end-to-end tests exercise both dependent scans. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
49dcd37 to
f0c7dab
Compare
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
704fb34
into
microsoft:master
Summary
Fixes #1697.
ComputeModelStatisticsnow resolves scored-model metadata deterministically after repeated training/evaluation in the same DataFrame lineage. It ignores orphaned entries, collapses semantically equivalent duplicates, rejects conflicting metadata independently of column order, honors complete explicit settings, and reports actionable missing/ambiguous column errors instead of reachingcol(null).Key changes
copy, pipelines, and serialization viadefaultCopy.Coverage
Added regression and negative coverage for:
Validation
VerifyComputeModelStatistics: 32/32 passed.VerifyComputePerInstanceStatistics: 5/5 passed.core/codegen: passed; generatedComputeModelStatistics.pycompiles.tools/ci/tests/test_pipeline_yaml.py: 59/59 passed.test:compile: passed.No existing public method signature was removed or changed; the original
MetricUtils.getSchemaInfoandComputeModelStatistics.copysignatures remain intact.