Dissecting AI
All modules

Recurrent Decoder Feedback Over Parallel Encoder Memory

Fixed-depth Transformers struggle to carry algorithmic state across long inputs; RLT adds a recurrent decoder update that reuses causal encoder memory while feeding each token the previous decoder output.

The short version

What it is

  • Recurrent decoder feedback Each token's decoder input mixes its encoder representation with the previous token's final decoder output, so later tokens can build on earlier computation.
  • Reusable encoder memory A causal encoder builds token memory that the decoder can attend to as it advances; the decoder also carries its own recent attention cache.

Why it matters

This design gives the model a computation path that grows across tokens without adding more layers to each token's encoder-decoder pass. The tradeoff is that per-token decoder updates must proceed in order.

Before getting into the mechanics, here is the short version: RLT keeps a parallel causal encoder, then gives the decoder a small piece of its own previous result at every token. That creates a route for computation to accumulate across a sequence, while the encoder's token memory remains available for reference.

  1. State tracking: Some tasks are naturally updates, not isolated predictions. The canonical example is parity: each new bit changes a running answer. Permutation tracking has the same shape, except each input composes another group element. A fixed-depth Transformer gives each position a fixed number of layers; recurrence lets the computation path grow as tokens arrive. The question is whether that path can be added without rebuilding the whole model as a plain recurrent network.

  2. Separate representation from accumulation: The encoder processes known tokens causally and makes token representations and key–value memory. The decoder uses that memory while carrying forward its own previous result. Think of the encoder as a searchable notebook and the decoder output as the running calculation beside it. The analogy stops at lookup: the actual decoder also updates an attention cache and performs learned nonlinear transformations.

  3. The cost of order: The encoder can process known tokens in parallel, but when each decoder update consumes the previous update's result, those decoder steps must follow token order. RLT-1 does this at every token. So the useful question is not merely whether recurrence helps state tracking; it is how much sequential decoder work you are willing to pay for it.

What does the feedback actually carry? In mechanism terms, the decoder does not discard its old result or blindly overwrite it: a learned gate chooses, feature by feature, how much of the current encoder representation and previous decoder output to pass onward. The merge is written as ut=gt⊙Weet+(1−gt)⊙Wsst−1u_t=g_t\odot W_e e_t+(1-g_t)\odot W_s s_{t-1}. In words, project the new encoder feature and old decoder result, then blend them using a gate computed from both; the feedback scale controls the old-state contribution. The notebook analogy is useful here: the decoder can keep some of its running notes and replace others, but it is not literally erasing entries from a symbolic ledger.

What does the decoder do with that merged input? It attends to its recent decoder activations and the encoder prefix, then updates its final output and its cache. In symbols, Ht=(st,CtD)H_t=(s_t,C^D_t) means the state includes both the output vector and the decoder's retained attention keys and values. That is why later positions inherit more than a single summary vector: they also have the recent decoder context needed by sliding-window attention. The encoder memory is a separate resource, not the recurrent state itself.

Can the decoder look at all the encoder memory during prompt processing? It can have the full prompt memory computed, but position tt is restricted to the causal prefix M≤tM_{\le t}. This is a subtle but important split: encoder computation over known tokens is parallel, while RLT-1's decoder transitions remain sequential. During generation, a token is encoded, its memory entry is appended, and the decoder state advances. What changes if you relax the every-token feedback schedule? Other feedback intervals alter that schedule, but the per-token mechanism here makes the tradeoff clear: richer recurrent accumulation in exchange for ordered decoder work.

Read the deep dive

Why People Wanted It

A fixed-depth Transformer gives each position a bounded number of layers to compute with. That is a problem when the task is to update a state one input at a time: parity accumulates bits, while permutation tracking composes group elements. The real question is whether a Transformer can let later tokens build on earlier computation without making every token traverse an ever-growing stack of layers.

RLT splits the work. A causal encoder processes token representations and builds reusable key–value memory. A decoder then processes positions in order, combining each position's encoder representation with the previous position's final decoder output. Thus, with decoder depth LDL_D, a sequence of tt tokens creates a recurrent path through tLDtL_D decoder blocks, while each token still passes through only LE+LDL_E+L_D layers.

The Core Move

Keep a causal encoder's memory available, but make the decoder's input depend on its own previous output: ut=Merge⁡(et,st−1)u_t = \operatorname{Merge}(e_t,s_{t-1}), then st=Dϕ(ut;M≤t,C<tD)s_t = D_\phi(u_t;M_{\le t},C^D_{<t}).

