ayh015's picture
Upload folder using huggingface_hub
6011e08 verified
Raw
History Blame Contribute Delete
3.33 kB
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
import argparse
import dataclasses
from dataclasses import dataclass
import yaml
@dataclass
class FSDPArgs:
# Optim
optimizer: str = "adam" # Optimizer type: "adam" (AdamW)
lr: float = 2e-5
lr_warmup_init: float = 0.0
min_lr: float = 0.0
lr_decay_style: str = "constant"
lr_decay_iters: int | None = None
lr_warmup_iters: int = 0
lr_warmup_fraction: float | None = None
lr_wsd_decay_iters: int | None = None
lr_wsd_decay_style: str | None = None
use_checkpoint_lr_scheduler: bool = True
override_lr_scheduler: bool = False
weight_decay: float = 0.0
adam_beta1: float = 0.9
adam_beta2: float = 0.95
adam_eps: float = 1e-8
warmup_ratio: float = 0.03
attn_implementation: str = "flash_attention_2"
# Logging
wandb_project: str = "slime-fsdp"
wandb_run_name: str | None = None
# Precision
gradient_checkpointing: bool = False
fp16: bool = False
# FSDP configuration
fsdp_state_dict_cpu_offload: bool = True # If True, offload full state dict to CPU during collection.
fsdp_cpu_offload: bool = (
False # If True, offload parameters, gradients, and optimizer states to CPU (optimizer runs on CPU)
)
fsdp_cpu_backend: str | None = (
"gloo" # CPU backend for FSDP CPU offload (e.g., "gloo"). Set to None to disable hybrid backend.
)
deterministic_mode: bool = False # This name must be the same as Megatron's
# Context Parallelism
context_parallel_size: int = 1 # Context Parallelism size
# Profile
record_memory_history: bool = False
memory_snapshot_path: str = "snapshot.pickle"
use_pytorch_profiler: bool = False
profile_step_start: int = 10
profile_step_end: int = 12
tensorboard_dir: str | None = None
# YAML bookkeeping
config: str | None = None
def parse_fsdp_cli(extra_args_provider=None):
parser = argparse.ArgumentParser("FSDP Training (slime)")
parser.add_argument("--config", type=str, default=None, help="YAML config path")
for f in dataclasses.fields(FSDPArgs):
if f.name == "config":
continue
# Handle union types like int | None, str | None, etc.
if hasattr(f.type, "__args__"): # Check if it's a Union type
# For T | None, use T as the type
non_none_types = [t for t in f.type.__args__ if t is not type(None)]
arg_type = non_none_types[0] if non_none_types else str
else:
arg_type = f.type
if arg_type is bool:
parser.add_argument(f"--{f.name.replace('_', '-')}", action="store_true")
else:
parser.add_argument(f"--{f.name.replace('_', '-')}", type=arg_type, default=f.default)
if extra_args_provider is not None:
parser = extra_args_provider(parser)
args = parser.parse_args()
return args
def load_fsdp_args(extra_args_provider=None):
args = parse_fsdp_cli(extra_args_provider)
if args.config:
with open(args.config) as f:
data = yaml.safe_load(f) or {}
for k, v in data.items():
if not hasattr(args, k):
setattr(args, k, v)
return args