Skip to content

fix: diagnose LightGBM reproducibility mismatches - #2663

Open
Rana Singh (ranadeepsingh) wants to merge 5 commits into
microsoft:masterfrom
ranadeepsingh:copilot/issue-2394-lightgbm-reproducibility
Open

fix: diagnose LightGBM reproducibility mismatches#2663
Rana Singh (ranadeepsingh) wants to merge 5 commits into
microsoft:masterfrom
ranadeepsingh:copilot/issue-2394-lightgbm-reproducibility

Conversation

@ranadeepsingh

@ranadeepsingh Rana Singh (ranadeepsingh) commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • warn when effective deterministic=true training uses nondeterministic Spark lineage
  • restrict LightGBM forced-histogram guidance to effective CPU training, honoring typed and pass-through device precedence
  • recognize all covered LightGBM true values, including on
  • document snapshot materialization and the difference between training overfit and data mismatch
  • add a public LightGBMClassifier Parquet regression covering exact rows, metadata, vector representation, weights, init scores, repeated native model dumps, predictions, and AUC

Findings

The issue's dramatic AUC difference was not reproducible as a Parquet or SynapseML serialization defect. Under LightGBM's documented deterministic contract, exact model comparison succeeds when the same stable snapshot and physical row/partition layout are used.

The report's unseeded Spark random ordering is a nondeterministic query plan, and write, fit, and evaluation are separate actions. A Parquet read can also change physical row/partition order without changing serialized values or metadata. The regression therefore keeps nondeterministic lineage solely in a cheap plan-only warning fixture, verifies exact rows/metadata/vector representation, then canonicalizes and materializes both training layouts only inside the test before exact model/prediction comparison. No product sort, repartition, caching, estimator-default, or serialization behavior changed.

A near-perfect training AUC with stable validation AUC can additionally reflect overfit rather than data corruption.

Maintainability audit

  • Diagnostics reuse the existing pass-through parser and effective-device resolver; no duplicate device-precedence implementation was added.
  • Query inspection is gated on effective deterministic training, reads only Spark's optimized logical plan, and launches no Spark action.
  • Default training behavior and serialized parameters are unchanged; the product change only logs actionable warnings.
  • The warning test uses a ten-row nondeterministic plan without fitting the full feature pipeline.
  • The parity test retains only two justified canonical caches. Required row collection materializes them, and try/finally guarantees cleanup; redundant source caching and three count actions were removed.

Review fixes

  • CPU-only histogram warnings use the existing effective-device resolver; tests cover CPU, typed GPU, pass-through CUDA, typed GPU overridden to CPU, and typed CPU overridden to GPU.
  • The parity regression uses deterministic source data, canonical test-only row/partition layout, and guaranteed cleanup.
  • The suite uses getAndIncrementPort() instead of fixed port 13940.
  • LightGBM boolean on is recognized and covered by parser regression tests.
  • Documentation distinguishes device-independent lineage warnings from CPU-only histogram guidance.
  • All prior Copilot review threads were answered with evidence and resolved; the suppressed on finding was addressed and recorded in a PR comment.

Validation

Spark 3.5 / Scala 2.12 / JDK 11

  • full LightGBMParquetReproducibilitySuite: 2/2 passed on head 79f16fdb2c
  • lightgbm/compile and lightgbm/Test/compile
  • LightGBM production/test scalastyle: 0 findings
  • sbt codegen
  • pinned black==22.3.0 --check --extend-exclude 'docs/' .

Spark 4.1 / Scala 2.13 / JDK 17 replay

  • full LightGBMParquetReproducibilitySuite: 2/2 passed on replay of head 79f16fdb2c
  • lightgbm/compile and lightgbm/Test/compile
  • LightGBM production/test scalastyle: 0 findings
  • sbt codegen
  • pinned black==22.3.0 --check --extend-exclude 'docs/' .

Azure validation is intentionally not retriggered here; build 231708782 was canceled before useful validation, and the parent will rerun serialized.

Refs #2394

## Summary
Add targeted LightGBM reproducibility warnings, documentation, and a public-estimator Parquet round-trip regression covering rows, metadata, vector representation, model dumps, predictions, and AUC.

