Skip to content

[ARCH-PROP] Cubit: Token Mixer with Kernel Ridge Regression #20

Description

@chuanyang-Zheng

Architecture Name

Cubit: Use $Kernel(QK^T)(Kernel(KK^T))^{-1}V$ to replace $Kernel(QK^T)V$

Parent issue

#1

Motivations

Since its introduction in 2017, the Transformer has become one of the most widely adopted architectures in modern deep learning. Despite extensive efforts to improve positional encoding, attention mechanisms, and feed-forward networks, the core token-mixing mechanism in Transformers remains attention. In this work, we show that the attention module in Transformers can be interpreted as performing Nadaraya-Watson regression, where it computes similarities between tokens and aggregates the corresponding values accordingly. Motivated by this perspective, we propose Cubit, a potential next-generation architecture that leverages Kernel Ridge Regression (KRR), while the vanilla Transformer relies on Nadaraya-Watson regression. Specifically, Cubit modifies the classical attention computation by incorporating the closed-form solution of KRR, combining value aggregation through kernel similarities with normalization via the inverse of the kernel matrix. To improve the training stability, we further propose the Limited-Range Rescale (LRR), which rescales the value layer within a controlled range. We argue that Cubit, as a KRR-based architecture, provides a stronger mathematical foundation than the vanilla Transformer, whose attention mechanism corresponds to Nadaraya-Watson regression. We validate this claim through comprehensive experiments. The experimental results suggest that Cubit may exhibit stronger long-sequence modeling capability. In particular, its performance gain over the Transformer appears to increase as the training sequence length grows.

Proposed Architecture

class Cubit(nn.Module):
    def __init__(
        self,
        hidden_size: int,
        attention_head: int,
        eps: float = 1e-10,
        upper: float = 2.0,
        lower: float = 0.5,
        share: bool = True,
        causal_mask: bool = True
    ):
        super().__init__()

        self.hidden_size = hidden_size
        self.attention_head = attention_head
        self.hidden_size_per_head = hidden_size // attention_head
        self.share = share
        self.causal_mask = causal_mask
        self.eps = eps

        # Linear projections for Q, K, V
        self.q = nn.Linear(hidden_size, hidden_size)
        self.k = nn.Linear(hidden_size, hidden_size)
        self.v = nn.Linear(hidden_size, hidden_size)

        # Optional separate R projection
        if not share:
            self.r = nn.Linear(hidden_size, hidden_size)
        

        # Learnable bounds for LR scale - shape: (1, attention_head, 1, 1)
        self.lower = nn.Parameter(torch.full((1, attention_head, 1, 1), lower))
        self.upper_scale = nn.Parameter(torch.full((1, attention_head, 1, 1), upper - lower))

        # LR scaling factor per head
        self.LRR = nn.Linear(hidden_size, attention_head)

        # Learnable scale for normalized R - shape: (1, attention_head, 1, 1)
        self.scale = nn.Parameter(torch.ones(1, attention_head, 1, 1))

        # Regularization strength lambda (log space for stability) - shape: (1, attention_head, 1, 1)
        self.log_lambda = nn.Parameter(
            torch.full((1, attention_head, 1, 1), math.log(eps)),
            requires_grad=True
        )



    def forward(self, x, pos_encoding_function,softmax, mask) -> torch.Tensor:
        b, t, d = x.shape
        device = x.device

        # Q, K, V, R projections
        q=self.q(x).reshape(b,t,self.attention_head,self.hidden_size_per_head).permute(0,2,1,3)
        k=self.k(x).reshape(b,t,self.attention_head,self.hidden_size_per_head).permute(0,2,1,3) 
        v=self.v(x).reshape(b,t,self.attention_head,self.hidden_size_per_head).permute(0,2,1,3) 
        # Determine R: separate if share=False, else reuse K
        if self.share:
             r=k
        else:
            r=self.r(x).reshape(b,t,self.attention_head,self.hidden_size_per_head).permute(0,2,1,3)
        # LR factor: sigmoid-scaled between lower and upper
        # lrr_logits shape: (B, n_head, T, 1)
        lrr_logits = self.lrr(x).reshape(b, t, self.attention_head, 1).permute(0, 2, 1, 3)
        # lrr shape: (B, n_head, T, 1)
        lrr = self.lower + self.upper_scale * torch.sigmoid(lrr_logits)




        # Normalize R with learnable scale
        # norm_r shape: (B, n_head, T, head_dim)
        norm_r = r / torch.norm(r, dim=-1, p=2, 
        keepdim=True) * self.scale
        
        # add position encoding
        q,k,r,norm_r=pos_encoding_function(q,k,r,norm_r)

        # Sigma inverse: softmax similarity + lambda * I
        # r @ norm_r.transpose(-2, -1) shape: (B, n_head, T, T)
        sigma_inv = softmax(r @ norm_r.transpose(-2, -1), mask)
        
        # I shape: (1, 1, T, T) -> broadcast to (B, n_head, T, T)
        I = torch.eye(t, device=device).unsqueeze(0).unsqueeze(0)
        lambda_reg = torch.exp(self.log_lambda)  # shape: (1, n_head, 1, 1)
        sigma_inv = sigma_inv + lambda_reg * I

        # Solve linear system for each head
        # rhs shape: (B, n_head, T, head_dim)
        rhs = lrr * v
        

        # solution shape: (B, n_head, T, head_dim)

        if self.casual_mask:
            solution = torch.linalg.solve_triangular(sigma_inv, rhs,upper=False)
        else:
            solution = torch.linalg.solve(sigma_inv, rhs)
        


        # Standard attention with Q, K
        A_weights = softmax(
            q @ k.transpose(-2, -1) / math.sqrt(self.hidden_size_per_head), 
            mask
        )  # shape: (B, n_head, T, T)

        # Final output
        output = A_weights @ solution  # shape: (B, n_head, T, head_dim)
        
        # Reshape back to (B, T, hidden_size)
        output = output.permute(0, 2, 1, 3).reshape(b, t, self.hidden_size)
        
        return output

Preliminary Results (if any)

https://arxiv.org/pdf/2605.06501

Experiments Plan

The primary results already give detailed evaluation. We hope that industry could further push it forward.

Ridge Regression: Linear Attention
Nadaraya-Watson Regression: Transformer
Kernel Ridge Regression (Minmax Optimal): Cubit

Metadata

Metadata

Labels

architecture proposalPropose an LLM architecture modificationin-progressImplementation or experiment is in progress

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions