microsoft/qlib · error · NotImplementedError

optimizer {} is not supported!

Error message

optimizer {} is not supported!

What it means

Thrown in TCTSModel.fit while building the optimizer for the forecasting head (fore_model). The `fore_optimizer` hyperparameter is matched case-insensitively against 'adam' and 'gd'; anything else raises NotImplementedError before training starts. This is the forecasting model's optimizer, distinct from the weight model's.

Source

Thrown at qlib/contrib/model/pytorch_tcts.py:298

        self.fore_model = GRUModel(
            d_feat=self.d_feat,
            hidden_size=self.hidden_size,
            num_layers=self.num_layers,
            dropout=self.dropout,
        )
        self.weight_model = MLPModel(
            d_feat=self.input_dim + 3 * self.output_dim + 1,
            hidden_size=self.hidden_size,
            num_layers=self.num_layers,
            dropout=self.dropout,
            output_dim=self.output_dim,
        )
        if self._fore_optimizer.lower() == "adam":
            self.fore_optimizer = optim.Adam(self.fore_model.parameters(), lr=self.fore_lr)
        elif self._fore_optimizer.lower() == "gd":
            self.fore_optimizer = optim.SGD(self.fore_model.parameters(), lr=self.fore_lr)
        else:
            raise NotImplementedError("optimizer {} is not supported!".format(self._fore_optimizer))
        if self._weight_optimizer.lower() == "adam":
            self.weight_optimizer = optim.Adam(self.weight_model.parameters(), lr=self.weight_lr)
        elif self._weight_optimizer.lower() == "gd":
            self.weight_optimizer = optim.SGD(self.weight_model.parameters(), lr=self.weight_lr)
        else:
            raise NotImplementedError("optimizer {} is not supported!".format(self._weight_optimizer))

        self.fitted = False
        self.fore_model.to(self.device)
        self.weight_model.to(self.device)

        best_loss = np.inf
        best_epoch = 0
        stop_round = 0

        for epoch in range(self.n_epochs):
            print("Epoch:", epoch)

View on GitHub (pinned to 79633dd950)

Solutions

  1. Set fore_optimizer='adam' or fore_optimizer='gd'.
  2. If you meant plain SGD, note this codebase spells it 'gd'.
  3. For other optimizers, subclass TCTSModel and construct the fore optimizer manually in an overridden fit.

Example fix

# before
model = TCTSModel(..., fore_optimizer="sgd")

# after
model = TCTSModel(..., fore_optimizer="gd")
Defensive patterns

Strategy: validation

Validate before calling

for key in ("fore_optimizer", "weight_optimizer"):
    v = model_kwargs.get(key, "adam")
    assert v.lower() in ("adam", "gd"), f"TCTSModel {key} must be 'adam' or 'gd', got {v!r}"

Try / catch

try:
    model.fit(dataset)
except NotImplementedError as e:
    if "optimizer" in str(e):
        model_kwargs.setdefault("fore_optimizer", "adam")
        if model_kwargs["fore_optimizer"].lower() not in ("adam", "gd"):
            model_kwargs["fore_optimizer"] = "adam"
        model = TCTSModel(**model_kwargs)
        model.fit(dataset)
    else:
        raise

Prevention

When it happens

Trigger: TCTSModel(fore_optimizer='sgd'|'adamw'|...) followed by fit(); the if/elif over self._fore_optimizer falls through to the raise.

Common situations: 'sgd' spelled as in other qlib models instead of 'gd'; using 'adamw' expecting modern support; mixing up fore_optimizer and weight_optimizer keys and setting one to an unsupported value.

Related errors


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