microsoft/qlib · error · ValueError
model is not fitted yet!
Error message
model is not fitted yet!
What it means
LOCALTransformerModel.predict() refuses to run when the instance flag self.fitted is False. The flag is only set to True after a successful fit() completes (including early stop, where the best checkpoint is reloaded). Calling predict() on a fresh or failed-to-fit model raises ValueError('model is not fitted yet!') immediately, before any data is prepared.
Source
Thrown at qlib/contrib/model/pytorch_localformer.py:218
stop_steps = 0
best_epoch = step
best_param = copy.deepcopy(self.model.state_dict())
else:
stop_steps += 1
if stop_steps >= self.early_stop:
self.logger.info("early stop")
break
self.logger.info("best score: %.6lf @ %d" % (best_score, best_epoch))
self.model.load_state_dict(best_param)
torch.save(best_param, save_path)
if self.use_gpu:
torch.cuda.empty_cache()
def predict(self, dataset: DatasetH, segment: Union[Text, slice] = "test"):
if not self.fitted:
raise ValueError("model is not fitted yet!")
x_test = dataset.prepare(segment, col_set="feature", data_key=DataHandlerLP.DK_I)
index = x_test.index
self.model.eval()
x_values = x_test.values
sample_num = x_values.shape[0]
preds = []
for begin in range(sample_num)[:: self.batch_size]:
if sample_num - begin < self.batch_size:
end = sample_num
else:
end = begin + self.batch_size
x_batch = torch.from_numpy(x_values[begin:end]).float().to(self.device)
with torch.no_grad():
pred = self.model(x_batch).detach().cpu().numpy()
View on GitHub (pinned to 79633dd950)
Solutions
- Call model.fit(dataset, evals_result) to completion before model.predict(dataset); only a finished fit sets self.fitted = True.
- If fit() threw earlier, fix that root cause first (see its exception) and re-fit; predict will keep failing until fit succeeds.
- To reuse a previously trained model, load the saved state dict (torch.load(save_path); model.model.load_state_dict(state)) AND set model.fitted = True explicitly before predict.
- In multi-segment workflows, confirm your task config actually runs the train segment before the backtest/record step.
Example fix
# before model = LOCALTransformerModel(d_feat=6) preds = model.predict(dataset) # ValueError: model is not fitted yet! # after model = LOCALTransformerModel(d_feat=6) model.fit(dataset, evals_result) preds = model.predict(dataset)
Defensive patterns
Strategy: validation
Validate before calling
# before predicting, confirm the model completed fit
if not getattr(model, "fitted", False):
raise RuntimeError("LOCALTransformerModel is not fitted; call fit() before predict()")
preds = model.predict(dataset) Type guard
def is_fitted_localformer(model) -> bool:
"""True only after a successful fit() on a LOCALTransformerModel."""
return bool(getattr(model, "fitted", False)) and hasattr(model, "model") Try / catch
try:
preds = model.predict(dataset)
except ValueError as e:
if "not fitted" in str(e):
model.fit(dataset, evals_result) # or load checkpoint + set fitted
preds = model.predict(dataset)
else:
raise Prevention
- Treat fit() and predict() as ordered steps; assert model.fitted before predict in pipeline code.
- Check that fit() logged 'best score: ...' before continuing to backtest.
- When restoring from checkpoints, set model.fitted = True explicitly after load_state_dict.
- Make training failures fatal in workflow scripts so predict never runs on an unfitted model.
When it happens
Trigger: Calling model.predict(dataset) on a LOCALTransformerModel whose fit() was never called, whose fit() raised before setting self.fitted = True, or on a newly constructed model after a failed/interrupted training run.
Common situations: Running a workflow (e.g. qrun) with a pickle-loaded model whose training step was skipped; fit() crashed on empty data or CUDA OOM and the script continued to backtest; instantiating the model directly in a notebook and jumping straight to predict.
Related errors
- model is not fitted yet!
- model is not fitted yet!
- model is not fitted yet!
- unknown metric `%s`
- unknown metric `%s`
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/7b9f7a06e7f85d33.
Report an issue: GitHub.