## Prompting Intent
Investigate GitHub issue microsoft#2394 end-to-end on Spark 3.5, distinguish input and configuration nondeterminism from a SynapseML serialization defect, avoid changing training semantics or performance without evidence, and provide a before/after regression plus actionable diagnostics.

## Linked Sources
- GitHub issue: microsoft#2394
- LightGBM deterministic parameter documentation: https://lightgbm.readthedocs.io/en/latest/Parameters.html#deterministic
- LightGBM determinism discussion: lightgbm-org/LightGBM#3761
- LightGBM row-order discussion: lightgbm-org/LightGBM#6320

## Rationale
The regression found exact parity between in-memory and Parquet-reloaded inputs and outputs when LightGBM's documented deterministic contract is followed. Rather than sorting, repartitioning, caching, or altering estimator defaults, warn only for effective deterministic training with nondeterministic Spark lineage or an incomplete/conflicting histogram configuration, and document snapshot materialization and training-overfit interpretation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions

Copy link
Copy Markdown

Hey Rana Singh (@ranadeepsingh) 👋!
Thank you so much for contributing to our repository 🙌.
Someone from SynapseML Team will be reviewing this pull request soon.

We use semantic commit messages to streamline the release process.
Before your pull request can be merged, you should make sure your first commit and PR title start with a semantic prefix.
This helps us to create release messages and credit you for your hard work!

Examples of commit messages with semantic prefixes:

  • fix: Fix LightGBM crashes with empty partitions
  • feat: Make HTTP on Spark back-offs configurable
  • docs: Update Spark Serving usage
  • build: Add codecov support
  • perf: improve LightGBM memory usage
  • refactor: make python code generation rely on classes
  • style: Remove nulls from CNTKModel
  • test: Add test coverage for CNTKModel

To test your commit locally, please follow our guild on building from source.
Check out the developer guide for additional guidance on testing your change.

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@ranadeepsingh
Rana Singh (ranadeepsingh) marked this pull request as ready for review August 18, 2026 18:59
Copilot AI lite review requested due to automatic review settings August 18, 2026 18:59
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds diagnostics and documentation to help users understand and debug LightGBM “reproducibility” mismatches that stem from nondeterministic Spark lineage and incomplete deterministic LightGBM configuration, and introduces a regression suite that validates Parquet round-trip parity for LightGBMClassifier training inputs/outputs.

Changes:

  • Add reproducibility warning logic to LightGBM training when deterministic mode is enabled.
  • Add a comprehensive Parquet round-trip reproducibility regression suite for LightGBMClassifier.
  • Improve pass-through parameter parsing utilities and document recommended deterministic training practices.
Show a summary per file
File Description
lightgbm/src/main/scala/com/microsoft/azure/synapse/ml/lightgbm/LightGBMBase.scala Logs reproducibility warnings for deterministic training (Spark lineage + histogram strategy).
lightgbm/src/main/scala/com/microsoft/azure/synapse/ml/lightgbm/LightGBMUtils.scala Adds helpers to extract pass-through parameter values and recognize LightGBM “true” boolean values.
lightgbm/src/test/scala/com/microsoft/azure/synapse/ml/lightgbm/split1/VerifyLightGBMCommon.scala Adds a unit test asserting boolean pass-through parsing behavior matches expected LightGBM syntax.
lightgbm/src/test/scala/com/microsoft/azure/synapse/ml/lightgbm/split1/LightGBMParquetReproducibilitySuite.scala New regression suite validating Parquet row/metadata parity and deterministic model/prediction stability.
docs/Explore Algorithms/LightGBM/Overview.md Documents deterministic training requirements and the need to materialize a single Spark snapshot.

Review details

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 5/5 changed files
  • Comments generated: 3
  • Review effort level: Lite

SynapseML CI and others added 2 commits August 18, 2026 12:42
## Summary
Restrict deterministic histogram guidance to effective CPU training, materialize and clean up one stable in-memory snapshot in the Parquet regression, and allocate the suite's LightGBM listen port dynamically.

## Prompting Intent
Resolve all three blocking Copilot review threads on PR microsoft#2663 without changing estimator defaults: honor typed and pass-through device precedence, keep nondeterministic-lineage coverage separate from stable parity proof, prevent parallel port collisions, and validate the changes across Spark 3.5 and Spark 4.1.