Here ete_t is the current encoder representation, M≤tM_{\le t} is the encoder memory through position tt, and C<tDC^D_{<t} is the decoder's recent self-attention cache. The decoder state passed forward includes both its final output and that cache.

Quiz
What creates the recurrent computation path in RLT-1?
The encoder repeats its full stack once for every token.
The previous decoder output is fed into the next token's decoder input through a gated merge.
The current token attends to all future encoder representations.
The decoder shares one fixed output across the whole sequence.

Why the Merge Is Gated

Here is the part that gets technical: the merge is not just a sum of the new encoder feature and old decoder state; it uses a learned gate to choose how much each contributes. In the paper's notation, ut=gt⊙Weet+(1−gt)⊙Wsst−1u_t = g_t \odot W_e e_t + (1-g_t) \odot W_s s_{t-1}, where gt=σ(Wg[et;st−1])g_t = \sigma(W_g[e_t;s_{t-1}]) and the feedback contribution is scaled by α\alpha in the implemented form.

The gate is computed from both inputs, so its choice can depend on the current token representation and the accumulated decoder result. WeW_e and WsW_s project the two signals into the decoder width; WgW_g produces an elementwise mixing coefficient, and α\alpha controls feedback scale. The main comparison uses α=0.1\alpha=0.1. This gives the decoder a learned route to retain its recurrent computation or emphasize new encoder evidence, rather than forcing a fixed blend.

Why the Decoder Cache Is Part of the Recurrent State

Now the version for readers who want more of the machinery: the recurrent state is not only sts_t; it is Ht=(st,CtD)H_t=(s_t,C^D_t), because later decoder updates need both the previous final output and the self-attention keys and values retained from earlier positions.

At each decoder block, the current input forms its key and value before causal sliding-window attention, avoiding a circular dependency at the current position. The block then uses encoder-memory cross-attention and an FFN. After the update, the decoder retains the recent key–value positions allowed by its window. So the transition updates the feedback vector and decoder cache together; the encoder memory supplies conditioning, rather than being the recurrent state itself.

Why Encoder Memory Can Be Reused

Here is the deeper execution constraint: the encoder is causal, and decoder position tt attends only to the encoder prefix M≤tM_{\le t}, even if prefill has already computed memory for the whole prompt. During generation, a new token is encoded incrementally, its encoder key–value entry is appended, and the decoder advances with the updated memory and its own cache.

This lets the decoder revisit token representations through encoder-memory attention without recomputing the encoder stack for every decoder step. But it does not remove sequential dependence in RLT-1: prompt prefill still evaluates decoder states H1,…,HTH_1,\ldots,H_T in order, because each update feeds the next. Chunked feedback changes that scheduling; it is a separate variant, not a property of the per-token recurrence described here.

Minimal Causal Code

The sketch exposes the state transition; attention and projections are abbreviated, not optimized.

state = initial_decoder_state()
encoder_memory = []

for t, token in enumerate(tokens):
    e_t, encoder_kv = causal_encoder_step(token)
    encoder_memory.append(encoder_kv)

    # Only the causal prefix is visible to this position.
    memory_prefix = encoder_memory[: t + 1]
    u_t = gated_merge(e_t, state.output)

    # The decoder uses its prior cache and returns both the new output
    # and the updated cache as the next recurrent state.
    output_t, decoder_cache = decoder_step(
        u_t, memory_prefix, state.cache
    )
    state = DecoderState(output=output_t, cache=decoder_cache)

What You Gain, and What You Lose

The gain is a computation path whose depth grows with sequence length, while each token still evaluates only the encoder and decoder stacks once. Reusing encoder memory also gives the decoder access to the causal token representations as its recurrent state evolves. This is aimed at tasks where later decisions need to build on earlier state updates.

The cost is order-dependent decoder work: RLT-1 needs one decoder update per known token, so prompt prefill is sequential through those updates even though the encoder processes known tokens in parallel. More decoder depth lengthens the recurrent path but adds decoder work in token order. The decoder cache is part of the state and must be carried forward as well. The design therefore trades parallel decoder scheduling for recurrent computation; it does not make the whole model parallel across positions.

Quiz
Which components make up the recurrent decoder state described for RLT-1?
Only the current encoder representation.
The entire sequence of token IDs and no cache.
Only the encoder's global key–value memory.
The decoder output and its self-attention cache.
Core Takeaway

RLT keeps encoder memory parallel and reusable, but makes decoder updates walk forward one token at a time, carrying both the output and its cache.