Skip to content

fix: fsdp_config validation being None#3061

Merged
winglian merged 3 commits into
mainfrom
feat/fsdp-validation
Aug 14, 2025
Merged

fix: fsdp_config validation being None#3061
winglian merged 3 commits into
mainfrom
feat/fsdp-validation

Conversation

@NanoCode012

@NanoCode012 NanoCode012 commented Aug 13, 2025

Copy link
Copy Markdown
Collaborator

Description

Had a minor report in Discord https://discord.com/channels/1104757954588196865/1111279858136383509/1403385346288259225 where fsdp_config was None which would lead to

  File "/workspace/axolotl/src/axolotl/utils/schemas/validation.py", line 1155, in check_gpt_oss_fsdp_loading
    data.get("fsdp_config", {}).get("cpu_ram_efficient_loading", False)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

This PR fixes the check.

Reason for error:

  1. We pass fsdp_config=None in merge_lora
    fsdp_config=None,
  2. The get( found the variable exists and returns that, even if it's None

Motivation and Context

How has this been tested?

Screenshots (if appropriate)

Types of changes

Social Handles (Optional)

Summary by CodeRabbit

  • Bug Fixes

    • Prevented errors when FSDP-related settings are missing or null by hardening validation and loading logic.
  • Refactor

    • Improved resilience of configuration parsing for FSDP options to handle absent or null configs safely.
  • Chores

    • Automatically migrate fsdp_version from nested FSDP settings to the top-level with a deprecation warning for smoother user transitions.

@coderabbitai

coderabbitai Bot commented Aug 13, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Refactors validation utilities to safely access a possibly missing fsdp_config by using a local fsdp_config = data.get("fsdp_config") or {}. Promotes nested fsdp_version to top-level with a deprecation log (popping it from the nested dict) and adjusts checks for activation_checkpointing / cpu_ram_efficient_loading. No API changes.

Changes

Cohort / File(s) Summary of changes
Validation utils
src/axolotl/utils/schemas/validation.py
Replace chained data.get("fsdp_config", {}).get(...) with fsdp_config = data.get("fsdp_config") or {} for None-safety; in check_fsdp_version_in_fsdp_config log deprecation and promote fsdp_version from fsdp_config to top-level (pop from nested dict); update check_fp8_config and check_gpt_oss_fsdp_loading to read keys from local fsdp_config.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~7 minutes

Possibly related PRs

Suggested labels

ready to merge

Suggested reviewers

  • SalmanMohammadi

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b5d034 and 156a32a.

📒 Files selected for processing (1)
  • src/axolotl/utils/schemas/validation.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/axolotl/utils/schemas/validation.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: PyTest (3.11, 2.7.1)
  • GitHub Check: PyTest (3.11, 2.7.0)
  • GitHub Check: PyTest (3.11, 2.6.0)
  • GitHub Check: pre-commit
  • GitHub Check: PyTest from Source Dist (3.11, 2.7.1)
  • GitHub Check: PyTest from Source Dist (3.11, 2.7.0)
  • GitHub Check: PyTest from Source Dist (3.11, 2.6.0)
  • GitHub Check: pre-commit
  • GitHub Check: preview
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/fsdp-validation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@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: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d45620 and 4b5d034.

📒 Files selected for processing (1)
  • src/axolotl/utils/schemas/validation.py (2 hunks)
🔇 Additional comments (1)
src/axolotl/utils/schemas/validation.py (1)

1154-1156: LGTM: None-safe fsdp_config access prevents AttributeError

Switching to a local fsdp_config = data.get("fsdp_config") or {} correctly guards against the case where fsdp_config exists but is set to None. This directly addresses the reported AttributeError.

Comment on lines +820 to +826
fsdp_config = data.get("fsdp_config") or {}
if fsdp_config and fsdp_config.get("fsdp_version"):
LOG.warning(
"Configuring `fsdp_version` in `fsdp_config` is deprecated. "
"Please configure `fsdp_version` as a top-level field."
)
data["fsdp_version"] = fsdp_config.pop("fsdp_version")

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.

🛠️ Refactor suggestion

Avoid silently overriding top-level fsdp_version when both are set; handle conflicts and reduce log spam

Current code promotes the nested value unconditionally, which can overwrite an explicitly-set top-level fsdp_version without warning if both are present and differ. Also, switch to warning_once to avoid repeated logs across multiple validations.

Proposed update:

  • If both top-level and nested fsdp_version exist and differ, keep the top-level and drop the nested with a warning about the conflict.
  • Otherwise, promote nested to top-level and pop it from fsdp_config.
  • Keep the None-safe pattern.
-        fsdp_config = data.get("fsdp_config") or {}
-        if fsdp_config and fsdp_config.get("fsdp_version"):
-            LOG.warning(
-                "Configuring `fsdp_version` in `fsdp_config` is deprecated. "
-                "Please configure `fsdp_version` as a top-level field."
-            )
-            data["fsdp_version"] = fsdp_config.pop("fsdp_version")
+        fsdp_config = data.get("fsdp_config") or {}
+        nested_version = fsdp_config.get("fsdp_version")
+        if nested_version is not None:
+            existing = data.get("fsdp_version")
+            if existing is not None and str(existing) != str(nested_version):
+                LOG.warning(
+                    "Conflicting `fsdp_version`: top-level=%s, fsdp_config=%s; "
+                    "keeping top-level and dropping nested.",
+                    existing,
+                    nested_version,
+                )
+                fsdp_config.pop("fsdp_version", None)
+            else:
+                LOG.warning_once(
+                    "Configuring `fsdp_version` in `fsdp_config` is deprecated. "
+                    "Please configure `fsdp_version` as a top-level field."
+                )
+                data["fsdp_version"] = fsdp_config.pop("fsdp_version")
📝 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
fsdp_config = data.get("fsdp_config") or {}
if fsdp_config and fsdp_config.get("fsdp_version"):
LOG.warning(
"Configuring `fsdp_version` in `fsdp_config` is deprecated. "
"Please configure `fsdp_version` as a top-level field."
)
data["fsdp_version"] = fsdp_config.pop("fsdp_version")
fsdp_config = data.get("fsdp_config") or {}
nested_version = fsdp_config.get("fsdp_version")
if nested_version is not None:
existing = data.get("fsdp_version")
if existing is not None and str(existing) != str(nested_version):
LOG.warning(
"Conflicting `fsdp_version`: top-level=%s, fsdp_config=%s; "
"keeping top-level and dropping nested.",
existing,
nested_version,
)
fsdp_config.pop("fsdp_version", None)
else:
LOG.warning_once(
"Configuring `fsdp_version` in `fsdp_config` is deprecated. "
"Please configure `fsdp_version` as a top-level field."
)
data["fsdp_version"] = fsdp_config.pop("fsdp_version")
🤖 Prompt for AI Agents
In src/axolotl/utils/schemas/validation.py around lines 820 to 826, the current
code unconditionally promotes a nested fsdp_version into the top-level which can
silently overwrite an explicit top-level value and spam logs; change the logic
to: read fsdp_config safely, if nested fsdp_version exists then check if data
already has a top-level fsdp_version — if both exist and differ, keep the
top-level value, pop the nested fsdp_config["fsdp_version"], and emit a single
warning_once describing the conflict and that the nested value was ignored;
otherwise (no top-level present) promote the nested value to
data["fsdp_version"], pop it from fsdp_config, and use warning_once for the
deprecation message when promoting.

Comment thread src/axolotl/utils/schemas/validation.py
@codecov

codecov Bot commented Aug 13, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.42857% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/axolotl/utils/schemas/validation.py 71.42% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions

Copy link
Copy Markdown
Contributor

📖 Documentation Preview: https://689c6dce7dc401466a7e45bc--resonant-treacle-0fd729.netlify.app

Deployed on Netlify from commit c77a96f

@winglian winglian merged commit 506e3a3 into main Aug 14, 2025
17 checks passed
@winglian winglian deleted the feat/fsdp-validation branch August 14, 2025 01:21
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.

3 participants