{"record":{"id":"573848b44cf32bd9","repo":"microsoft/qlib","slug":"optimizer-is-not-supported-573848","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_lstm.py","lineNumber":123,"sourceCode":"            )\n        )\n\n        if self.seed is not None:\n            np.random.seed(self.seed)\n            torch.manual_seed(self.seed)\n\n        self.lstm_model = LSTMModel(\n            d_feat=self.d_feat,\n            hidden_size=self.hidden_size,\n            num_layers=self.num_layers,\n            dropout=self.dropout,\n        )\n        if optimizer.lower() == \"adam\":\n            self.train_optimizer = optim.Adam(self.lstm_model.parameters(), lr=self.lr)\n        elif optimizer.lower() == \"gd\":\n            self.train_optimizer = optim.SGD(self.lstm_model.parameters(), lr=self.lr)\n        else:\n            raise NotImplementedError(\"optimizer {} is not supported!\".format(optimizer))\n\n        self.fitted = False\n        self.lstm_model.to(self.device)\n\n    @property\n    def use_gpu(self):\n        return self.device != torch.device(\"cpu\")\n\n    def mse(self, pred, label):\n        loss = (pred - label) ** 2\n        return torch.mean(loss)\n\n    def loss_fn(self, pred, label):\n        mask = ~torch.isnan(label)\n\n        if self.loss == \"mse\":\n            return self.mse(pred[mask], label[mask])\n","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/model/pytorch_lstm.py#L105-L141","documentation":"LSTMModel's constructor wires up exactly two optimizers: 'adam' (optim.Adam, lr only) and 'gd' (optim.SGD, lr only) — note neither applies weight decay in this model. Any other optimizer string raises NotImplementedError('optimizer {} is not supported!') during __init__, so the model is unusable until fixed.","triggerScenarios":"Constructing LSTMModel(..., optimizer=X) in qlib/contrib/model/pytorch_lstm.py with X.lower() not in {'adam','gd'} — e.g. 'sgd', 'adamw', 'rmsprop', or a typo.","commonSituations":"Reusing YAML from another contrib model; expecting 'sgd' as the SGD keyword when this codebase uses 'gd'; copy-paste of optimizer names from raw PyTorch examples.","solutions":["Change the model kwarg to optimizer='adam' or optimizer='gd'.","For other optimizers, subclass, call super().__init__(), then set self.train_optimizer = optim.<Opt>(self.lstm_model.parameters(), lr=self.lr, ...).","Double-check spelling; matching is lowercased but exact."],"exampleFix":"# before\nmodel = LSTMModel(..., optimizer=\"sgd\")  # NotImplementedError\n\n# after\nmodel = LSTMModel(..., optimizer=\"adam\")  # or \"gd\" for SGD","handlingStrategy":"validation","validationCode":"assert optimizer.lower() in {\"adam\", \"gd\"}, \"LSTMModel supports only 'adam' and 'gd'\"\nmodel = LSTMModel(..., optimizer=optimizer)","typeGuard":"def is_supported_optimizer(name: str) -> bool:\n    return isinstance(name, str) and name.lower() in {\"adam\", \"gd\"}","tryCatchPattern":"try:\n    model = LSTMModel(..., optimizer=opt)\nexcept NotImplementedError as e:\n    raise ValueError(f\"{e} — use 'adam' or 'gd'\") from e","preventionTips":["Use 'gd' (not 'sgd') for SGD across qlib pytorch contrib models.","Keep a shared supported-optimizer set next to your experiment configs.","Validate model kwargs in one place before building models."],"tags":["pytorch","qlib","optimizer","lstm","config"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}