## Linked Sources
- Pull request: microsoft#2663
- CPU warning review: microsoft#2663 (comment)
- Snapshot materialization review: microsoft#2663 (comment)
- Dynamic port review: microsoft#2663 (comment)

## Rationale
Reuse the existing effective-device resolver so passThroughArgs retains precedence over typed device parameters. MEMORY_AND_DISK plus an eager count creates one exact snapshot while try/finally guarantees unpersist cleanup; the separate warning test retains the unseeded lineage. Reusing getAndIncrementPort follows existing suite conventions without changing product networking behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Canonicalize and materialize the in-memory and Parquet training layouts before comparing native models, predictions, and AUC in the reproducibility regression.

## Prompting Intent
Keep the regression's exact input snapshot and cleanup guarantees while making its model comparison valid on both Spark 3.5 and Spark 4.1, where a Parquet read can change physical row and partition order independently of serialized values or metadata.

## Linked Sources
- Pull request: microsoft#2663
- Snapshot materialization review: microsoft#2663 (comment)

## Rationale
Spark 4.1 replay showed stable repeated models within each source but different models and predictions across storage layouts despite identical rows, metadata, and AUC. Hash repartitioning by the stable row ID plus per-partition sorting is confined to the test and isolates Parquet encoding without changing product semantics. Both canonical inputs use MEMORY_AND_DISK and guaranteed unpersist cleanup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 18, 2026 20:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

lightgbm/src/main/scala/com/microsoft/azure/synapse/ml/lightgbm/LightGBMUtils.scala:18

  • LightGBM boolean parameters also accept "on" (e.g., force_col_wise=on / deterministic=on). isEnabledParameterValue currently treats only 1/+1/true/yes as enabled, which can trigger incorrect histogram warnings (or suppress deterministic warnings) when users use the valid "on" syntax.
  private val DeviceParamNames = Set("device", "device_type")
  private val TrueValues = Set("1", "+1", "true", "yes")
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread docs/Explore Algorithms/LightGBM/Overview.md Outdated
## Summary
Recognize LightGBM boolean value `on`, cover it in parser regression tests, and clarify that forced-histogram warnings apply only to effective CPU training.

## Prompting Intent
Address the new current-head Copilot review threads and suppressed finding on PR microsoft#2663 without broadening product behavior: match accepted LightGBM boolean syntax and align user documentation with the CPU-gated implementation.

## Linked Sources
- Pull request: microsoft#2663
- Boolean syntax review: microsoft#2663 (comment)
- Documentation review: microsoft#2663 (comment)
- Suppressed current-head finding in Copilot review submitted 2026-08-18T20:40:58Z

## Rationale
Extending the shared enabled-value set keeps deterministic and forced-histogram parsing consistent for `on` without changing parameter serialization. Updating the existing documentation sentence avoids implying that CPU-only histogram guidance applies to GPU or CUDA training.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 18, 2026 21:11
@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

Addressed the current-head suppressed finding in 3e62306: LightGBM boolean value on is now recognized by the shared parser and covered by regression tests. Spark 3.5 and Spark 4.1 targeted tests, compile/test-compile, and scalastyle passed. Azure was not triggered.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

## Summary
Separate the cheap nondeterministic-plan warning fixture from the full LightGBM training fixture and remove redundant source caching and count actions from the Parquet regression.

## Prompting Intent
Perform a maintainability and overengineering audit of PR microsoft#2663, retaining exact public-estimator proof while avoiding unnecessary materialization, flaky nondeterministic training input, hot-path changes, or altered estimator semantics.

## Linked Sources
- Pull request: microsoft#2663
- GitHub issue: microsoft#2394
- Snapshot review: microsoft#2663 (comment)

## Rationale
The warning test only needs a nondeterministic logical plan, so it now uses a ten-row range instead of fitting StringIndexer and assembling the full training fixture. The parity test uses deterministic source data and materializes only its two canonical comparison layouts; the required row collection both proves equality and fills those caches, eliminating a third cache and three redundant count actions without weakening repeated model, prediction, metadata, or AUC checks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 18, 2026 22:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants