Skip to content

feat(automodel): expose activation_checkpointing on customization jobs - #1252

Open
htolentino-nvidia wants to merge 2 commits into
mainfrom
automodel-activation-checkpointing/htolentino
Open

feat(automodel): expose activation_checkpointing on customization jobs#1252
htolentino-nvidia wants to merge 2 commits into
mainfrom
automodel-activation-checkpointing/htolentino

Conversation

@htolentino-nvidia

@htolentino-nvidia htolentino-nvidia commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Automodel supports activation checkpointing end to end — the finetune recipe reads distributed.activation_checkpointing off the config (recipes/_dist_utils.py) and normalizes bool | "full" | "selective" — but the platform had no way to set it, and FSDP2Config defaults it to False. Every customization job therefore trained with it off.

That blocks porting the NVIDIA Nemotron LoRA cookbooks, which set activation_checkpointing: true; the Nemotron 3 Super recipe annotates it "reduces peak memory (avoids OOM on 80GB)".

Adds the field alongside expert_parallel_size at each layer it already travels through: plugin schema, adapter, service API schema, compiler, task config, and YAML emission.

Typed bool | Literal["full", "selective"] | None to match what Automodel parses, rather than a plain bool, so selective checkpointing — the cheaper mode — stays reachable.

Defaults to None and is omitted from the emitted YAML when unset, so existing jobs compile byte-identically; the 15 golden contract configs are unchanged. An explicit false is still emitted, to distinguish "user turned it off" from "not configured".

Note the pre-existing embedding branch it now precedes is unreachable: embedding_config is a bare EmbeddingConfig() that is never populated, so do_gradient_checkpointing is always False. It is left in place as the fallback in case that config is ever wired up.

Not included: OpenAPI regeneration (make refresh-openapi) and the Stainless SDK sync, which need to run before the field reaches the CLI, Python SDK, or Studio.

Summary

Related Issue

Changes

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with documentation updates
  • Documentation only
  • Contributor tooling or automation
  • CI, build, or test infrastructure

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Documentation updated for user-visible behavior
  • Documentation not applicable — justification:

Verification

  • Pull request title follows the repository's Conventional Commit format
  • Every commit includes an appropriate Signed-off-by: trailer
  • uv run pre-commit run -a passes, or any blocked checks are identified below
  • Targeted tests pass, or tests are marked not applicable above
  • No secrets, API keys, or credentials are included

Targeted validation:

Summary by CodeRabbit

  • New Features

    • Added configurable activation checkpointing for training workflows.
    • Supports enabled, disabled, full, and selective checkpointing modes.
    • Configuration is available through training settings and API schemas.
    • When unspecified, existing embedding-model fallback behavior is preserved.
  • Bug Fixes

    • Explicit checkpointing settings are now consistently applied throughout training configuration.
  • Tests

    • Added coverage for enabled, disabled, full, selective, and unset configurations.

Automodel supports activation checkpointing end to end — the finetune
recipe reads `distributed.activation_checkpointing` off the config
(recipes/_dist_utils.py) and normalizes bool | "full" | "selective" — but
the platform had no way to set it, and FSDP2Config defaults it to False.
Every customization job therefore trained with it off.

That blocks porting the NVIDIA Nemotron LoRA cookbooks, which set
`activation_checkpointing: true`; the Nemotron 3 Super recipe annotates it
"reduces peak memory (avoids OOM on 80GB)".

Adds the field alongside expert_parallel_size at each layer it already
travels through: plugin schema, adapter, service API schema, compiler, task
config, and YAML emission.

Typed bool | Literal["full", "selective"] | None to match what Automodel
parses, rather than a plain bool, so selective checkpointing — the cheaper
mode — stays reachable.

Defaults to None and is omitted from the emitted YAML when unset, so
existing jobs compile byte-identically; the 15 golden contract configs are
unchanged. An explicit false is still emitted, to distinguish "user turned
it off" from "not configured".

Note the pre-existing embedding branch it now precedes is unreachable:
`embedding_config` is a bare EmbeddingConfig() that is never populated, so
`do_gradient_checkpointing` is always False. It is left in place as the
fallback in case that config is ever wired up.

Not included: OpenAPI regeneration (`make refresh-openapi`) and the
Stainless SDK sync, which need to run before the field reaches the CLI,
Python SDK, or Studio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Henrique Tolentino <htolentino@nvidia.com>
@htolentino-nvidia
htolentino-nvidia requested review from a team as code owners August 12, 2026 15:27
@github-actions github-actions Bot added the feat label Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Activation checkpointing now accepts boolean and "full" or "selective" modes. The setting propagates from plugin and API schemas through training compilation to backend configuration, with fallback behavior when unset.

Changes

Activation checkpointing

Layer / File(s) Summary
Configuration contracts and propagation
plugins/nemo-automodel/src/nemo_automodel_plugin/schema.py, services/automodel/src/nmp/automodel/api/v2/jobs/schemas.py, services/automodel/src/nmp/automodel/app/jobs/training/schemas.py, services/automodel/src/nmp/automodel/adapter.py, services/automodel/src/nmp/automodel/app/jobs/training/compiler.py, plugins/nemo-customizer/openapi/openapi.yaml
Schemas accept bool, "full", "selective", or None. Adapters and compilers propagate the value. The OpenAPI schema exposes the same setting.
Backend checkpointing selection
services/automodel/src/nmp/automodel/tasks/training/backends/config.py
Explicit values control distributed activation checkpointing. Unset values preserve the embedding-model gradient-checkpointing fallback.
Propagation and backend validation
services/automodel/tests/tasks/training/backends/test_config.py, services/automodel/tests/test_adapter.py
Tests cover unset, boolean, "full", and "selective" values, including explicit False and adapter defaults.

