docs/api-backwards-compatibility-check.md
Megatron Core uses automated API compatibility checking to ensure stable interfaces between releases. This prevents accidental breaking changes that could affect users upgrading between versions.
The compatibility checker:
megatron/coretest_@internal_api, @experimental_api, or @deprecatedtests/, experimental/, legacy/# Install griffe
pip install griffe
# Check against latest release
python scripts/check_api_backwards_compatibility.py --baseline core_r0.8.0
# Check with verbose output
python scripts/check_api_backwards_compatibility.py --baseline core_r0.8.0 -v
# Compare two specific branches
python scripts/check_api_backwards_compatibility.py --baseline core_r0.8.0 --current main
If you need to make breaking changes to internal or experimental APIs:
from megatron.core.utils import internal_api
@internal_api
def experimental_feature(x, y):
"""
This API is experimental and may change.
NOT FOR EXTERNAL USE.
"""
pass
When to use @internal_api:
from megatron.core.utils import experimental_api
@experimental_api
def new_experimental_feature(x, y):
"""
This API is experimental and may change without notice.
"""
pass
When to use @experimental_api:
For planned API changes, use the deprecation workflow:
from megatron.core.backwards_compatibility_decorators import deprecated
@deprecated(
version="1.0.0", # When deprecation starts
removal_version="2.0.0", # When it will be removed
alternative="new_function", # Recommended replacement
reason="Improved performance and cleaner API"
)
def old_function(x):
"""This function is deprecated."""
pass
Deprecation Timeline:
@deprecated decorator, function still worksIf the compatibility check fails on your PR:
@internal_api if intentional# ✅ BEFORE (v1.0)
def train_model(config, dataloader):
pass
# ✅ AFTER (v1.1) - Added optional parameter
def train_model(config, dataloader, optimizer="adam"):
pass
Result: ✅ Check passes
# BEFORE (v1.0)
def train_model(config, dataloader, optimizer="adam"):
pass
# ❌ AFTER (v1.1) - Removed parameter
def train_model(config, dataloader):
pass
Result: ❌ Check fails - "Parameter 'optimizer' removed"
from megatron.core.utils import internal_api
# BEFORE (v1.0)
@internal_api
def _internal_compute(x, y):
pass
# ✅ AFTER (v1.1) - Can change freely
@internal_api
def _internal_compute(x, y, z): # Added parameter
pass
Result: ✅ Check passes (function is exempt)
from megatron.core.utils import deprecated
# Version 1.0 - Add deprecation
@deprecated(
version="1.0.0",
removal_version="2.0.0",
alternative="train_model_v2"
)
def train_model(config):
"""Old training function - DEPRECATED"""
pass
def train_model_v2(config, **options):
"""New improved training function"""
pass
# Version 1.1 - Keep both (users migrate)
# Version 2.0 - Remove train_model()
Developer commits code
↓
GitHub Actions triggers
↓
CI runs check_api_backwards_compatibility.py
↓
Script loads code via griffe:
• Baseline: latest release (e.g., core_r0.8.0)
• Current: PR branch
↓
Apply filtering:
• Skip @internal_api, @experimental_api, and @deprecated
• Skip private functions (_prefix)
• Skip test/experimental paths
↓
Griffe compares signatures:
• Parameters
• Types
• Return types
• Defaults
↓
Report breaking changes
↓
Exit: 0=pass, 1=fail
↓
CI fails if breaking changes detected
Edit scripts/check_api_backwards_compatibility.py:
# Add more exempt decorators
EXEMPT_DECORATORS = [
"internal_api",
"experimental_api",
"deprecated",
]
# Add more path exclusions
EXCLUDE_PATHS = {
"tests",
"experimental",
"legacy",
"your_custom_path", # ← Add here
}
The workflow auto-detects the latest core_r* tag. To manually specify:
# In .github/workflows/check_api_backwards_compatibility_workflow.yml
- name: Run compatibility check
run: |
python scripts/check_api_backwards_compatibility.py \
--baseline your_custom_baseline
A: Your code introduced breaking changes compared to the last release. Review the CI logs to see what changed.
A: No, but you can mark specific functions as exempt using @internal_api or @experimental_api.
A: Use the @deprecated decorator for a gradual transition, or mark the function as exempt using @internal_api (for internal code) or @experimental_api (for experimental features).
A: No, only megatron/core/** (Megatron Core). Legacy code is excluded.
A: Yes, class methods are checked just like functions.
A: Yes! Run python scripts/check_api_backwards_compatibility.py --baseline core_r0.8.0
A: The workflow will use main as the baseline. Update it once you have release tags.
pip install griffe
The repository doesn't have release tags yet. The workflow will fall back to main.
If the checker reports a breaking change that isn't actually breaking, file an issue and use @internal_api as a temporary workaround.
scripts/check_api_backwards_compatibility.py.github/workflows/check_api_backwards_compatibility_workflow.ymlmegatron/core/backwards_compatibility_decorators.pyFor questions or issues: