Skip to content

Commit 55f9443

Browse files
committed
perf: reduce redundant CUDA initialization and synchronization
- defer loss host synchronization until after backward across training paths - skip zero fills when CUDA kernels or cuBLAS fully overwrite outputs - retain and document initialization required by partial-write paths - add CPU and CUDA numerical tests for affected operators
1 parent 751a7b8 commit 55f9443

21 files changed

Lines changed: 252 additions & 34 deletions

example/gpt2/main.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,10 @@ void Train(const nn::parallel::Rank &rank) {
479479

480480
LOG(INFO) << "Rank " << rank.GlobalRank() << ": finish loss forward";
481481

482-
auto loss_cpu = loss->To(Device());
483-
lossf += static_cast<const float *>(loss_cpu.DataPtr())[0];
484482
LOG(INFO) << "Rank " << rank.GlobalRank() << ": start backward";
485483
loss->Backward();
484+
auto loss_cpu = loss->To(Device());
485+
lossf += static_cast<const float *>(loss_cpu.DataPtr())[0];
486486
LOG(INFO) << "Rank " << rank.GlobalRank() << ": finish backward";
487487
}
488488

example/llama3/main.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,10 +456,10 @@ void Train(const nn::parallel::Rank &rank) {
456456

457457
LOG(INFO) << "Rank " << rank.GlobalRank() << ": finish loss forward";
458458

459-
auto loss_cpu = loss->To(Device());
460-
lossf += static_cast<const float *>(loss_cpu.DataPtr())[0];
461459
LOG(INFO) << "Rank " << rank.GlobalRank() << ": start backward";
462460
loss->Backward();
461+
auto loss_cpu = loss->To(Device());
462+
lossf += static_cast<const float *>(loss_cpu.DataPtr())[0];
463463
LOG(INFO) << "Rank " << rank.GlobalRank() << ": finish backward";
464464
}
465465

example/mixtral/main.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ int main(int argc, char *argv[]) {
133133
auto y = std::make_shared<Tensor>(y_cpu->To(train_device));
134134
auto logits = (*model)({x})[0];
135135
auto loss = (*loss_fn)({logits, y})[0];
136-
auto loss_cpu = loss->To(Device());
137-
lossf += static_cast<const float *>(loss_cpu.DataPtr())[0] / grad_accum_steps;
138136
loss = loss / static_cast<float>(grad_accum_steps);
139137
autocast_guard.Disable();
140138
loss->Backward();
139+
auto loss_cpu = loss->To(Device());
140+
lossf += static_cast<const float *>(loss_cpu.DataPtr())[0];
141141
}
142142
optimizer->Step();
143143

example/mnist/main.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ int main(int argc, char *argv[]) {
7070
optimizer.ZeroGrad();
7171

7272
auto loss = loss_fn.Forward({outputs[0], new_label});
73+
loss[0]->Backward();
74+
7375
auto loss_cpu = loss[0]->To(cpu_device);
7476
float current_loss = static_cast<float *>(loss_cpu.DataPtr())[0];
7577
total_loss += current_loss;
@@ -79,7 +81,6 @@ int main(int argc, char *argv[]) {
7981
<< " loss: " << current_loss;
8082
}
8183

82-
loss[0]->Backward();
8384
optimizer.Step();
8485
train_idx += 1;
8586
}

