microsoft/qlib · error · ValueError

unknown rnn_type `%s`

Error message

unknown rnn_type `%s`

What it means

The ALSTM internal network builds its recurrent layer by looking up torch.nn for the attribute rnn_type.upper() (e.g. 'gru' -> nn.GRU, 'lstm' -> nn.LSTM). If that attribute does not exist, getattr raises AttributeError which is caught and re-raised as ValueError('unknown rnn_type ...'). Note that any non-RNN nn attribute that happens to match (e.g. 'linear') would pass this check and fail later with a construction TypeError, since the code relies on name lookup rather than an explicit allowlist.

Source

Thrown at qlib/contrib/model/pytorch_alstm_ts.py:322

        return pd.Series(np.concatenate(preds), index=dl_test.get_index())


class ALSTMModel(nn.Module):
    def __init__(self, d_feat=6, hidden_size=64, num_layers=2, dropout=0.0, rnn_type="GRU"):
        super().__init__()
        self.hid_size = hidden_size
        self.input_size = d_feat
        self.dropout = dropout
        self.rnn_type = rnn_type
        self.rnn_layer = num_layers
        self._build_model()

    def _build_model(self):
        try:
            klass = getattr(nn, self.rnn_type.upper())
        except Exception as e:
            raise ValueError("unknown rnn_type `%s`" % self.rnn_type) from e
        self.net = nn.Sequential()
        self.net.add_module("fc_in", nn.Linear(in_features=self.input_size, out_features=self.hid_size))
        self.net.add_module("act", nn.Tanh())
        self.rnn = klass(
            input_size=self.hid_size,
            hidden_size=self.hid_size,
            num_layers=self.rnn_layer,
            batch_first=True,
            dropout=self.dropout,
        )
        self.fc_out = nn.Linear(in_features=self.hid_size * 2, out_features=1)
        self.att_net = nn.Sequential()
        self.att_net.add_module(
            "att_fc_in",
            nn.Linear(in_features=self.hid_size, out_features=int(self.hid_size / 2)),
        )
        self.att_net.add_module("att_dropout", torch.nn.Dropout(self.dropout))
        self.att_net.add_module("att_act", nn.Tanh())

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use one of the supported values: 'gru', 'lstm', or 'rnn' (any string whose uppercase matches an nn RNN class).
  2. Verify the exact string has no typos, whitespace, or mixed characters.
  3. If you need a custom recurrent cell, subclass the model and override _build_model to construct self.rnn directly.

Example fix

# before
model = ALSTMTSModel(rnn_type='sru')

# after
model = ALSTMTSModel(rnn_type='gru')
Defensive patterns

Strategy: validation

Validate before calling

import torch.nn as nn
assert hasattr(nn, model.rnn_type.upper()), f"rnn_type {model.rnn_type!r} has no torch.nn counterpart"

Type guard

import torch.nn as nn

def is_valid_rnn_type(rnn_type: str) -> bool:
    return hasattr(nn, rnn_type.upper())

Try / catch

try:
    model.fit(dataset)
except ValueError as e:
    if 'unknown rnn_type' in str(e):
        model.rnn_type = 'gru'
        model.init_dataset()  # rebuild if applicable
    raise

Prevention

When it happens

Trigger: Passing rnn_type='transformer', 'srnn', or any string whose uppercase form is not an nn module name; typos like 'gruu' or '1stm'; a PyTorch version that removed/renamed the requested RNN class (does not happen for GRU/LSTM/RNN but can for exotic names).

Common situations: Experimenting with recurrent cell types not supported by the model; copying hyperparameter blocks from a custom fork; case errors ('GRU' works because .upper() normalizes it, but 'gru ' with whitespace fails).

Related errors


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