microsoft/qlib · error · ValueError
unknown loss `%s`
Error message
unknown loss `%s`
What it means
GATsModel.loss_fn supports exactly one loss: self.loss == 'mse'. Any other value skips the branch and raises ValueError from loss_fn, which is called by both the training loop and metric_fn, so the error surfaces on the first training batch of fit().
Source
Thrown at qlib/contrib/model/pytorch_gats.py:154
self.fitted = False
self.GAT_model.to(self.device)
@property
def use_gpu(self):
return self.device != torch.device("cpu")
def mse(self, pred, label):
loss = (pred - label) ** 2
return torch.mean(loss)
def loss_fn(self, pred, label):
mask = ~torch.isnan(label)
if self.loss == "mse":
return self.mse(pred[mask], label[mask])
raise ValueError("unknown loss `%s`" % self.loss)
def metric_fn(self, pred, label):
mask = torch.isfinite(label)
if self.metric in ("", "loss"):
return -self.loss_fn(pred[mask], label[mask])
raise ValueError("unknown metric `%s`" % self.metric)
def get_daily_inter(self, df, shuffle=False):
# organize the train data into daily batches
daily_count = df.groupby(level=0, group_keys=False).size().values
daily_index = np.roll(np.cumsum(daily_count), 1)
daily_index[0] = 0
if shuffle:
# shuffle data
daily_shuffle = list(zip(daily_index, daily_count))
np.random.shuffle(daily_shuffle)View on GitHub (pinned to 79633dd950)
Solutions
- Set loss='mse' (the default) in the GATsModel constructor or workflow config.
- Audit the loss hyperparameter for typos or values ported from other model configs.
- Subclass GATsModel and extend loss_fn with a new elif branch for a custom loss.
Example fix
# before model = GATsModel(loss='huber') # after model = GATsModel(loss='mse')
Defensive patterns
Strategy: validation
Validate before calling
assert model.loss == 'mse', f"GATsModel only supports loss='mse', got {model.loss!r}" Type guard
def is_supported_gats_loss(loss: str) -> bool:
return loss == 'mse' Try / catch
try:
model.fit(dataset)
except ValueError as e:
if 'unknown loss' in str(e):
model.loss = 'mse'
model.fit(dataset)
else:
raise Prevention
- Pin loss='mse' for GATs in config templates.
- Do not port loss names between qlib contrib models.
- Add a pre-fit assertion in experiment scripts that enumerate loss variants.
When it happens
Trigger: Constructing GATsModel(loss='mae') or loss='' and calling fit(); feeding a loss name valid in another qlib model (ALSTM, TRA) into GATs.
Common situations: Copying a hyperparameter YAML between qlib contrib models where 'mse' is the only supported value here; leaving loss unset in a config template whose default differs from the class default.
Related errors
- optimizer {} is not supported!
- unknown metric `%s`
- unknown base model name `%s`
- unknown loss `%s`
- unknown metric `%s`
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/6e8dc8094d0f1d0c.
Report an issue: GitHub.