def fit(
        self,
        series: Union[TimeSeries, Sequence[TimeSeries]],
        past_covariates: Optional[Union[TimeSeries, Sequence[TimeSeries]]] = None,
        future_covariates: Optional[Union[TimeSeries, Sequence[TimeSeries]]] = None,
        sample_weight: Optional[Union[TimeSeries, Sequence[TimeSeries], str]] = None,
    ):
        """
        Fits the forecasting models with the entire series except the last `regression_train_n_points` values, which
        are used to train the regression model.

        If `forecasting_models` contains fitted `GlobalForecastingModels` and `train_forecasting_model=False`,
        only the regression model will be trained.

        Parameters
        ----------
        series
            TimeSeries or Sequence[TimeSeries] object containing the target values.
        past_covariates
            Optionally, a series or sequence of series specifying past-observed covariates passed to the
            forecasting models
        future_covariates
            Optionally, a series or sequence of series specifying future-known covariates passed to the
            forecasting models
        sample_weight
            Optionally, some sample weights to apply to the target `series` labels. They are applied per observation,
            per label (each step in `output_chunk_length`), and per component.
            If a series or sequence of series, then those weights are used. If the weight series only have a single
            component / column, then the weights are applied globally to all components in `series`. Otherwise, for
            component-specific weights, the number of components must match those of `series`.
            If a string, then the weights are generated using built-in weighting functions. The available options are
            `"linear"` or `"exponential"` decay - the further in the past, the lower the weight. The weights are
            computed globally based on the length of the longest series in `series`. Then for each series, the weights
            are extracted from the end of the global weights. This gives a common time weighting across all series.
        """
        super().fit(
            series, past_covariates=past_covariates, future_covariates=future_covariates
        )

        # spare train_n_points points to serve as regression target
        is_single_series = isinstance(series, TimeSeries)
        if self.train_n_points == -1:
            if is_single_series:
                train_n_points = [len(series)]
            else:
                # maximize each series usage
                train_n_points = [len(ts) for ts in series]

            # shift by the forecasting models' largest input length
            all_shifts = []
            # when it's not clearly defined, extreme_lags returns
            # `min_train_series_length` for the LocalForecastingModels
            for model in self.forecasting_models:
                min_target_lag, _, _, _, _, _, _, _ = model.extreme_lags
                if min_target_lag is not None:
                    all_shifts.append(-min_target_lag)

            input_shift = max(all_shifts)
            idx_series_too_short = []
            tmp_train_n_points = []
            for idx, ts_length in enumerate(train_n_points):
                ajusted_length = ts_length - input_shift
                if ajusted_length < 0:
                    idx_series_too_short.append(idx)
                else:
                    tmp_train_n_points.append(ajusted_length)

            raise_if(
                len(idx_series_too_short) > 0,
                f"TimeSeries at indexes {idx_series_too_short} of `series` are too short to train the regression "
                f"model due to the number of values necessary to produce one prediction : {input_shift}.",
                logger,
            )

            if is_single_series:
                self.train_n_points = tmp_train_n_points[0]
            else:
                self.train_n_points = tmp_train_n_points

            train_n_points_too_big = False
        else:
            # self.train_n_points is necessarily an integer
            if is_single_series:
                train_n_points_too_big = len(series) <= self.train_n_points
            else:
                train_n_points_too_big = any([
                    len(s) <= self.train_n_points for s in series
                ])

        raise_if(
            train_n_points_too_big,
            "`regression_train_n_points` parameter too big (must be strictly smaller than "
            "the number of points in training_series)",
            logger,
        )

        if is_single_series:
            forecast_training = series[: -self.train_n_points]
            regression_target = series[-self.train_n_points :]
        else:
            forecast_training, regression_target = self._split_multi_ts_sequence(
                self.train_n_points, series
            )

        if self.train_forecasting_models:
            for model in self.forecasting_models:
                # maximize covariate usage
                model._fit_wrapper(
                    series=forecast_training,
                    past_covariates=(
                        past_covariates if model.supports_past_covariates else None
                    ),
                    future_covariates=(
                        future_covariates if model.supports_future_covariates else None
                    ),
                    sample_weight=sample_weight
                    if model.supports_sample_weight
                    else None,
                )

        # we can call direct prediction in any case. Even if we overwrite with historical
        # forecasts later on, it serves as a input validation
        predictions = self._make_multiple_predictions(
            n=self.train_n_points,
            series=forecast_training,
            past_covariates=past_covariates,
            future_covariates=future_covariates,
            num_samples=self.train_num_samples,
        )

        if self.train_using_historical_forecasts:
            predictions = self._make_multiple_historical_forecasts(
                train_n_points=self.train_n_points,
                series=series,
                direct_predictions=predictions,
                past_covariates=past_covariates,
                future_covariates=future_covariates,
                num_samples=self.train_num_samples,
            )

        # train the regression model on the individual models' predictions
        self.regression_model.fit(
            series=regression_target,
            future_covariates=predictions,
            sample_weight=sample_weight,
        )

        # prepare the forecasting models for further predicting by fitting them with the entire data
        if self.train_forecasting_models:
            # Some models may need to be 'reset' to allow being retrained from scratch, especially torch-based models
            self.forecasting_models: list[ForecastingModel] = [
                model.untrained_model() for model in self.forecasting_models
            ]
            for model in self.forecasting_models:
                model._fit_wrapper(
                    series=series,
                    past_covariates=(
                        past_covariates if model.supports_past_covariates else None
                    ),
                    future_covariates=(
                        future_covariates if model.supports_future_covariates else None
                    ),
                    sample_weight=sample_weight
                    if model.supports_sample_weight
                    else None,
                )
        return self

        Fits the forecasting models with the entire series except the last `regression_train_n_points` values, which
        are used to train the regression model.

        If `forecasting_models` contains fitted `GlobalForecastingModels` and `train_forecasting_model=False`,
        only the regression model will be trained.

        Parameters
        ----------
        series
            TimeSeries or Sequence[TimeSeries] object containing the target values.
        past_covariates
            Optionally, a series or sequence of series specifying past-observed covariates passed to the
            forecasting models
        future_covariates
            Optionally, a series or sequence of series specifying future-known covariates passed to the
            forecasting models
        sample_weight
            Optionally, some sample weights to apply to the target `series` labels. They are applied per observation,
            per label (each step in `output_chunk_length`), and per component.
            If a series or sequence of series, then those weights are used. If the weight series only have a single
            component / column, then the weights are applied globally to all components in `series`. Otherwise, for
            component-specific weights, the number of components must match those of `series`.
            If a string, then the weights are generated using built-in weighting functions. The available options are
            `"linear"` or `"exponential"` decay - the further in the past, the lower the weight. The weights are
            computed globally based on the length of the longest series in `series`. Then for each series, the weights
            are extracted from the end of the global weights. This gives a common time weighting across all series.
        
darts/models/forecasting/regression_ensemble_model.py