microsoft/qlib · error · ValueError

Unsupported data shape.

Error message

Unsupported data shape.

What it means

Raised by DNNModelPytorch._get_fl when a batch tensor passed to training/prediction is neither 2-D (tabular: [batch, feature_dim]) nor 3-D (time series: [batch, step, feature_dim]). The method slices features and the label off the last axis, which is only meaningful for those two shapes. Any other dimensionality (most commonly 1-D or 4-D) is rejected immediately.

Source

Thrown at qlib/contrib/model/pytorch_general_nn.py:199

        data : torch.Tensor
            input data which maybe 3 dimension or 2 dimension
            - 3dim: [batch_size, time_step, feature_dim]
            - 2dim: [batch_size, feature_dim]

        Returns
        -------
        Tuple[torch.Tensor, torch.Tensor]
        """
        if data.dim() == 3:
            # it is a time series dataset
            feature = data[:, :, 0:-1].to(self.device)
            label = data[:, -1, -1].to(self.device)
        elif data.dim() == 2:
            # it is a tabular dataset
            feature = data[:, 0:-1].to(self.device)
            label = data[:, -1].to(self.device)
        else:
            raise ValueError("Unsupported data shape.")
        return feature, label

    def train_epoch(self, data_loader):
        self.dnn_model.train()

        for data, weight in data_loader:
            feature, label = self._get_fl(data)

            pred = self.dnn_model(feature.float())
            loss = self.loss_fn(pred, label, weight.to(self.device))

            self.train_optimizer.zero_grad()
            loss.backward()
            torch.nn.utils.clip_grad_value_(self.dnn_model.parameters(), 3.0)
            self.train_optimizer.step()

    def test_epoch(self, data_loader):
        self.dnn_model.eval()

View on GitHub (pinned to 79633dd950)

Solutions

  1. Inspect data.shape right before _get_fl: for tabular it must be (batch, n_features+1); for time series (batch, step, n_features+1) with the label in the last column of the last step.
  2. Use TSDatasetH with the matching handler when you want 3-D input, and plain DatasetH for 2-D input; do not mix.
  3. If you have a legitimate 4-D input (e.g. multi-horizon), subclass and override _get_fl to flatten or slice appropriately.

Example fix

# before: tabular dataset but handler returns 1-D rows
for data, weight in data_loader:
    feature, label = self._get_fl(data)  # data.dim()==1 -> ValueError

# after: ensure batched 2-D tensor
assert data.dim() in (2, 3)
feature, label = self._get_fl(data)
Defensive patterns

Strategy: validation

Validate before calling

sample = next(iter(train_loader))[0]
assert sample.dim() in (2, 3), f"expected 2-D tabular or 3-D time-series batch, got shape {tuple(sample.shape)}"

Type guard

def has_supported_batch_shape(t) -> bool:
    return t.dim() in (2, 3)

Try / catch

try:
    feature, label = model._get_fl(data)
except ValueError:
    raise ValueError(f"batch shape {tuple(data.shape)} unsupported; use DatasetH (2-D) or TSDatasetH (3-D)")

Prevention

When it happens

Trigger: Feeding the model with a dataset whose prepared arrays collapse to 1-D (e.g. only one column so a squeeze happened, or a misconfigured TSDatasetH step size), or reusing the class's train_epoch with a custom data loader yielding 4-D tensors. Also triggered if num_features is set such that the ConcatDataset yields per-sample 1-D vectors while the model expects tabular batches.

Common situations: Switching a workflow from DatasetH (tabular) to TSDatasetH (time series) or vice versa without matching the model input; a custom data handler that returns squeezed arrays; edge case where step=1 in TS processing produces an unexpected shape.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/e39bb563189447d8. Report an issue: GitHub.