Golden Notebook Comparison¶
Overview¶
The Jupyter Notebook Validator Operator supports golden notebook comparison to detect regressions in notebook execution. This feature compares the output of an executed notebook against a "golden" reference notebook to ensure consistency.
Implementation Status¶
✅ Phase 3 Complete (2025-11-08)
- Golden notebook fetching via second init container
- Cell-by-cell output comparison
- Multiple comparison strategies (exact, normalized)
- Diff generation and reporting
- Status updates with comparison results
Architecture¶
Pod Structure¶
When a golden notebook is specified, the validation pod includes two init containers:
initContainers:
- name: git-clone
# Clones the target notebook to /workspace/repo
- name: golden-git-clone
# Clones the golden notebook to /workspace/golden
containers:
- name: validator
# Executes notebook and performs comparison
Comparison Flow¶
- Notebook Execution: Target notebook is executed with Papermill
- Golden Parsing: Golden notebook is parsed from
/workspace/golden - Cell-by-Cell Comparison: Each cell's output is compared
- Diff Generation: Differences are identified and categorized
- Status Update: Comparison results are stored in CR status
Usage¶
Basic Example¶
apiVersion: mlops.mlops.dev/v1alpha1
kind: NotebookValidationJob
metadata:
name: my-validation-job
spec:
notebook:
git:
url: "https://github.com/myorg/notebooks.git"
ref: "main"
path: "notebooks/my-notebook.ipynb"
goldenNotebook:
git:
url: "https://github.com/myorg/notebooks.git"
ref: "main"
path: "notebooks/my-notebook-golden.ipynb"
podConfig:
containerImage: "jupyter/scipy-notebook:latest"
Comparison Strategies¶
Configure comparison strategy via annotations:
Available Strategies¶
- exact (default)
- Byte-for-byte comparison of outputs
- Strictest comparison mode
-
Best for deterministic notebooks
-
normalized (Phase 3)
- Ignores whitespace differences
- Ignores timestamps (configurable patterns)
-
Best for notebooks with timestamps or formatting variations
-
fuzzy (Phase 4 - Planned)
- Floating-point tolerance
- Configurable epsilon for numeric comparisons
-
Best for notebooks with floating-point calculations
-
semantic (Phase 4 - Planned)
- Semantic comparison of outputs
- Understands data structures
- Best for complex data outputs
Comparison Configuration¶
Additional configuration via annotations:
metadata:
annotations:
mlops.dev/comparison-strategy: "normalized"
mlops.dev/numeric-tolerance: "0.001"
mlops.dev/ignore-timestamps: "true"
mlops.dev/ignore-execution-count: "true"
Comparison Results¶
Status Fields¶
Comparison results are stored in the CR status:
status:
comparisonResult:
strategy: "exact"
result: "matched" # or "failed"
totalCells: 5
matchedCells: 5
mismatchedCells: 0
diffs: []
Diff Format¶
When cells do not match, diffs are generated:
diffs:
- cellIndex: 2
cellType: "code"
diffType: "output_mismatch"
expected: "Expected output"
actual: "Actual output"
severity: "major"
Diff Types¶
- output_mismatch: Cell outputs do not match
- extra_cell: Executed notebook has extra cells
- missing_cell: Executed notebook is missing cells
- cell_type_mismatch: Cell types do not match
Severity Levels¶
- minor: Whitespace or formatting differences
- major: Content differences
- critical: Structural differences (missing/extra cells)
Creating Golden Notebooks¶
Best Practices¶
- Execute Once: Run the notebook once to generate expected outputs
- Review Outputs: Manually verify all outputs are correct
- Commit to Git: Store golden notebook in version control
- Update Regularly: Update golden notebook when expected behavior changes
Example Workflow¶
# 1. Execute notebook to generate outputs
jupyter nbconvert --execute --to notebook \
--output my-notebook-golden.ipynb \
my-notebook.ipynb
# 2. Review the golden notebook
jupyter notebook my-notebook-golden.ipynb
# 3. Commit to Git
git add my-notebook-golden.ipynb
git commit -m "Add golden notebook for regression testing"
git push
Golden Notebook Naming Convention¶
Recommended naming pattern:
Authentication¶
Golden notebooks support the same authentication methods as target notebooks:
HTTPS Authentication¶
goldenNotebook:
git:
url: "https://github.com/myorg/notebooks.git"
ref: "main"
credentialsSecret: "git-credentials"
path: "notebooks/golden.ipynb"
SSH Authentication¶
goldenNotebook:
git:
url: "git@github.com:myorg/notebooks.git"
ref: "main"
credentialsSecret: "git-ssh-credentials"
path: "notebooks/golden.ipynb"
Different Repositories¶
Golden notebooks can be in a different repository:
spec:
notebook:
git:
url: "https://github.com/myorg/notebooks.git"
ref: "main"
path: "notebooks/my-notebook.ipynb"
goldenNotebook:
git:
url: "https://github.com/myorg/golden-notebooks.git"
ref: "main"
credentialsSecret: "golden-git-credentials"
path: "golden/my-notebook-golden.ipynb"
Troubleshooting¶
Golden Notebook Not Found¶
Error: Golden notebook not found at path: notebooks/golden.ipynb
Solution: Verify the path is correct and the file exists in the repository
Comparison Failed¶
Error: Validation failed: golden notebook comparison failed (3/5 cells matched)
Solution: Check the diff details in the CR status:
Golden Notebook Parsing Failed¶
Error: golden notebook parsing failed: invalid JSON
Solution: Ensure the golden notebook is a valid Jupyter notebook:
Examples¶
Example 1: Simple Comparison¶
apiVersion: mlops.mlops.dev/v1alpha1
kind: NotebookValidationJob
metadata:
name: simple-comparison
spec:
notebook:
git:
url: "https://github.com/myorg/notebooks.git"
ref: "main"
path: "notebooks/hello-world.ipynb"
goldenNotebook:
git:
url: "https://github.com/myorg/notebooks.git"
ref: "main"
path: "notebooks/hello-world-golden.ipynb"
podConfig:
containerImage: "jupyter/scipy-notebook:latest"
Example 2: Normalized Comparison¶
apiVersion: mlops.mlops.dev/v1alpha1
kind: NotebookValidationJob
metadata:
name: normalized-comparison
annotations:
mlops.dev/comparison-strategy: "normalized"
mlops.dev/ignore-timestamps: "true"
spec:
notebook:
git:
url: "https://github.com/myorg/notebooks.git"
ref: "main"
path: "notebooks/data-analysis.ipynb"
goldenNotebook:
git:
url: "https://github.com/myorg/notebooks.git"
ref: "main"
path: "notebooks/data-analysis-golden.ipynb"
podConfig:
containerImage: "jupyter/scipy-notebook:latest"
Related Documentation¶
Future Enhancements¶
Phase 4 (Planned)¶
- Fuzzy comparison with floating-point tolerance
- Semantic comparison for complex data structures
- Configurable comparison rules per cell
- Visual diff reports
- Comparison metrics and trends
Phase 5 (Planned)¶
- Multiple golden notebooks (A/B testing)
- Golden notebook versioning
- Automatic golden notebook updates
- Comparison performance optimizations