microsoft/qlib · error · NotImplementedError

optimizer {} is not supported!

Error message

optimizer {} is not supported!

What it means

LocalTransformerModel supports only 'adam' (optim.Adam with weight_decay=self.reg) and 'gd' (optim.SGD with the same reg), case-insensitive. Any other optimizer string raises NotImplementedError in __init__, so the model object is never fully constructed.

Source

Thrown at qlib/contrib/model/pytorch_localformer.py:76

        self.optimizer = optimizer.lower()
        self.loss = loss
        self.n_jobs = n_jobs
        self.device = torch.device("cuda:%d" % GPU if torch.cuda.is_available() and GPU >= 0 else "cpu")
        self.seed = seed
        self.logger = get_module_logger("TransformerModel")
        self.logger.info("Naive Transformer:" "\nbatch_size : {}" "\ndevice : {}".format(self.batch_size, self.device))

        if self.seed is not None:
            np.random.seed(self.seed)
            torch.manual_seed(self.seed)

        self.model = Transformer(d_feat, d_model, nhead, num_layers, dropout, self.device)
        if optimizer.lower() == "adam":
            self.train_optimizer = optim.Adam(self.model.parameters(), lr=self.lr, weight_decay=self.reg)
        elif optimizer.lower() == "gd":
            self.train_optimizer = optim.SGD(self.model.parameters(), lr=self.lr, weight_decay=self.reg)
        else:
            raise NotImplementedError("optimizer {} is not supported!".format(optimizer))

        self.fitted = False
        self.model.to(self.device)

    @property
    def use_gpu(self):
        return self.device != torch.device("cpu")

    def mse(self, pred, label):
        loss = (pred.float() - label.float()) ** 2
        return torch.mean(loss)

    def loss_fn(self, pred, label):
        mask = ~torch.isnan(label)

        if self.loss == "mse":
            return self.mse(pred[mask], label[mask])

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use optimizer='adam' or optimizer='gd'
  2. Subclass to register additional optimizers if needed

Example fix

# before
LocalTransformerModel(optimizer="adamw")

# after
LocalTransformerModel(optimizer="adam")
Defensive patterns

Strategy: validation

Validate before calling

assert optimizer.lower() in ("adam", "gd"), f"unsupported optimizer {optimizer!r}"

Type guard

def is_supported_optimizer(name: str) -> bool:
    return name.lower() in ("adam", "gd")

Prevention

When it happens

Trigger: LocalTransformerModel(optimizer='adamw'|'rmsprop'|anything else); construction fails before fit is ever called.

Common situations: Hyperparameter search spaces that enumerate optimizer names from other libraries; typos; configs ported from models with broader optimizer support.

Related errors


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