{"record":{"id":"71ff803d59c1dad0","repo":"microsoft/qlib","slug":"model-is-not-fitted-yet-71ff80","errorCode":null,"errorMessage":"model is not fitted yet!","messagePattern":"model is not fitted yet!","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/contrib/model/pytorch_alstm_ts.py","lineNumber":289,"sourceCode":"                stop_steps = 0\n                best_epoch = step\n                best_param = copy.deepcopy(self.ALSTM_model.state_dict())\n            else:\n                stop_steps += 1\n                if stop_steps >= self.early_stop:\n                    self.logger.info(\"early stop\")\n                    break\n\n        self.logger.info(\"best score: %.6lf @ %d\" % (best_score, best_epoch))\n        self.ALSTM_model.load_state_dict(best_param)\n        torch.save(best_param, save_path)\n\n        if self.use_gpu:\n            torch.cuda.empty_cache()\n\n    def predict(self, dataset: DatasetH, segment: Union[Text, slice] = \"test\"):\n        if not self.fitted:\n            raise ValueError(\"model is not fitted yet!\")\n\n        dl_test = dataset.prepare(segment, col_set=[\"feature\", \"label\"], data_key=DataHandlerLP.DK_I)\n        dl_test.config(fillna_type=\"ffill+bfill\")\n        test_loader = DataLoader(dl_test, batch_size=self.batch_size, num_workers=self.n_jobs)\n        self.ALSTM_model.eval()\n        preds = []\n\n        for data in test_loader:\n            feature = data[:, :, 0:-1].to(self.device)\n\n            with torch.no_grad():\n                pred = self.ALSTM_model(feature.float()).detach().cpu().numpy()\n\n            preds.append(pred)\n\n        return pd.Series(np.concatenate(preds), index=dl_test.get_index())\n\n","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/model/pytorch_alstm_ts.py#L271-L307","documentation":"ALSTMTSModel.predict() first checks the self.fitted flag, which is set to True only after fit() completes its training loop. Calling predict() on a model whose fit() never ran (or raised before finishing) raises ValueError immediately, before any data is prepared. This guard prevents running an untrained, randomly-initialized network on test data.","triggerScenarios":"Instantiating ALSTMTSModel and calling predict(dataset) directly; calling predict() after a fit() that raised (empty data, bad metric, CUDA OOM) so fitted was never set; re-creating the model object in a new process without restoring a fitted state.","commonSituations":"Notebook workflows where the fit cell errored but later cells keep running; checkpoint-reload scripts that build a fresh model and forget to load weights or refit; an exception during fit() being swallowed by a bare try/except so the caller believes training succeeded.","solutions":["Call fit(dataset) successfully before predict(dataset).","If fit() raised earlier, fix that error and rerun fit; fitted only becomes True at the end of a clean fit().","If you meant to restore a trained model, reload its parameters and set model.fitted = True manually before predict()."],"exampleFix":"# before\nmodel = ALSTMTSModel(d_feat=6)\nmodel.predict(dataset)  # ValueError\n\n# after\nmodel = ALSTMTSModel(d_feat=6)\nmodel.fit(dataset)\nmodel.predict(dataset)","handlingStrategy":"validation","validationCode":"if not getattr(model, 'fitted', False):\n    raise RuntimeError('ALSTMTSModel is not fitted; call fit() before predict()')","typeGuard":"def is_fitted(m) -> bool:\n    return bool(getattr(m, 'fitted', False))","tryCatchPattern":"try:\n    pred = model.predict(dataset)\nexcept ValueError as e:\n    if 'not fitted' in str(e):\n        model.fit(dataset)\n        pred = model.predict(dataset)\n    else:\n        raise","preventionTips":["Treat a failed fit() as 'model unusable': check model.fitted before predict in pipeline code.","Do not swallow exceptions from fit(); a half-trained model never sets fitted=True.","When restoring saved models in a new process, reload weights and set fitted=True explicitly."],"tags":["pytorch","qlib","lifecycle","state-error","prediction"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}