microsoft/qlib · error · NotImplementedError
optimizer {} is not supported!
Error message
optimizer {} is not supported! What it means
LOCALTransformerModel's constructor only accepts two optimizers: 'adam' (torch.optim.Adam with lr and weight_decay=reg) and 'gd' (torch.optim.SGD with lr and weight_decay=reg). Any other optimizer string raises NotImplementedError('optimizer {} is not supported!') at __init__ time, before any training happens.
Source
Thrown at qlib/contrib/model/pytorch_localformer_ts.py:76
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(
"Improved 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
- Set optimizer='adam' (recommended default) or optimizer='gd' for plain SGD in the model kwargs.
- If you truly need another optimizer, subclass LOCALTransformerModel, override __init__ after super() and reassign self.train_optimizer with your torch.optim optimizer over self.model.parameters().
- Check for typos/case: matching is via optimizer.lower(), so 'Adam' works but 'adamw' does not.
Example fix
# before model = LOCALTransformerModel(..., optimizer="sgd") # NotImplementedError # after model = LOCALTransformerModel(..., optimizer="adam") # or plain SGD: model = LOCALTransformerModel(..., optimizer="gd")
Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED = {"adam", "gd"}
opt = "adam" # your desired optimizer
assert opt.lower() in SUPPORTED, f"optimizer must be one of {SUPPORTED}, got {opt!r}"
model = LOCALTransformerModel(..., optimizer=opt) Type guard
def is_supported_optimizer(name: str) -> bool:
return isinstance(name, str) and name.lower() in {"adam", "gd"} Try / catch
try:
model = LOCALTransformerModel(..., optimizer=opt)
except NotImplementedError as e:
raise ValueError(f"Bad config: {e}; supported optimizers are 'adam' and 'gd'") from e Prevention
- Centralize optimizer names in config constants instead of free strings in YAML.
- Remember the SGD keyword in qlib's pytorch contrib models is 'gd', not 'sgd'.
- Fail fast: validate kwargs before constructing models in long pipelines.
When it happens
Trigger: Passing optimizer='sgd', 'adamw', 'rmsprop', or any non-'adam'/'gd' string (case-insensitive) to LOCALTransformerModel(...) in qlib/contrib/model/pytorch_localformer_ts.py.
Common situations: Copying a config written for another qlib model that supports more optimizers; trying to use a modern optimizer like AdamW; a typo such as 'ada' or 'SDG'; assuming 'sgd' is the name for gradient descent instead of 'gd'.
Related errors
- unknown loss `%s`
- unknown metric `%s`
- optimizer {} is not supported!
- optimizer {} is not supported!
- optimizer {} is not supported!
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/318fea013921abc1.
Report an issue: GitHub.