Instructions to use KexuanShi/Megatron-LM with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- NeMo
How to use KexuanShi/Megatron-LM with NeMo:
# tag did not correspond to a valid NeMo domain.
- Notebooks
- Google Colab
- Kaggle
| # Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved. | |
| from __future__ import annotations | |
| import logging | |
| from typing import List, Tuple | |
| import torch | |
| import torch.distributed as dist | |
| from .copy_services.base import CopyService | |
| from .utils import ReshardPlan | |
| logger = logging.getLogger(__name__) | |
| def execute_reshard_plan( | |
| plan: ReshardPlan, | |
| src_module: torch.nn.Module, | |
| dst_module: torch.nn.Module, | |
| service: CopyService, | |
| ) -> None: | |
| """ | |
| Execute a reshard plan (from centralized controller). | |
| A communication service must be provided to abstract transport. | |
| Expected service API: submit_send(tensor, dest_rank), submit_recv(tensor, src_rank), run(). | |
| """ | |
| src_params = {name: p for name, p in src_module.named_parameters(recurse=True)} | |
| dst_params = {name: p for name, p in dst_module.named_parameters(recurse=True)} | |
| submit_send_with_id = getattr(service, "submit_send_with_id", None) | |
| submit_recv_with_id = getattr(service, "submit_recv_with_id", None) | |
| # Submit sends | |
| for op in plan.send_ops: | |
| src_param = src_params.get(op.param_name) | |
| if src_param is not None: | |
| src_view = src_param.data[op.my_slice].contiguous() | |
| if submit_send_with_id is not None and op.task_id is not None: | |
| submit_send_with_id(op.task_id, src_view, op.peer_rank) | |
| else: | |
| service.submit_send(src_view, op.peer_rank) | |
| # Submit recvs | |
| recv_writebacks: List[Tuple[torch.Tensor, torch.nn.Parameter, tuple[slice, ...]]] = [] | |
| for op in plan.recv_ops: | |
| dst_param = dst_params.get(op.param_name) | |
| if dst_param is not None: | |
| dst_slice_view = dst_param.data[op.my_slice] | |
| recv_buffer = torch.empty_like(dst_slice_view.contiguous()) | |
| if submit_recv_with_id is not None and op.task_id is not None: | |
| submit_recv_with_id(op.task_id, recv_buffer, op.peer_rank) | |
| else: | |
| service.submit_recv(recv_buffer, op.peer_rank) | |
| recv_writebacks.append((recv_buffer, dst_param, op.my_slice)) | |
| # Execute | |
| logger.info(f"Executing {len(plan.send_ops)} sends + {len(plan.recv_ops)} recvs") | |
| service.run() | |
| dist.barrier() | |
| # Write back received buffers into their destination parameter slices | |
| for recv_buffer, dst_param, dst_slice in recv_writebacks: | |
| with torch.no_grad(): | |
| dst_param.data[dst_slice].copy_(recv_buffer) | |
| logger.info("Reshard complete") | |