{"record":{"id":"f88e37d4bc3a234c","repo":"microsoft/qlib","slug":"model-is-not-fitted-yet-f88e37","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_tcn.py","lineNumber":274,"sourceCode":"                stop_steps = 0\n                best_epoch = step\n                best_param = copy.deepcopy(self.tcn_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.tcn_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        x_test = dataset.prepare(segment, col_set=\"feature\", data_key=DataHandlerLP.DK_I)\n        index = x_test.index\n        self.tcn_model.eval()\n        x_values = x_test.values\n        sample_num = x_values.shape[0]\n        preds = []\n\n        for begin in range(sample_num)[:: self.batch_size]:\n            if sample_num - begin < self.batch_size:\n                end = sample_num\n            else:\n                end = begin + self.batch_size\n\n            x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device)\n\n            with torch.no_grad():\n                pred = self.tcn_model(x_batch).detach().cpu().numpy()","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/model/pytorch_tcn.py#L256-L292","documentation":"Thrown by TCNModel.predict when the model's internal `fitted` flag is False. The flag is only set to True at the end of a successful fit() run, so this error means the TCN model state was never trained (or training crashed before completion) and there are no learned weights to predict with.","triggerScenarios":"Creating TCNModel and calling predict(dataset) without calling fit(dataset) first; or calling predict after a fit() that raised partway through (early crash, empty data, or an interrupt), leaving fitted=False.","commonSituations":"Notebook workflows where the fit cell fails (e.g. CUDA OOM, empty dataset) but later cells still run; loading a model object from a pickle without re-fitting; re-running a partial script after an exception.","solutions":["Call model.fit(dataset, evals_result) to completion before model.predict(dataset).","If fit() appeared to run, inspect the traceback for an earlier failure — an aborted fit never sets fitted=True; fix that root cause and retrain.","If the model was trained in a previous process, restore weights explicitly (e.g. torch.load of the saved state dict + set fitted=True) or persist the fitted object with pickle/joblib and load that instead."],"exampleFix":"# before\nmodel = TCNModel(**model_kwargs)\npreds = model.predict(dataset)  # ValueError\n\n# after\nmodel = TCNModel(**model_kwargs)\nmodel.fit(dataset, evals_result)\npreds = model.predict(dataset)","handlingStrategy":"validation","validationCode":"if not getattr(model, \"fitted\", False):\n    raise RuntimeError(\"TCNModel must be fitted before predict — call model.fit(dataset) first\")","typeGuard":"def is_fitted_tcn(model) -> bool:\n    return getattr(model, \"fitted\", False) and getattr(model, \"tcn_model\", None) is not None","tryCatchPattern":"try:\n    preds = model.predict(dataset)\nexcept ValueError as e:\n    if \"not fitted\" in str(e):\n        model.fit(dataset, evals_result)\n        preds = model.predict(dataset)\n    else:\n        raise","preventionTips":["Structure runners as fit-then-predict stages gated on fit success.","Persist fitted model objects (pickle/joblib) rather than reconstructing unfitted ones for prediction."],"tags":["qlib","pytorch","tcn","lifecycle","state"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}