{"record":{"id":"318fea013921abc1","repo":"microsoft/qlib","slug":"optimizer-is-not-supported-318fea","errorCode":null,"errorMessage":"optimizer {} is not supported!","messagePattern":"optimizer (.+?) is not supported!","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/contrib/model/pytorch_localformer_ts.py","lineNumber":76,"sourceCode":"        self.n_jobs = n_jobs\r\n        self.device = torch.device(\"cuda:%d\" % GPU if torch.cuda.is_available() and GPU >= 0 else \"cpu\")\r\n        self.seed = seed\r\n        self.logger = get_module_logger(\"TransformerModel\")\r\n        self.logger.info(\r\n            \"Improved Transformer:\" \"\\nbatch_size : {}\" \"\\ndevice : {}\".format(self.batch_size, self.device)\r\n        )\r\n\r\n        if self.seed is not None:\r\n            np.random.seed(self.seed)\r\n            torch.manual_seed(self.seed)\r\n\r\n        self.model = Transformer(d_feat, d_model, nhead, num_layers, dropout, self.device)\r\n        if optimizer.lower() == \"adam\":\r\n            self.train_optimizer = optim.Adam(self.model.parameters(), lr=self.lr, weight_decay=self.reg)\r\n        elif optimizer.lower() == \"gd\":\r\n            self.train_optimizer = optim.SGD(self.model.parameters(), lr=self.lr, weight_decay=self.reg)\r\n        else:\r\n            raise NotImplementedError(\"optimizer {} is not supported!\".format(optimizer))\r\n\r\n        self.fitted = False\r\n        self.model.to(self.device)\r\n\r\n    @property\r\n    def use_gpu(self):\r\n        return self.device != torch.device(\"cpu\")\r\n\r\n    def mse(self, pred, label):\r\n        loss = (pred.float() - label.float()) ** 2\r\n        return torch.mean(loss)\r\n\r\n    def loss_fn(self, pred, label):\r\n        mask = ~torch.isnan(label)\r\n\r\n        if self.loss == \"mse\":\r\n            return self.mse(pred[mask], label[mask])\r\n\r","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/model/pytorch_localformer_ts.py#L58-L94","documentation":"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.","triggerScenarios":"Passing optimizer='sgd', 'adamw', 'rmsprop', or any non-'adam'/'gd' string (case-insensitive) to LOCALTransformerModel(...) in qlib/contrib/model/pytorch_localformer_ts.py.","commonSituations":"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'.","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."],"exampleFix":"# before\nmodel = LOCALTransformerModel(..., optimizer=\"sgd\")  # NotImplementedError\n\n# after\nmodel = LOCALTransformerModel(..., optimizer=\"adam\")\n# or plain SGD:\nmodel = LOCALTransformerModel(..., optimizer=\"gd\")","handlingStrategy":"validation","validationCode":"SUPPORTED = {\"adam\", \"gd\"}\nopt = \"adam\"  # your desired optimizer\nassert opt.lower() in SUPPORTED, f\"optimizer must be one of {SUPPORTED}, got {opt!r}\"\nmodel = LOCALTransformerModel(..., optimizer=opt)","typeGuard":"def is_supported_optimizer(name: str) -> bool:\n    return isinstance(name, str) and name.lower() in {\"adam\", \"gd\"}","tryCatchPattern":"try:\n    model = LOCALTransformerModel(..., optimizer=opt)\nexcept NotImplementedError as e:\n    raise ValueError(f\"Bad config: {e}; supported optimizers are 'adam' and 'gd'\") from e","preventionTips":["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."],"tags":["pytorch","qlib","optimizer","transformer","config"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}