infini_train/src/kernels/cuda/concat.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ std::vector<std::shared_ptr<Tensor>> ConcatBackward(const std::shared_ptr<Tensor
186186
grads.reserve(input_dims_list.size());
187187
for (const auto &dvec : input_dims_list) {
188188
auto t = std::make_shared<Tensor>(dvec, dtype, device);
189-
t->Fill(0.0);
189+
// ConcatBackwardKernel maps every grad_output element to exactly one grad tensor element; no Fill is needed.
190190
grads.push_back(t);
191191
}
192192

infini_train/src/kernels/cuda/cross_entropy.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ std::shared_ptr<Tensor> CrossEntropyBackward(const std::shared_ptr<Tensor> &inpu
204204
DataTypeList<INFINI_ALL_FLOATING_TYPES>>(
205205
{target->Dtype(), input_casted->Dtype()},
206206
[=]<typename Ttarget, typename Tinput>() {
207-
grad_input->Fill(0.0);
207+
// One sample block writes all of its num_classes gradient elements; no Fill is needed.
208208
const Tinput *output_grad_ptr = static_cast<const Tinput *>(grad_output->DataPtr());
209209
const Ttarget *target_ptr = static_cast<const Ttarget *>(target->DataPtr());
210210
const Tinput *input_ptr = static_cast<const Tinput *>(input_casted->DataPtr());

infini_train/src/kernels/cuda/layernorm.cu

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ LayerNormForward(const std::shared_ptr<Tensor> &input, const std::shared_ptr<Ten
8989
core::cuda::DispatchCudaFunc<INFINI_ALL_FLOATING_TYPES>(
9090
dtype,
9191
[=]<typename T>() {
92-
mean->Fill(0.0);
93-
rstd->Fill(0.0);
92+
// Each token block writes its mean and rstd exactly once; no Fill is needed.
9493
LayerNormForwardKernel<BLOCK_SIZE><<<num_blocks, threads_per_block, 0, cuda_stream>>>(
9594
static_cast<const T *>(input->DataPtr()), static_cast<const T *>(weight->DataPtr()),
9695
static_cast<const T *>(bias->DataPtr()), static_cast<float *>(mean->DataPtr()),
@@ -183,7 +182,7 @@ LayerNormBackward(const std::shared_ptr<Tensor> &input, const std::shared_ptr<Te
183182
core::cuda::DispatchCudaFunc<INFINI_ALL_FLOATING_TYPES>(
184183
dtype,
185184
[=]<typename T>() {
186-
grad_input->Fill(0.0);
185+
// Each token block writes its complete grad_input slice; no Fill is needed.
187186
grad_weight->Fill(0.0);
188187
grad_bias->Fill(0.0);
189188
LayerNormBackwardKernel<BLOCK_SIZE><<<num_blocks, threads_per_block, 0, cuda_stream>>>(

infini_train/src/kernels/cuda/linear.cu

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ std::shared_ptr<Tensor> LinearForward(const std::shared_ptr<Tensor> &input, cons
6565
infini_train::core::GetDeviceGuardImpl(device.type())->GetStream(device))
6666
->cuda_stream();
6767

68+
const float beta = bias ? 1.0f : 0.0f;
6869
if (bias) {
6970
CHECK_EQ(bias->Dims().size(), 1);
7071
CHECK_EQ(bias->Dims()[0], out_features);
@@ -78,9 +79,8 @@ std::shared_ptr<Tensor> LinearForward(const std::shared_ptr<Tensor> &input, cons
7879
static_cast<T *>(output->DataPtr()), static_cast<const T *>(bias->DataPtr()), bs, out_features);
7980
},
8081
"CUDA LinearForward");
81-
} else {
82-
output->Fill(0.0);
8382
}
83+
// In the no-bias path, beta=0 makes cuBLAS fully overwrite output; no Fill is needed.
8484

8585
// When bs==1 and fp32, use cublasSgemv (more efficient than GEMM for matrix-vector).
8686
// cublasSgemv does not support bf16, so bf16 falls through to Gemm.
@@ -94,7 +94,7 @@ std::shared_ptr<Tensor> LinearForward(const std::shared_ptr<Tensor> &input, cons
9494
.x = static_cast<const float *>(input->DataPtr()),
9595
.y = static_cast<float *>(output->DataPtr()),
9696
.alpha = 1.0f,
97-
.beta = 1.0f, // output already initialized with bias or zero above
97+
.beta = beta,
9898
});
9999
} else {
100100
// cuBLAS is colmun-major
@@ -125,7 +125,7 @@ std::shared_ptr<Tensor> LinearForward(const std::shared_ptr<Tensor> &input, cons
125125
.C = output->DataPtr(),
126126
.ldc = static_cast<int>(out_features),
127127
.alpha = 1.0f,
128-
.beta = 1.0f, // bias already written into output; beta=1 accumulates
128+
.beta = beta,
129129
.batch_count = 1,
130130
.input_dtype = dtype,
131131
.output_dtype = dtype,

infini_train/src/kernels/cuda/reduction.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ std::shared_ptr<Tensor> ReduceOpBackward(const std::shared_ptr<Tensor> &grad_out
181181
core::cuda::DispatchCudaFunc<INFINI_ALL_FLOATING_TYPES>(
182182
dtype,
183183
[=]<typename T>() {
184-
grad_input->Fill(0.0);
184+
// The backward kernel assigns every grad_input element on all reduction branches; no Fill is needed.
185185
GenericReduceBackwardKernel<<<num_blocks, threads_per_block, 0, cuda_stream>>>(
186186
static_cast<T *>(grad_input->DataPtr()), static_cast<const T *>(grad_output->DataPtr()),
187187
input ? static_cast<const T *>(input->DataPtr()) : nullptr,

infini_train/src/kernels/cuda/slice.cu

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ std::shared_ptr<Tensor> SliceForward(const std::shared_ptr<Tensor> &input, const
4848

4949
auto dtype = input->Dtype();
5050
auto new_tensor = std::make_shared<Tensor>(new_dims, dtype, input->GetDevice());
51-
// NOTE(zbl): must initialize with 0
52-
new_tensor->Fill(0.0);
51+
// SliceForwardKernel writes every output index in [0, total_elements); no Fill is needed.
5352

5453
std::vector<int64_t> src_strides(dims.size(), 0), dst_strides(new_dims.size(), 0);
5554
int64_t stride = 1;

0 commit comments

Comments
 (0)