Suggested reviewers: a2bondar, aahunt-nv, ajaythorve

Sequence Diagram(s)

sequenceDiagram
  participant AutomodelConfig
  participant TrainingCompiler
  participant BackendConfig
  participant DistributedTraining
  AutomodelConfig->>TrainingCompiler: activation_checkpointing
  TrainingCompiler->>BackendConfig: ParallelismConfig
  BackendConfig->>DistributedTraining: explicit checkpointing mode
  BackendConfig->>DistributedTraining: fallback when setting is unset
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes exposing activation_checkpointing for Automodel customization jobs.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch automodel-activation-checkpointing/htolentino

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
services/automodel/src/nmp/automodel/app/jobs/training/compiler.py (1)

173-182: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Omit unset activation_checkpointing from PlatformJobStep.config.

model_dump(mode="json") includes None, but backend tests require the unset key to be absent. Remove only parallelism.activation_checkpointing when its value is None; preserve explicit False and string modes. Add compiler coverage for all three cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/automodel/src/nmp/automodel/app/jobs/training/compiler.py` around
lines 173 - 182, Update the compiler flow constructing
TrainingStepConfig.ParallelismConfig so parallelism.activation_checkpointing is
omitted from the serialized PlatformJobStep.config when unset (None), while
preserving explicit False and string modes; add compiler coverage for unset,
False, and string values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@services/automodel/src/nmp/automodel/app/jobs/training/compiler.py`:
- Around line 173-182: Update the compiler flow constructing
TrainingStepConfig.ParallelismConfig so parallelism.activation_checkpointing is
omitted from the serialized PlatformJobStep.config when unset (None), while
preserving explicit False and string modes; add compiler coverage for unset,
False, and string values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4b22ddda-a099-4a61-8e4b-2fdeaca0aabd

📥 Commits

Reviewing files that changed from the base of the PR and between 95f9fb1 and bebd07d.

📒 Files selected for processing (8)
  • plugins/nemo-automodel/src/nemo_automodel_plugin/schema.py
  • services/automodel/src/nmp/automodel/adapter.py
  • services/automodel/src/nmp/automodel/api/v2/jobs/schemas.py
  • services/automodel/src/nmp/automodel/app/jobs/training/compiler.py
  • services/automodel/src/nmp/automodel/app/jobs/training/schemas.py
  • services/automodel/src/nmp/automodel/tasks/training/backends/config.py
  • services/automodel/tests/tasks/training/backends/test_config.py
  • services/automodel/tests/test_adapter.py

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 32015/40717 78.6% 63.4%
Integration Tests 18567/38643 48.0% 20.8%

Runs script/generate-openapi-spec.sh after adding the field, adding
activation_checkpointing to AutomodelParallelismSpec in the customizer
plugin spec as anyOf[boolean, enum[full, selective]].

Only the plugin spec changes; openapi/openapi.yaml is untouched because the
customization API is served through the plugin router. No drift beyond the
new field.

The Stainless sync for the Python SDK is not included — it needs
STAINLESS_API_KEY and is a separate maintainer step.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Henrique Tolentino <htolentino@nvidia.com>

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/nemo-customizer/openapi/openapi.yaml`:
- Around line 1583-1585: Update the source schema description for
activation_checkpointing to state that omission preserves the embedding-model
fallback, while an explicit false disables activation checkpointing; then
regenerate the OpenAPI file so the generated description matches the backend
contract.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 67900e29-e0fd-4cc2-83ec-20147ffae0d4

📥 Commits

Reviewing files that changed from the base of the PR and between bebd07d and f0d540e.

📒 Files selected for processing (1)
  • plugins/nemo-customizer/openapi/openapi.yaml

Comment on lines +1583 to +1585
description: Recompute activations during the backward pass to cut peak
memory at the cost of speed. 'selective' checkpoints only the most memory-heavy
ops. Left unset, Automodel defaults to disabled.

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Document the unset fallback correctly.

When activation_checkpointing is omitted, the backend preserves the embedding-model fallback. An explicit false disables activation checkpointing. Update the source schema description before regenerating this file.

Suggested wording
-            ops. Left unset, Automodel defaults to disabled.
+            ops. When unset, Automodel uses its model-specific default; set
+            false to disable activation checkpointing explicitly.

The supplied backend contract and plugins/nemo-automodel/src/nemo_automodel_plugin/schema.py:122-137 distinguish omitted values from explicit false.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
description: Recompute activations during the backward pass to cut peak
memory at the cost of speed. 'selective' checkpoints only the most memory-heavy
ops. Left unset, Automodel defaults to disabled.
description: Recompute activations during the backward pass to cut peak
memory at the cost of speed. 'selective' checkpoints only the most memory-heavy
ops. When unset, Automodel uses its model-specific default; set
false to disable activation checkpointing explicitly.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-customizer/openapi/openapi.yaml` around lines 1583 - 1585,
Update the source schema description for activation_checkpointing to state that
omission preserves the embedding-model fallback, while an explicit false
disables activation checkpointing; then regenerate the OpenAPI file so the
generated description matches the backend contract.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant