{"record":{"id":"1ec9a4ff1eaf4eb4","repo":"microsoft/qlib","slug":"optimizer-is-not-supported-1ec9a4","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_nn.py","lineNumber":147,"sourceCode":"        self._scorer = mean_squared_error if loss == \"mse\" else roc_auc_score\n\n        if init_model is None:\n            self.dnn_model = init_instance_by_config({\"class\": pt_model_uri, \"kwargs\": pt_model_kwargs})\n\n            if self.data_parall:\n                self.dnn_model = DataParallel(self.dnn_model).to(self.device)\n        else:\n            self.dnn_model = init_model\n\n        self.logger.info(\"model:\\n{:}\".format(self.dnn_model))\n        self.logger.info(\"model size: {:.4f} MB\".format(count_parameters(self.dnn_model)))\n\n        if optimizer.lower() == \"adam\":\n            self.train_optimizer = optim.Adam(self.dnn_model.parameters(), lr=self.lr, weight_decay=self.weight_decay)\n        elif optimizer.lower() == \"gd\":\n            self.train_optimizer = optim.SGD(self.dnn_model.parameters(), lr=self.lr, weight_decay=self.weight_decay)\n        else:\n            raise NotImplementedError(\"optimizer {} is not supported!\".format(optimizer))\n\n        if scheduler == \"default\":\n            # In torch version 2.7.0, the verbose parameter has been removed. Reference Link:\n            # https://github.com/pytorch/pytorch/pull/147301/files#diff-036a7470d5307f13c9a6a51c3a65dd014f00ca02f476c545488cd856bea9bcf2L1313\n            if version.parse(str(torch.__version__).split(\"+\", maxsplit=1)[0]) <= version.parse(\"2.6.0\"):\n                # Reduce learning rate when loss has stopped decrease\n                self.scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(  # pylint: disable=E1123\n                    self.train_optimizer,\n                    mode=\"min\",\n                    factor=0.5,\n                    patience=10,\n                    verbose=True,\n                    threshold=0.0001,\n                    threshold_mode=\"rel\",\n                    cooldown=0,\n                    min_lr=0.00001,\n                    eps=1e-08,\n                )","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/model/pytorch_nn.py#L129-L165","documentation":"DNNModelPytorch maps only two optimizer names to torch optimizers: 'adam' -> optim.Adam(lr, weight_decay) and 'gd' -> optim.SGD(lr, weight_decay). Any other string raises NotImplementedError('optimizer {} is not supported!') in __init__ after the network is created. A scheduler ('default' ReduceLROnPlateau, with a torch-version-sensitive verbose argument) is then attached to the chosen optimizer.","triggerScenarios":"DNNModelPytorch(optimizer=opt) with opt.lower() not in {'adam','gd'} — 'sgd', 'adamw', 'rmsprop', 'lbfgs', or a typo. Raised at construction, before fit().","commonSituations":"Users expecting the PyTorch class name to work ('SGD'); migrating configs from other contrib models; wanting AdamW for decoupled weight decay.","solutions":["Set optimizer='adam' or optimizer='gd' (weight_decay is honored for both via the weight_decay kwarg).","For other optimizers, subclass DNNModelPytorch and override __init__ to install your own self.train_optimizer over self.dnn_model.parameters().","Check YAML/kwargs for typos; matching is exact after lowercasing."],"exampleFix":"# before\nmodel = DNNModelPytorch(optimizer=\"sgd\", ...)  # NotImplementedError\n\n# after\nmodel = DNNModelPytorch(optimizer=\"adam\", weight_decay=1e-4, ...)\n# plain SGD with decay:\nmodel = DNNModelPytorch(optimizer=\"gd\", weight_decay=1e-4, ...)","handlingStrategy":"validation","validationCode":"assert optimizer.lower() in {\"adam\", \"gd\"}, \"DNNModelPytorch supports only 'adam' and 'gd'\"\nmodel = DNNModelPytorch(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 = DNNModelPytorch(optimizer=opt, ...)\nexcept NotImplementedError as e:\n    raise ValueError(f\"{e} — use 'adam' or 'gd' (both honor weight_decay)\") from e","preventionTips":["'gd' + weight_decay gives you L2-SGD; 'adamw' is not available without subclassing.","Validate optimizer strings in your config loader before model construction.","Note the attached ReduceLROnPlateau scheduler operates on the chosen optimizer."],"tags":["pytorch","qlib","optimizer","dnn","config"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}