NeMo
KexuanShi's picture
Upload folder using huggingface_hub
88e6849 verified
Raw
History Blame Contribute Delete
3.59 kB
# Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
from __future__ import annotations
"""
High-level refit/reshard orchestration:
- swap_model_weights: public API; accepts a backend name or CopyService and delegates.
- reshard_model_weights: transport-agnostic core; builds/caches plan and executes.
"""
from typing import Any, Literal, Optional, Union
from megatron.core import parallel_state
from megatron.core.models.common.language_module.language_module import LanguageModule
from megatron.core.utils import unwrap_model
from . import build_centralized_reshard_plan, execute_reshard_plan
from .copy_services.base import CopyService
from .copy_services.gloo_copy_service import GlooCopyService
from .copy_services.nccl_copy_service import NCCLCopyService
# Supported refit backend names
RefitBackendName = Literal["nccl", "gloo"]
def swap_model_weights(
src_model: LanguageModule,
target_model: LanguageModule,
refit_method: Union[RefitBackendName, CopyService],
):
"""
Orchestrate weight swap/refit.
- refit_method can be:
* a string backend name (one of the supported refit backends), or
* a CopyService instance.
"""
if isinstance(refit_method, CopyService):
service = refit_method
reshard_model_weights(src_model, target_model, service=service)
elif isinstance(refit_method, str):
if refit_method == "nccl":
service = NCCLCopyService()
reshard_model_weights(src_model, target_model, service=service)
elif refit_method == "gloo":
# Debug / fallback backend: run refit over CPU/Gloo instead of NCCL.
service = GlooCopyService()
reshard_model_weights(src_model, target_model, service=service)
else:
raise ValueError(f"Unknown refit_method '{refit_method}'")
else:
raise TypeError("refit_method must be a str backend name or a CopyService instance")
def reshard_model_weights(
src_model: LanguageModule, target_model: LanguageModule, service: CopyService
):
"""Reshard and copy model weights from ``src_model`` to ``target_model`` using ``service``."""
# Handle list-wrapped modules used throughout training utils
src_lm = src_model[0] if isinstance(src_model, (list, tuple)) else src_model
tgt_lm = target_model[0] if isinstance(target_model, (list, tuple)) else target_model
num_experts = src_lm.config.num_moe_experts
# Unwrap to get owning modules (with parameters and pg_collection)
src_core = unwrap_model(src_lm)
tgt_core = unwrap_model(tgt_lm)
# Ensure pg_collection exists
if not hasattr(src_core, "pg_collection") or src_core.pg_collection is None:
raise RuntimeError("Source model missing pg_collection required for NCCL reshard")
if not hasattr(tgt_core, "pg_collection") or tgt_core.pg_collection is None:
raise RuntimeError("Target model missing pg_collection required for NCCL reshard")
# Fill missing DP group on the source using Megatron's parallel state if not provided
if getattr(src_core.pg_collection, "dp", None) is None:
src_core.pg_collection.dp = parallel_state.get_data_parallel_group()
# caching plan for reuse
cached_plan: Optional[Any] = getattr(tgt_core, "_cached_reshard_plan", None)
if cached_plan is None:
plan = build_centralized_reshard_plan(src_core, tgt_core, num_experts=num_experts)
setattr(tgt_core, "_cached_reshard_plan", plan)
else:
plan = cached_plan
execute_reshard_plan(plan, src_core, tgt_core, service=service)