def fit(self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 10, **kwargs) -> None:
        """
        Fit the estimator on the training set `(x, y)`.

        :param x: Samples of shape (nb_samples, seq_length). Note that, it is allowable that sequences in the batch
                  could have different lengths. A possible example of `x` could be:
                  `x = np.array([np.array([0.1, 0.2, 0.1, 0.4]), np.array([0.3, 0.1])])`.
        :param y: Target values of shape (nb_samples). Each sample in `y` is a string, and it may possess different
                  lengths. A possible example of `y` could be: `y = np.array(['SIXTY ONE', 'HELLO'])`.
        :param batch_size: Size of batches.
        :param nb_epochs: Number of epochs to use for training.
        :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for PyTorch
               and providing it takes no effect.
        """
        import random

        # Apply preprocessing
        x_preprocessed, _ = self._apply_preprocessing(x, None, fit=True)
        y_preprocessed = y

        x_in = np.empty(len(x_preprocessed), dtype=object)
        x_in[:] = list(x_preprocessed)

        # Put the model in the training mode
        self._model.train()

        if self.optimizer is None:  # pragma: no cover
            raise ValueError("An optimizer is required to train the model, but none was provided.")

        # Train with batch processing
        num_batch = int(np.ceil(len(x_preprocessed) / float(batch_size)))
        ind = np.arange(len(x_preprocessed)).tolist()

        # Start training
        for _ in range(nb_epochs):
            # Shuffle the examples
            random.shuffle(ind)

            # Train for one epoch
            for m in range(num_batch):
                # Batch indexes
                begin, end = (
                    m * batch_size,
                    min((m + 1) * batch_size, x_preprocessed.shape[0]),
                )

                # Extract random batch
                i_batch = np.empty(len(x_preprocessed[ind[begin:end]]), dtype=object)
                i_batch[:] = list(x_preprocessed[ind[begin:end]])
                o_batch = y_preprocessed[ind[begin:end]]

                # Transform data into the model input space
                inputs, targets, input_rates, target_sizes, _ = self._transform_model_input(
                    x=i_batch, y=o_batch, compute_gradient=False
                )

                # Compute real input sizes
                input_sizes = input_rates.mul_(inputs.size(-1)).int()

                # Zero the parameter gradients
                self.optimizer.zero_grad()

                # Call to DeepSpeech model for prediction
                outputs, output_sizes, _ = self._model(inputs.to(self._device), input_sizes.to(self._device))
                outputs = outputs.transpose(0, 1)

                if self._version == 2:
                    outputs = outputs.float()
                else:
                    outputs = outputs.log_softmax(-1)

                # Compute the loss
                loss = self.criterion(outputs, targets, output_sizes, target_sizes).to(self._device)

                # Average the loss by mini batch if version 2 of DeepSpeech is used
                if self._version == 2:
                    loss = loss / inputs.size(0)

                # Actual training
                if self.use_amp:  # pragma: no cover
                    from apex import amp

                    with amp.scale_loss(loss, self.optimizer) as scaled_loss:
                        scaled_loss.backward()

                else:
                    loss.backward()

                self.optimizer.step()

        Fit the estimator on the training set `(x, y)`.

        :param x: Samples of shape (nb_samples, seq_length). Note that, it is allowable that sequences in the batch
                  could have different lengths. A possible example of `x` could be:
                  `x = np.array([np.array([0.1, 0.2, 0.1, 0.4]), np.array([0.3, 0.1])])`.
        :param y: Target values of shape (nb_samples). Each sample in `y` is a string, and it may possess different
                  lengths. A possible example of `y` could be: `y = np.array(['SIXTY ONE', 'HELLO'])`.
        :param batch_size: Size of batches.
        :param nb_epochs: Number of epochs to use for training.
        :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for PyTorch
               and providing it takes no effect.
        
art/estimators/speech_recognition/pytorch_deep_speech.py