FastPrepTransformer Attention and SwiGLU Forward Pass

Transformer Attention and SwiGLU Forward Pass

Google logoGoogle● HardFULLTIMEONSITE INTERVIEW
Learn

Problem statement

Implement a Transformer attention and SwiGLU forward pass for one sequence of token vectors.

For this exercise, assume the pass consists exactly of bias-free multi-head self-attention followed by a bias-free SwiGLU feed-forward layer. The formulas below define the complete judged computation.

Inputs and shapes

  • x has shape n by d.
  • wq, wk, wv and wo each have shape d by d.
  • wg and wu each have shape d by f; wd has shape f by d.
  • heads divides d. Each head uses width = d / heads consecutive feature coordinates.

Multi-head self-attention

  1. Project the tokens: Q = x * wq, K = x * wk and V = x * wv.
  2. For head h, use coordinates h * width through (h + 1) * width - 1. For query token i and key token j, its score is the dot product of their head slices divided by sqrt(width).
  3. Apply softmax across all n key tokens independently for each query and head: p[j] = exp(score[j]) / sum(exp(score)). Form the weighted sum of that head's value slices.
  4. Concatenate heads in increasing head order to obtain C of shape n by d, then compute A = C * wo.

Parallel SwiGLU branches

Compute G = A * wg and U = A * wu from the same A. For every coordinate, define SiLU(z) = z / (1 + exp(-z)). Multiply element by element to obtain B = SiLU(G) elementwise-multiplied-by U. Return B * wd, an n by d matrix.

For this exercise, assume there is no batch dimension, causal or padding mask, bias, residual addition, normalization, positional encoding, dropout, training or backward pass. Use ordinary matrix loops and standard mathematical functions without a machine-learning or numerical-array library. A stable softmax may subtract the row maximum before exponentiation.

Function

transformerForward(x: double[][], wq: double[][], wk: double[][], wv: double[][], wo: double[][], wg: double[][], wu: double[][], wd: double[][], heads: int) → double[][]

Examples

Example 1

x = [[1]]wq = [[1]]wk = [[1]]wv = [[1]]wo = [[1]]wg = [[1]]wu = [[1]]wd = [[1]]heads = 1return = [[0.7310585786300049]]

There is one token and one head, so its attention probability is one. All projections preserve 1. The gate and up branches are both 1, giving SiLU(1) times 1 = approximately 0.7310585786.

Example 2

x = [[1,0],[0,1]]wq = [[1,0],[0,1]]wk = [[1,0],[0,1]]wv = [[1,0],[0,1]]wo = [[1,0],[0,1]]wg = [[1,0],[0,1]]wu = [[1,0],[0,1]]wd = [[1,0],[0,1]]heads = 2return = [[0.3607715420179067,0.15561483280046365],[0.15561483280046365,0.3607715420179067]]

Each one-coordinate head has its own softmax. The concatenated attention rows are approximately [0.7310585786,0.5] and [0.5,0.7310585786]; applying the two parallel identity branches and SiLU gives the displayed output.

Example 3

x = [[1,2],[-1,0]]wq = [[0,0],[0,0]]wk = [[1,0],[0,1]]wv = [[1,0],[0,1]]wo = [[1,0],[0,1]]wg = [[1,0],[0,1]]wu = [[1,0],[0,1]]wd = [[1,0],[0,1]]heads = 1return = [[0.0,0.7310585786300049],[0.0,0.7310585786300049]]

Every projected query is zero, so both tokens receive weight 0.5. Their average value is [0,1], and the identity output projection preserves it. Both output rows are [0,SiLU(1)].

Constraints

  • For this exercise, assume 1 <= n <= 16, 1 <= d <= 8, 1 <= f <= 16, and 1 <= heads <= d with d % heads = 0.
  • Every matrix is nonempty, rectangular and has the stated compatible shape.
  • Token coordinates are finite values in [-8,8]; weight coordinates are finite values in [-2,2].
  • Compute in double precision. Each returned coordinate is accepted when its absolute error is at most 10^-7 * max(1, abs(expected)).

More Google problems

See Google hiring insights
public double[][] transformerForward(double[][] x, double[][] wq, double[][] wk, double[][] wv, double[][] wo, double[][] wg, double[][] wu, double[][] wd, int heads) {
    // Write your code here
}
x[[1]]
wq[[1]]
wk[[1]]
wv[[1]]
wo[[1]]
wg[[1]]
wu[[1]]
wd[[1]]
heads1
expected[[0.7310585786300049]]
Checking account…