-
Notifications
You must be signed in to change notification settings - Fork 61
fix: fix grad accumulation/overlap under ZeRO-2 #213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
7611664
df14b83
b55969a
1dc3da0
a459eff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 实现放到 .cc 里。
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 改了 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,23 @@ | ||
| #include "infini_train/include/autograd/function_hook.h" | ||
|
|
||
| #include <utility> | ||
|
|
||
| #include "infini_train/include/nn/parallel/parallel_functional.h" | ||
| #include "infini_train/include/nn/parallel/process_group.h" | ||
| #include "infini_train/include/tensor.h" | ||
|
|
||
| namespace infini_train::autograd { | ||
| AllReducePostAccumulateHook::AllReducePostAccumulateHook(infini_train::nn::parallel::function::ReduceOpType reduce_op, | ||
| const infini_train::nn::parallel::ProcessGroup *pg) | ||
| const infini_train::nn::parallel::ProcessGroup *pg, | ||
| std::shared_ptr<const std::atomic_bool> enabled) | ||
| : reduce_op_(reduce_op), | ||
| pg_(pg ? pg : infini_train::nn::parallel::ProcessGroupFactory::Instance()->GetDefaultProcessGroup()) {} | ||
| pg_(pg ? pg : infini_train::nn::parallel::ProcessGroupFactory::Instance()->GetDefaultProcessGroup()), | ||
| enabled_(std::move(enabled)) {} | ||
|
|
||
| void AllReducePostAccumulateHook::operator()(const std::shared_ptr<Tensor> &tensor) { | ||
| if (enabled_ && !enabled_->load(std::memory_order_relaxed)) { | ||
| return; | ||
| } | ||
| infini_train::nn::parallel::function::AllReduce(tensor, reduce_op_, pg_); | ||
| } | ||
| } // namespace infini_train::autograd |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -146,6 +146,8 @@ void ParamAndGradBucketGroup::Reset() { | |
| } | ||
| } | ||
|
|
||
| void ParamAndGradBucketGroup::SetIsLastMicrobatch(bool is_last_microbatch) { is_last_microbatch_ = is_last_microbatch; } | ||
|
|
||
| void ParamAndGradBucketGroup::RegisterGradReady(const std::shared_ptr<Tensor> ¶meter) { | ||
| if (!ddp_config_.overlap_grad_reduce) { | ||
| LOG(WARNING) | ||
|
|
@@ -154,19 +156,23 @@ void ParamAndGradBucketGroup::RegisterGradReady(const std::shared_ptr<Tensor> &p | |
| return; | ||
| } | ||
|
|
||
| // TODO(zbl): Only register grads as ready and trigger grad sync when processing the last microbatch | ||
| // For now, is_last_microbatch_ is always true | ||
| // Only the last microbatch registers ready grads so the reduce can overlap with its backward pass. | ||
| if (is_last_microbatch_) { | ||
| if (!parameter || params_.find(parameter.get()) == params_.end()) { | ||
| return; | ||
| } | ||
|
|
||
| params_with_grad_.insert(parameter.get()); | ||
| // TODO(zbl): check this if sync is only done in last mircobatch | ||
| // if (!inserted) { | ||
| // LOG(FATAL) << "ParamAndGradBucketGroup: RegisterGradReady() was called twice for the same parameter in a | ||
| // bucket group."; return; | ||
| // } | ||
| if (grad_reduce_dispatched_) { | ||
| LOG(FATAL) << "ParamAndGradBucketGroup: RegisterGradReady() was called after grad sync was dispatched."; | ||
| return; | ||
| } | ||
|
|
||
| auto [_, inserted] = params_with_grad_.insert(parameter.get()); | ||
| if (!inserted) { | ||
| LOG(FATAL) << "ParamAndGradBucketGroup: RegisterGradReady() was called twice for the same parameter in a " | ||
| "bucket group."; | ||
| return; | ||
| } | ||
|
|
||
| if (params_with_grad_.size() == params_.size()) { | ||
| // All param grads are ready in this group, trigger grad sync | ||
|
|
@@ -297,8 +303,6 @@ void ParamAndGradBucketGroup::StartGradSync() { | |
| } | ||
|
|
||
| grad_reduce_dispatched_ = true; | ||
| // TODO(zbl): no need to clear params_with_grad_ here if grad sync is only done on last microbatch | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 我看注释里说如果只在 last microbatch sync 的话,这里就不需要 clear 了,但下面的 clear 没有删,确认下是否需要删除?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可以删,这块是忘删了。 |
||
| params_with_grad_.clear(); | ||
| } | ||
|
|
||
| void ParamAndGradBucketGroup::FinishGradSync() { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
实现放到 .cc 里。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
改了