GRU
The LSTM's cheaper, lighter cousin — as a node you can stack
- model
Vanilla RNNs have a memory problem: by the time they've processed a long sentence, the signal from the beginning has been washed out by repeated multiplication through tanh. The GRU - gated recurrent unit - fixes that with a pair of learned gates that decide what to remember and what to forget, and it does it with fewer parameters and less machinery than the LSTM. ComfyDL's CdlGRU hands you a real nn.GRU - and, unlike the single-layer CdlRNN node, it lets you stack multiple layers and add inter-layer dropout.
This is the recurrent cell you'll actually want for a language-model experiment. In ComfyDL's Dive into Deep Learning (d2l) lineage it's the upgrade path: build with CdlRNN to learn the concepts, switch to GRU when you want the sequence model to carry context properly.
How it works
The node constructs nn.GRU(num_inputs, num_hiddens, num_layers, dropout). Inside, each GRU cell maintains a hidden state and runs two gates at every step: a reset gate that decides how much of the past state to discard when forming a candidate new state, and an update gate that decides how much of the old state to keep versus how much of that candidate to adopt. That gating is why gradients can flow much farther back than in a vanilla RNN - the update gate gives memory an "almost copy" path.
Stacking layers (num_layers > 1) means the second layer takes the first layer's hidden states as its input, letting the model build hierarchical representations. When you stack, dropout is applied between layers - never on the final one.
Inputs and outputs that matter
num_inputs(default 32) - width of each input vector; in a language model, your vocabulary size.num_hiddens(default 64) - hidden units per layer.num_layers(default 1, up to 20) - how many GRU layers to stack. One layer is plenty for first experiments; two is the common sweet spot for the toy text models in d2l.dropout(default 0, max 0.9) - regularization between layers. Withnum_layers = 1it does nothing, by PyTorch's design, so don't raise it and wonder why nothing changed.
The model output is a cdlModel. Give it (num_steps, batch_size, num_inputs) and it returns (outputs, state), where the state is now 3D - (num_layers, batch, num_hiddens) - because the node has to hand you a per-layer state. Feed the model into CdlRNNLM or CdlRNNLMScratch to turn it into a next-token predictor, then into RNN LM Predict for generation.
Installing ComfyDL
cd ComfyUI/custom_nodes
git clone https://github.com/Cynthia-lxx/ComfyDL ./ComfyDL
pip install -r ./ComfyDL/requirements.txt
Restart ComfyUI. Light dependencies (matplotlib, IPython, matplotlib-inline), no downloads for this node. If ComfyUI Manager doesn't find "ComfyDL" (this pack is young and may not be in the registry), the clone command above always works.
Gotchas
The 3D hidden state is the thing that breaks people migrating from the vanilla RNN node - your downstream code that expected a flat state now gets (num_layers, batch, hidden), and layer 0 is the bottom. And don't forget num_inputs must equal the vocabulary size if you're wiring into a language model; mismatch it and the first forward pass complains about incompatible shapes.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| num_inputs | INT | 321–100000 | — |
| num_hiddens | INT | 641–4096 | — |
| num_layers | INT | 11–20 | — |
| dropout | FLOAT | 0.000–0.9 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| model | cdlModel | — |