microsoft/qlib · error · ValueError

unknown base model name `%s`

Error message

unknown base model name `%s`

What it means

GATsModel.fit() instantiates a pretrained base RNN to warm-start the GAT network: only base_model == 'LSTM' and 'GRU' (exact case) are recognized; anything else raises ValueError before weights are loaded. Note the comparison is case-sensitive, so 'lstm' fails here even though other hyperparameters in qlib are matched case-insensitively.

Source

Thrown at qlib/contrib/model/pytorch_gats.py:254

            raise ValueError("Empty data from dataset, please check your dataset config.")

        x_train, y_train = df_train["feature"], df_train["label"]
        x_valid, y_valid = df_valid["feature"], df_valid["label"]

        save_path = get_or_create_path(save_path)
        stop_steps = 0
        best_score = -np.inf
        best_epoch = 0
        evals_result["train"] = []
        evals_result["valid"] = []

        # load pretrained base_model
        if self.base_model == "LSTM":
            pretrained_model = LSTMModel()
        elif self.base_model == "GRU":
            pretrained_model = GRUModel()
        else:
            raise ValueError("unknown base model name `%s`" % self.base_model)

        if self.model_path is not None:
            self.logger.info("Loading pretrained model...")
            pretrained_model.load_state_dict(torch.load(self.model_path, map_location=self.device))

        model_dict = self.GAT_model.state_dict()
        pretrained_dict = {
            k: v for k, v in pretrained_model.state_dict().items() if k in model_dict  # pylint: disable=E1135
        }
        model_dict.update(pretrained_dict)
        self.GAT_model.load_state_dict(model_dict)
        self.logger.info("Loading pretrained model Done...")

        # train
        self.logger.info("training...")
        self.fitted = True

        for step in range(self.n_epochs):

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use the exact strings 'LSTM' or 'GRU' for base_model.
  2. Fix lowercase 'lstm'/'gru' values in your workflow config.
  3. Subclass GATsModel to add a custom base model class if you need one.

Example fix

# before
model = GATsModel(base_model='lstm')

# after
model = GATsModel(base_model='LSTM')
Defensive patterns

Strategy: validation

Validate before calling

assert model.base_model in ('LSTM', 'GRU'), f"base_model must be exactly 'LSTM' or 'GRU', got {model.base_model!r}"

Type guard

def is_valid_base_model(name: str) -> bool:
    return name in ('LSTM', 'GRU')

Try / catch

try:
    model.fit(dataset)
except ValueError as e:
    if 'unknown base model name' in str(e):
        model.base_model = model.base_model.upper()
        if model.base_model in ('LSTM', 'GRU'):
            model.fit(dataset)
            return
    raise

Prevention

When it happens

Trigger: Calling fit() with base_model='lstm' (lowercase), 'Transformer', 'SRNN', or any string other than the exact 'LSTM'/'GRU'.

Common situations: Lowercasing hyperparameters in workflow YAMLs; porting configs between GATs variants; assuming case-insensitive matching as used for the optimizer parameter.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/1a1dd723b0cc3698. Report an issue: GitHub.