MCPcopy Create free account
hub / github.com/deepspeedai/DeepSpeed / _exec_forward_pass

Method _exec_forward_pass

deepspeed/runtime/pipe/engine.py:718–809  ·  view source on GitHub ↗
(self, buffer_id)

Source from the content-addressed store, hash-verified

716 return batch
717
718 def _exec_forward_pass(self, buffer_id):
719 self.tput_timer.start()
720
721 if isinstance(self.pipe_buffers['inputs'][buffer_id], tuple):
722 inputs = tuple(t.clone() for t in self.pipe_buffers['inputs'][buffer_id])
723 else:
724 inputs = self.pipe_buffers['inputs'][buffer_id].clone()
725
726 # collect the partitioned input from the previous stage
727 if self.is_pipe_partitioned and not self.is_first_stage():
728 if self.pipe_partition_input_meta_cache is None:
729 self.pipe_partition_input_meta_cache = inputs[0].to('cpu')
730 part_input = PartitionedTensor.from_meta(meta=self.pipe_partition_input_meta_cache,
731 local_part=inputs[1],
732 group=self.grid.get_slice_parallel_group())
733
734 inputs = (part_input.full(), *inputs[2:])
735 inputs[0].requires_grad = True
736 # skip mask
737 #inputs[1].requires_grad = True
738 part_input = None
739 inputs = inputs[0] if len(inputs) == 1 else inputs
740 self.pipe_buffers['inputs'][buffer_id] = inputs
741
742 # inputs has no gradient because it is from a cloned tensor
743 outputs = super().forward(inputs)
744
745 # Reset activation checkpointing buffers.
746 # Need to call this between evaluation iterations
747 if not self.module.training:
748 ds_checkpointing.reset()
749
750 # Partition the outputs if we are not the last stage
751 if self.is_pipe_partitioned and not self.is_last_stage():
752 if isinstance(outputs, tuple):
753 first_output = outputs[0]
754 # TODO: Improve pipe partitioning to pass multiple tensors that require grads
755 assert all([torch.is_tensor(elt) and elt.requires_grad is False for elt in outputs[1:]])
756 outputs_tail = outputs[1:]
757 elif torch.is_tensor(outputs):
758 first_output = outputs
759 outputs_tail = []
760 else:
761 raise ValueError("expecting a tensor or a tuple of tensors")
762 part = PartitionedTensor(tensor=first_output, group=self.grid.get_slice_parallel_group())
763 # Clear the large output data, but save the computation graph
764 first_output.data = torch.zeros(1, device=first_output.data.device)
765 self.pipe_buffers['output_tensors'][buffer_id] = first_output
766 # Inject the partitioned tensor into the output before sending
767 outputs = (part.to_meta(), part.data(), *outputs_tail)
768 part = None
769
770 self.pipe_buffers['outputs'][buffer_id] = outputs
771
772 # Optionally compute loss on the last device
773 if self.is_last_stage():
774 if self._compute_loss and self.module.loss_fn is not None:
775 labels = self.pipe_buffers['labels'][buffer_id]

Callers

nothing calls this directly

Calls 15

is_first_stageMethod · 0.95
is_last_stageMethod · 0.95
to_metaMethod · 0.95
dataMethod · 0.95
PartitionedTensorClass · 0.85
from_metaMethod · 0.80
fullMethod · 0.80
appendMethod · 0.80
startMethod · 0.45
toMethod · 0.45
forwardMethod · 0.45

Tested by

no test coverage detected