Cross-Attention
Cross-attention is a mechanism that allows one sequence (the query source) to attend to and extract information from a different sequence (the key-value source), enabling learned, dynamic information routing between two distinct modalities or contexts. It is the architectural bridge that makes encoder-decoder transformers coherent — powering machine translation, image-conditioned generation, and multimodal fusion — and is arguably the single most important operation in modern generative AI. The counterintuitive fact: cross-attention adds zero parameters beyond what self-attention uses structurally; the only difference is where Q, K, and V come from.
In self-attention, a sequence asks questions about itself. In cross-attention, one sequence asks questions (queries) and a completely different sequence provides both the reference index (keys) and the actual content (values). The "aha moment" is realizing this is simply a soft, differentiable lookup table: the query sequence searches the key sequence to compute relevance weights, then uses those weights to blend the value sequence into a new representation. Every query token ends up as a weighted mixture of all value tokens, where the mixture is determined by how well each query matches each key — and the whole thing is end-to-end trainable.
How It Works
Cross-attention operates on two sequences: a query sequence and a key-value sequence . Three learned linear projections map these into the attention's internal space:
Explanation: The query matrix Q comes from one source sequence, while K and V both come from a separate source — this asymmetry is the entire definition of cross-attention versus self-attention. Here and are learned weight matrices. The raw attention logits (affinities) are computed as a scaled dot product:
Explanation: Each of the query vectors is compared against each of the key vectors, producing a full affinity matrix whose entry scores how relevant the -th key-value position is to the -th query. The scaling prevents dot products from growing large in magnitude (which would push softmax into saturation regions with near-zero gradients). Softmax normalizes each row independently:
Explanation: Each query position now holds a valid probability distribution over all key-value positions, expressing how much attention that query pays to each part of the conditioning sequence. Finally, the output is a weighted mixture of value vectors:
Explanation: Every output token is a convex combination of all value vectors, with weights given by the corresponding row of the attention matrix — the output length equals , not . For multi-head cross-attention, independent attention heads run in parallel, each with its own projections , and their outputs are concatenated and projected:
Explanation: Multiple heads allow the model to simultaneously route different types of information from the conditioning sequence — for example, in translation one head might track syntactic correspondence while another tracks semantic meaning. A minimal PyTorch implementation clarifies the mechanics: ```python import torch import torch.nn as nn import torch.nn.functional as F class CrossAttention(nn.Module): def __init__(self, d_model: int, d_k: int, d_v: int, num_heads: int): super().__init__() self.num_heads = num_heads self.d_k = d_k
# Separate projections: Q from query seq, K/V from kv seq self.W_Q = nn.Linear(d_model, d_k num_heads, bias=False) self.W_K = nn.Linear(d_model, d_k num_heads, bias=False) self.W_V = nn.Linear(d_model, d_v num_heads, bias=False) self.W_O = nn.Linear(d_v num_heads, d_model, bias=False) def forward( self, x_q: torch.Tensor, # (B, T_Q, d_model) — query source x_kv: torch.Tensor, # (B, T_KV, d_model) — key/value source mask: torch.Tensor | None = None, ) -> torch.Tensor: B, T_Q, _ = x_q.shape T_KV = x_kv.shape[1] h = self.num_heads
# Project and split into heads Q = self.W_Q(x_q).view(B, T_Q, h, self.d_k).transpose(1, 2) # (B, h, T_Q, d_k) K = self.W_K(x_kv).view(B, T_KV, h, self.d_k).transpose(1, 2) # (B, h, T_KV, d_k) V = self.W_V(x_kv).view(B, T_KV, h, -1).transpose(1, 2) # (B, h, T_KV, d_v)
# Scaled dot-product attention scale = self.d_k ** -0.5 logits = torch.matmul(Q, K.transpose(-2, -1)) * scale # (B, h, T_Q, T_KV) if mask is not None: logits = logits.masked_fill(mask == 0, float('-inf')) attn = F.softmax(logits, dim=-1) # (B, h, T_Q, T_KV) out = torch.matmul(attn, V) # (B, h, T_Q, d_v)
# Merge heads and project out = out.transpose(1, 2).contiguous().view(B, T_Q, -1) return self.W_O(out) # (B, T_Q, d_model) ``` Note how `x_q` and `x_kv` are kept strictly separate — they can differ in length, token type, and even modality (text vs. image patches).
Vaswani led the Google Brain team that published Attention Is All You Need (2017), introducing the transformer architecture in which cross-attention plays the central role of connecting encoder and decoder. His formalization of scaled dot-product attention and multi-head attention became the standard that every subsequent model — GPT, BERT, DALL·E, Stable Diffusion — builds upon. Vaswani later left Google to co-found Essential AI, and the paper he led has accumulated over 130,000 citations, making it one of the most cited machine learning papers in history.
Intuition
Imagine you are a student (the query sequence) taking an open-book exam with access to a reference textbook (the key-value sequence). For each exam question, you scan the textbook's table of contents (the keys) to find which sections are most relevant, then read those sections (the values) to compose your answer. You don't rewrite the textbook — you selectively absorb information from it based on the relevance of each section to your current question. Crucially, your exam questions and the textbook are completely separate documents written by different people. The exam might be in English while the textbook is in French — the attention mechanism learns to bridge that gap. The output of cross-attention is a new "answer sheet" that has exactly as many entries as your questions (not as many as textbook sections), and each answer is a soft blend of textbook content weighted by relevance. In machine translation: the decoder (translating one word at a time into French) holds the queries — "what English context do I need right now?" The encoder output (representing the full English sentence) provides keys and values — "here is all the English information available, indexed and ready to retrieve." Cross-attention lets each generated French word selectively draw from whichever English words are most relevant at that moment. A useful contrast with self-attention: in self-attention, it is as if you are studying your own notes and finding connections between your own ideas. In cross-attention, you are consulting an external source — and the two documents can be completely different lengths.
Historical Development
Origins · 1 minhow this was discovered
Why It Matters
Prerequisites
What This Leads To
See Also
Self-Attention · Scaled Dot-Product Attention · Positional Encoding · Diffusion Models · Vision Transformers