def predict_step(
        self,
        batch: TorchInferenceBatch,
        batch_idx: int,
        dataloader_idx: Optional[int] = None,
    ) -> Sequence[TimeSeries]:
        """performs the prediction step

        batch
            output of Darts' :class:`TorchInferenceDataset` - tuple of ``(past target, past cov,
            future past cov, historic future cov, future cov, static cov, target series schema,
            prediction start time step)``
        batch_idx
            the batch index of the current batch
        dataloader_idx
            the dataloader index
        """
        # batch has elements (past target, past cov, future past cov, historic future cov, future cov,
        # static cov, target series schema, pred start time)
        input_data_tuple, batch_series_schemas, batch_pred_starts = (
            batch[:-2],
            batch[-2],
            batch[-1],
        )

        # number of individual series to be predicted in current batch
        num_series = input_data_tuple[0].shape[0]

        # number of times the input tensor should be tiled to produce predictions for multiple samples
        # this variable is larger than 1 only if the batch_size is at least twice as large as the number
        # of individual time series being predicted in current batch (`num_series`)
        batch_sample_size = min(
            max(self.pred_batch_size // num_series, 1), self.pred_num_samples
        )

        # counts number of produced prediction samples for every series to be predicted in current batch
        sample_count = 0

        # repeat prediction procedure for every needed sample
        batch_predictions = []
        while sample_count < self.pred_num_samples:
            # make sure we don't produce too many samples
            if sample_count + batch_sample_size > self.pred_num_samples:
                batch_sample_size = self.pred_num_samples - sample_count

            # stack multiple copies of the tensors to produce probabilistic forecasts
            input_data_tuple_samples = self._sample_tiling(
                input_data_tuple, batch_sample_size
            )

            # get predictions for 1 whole batch (can include predictions of multiple series
            # and for multiple samples if a probabilistic forecast is produced)
            batch_prediction = self._get_batch_prediction(
                self.pred_n, input_data_tuple_samples, self.pred_roll_size
            )

            # reshape from 3d tensor (num_series x batch_sample_size, ...)
            # into 4d tensor (batch_sample_size, num_series, ...), where dim 0 represents the samples
            out_shape = batch_prediction.shape
            batch_prediction = batch_prediction.reshape(
                (
                    batch_sample_size,
                    num_series,
                )
                + out_shape[1:]
            )

            # save all predictions and update the `sample_count` variable
            batch_predictions.append(batch_prediction)
            sample_count += batch_sample_size

        # concatenate the batch of samples, to form self.pred_num_samples samples
        batch_predictions = torch.cat(batch_predictions, dim=0)
        batch_predictions = batch_predictions.cpu().detach().numpy()
        return (
            batch_predictions,
            batch_series_schemas,
            batch_pred_starts,
        )
performs the prediction step

        batch
            output of Darts' :class:`TorchInferenceDataset` - tuple of ``(past target, past cov,
            future past cov, historic future cov, future cov, static cov, target series schema,
            prediction start time step)``
        batch_idx
            the batch index of the current batch
        dataloader_idx
            the dataloader index
        
darts/models/forecasting/pl_forecasting_module.py