docstr: Due to how lightwood implements the `update` procedure, expected inputs for this method are:
  
  :param dev_data: original `test` split (used to validate and select model if ensemble is `BestOf`).
  :param train_data: concatenated original `train` and `dev` splits.
  :param args: optional arguments to customize the finetuning process.
docstr_tok: ["Due","to","how","lightwood","implements","the","`","update","`","procedure",",","expected","inputs","for","this","method","are",":",":","param","dev_data",":","original","`","test","`","split","(","used","to","validate","and","select","model","if","ensemble","is","`","BestOf","`",")",".",":","param","train_data",":","concatenated","original","`","train","`","and","`","dev","`","splits",".",":","param","args",":","optional","arguments","to","customize","the","finetuning","process","."]
code: def partial_fit(
      self,
      train_data: EncodedDs,
      dev_data: EncodedDs,
      args: Optional[dict] = None,
  ) -> None:
      """
      Due to how lightwood implements the `update` procedure, expected inputs for this method are:
  
      :param dev_data: original `test` split (used to validate and select model if ensemble is `BestOf`).
      :param train_data: concatenated original `train` and `dev` splits.
      :param args: optional arguments to customize the finetuning process.
      """  # noqa
  
      # handle args
      if args is None:
          args = {}
      if args.get("n_epochs"):
          self.n_epochs = args["n_epochs"]
      if args.get("patience"):
          self.patience = args["patience"]
      self.estimator.trainer = Trainer(
          epochs=self.n_epochs,
          callbacks=[EarlyStop(patience=self.patience)],
      )
  
      # prepare data and fine-tune
      ds = ConcatedEncodedDs([train_data, dev_data])
      adjust_groups = (
          list(ds.data_frame[self.grouped_by[0]].unique())
          if self.grouped_by != ["__default"]
          else None
      )
      ds = self._make_initial_ds(
          ds.data_frame, phase="adjust", groups=adjust_groups
      )
      self.model = self.estimator.train_from(self.model, ds)
  
imports: import importlib
  from copy import deepcopy
  from typing import Dict, Union, Optional, List
  import numpy
  import pandas
  import mxnet
  from sklearn.preprocessing import OrdinalEncoder
  from gluonts.dataset.pandas import PandasDataset
  from gluonts.mx import DeepAREstimator, Trainer
  from gluonts.mx.trainer.callback import TrainingHistory
  from gluonts.mx.distribution.student_t import StudentTOutput
  from lightwood.helpers.log import log
  from lightwood.mixer.base import BaseMixer
  from lightwood.api.types import PredictionArguments
  from lightwood.data.encoded_ds import EncodedDs, ConcatedEncodedDs
label_desc: Use image node_id 3 for calling the GluonTSMixer obj's underlying member method code with example usage: obj.partial_fit(train_data, dev_data, args) without return types