🍐 nguyen

Một chút về Transformers (Phần 3): What the hell is Residual Stream

June 21, 2025
24 min read
index

Nếu các bạn chưa tự tin về Transformers thì hãy đọc qua phần 1 và phần 2 nhá. Phần 1 ở đây, phần 2 ở đây.

Toàn bộ bài viết này là note của mình cho bài báo [] (cũng là bài báo favorite của mình).

1. Một góc nhìn tổng quát

High-Level Architecture
Một góc nhìn tổng quan về kiến trúc Transformer

Một mô hình transformers sẽ bắt đầu token embedding, đưa một token tt (one-hot vector) thành một vector embedding x0x_0 thông qua embedding matrix WEW_E, tiếp sau đó là một chuỗi các residual blocks, và cuối cùng là đến token unembedding, đưa một vector embedding x1x_{-1} (layer cuối) sang vector logits T(t)T(t) thông qua unembedding matrix WUW_U.

Mỗi residual block (hay transformers block) sẽ bao gồm một attention layer và sau đó là một MLP layer. Cả attention layer và MLP layer read (đọc) input từ residual stream (đường thẳng từ xix_i đến xi+1x_{i+1} và tương tự xi+1x_{i+1} đến xi+2x_{i+2} như hình) và sau đó write (ghi) kết quả của chúng (các layer) vào residual stream bằng cách dùng residual connection xi+1=xi+layer(xi)x_{i+1} = x_i + \text{layer}(x_i).

2. Residual Stream là một kênh liên lạc giữa các component Transformers với nhau

Nếu ta xem Transformers như một cái máy tính siêu phức tạp thì Residual stream là một trong những tính năng chính của Transformers (thật ra residual stream đã xuất hiện trong những model xưa hơn ví dụ cell memory của LSTM hay ResNet). Residual stream chỉ đơn giản là tổng của ouput layer trước đó (ví dụ là attention layer hoặc MLP layer) với embedding ban đầu (ví dụ là vector embedding xix_i).

Ta xem residual stream là một communication channel bởi vì nó không thực hiện bất kỳ phép toán hay xử lý nào (ví dụ MLP sẽ thực hiện nhân ma trận) và mọi layers (hay các component) thực hiện liên lạc với nhau (bằng cách read thông tin từ layer trước đó và write để tạo thông tin mới cho layer sau) thông qua residual stream.

Residual stream có linear structure (cấu trúc tuyến tính) (khác với ResNet, ở mỗi residual connection của ResNet đều sử dụng thêm activation ví dụ như ReLU). Mỗi layer trong residual block thực hiện các linear transformation (ánh xạ tuyến tính) bất kỳ để read input từ residual stream. Ngoài ra, trước khi write outputs của layer ấy vào residual stream, layer cũng thực hiện các linear transformation.

  • Giờ ta sẽ tập trung vào attention layer trước, nhắc lại, mỗi vector embedding xix_i sẽ được chiếu (hay nói cách khác, nhân ma trận) để trở thành các query, key, value vector thông qua các ma trận WQ,WK,WVW_Q, W_K, W_V tương ứng (đây chính linear transformation để đọc input xix_i từ residual stream). Sau khi đã tính được giá trị headhead (chính là output của một attention head), giá trị này sẽ được chiếu lần nữa thông qua WOW_O (đây chính là linear transformation trước khi write ouputs của layer vào residual stream).
  • Thông thường (theo bài báo gốc), MLP của Transformers bao gồm 1 hidden layer, vậy tức là ở lần đầu tiên, input sẽ được chiếu vào hidden layer thông qua 1 linear transformation (read) sau đó hidden layer này được chiếu sang output layer thông qua 1 linear transformation nữa (before write) và cuối cùng đưa qua activation (write).

Một trong những hệ quả của tính linear, addtive (tuyến tính và cộng) của residual stream chính là residual stream không có cơ sở ưu tiên (privileged basis) 1. Vì vậy, ta có thể xoay (rotate) các ma trận mà tương tác với residual stream mà không làm thay đổi hành vi (behaviors) của model.

a. Cơ sở ưu tiên

  • Xét một không gian vector VV gồm NN chiều, khi đó basis (cơ sở) là tập hợp NN vector độc lập tuyến tính với nhau, gọi là b1,...,bNb_1, ..., b_N sao cho V=span(b1,...,bN)V = \text{span}(b_1, ..., b_N). Tức là mọi vector trong không gian vector đều có thể viết thành tổ hợp tuyến tính của basis tương ứng. Ở đây vector space có thể chính là không gian hidden state của model và vector space ấy có dd (model dimension) chiều.
  • Thông thường khi nhắc đến basis, ta quan tâm nhiều hơn đến standard basis (cơ sở chuẩn), gọi là e1,...,eNe_1, ..., e_N và có duy nhất vị trí ii11, còn lại là 00 (ví dụ như trục xyzxyz cho vector space 3 chiều).

Dựa theo định nghĩa của bài báo gốc 1:

A privileged basis occurs when some aspect of a model’s architecture encourages neural network features to align with basis dimensions, for example because of a sparse activation function such as ReLU.

Bây giờ ta sẽ giải thích từng câu để làm rõ cơ sở ưu tiên:

Dựa theo [], một đặc trưng (feature) là một thuộc tính có ý nghĩa mà neural network học được để phát hiện trong dữ liệu. Thay vì xem feature là một neuron cụ thể, ta nên xem nó là một khái niệm mà neural network sử dụng, ví dụ như “có tai nhọn”, “có màu đỏ”, “là một đường thẳng đứng”, hay “mang sắc thái tiêu cực”.

Điều quan trọng là feature này được biểu diễn như thế nào bên trong mạng.

  • Trong một cơ sở ưu tiên, một feature có thể được biểu diễn bởi một neuron duy nhất (hoặc một nhóm nhỏ các neuron). Bởi vì ta có thể mỗi neuron là một trục trong hệ cơ sở của không gian NN chiều (đối với NN neuron), do đó mỗi trục này sẽ gần như ứng với một feature.
  • Trong một cơ sở không ưu tiên (non-privileged basis), một feature có thể là một sự kết hợp phức tạp của nhiều neuron (như đã nói ở trên, một neuron xem như một vector, vì vậy feature là một tổ hợp tuyến tính của các neuron).

Để làm rõ hơn, giờ ta lấy ví dụ một neural network (MLP) đơn giản được huấn luyện để nhận dạng các hình dạng trong ảnh. Ta sẽ tập trung vào một hidden layer, gọi là Layer LL.

  • Layer L có N=4N=4 neuron. Vì vậy, không gian kích hoạt (activation space) của có 4 chiều.
  • Các vector cơ sở cho không gian này là các cơ sở chuẩn:
    • b1=[1,0,0,0]\mathbf{b}_1 = [1, 0, 0, 0] (trục của Neuron 1)
    • b2=[0,1,0,0]\mathbf{b}_2 = [0, 1, 0, 0] (trục của Neuron 2)
    • b3=[0,0,1,0]\mathbf{b}_3 = [0, 0, 1, 0] (trục của Neuron 3)
    • b4=[0,0,0,1]\mathbf{b}_4 = [0, 0, 0, 1] (trục của Neuron 4)

Mục tiêu của chúng ta là phát hiện ba hình dạng cơ bản: hình vuông, hình tam giác và hình tròn. Sau khi huấn luyện, mạng có thể học được rằng:

  • (1) Không có ReLU
    • Một hình vuông được biểu diễn bởi vector [1.2, -0.9, 0.8, 1.1]. Đây là một dense vector (ít các phần tử bằng 00) chỉ theo một hướng bất kỳ trong không gian 4D.
    • Một hình tam giác được biểu diễn bởi [-0.8, -1.1, 1.3, -0.9].
    • Một hình tròn được biểu diễn bởi [1.4, 1.2, 0.1, -0.7]
    • Có thể thấy, nếu không có ReLU, mỗi feature là một tổ hợp tuyến tính cụ thểphức tạp của cả bốn neuron. Ta không thể chỉ vào một neuron duy nhất và nói “đây là neuron chuyên phát hiện hình vuông”. Các feature không thẳng hàng (align) 2 với các vector cơ sở. Đây là một cơ sở không ưu tiên.
  • (2) Có sự xuất hiện của ReLU
    • Một hình vuông được biểu diễn bởi vector [1.2, -0.9, 0.8, 1.1] lúc này trở thành [1.5, 0, 0, 0.1]. Có thể thấy vector này sparse (thưa) và đặc biệt hơn là vector này có thể được xấp xỉ bằng αb1\alpha \mathbf{b}_1 với α=1.5\alpha = 1.5, do đó feature hình vuông này được “align” hoàn toàn với neuron đầu tiên.
    • Tương tự với hình trònhình tam giác, ta có các vector sau ReLU lần lượt là [1.4, 1.2, 0.1, 0][0, 0, 1.3, 0]. Feature hình tam giác hoàn toàn align với neuron 3. Trong khi đó feature hình tròn lại phức tạp hơn khi cần 2 neuron để biểu diễn là neuron 1 và neuron 2 (điều này còn cho thấy, neural network xem feature hình tròn rất gần với feature hình vuông).
  • Có thể thấy nhờ sự xuất hiện của ReLU (hay theo định nghĩa gốc, “occurs when some aspect of a model’s architecture encourages neural network features to align with basis dimensions”), các feature đã được align với từng neuron, vì vậy ta có thể “tự tin” chỉ tay vào từng neuron và bảo rằng neuron này trách nhiệm cho phát hiện hình vuông, … Điều này làm cho biểu diễn có thể diễn giải được, và đó là những gì ta gọi là một cơ sở ưu tiên (privileged basis). Một điều nữa đó là tính không tuyến tính (non-linear) của ReLU và cả tính sparse của vector kích hoạt (sau ReLU).

b. Xoay cơ sở

Hãy nghĩ về xoay như thế này:

  • Mô hình với cơ sở không ưu tiên giống như một người ngoài hành tinh nói một ngôn ngữ khó hiểu (u i i ai o uu ii a i). Nó biết câu trả lời đúng, nhưng cách nó biểu diễn “tại sao lại có câu trả lời” ấy thông qua các feature được encode theo những hướng (cực kì lộn xộn) trong không gian nhiều chiều (có khi là cả trăm ngàn chiều với trăm ngàn neuron).
  • Trục Neuron (cơ sở tiêu chuẩn) là ngôn ngữ duy nhất chúng ta (con người) có thể “đọc” và “diễn giải” một cách trực tiếp. Nhưng việc này là vô dụng nếu đây một cơ sở không ưu tiên.

Mục tiêu của việc “xoay cơ sở” 3 là tìm ra một hệ tọa độ (cơ sở) mới mà align với các feature thực sự mà mô hình đã học. Quá trình tìm hệ tọa độ mới này về mặt toán học chính là một phép xoay. Khi đã tìm được “cơ sở diễn giải được” (interpretable feature) này, chúng ta có thể chỉ vào một trục hay neuron mới (một hướng đã được xoay) và tự tin nói: “Hướng này phát hiện hình tròn”.

Chúng ta xoay cơ sở để chúng ta, con người, có thể hiểu được mô hình.

Và một điểm đặc biệt của Residual Stream đó chính là xoay cơ sở không làm thay đổi hành vi (hay chính xác là output) của mô hình. Tại sao lại vậy ?

  • Xét một ma trận xoay RR, đầu tiên RR là một orthogonal matrix (ma trận trực giao), tức là R1=RTR^{-1} = R^T hay RTR=RRT=IR^TR = RR^T = I. Giả sử vector embedding xix_i nằm trên residual stream được xoay bằng ma trận xoay RR, khi đó ta có xi=Rxix'_i = R x_i.
  • Mỗi component (attention, mlp, …) nếu muốn tương tác (read, write) với residual stream thì cần phải xoay ma trận chiếu tương ứng của nó.
  • Xét Attention Component:
    • Input từ residual stream sẽ được read thông qua 3 ma trận WQ,WK,WVW_Q, W_K, W_V, do xix_i đã rotate thông qua ma trận RR, để không làm thay đổi behavior, ta cần WQ,WK,WVW'_Q, W'_K, W'_V mới sao cho:
    WQxi=WQxi;WKxi=WKxi;WVxi=WVxiW_Q x_{i} = W'_{Q} x'_{i}; \quad W_{K} x_{i} = W'_{K} x'_{i}; \quad W_{V}x_{i} = W'_{V}x'_{i}
    • Có thể thấy WQxi=WQRxi=(WQR)xi    WQR=WQ    WQ=WQRTW'_Qx'_i = W'_{Q}Rx_{i} = (W'_{Q}R)x_{i} \implies W'_{Q}R = W_{Q} \implies W'_{Q} = W_{Q}R^T. Vậy, khi mà input ở residual stream bị xoay bởi ma trận RR thì các phép chiếu tuyến tính (hay chính là nhân ma trận) trong component sẽ “un-rotate” xix'_i thông qua ma trận RTR^T, tức là RTxi=(RTR)xi=xiR^Tx'_i = (R^TR)x_i = x_i. Điều này cho thấy, các cách tính toán (WQ,WK,WVW_Q, W_K, W_V) bên trong component vẫn giữ nguyên không thay đổi.
    • Tiếp theo ở operation write, attention layer sẽ write vào residual stream thông qua công thức sau:
    xi+1=xi+WOheadix'_{i+1} = x'_{i} + W'_{O} \text{head}_{i}
    • Do các giá trị trên residual stream đều rotate bởi RR, vì vậy:
    Rxi+1=Rxi+WOheadi    R(xi+WOheadi)=Rxi+WOheadi    RWOheadi=WOheadi\begin{aligned} Rx_{i+1} &= Rx_{i} + W'_{O} \text{head}_{i} \\ \implies R(x_{i} + W_{O}\text{head}_{i}) &= Rx_{i} + W'_{O}\text{head}_{i} \\ \implies RW_{O}\text{head}_{i} &= W'_{O}\text{head}_{i} \end{aligned}
    • Có thể thấy nếu input xoay bởi ma trận RR, thì cùng lúc đó ma trận output cũng xoay bởi ma trận RR 4.
  • Với residual stream, ta có thể thấy việc rotate input thông qua ma trận RR bất kỳ sẽ không làm ảnh hưởng đến các việc tính toán của các component (các component vẫn tính toán bằng đúng các tính toán trước khi rotate, ví dụ như: WQxi=WQ(RTR)xi=WQxiW_{Q}x_{i} = W_Q(R^TR)x_i = W'_Qx'_i). Vì vậy residual stream không phụ thuộc vào 1 basis bất kì nào (việc rotate sẽ thay đổi basis => ta nói residual stream là basis-free).

3. Virtual Weights (Trọng số “ảo”)

Virtual Weight
Nhờ tính Linear của Residual Stream, ta có thể xem như có một bộ trọng số 'ảo' kết nối input và output ở layer bất kỳ lại với nhau

Nhờ tính linear của Residual Stream mà ta có thể xem như có một bộ trọng số “ảo” kết nối một cặp layer bất kỳ (cho dù khoảng cách giữa hai layer ấy có xa hay không). Bộ trọng số ảo này chính là tích ma trận giữa trọng số output của một layer và trọng số input của layer còn lại.

Xét component (kí hiệu là CC) thứ 11, ta có x2=x1+WO1C1(WI1x1)x_2 = x_1 + W_O^1 C_1(W_I^1x_{1}), đặt yiy_i là output của component thứ ii (trước khi chiếu qua trọng số output), do đó x2=x1+WO1y1x_2 = x_1 + W_O^1 y_1. Tổng quát lên, với mỗi component thứ jj, ta có:

xj+1=xj+WOjyjx_{j+1} = x_{j} + W_{O}^j y_{j}

Khi đó, ở component tiếp theo j+2j+2, component này sẽ read information từ residual stream, do đó input của j+1j+1 sẽ là:

WIj+1xj+1=WIj+1xj+WIj+1WOjyjW_{I}^{j+1} x_{j+1} = W_{I}^{j+1}x_{j} + W_{I}^{j+1}W_{O}^j y_{j}

Có thể thấy, ở component layer sau, component này read information ở layer phía trước thông qua virtual weight WIj+1WOjW_I^{j+1}W_O^{j} (là tích của ma trận input layer hiện tại và ma trận output layer phía trước).

Tương tự, ở component tiếp theo, ta cũng có:

WIj+2xj+2=WIj+2xj+1+WIj+2WOj+1yj+1=(WIj+2xj+WIj+2WOjyj)+WIj+2WOj+1yj+1\begin{aligned} W_{I}^{j+2}x_{j+2} &= W_{I}^{j+2}x_{j+1} + W_{I}^{j+2}W_{O}^{j+1}y_{j+1} \\ &= (W_{I}^{j+2}x_{j} + W_{I}^{j+2}W_{O}^jy_{j}) + W_{I}^{j+2}W_{O}^{j+1}y_{j+1} \end{aligned}

Tổng quát lên, một component ii read information từ component jj (với j<ij < i) thông qua virtual weight WIiWOjW_I^iW_O^j. Virutal weight chính là thứ mà connect được output của component trước đó với input của component phía sau.

4. Không gian con và “thông lượng” (bandwitdh) của Residual Stream

Residual stream là một không gian nhiều chiều (thông thường, một mô hình nhỏ, ví dụ như bài báo gốc thì d=512d = 512, hay những model lớn hơn thì dd có thể hàng ngàn như ở Gemma-2-2B, d=2304d=2304). Điều này nghĩa là các layers gửi information (send information) của mình đến các layer khác bằng việc lưu trữ information trong một không gian con khác (ở đây residual stream là một không gian có dd chiều, trong đó sẽ có nhiều không gian khác nhau và các layers sẽ store information của mình trên những không gian con ấy).

Ta nói một tập hợp các subspace U1,U2,,UN{U_1, U_2, \dots, U_N} của vector space VV disjoint với nhau nếu:

  • U1U2UN={0}U_1 \cap U_{2} \cap \dots \cap U_{N} = \{\mathbf{0}\}
  • V=U1+U2+...+UNV = U_1 + U_2 + ... + U_N hay V={u1+u2++uNu1U1,...,uNUN}V = \{ u_1 + u_2 + \dots + u_N \mid u_1 \in U_1, ..., u_N \in U_N \} (này giống như một phép “hợp” trong tập hợp vậy).

Ở attention layer (thông thường là multi-head attetion), khi đó mỗi attention head sẽ có chiều là d/hd / h với hh là số lượng attention head (ở paper gốc, attention head có chiều là 6464), có thể thấy chiều của attention rất nhỏ so với residual stream. Do đó khi các attention head write (thông qua concatenation và linear projection) thì các information sẽ nằm trên một phần (hay một không gian con) của không gian vector residual stream, và các không gian con của các head ấy có thể disjoint với nhau 5.

Khi mà information được thêm (added) vào residual stream, nó sẽ nằm đó (persist) cho đến khi một layer khác thay đổi nó (bằng cách overwrite ví dụ như delete, add more, …). Từ góc nhìn này, ta có thể xem residual stream chính là memory hay bandwitdth, vì vậy (về mặt lý thuyết) việc tăng dmodeld_{model} lên thì ta có thể lưu trữ được nhiều information từ các component hơn.

Một điều nữa là token embedding hay token unembedding thông thường chỉ tương tác (interact) với một phần nhỏ các chiều trong residual stream 6, do đó còn rất nhiều các chiều trống trong residual stream (nói cách khác là những phân vùng trống trong bộ nhớ) cho các layer còn lại lưu trữ thông tin của mình.

Residual Stream Bandwidth

Ở đây ý chỉ đến chiều của những component có “khả năng tính toán” ví dụ như MLP, Attention Head (residual stream chỉ có khả năng lưu trữ information). Ví dụ chiều Attention Head layer thì có thể bằng dmodeld_{model} (sau khi concat các attention head) tuy nhiên chiều của MLP (ở đây ta nói đến hidden layer) thông thường gấp 4 lần chiều của dmodeld_{model}.

Ngoài ra, residual stream in very high demand (bởi vì đây là nơi duy nhất mà các layer có thể communicate với nhau, ngoài ra các layer liên tục read and write vào residual stream). Tuy nhiên, số chiều tính toán (computational dimensions) thường lớn hơn rất nhiều so với số chiều của residual stream (nghĩa là thông tin mà các component có thường rất lớn so với khả năng lưu trữ của residual stream memory).

Ta nói một (vector) activation là bottleneck activations nếu nó có chiều nhỏ hơn activations trước và sau nó (nằm giữa nhưng có chiều nhỏ hơn 2 activations còn lại     \implies gây ra nghẽn cổ chai). Tương tự như việc ta có một GPU và CPU quá mạnh nhưng memory lại quá yếu, do GPU và CPU chỉ có thể communicate với nhau thông qua memory => nghẽn cổ chai, làm chậm PC của chúng ta đi rất nhiều.

  • Ví dụ, residual stream chính là một bottleneck activation, các MLP ở các layer khác nhau (thông thường có activation nhiều chiều hơn residual stream) muốn comunicate với nhau phải thông qua residual stream (do đó residual stream nằm giữa 2 layer MLP có (rất) nhiều chiều hơn so với mình). Ngoài ra, residual stream chính là con đường duy nhất để một layer MLP bất kỳ communicate với các layer MLP phía sau, hơn nữa, residual stream còn phải lưu trữ các information đến từ các lớp MLP khác trên đường dẫn đến extreme bottleneck.
  • Tương tự, một value vector (trong Q,K,VQ, K, V của attention head) cũng là một bottleneck activation.
    • Đầu tiên, value vector sẽ có chiều là dmodel/hd_{model} / h với hh là số attention head do đó có chiều nhỏ hơn rất nhiều so với residual stream.
    • Đặt xsx_s là residual stream tại token ở position ss, do đó value vector của ss sẽ là vs=xsWVv_s = x_s W_V. Khi đó, value vector vsv_s được dùng để update residual stream ở position tt, tức là:
    xt=xs+(attention_score×vs)WOx_{t} = x_{s} + (\text{attention\_score} \times v_{s} )W_{O}
    • Có thể thấy, information từ residual stream xsx_s sẽ compressed (nén vào) vào vsv_s sau đó được chuyển sang residual stream ở token position mới là tt, vì vậy giữa 2 residual stream, value vector chính là bottleneck activation, ngoài ra có thể thấy value vector là cách duy nhất để move information từ token này sang token khác.

Bởi vì tính chất high demand của residual stream bandwidth, ta có thể thấy các một vài MLP neurons hoặc các attention head thực hiện chức năng memory management ví dụ như clearing residual stream dimensions by other layer bằng cách đọc information và write negative của information đó (giống như việc có một app thực hiện dọn bộ nhớ, dọn ở đây chính là ghi vào một thông tin “negative” của thông tin cần xoá, vì vậy triệt tiêu nhau).

5. Các Attention Head hoạt động độc lập với nhau

Có thể thấy, attention layers của Transformers bao gồm nhiều attention heads hHh \in H hoạt động độc lập và song song với nhau và sau đó, mỗi attention head sẽ thêm output của mình vào residual stream.

Nhắc lại Attention:

xi:[1×d]vi:[1×dv]qi:[1×dk]ki:[1×dk]αij:softmax(qjkidk) [1×1]hik:jiαijvj [1×dv]hi:(hi1hin) [1×(ndv)]ai:hiWO [1×d]xi+1:xi+ai [1×d]\begin{aligned} &x_{i}: [1 \times d] \\ &v_{i}: [1 \times d_{v}] \\ &q_{i}: [1 \times d_{k}] \\ &k_{i}: [1 \times d_{k}] \\ &\alpha_{ij}: \text{softmax}\left( \frac{q_{j}k_{i}}{\sqrt{ d_{k} }} \right) ~ [1 \times 1] \\ &h^{k}_{i}: \sum_{j \leq i} \alpha_{ij} v_{j} ~ [1 \times d_{v}]\\ &h_{i}: (h^1_{i} \oplus \dots \oplus h_{i}^n) ~ [1 \times (n* d_{v})] \\ &a_{i}: h_{i} W_{O} ~ [1 \times d] \\ &x_{i+1}: x_{i} + a_{i} ~ [1 \times d] \end{aligned}

Giả sử, rh1r^{h_{1}} là output của attention head thứ 11, tương tự ta có rhnr^{h_n} là output của attention head thứ nn (có chiều là [1×dv][1 \times d_v] và là vector dòng). Theo paper gốc, khi hoàn thành output, ta concat các attention head lại với nhau và nhân với output matrix WOW_O. Đặt WOiW_O^i là component (ma trận con) thứ ii của WOW_O có chiều là [dv×dmodel][d_v \times d_{model}], tức là sẽ gồm nn component của WOW_O và các component được vstack với nhau, ta có:

[rh1rhn]WO=[rh1rhn][WO1WOn]=rh1WO1++rhnWOn=i=1nrhiWOi\begin{aligned} \left[r^{h_{1}} \otimes \dots \otimes r^{h_{n}}\right]W_{O} &= \begin{bmatrix} r^{h_{1}} \dots r^{h_{n}} \end{bmatrix} \begin{bmatrix} W_{O}^1 \\ \vdots \\ \\ W_{O}^n \end{bmatrix} \\ &= r^{h_{1}}W_{O}^1 + \dots + r^{h_{n}}W_{O}^n \\ &= \sum_{i=1}^n r^{h_{i}}W_{O}^i \end{aligned}

Có thể thấy việc tính toán output cuối cùng tương tự như việc tính từng attention head một cách độc lập với nhau sau đó nhân với từng output matrix tương ứng (là các component của output matrix tổng), cuối cùng cộng lại rồi được kết quả cuối và lấy kết quả cuối cùng ấy đưa vào residual stream.

6. Attentions Heads chính là nơi để thông tin “di chuyển”

Attention Head Movement

Câu hỏi: Nếu các Attention Head hoạt động độc lập với nhau, chúng thực sự làm gì ?

Hoạt động cơ bản nhất của attention heads đó chính là moving information. Các attention head read information từ residual stream của một token này và sau đó write information ấy vào residual stream của token khác.

The main observation to take away from this section is that which tokens to move information from is completely separable from what information is “read” to be moved and how it is “written” to the destination (note: mình không hiểu câu này lắm).

Để nhìn rõ hơn, ta nhìn kĩ vào cách tính toán của Attention Head:

  • Đặt xix_i là residual stream value tại token ii (ở đây mình sẽ xem các vector này vector cột giống như paper thay vì vector dòng), khi đó value vector sẽ là vi=WVxiv_i = W_Vx_i.
  • Khi đó giá trị head (hay result vector trước khi nhân với output matrix) là ri=jAi,jvjr_i = \sum_{j} A_{i,j}v_{j} (trong đó Ai,jA_{i, j} là giá trị softmax của score giữa hai token iijj).
  • Cuối cùng, tính giá trị output vector h(x)i=WOrih(x)_i = W_{O}r_{i} (ở đây ta giả sử chỉ có 1 attention head duy nhất, nếu là nn attention head thì h(x)i=k=1nWOkrikh(x)_i = \sum_{k=1}^n W_{O}^k r^k_{i}).
  • Đặt XX là một ma trận gồm NN token, mỗi token có chiều dembedd_{embed} (chiều của embedding vector), khi đó XX sẽ có kích thước là [N×dembed][N \times d_{embed}].
  • Khi ta nhân một ma trận bất kỳ với XX, ta sẽ có 2 cách nhân, là per token (hay token side) và across position (hay position side).
  • Đầu tiên, các ma trận như WK,WQW_K, W_Q và đặc biệt là WVW_V hoạt động trên per token, có thể thấy mỗi dòng của V=XWVV = XW_V chính là vi=xiWVv_i = x_iW_V với xix_i là dòng của XX và mỗi dòng ấy tương ứng với một token.
  • Tiếp theo, đối với ma trận AA, ta có các dòng của rir_i sẽ là:
ri=jiAi,jvjr_{i} = \sum_{j \leq i} A_{i,j}v_{j}

Có thể thấy mỗi dòng của AA (là AiA_i) được sử dụng để nhân với các value vector vjv_j (vector dòng), vậy rir_i được tính bằng tính các value vector across position từ 00 (position đầu tiên) cho đến ii (position hiện tại).

Một bilinear map (ánh xạ song tuyến tính) ff là một hàm mà kết hợp phần tử từ hai vector spaces để cho ra một phần tử của vector space thứ 3. Ngoài ra bilinear map cũng là một hàm linear cho từng argument của nó. Tức là bilinear map f:X×YWf: X \times Y \to W sẽ có:

f(λX,Y)=f(X,λY)=λf(X,Y)λFf(x1+x2,y)=f(x1,y)+f(x2,y)f(x,y1+y2)=f(x,y1)+f(x,y2)\begin{aligned} f(\lambda X, Y) = f(X, \lambda Y) &= \lambda f(X,Y) \quad \forall \lambda \in F \\ f(x_{1} + x_{2}, y) &= f(x_{1}, y) + f(x_{2}, y) \\ f(x, y_{1} + y_{2}) &= f(x, y_{1}) + f(x, y_{2}) \end{aligned}

Một Tensor Product (tích Tensor) VWV \otimes W là một không gian vector cùng với một ánh xạ song tuyến tính (bilinear map) f:V×WVWf: V \times W \to V \otimes W.

Nếu AA là một ma trận m×nm \times nBB là một ma trận p×qp \times q thì Kronecker Product (tích Kronecker) của AABB, kí hiệu là ABA \otimes B, sẽ là một ma trận pm×qnpm \times qn gồm các block matrix:

AB=[a11Ba1nBam1BamnB]A \otimes B = \begin{bmatrix} a_{11}B & \dots & a_{1n}B \\ \vdots & \ddots & \vdots \\ a_{m1}B & \dots & a_{mn}B \end{bmatrix}
  • Kronecker product chính là một Tensor product giữa 2 vector space mà AABB là các linear transformation.
  • Ta đặt vec(X)\text{vec}(X) là operation mà vectorized XX thành một vector một chiều, ví dụ kích thước của XX[m,n][m, n] thì vec(X)\text{vec}(X) sẽ có chiều là [m×n,1][m \times n, 1] (hoặc [1,m×n][1, m \times n] nếu là vector dòng). Khi đó với ma trận AABB bất kì, ta có:
(AB)vec(X)=vec(BXAT)(A \otimes B) \text{vec}(X) = \text{vec}(BXA^T)
h(x)=(IdWO)Project resultvectors out foreach token(h(x)i=WOri)(AId)Mix value vectorsacross tokens tocompute resultvectors(ri=jAi,jvj)(IdWV)Compute valuevector for eachtoken(vi=WVxi)xh(x) = \underbrace{(\text{Id} \otimes W_O)}_{\substack{\text{Project result} \\ \text{vectors out for} \\ \text{each token} \\ (h(x)_i = W_O r_i)}} \cdot \underbrace{(A \otimes \text{Id})}_{\substack{\text{Mix value vectors} \\ \textit{across} \text{ tokens to} \\ \text{compute result} \\ \text{vectors} \\ (r_i = \sum_j A_{i,j} v_j)}} \cdot \underbrace{(\text{Id} \otimes W_V)}_{\substack{\text{Compute value} \\ \text{vector for each} \\ \text{token} \\ (v_i = W_V x_i)}} \cdot xh(x)=(AWOWV)A mixes across tokenswhile WOWV acts on each vectorindependentlyxh(x) = \underbrace{(A \otimes W_O W_V)}_{\substack{A \text{ mixes across tokens} \\ \text{while } W_O W_V \text{ acts on each vector} \\ \text{independently}}} \cdot x
  • Đặt xx là ma trận gồm các embedding vector, mỗi embedding được xếp thành cột, mục đích của ta là nhân WVW_V cho từng cột của XX, vì vậy, dùng tensor product (ta hiểu ở đây là Kronecker product), ta có:
(IdWV)vec(x)=vec(WVxIdT)=vec(WVx)(Id \otimes W_{V}) \text{vec}(x) = \text{vec}(W_{V}xId^T) = \text{vec}(W_{V}x)
  • Tương tự, sau đó đưa qua AA, ta có:
(AId)vec(WVx)=vec(WVxAT)(A \otimes Id)\text{vec}(W_{V}x) = \text{vec}(W_{V}xA^T)
  • Và cuối cùng,
vec(h(x))=(IdWO)vec(WVxAT)=vec(WOWVxAT)    h(x)=WOWVxAT\begin{aligned} \text{vec}(h(x)) &= (Id \otimes W_{O})\text{vec}(W_{V}xA^T) = \text{vec}(W_{O}W_{V}xA^T) \\ \implies h(x) &= W_{O}W_{V}xA^T \end{aligned}
  • Viết lại gọn hơn, ta có:
h(x)=(AWOWV)xh(x) = (A \otimes W_{O}W_{V}) \cdot x

Đặt xx là ma trận dòng, khi đó ta v=xWVv = xW_Vh(x)=AvWO=AxWVWOh(x) = AvW_O = AxW_{V}W_{O}, nếu viết theo tensor products, ta có:

h(x)=x(WVTId)(IdA)(WOTId)=x(WVTWOTA)\begin{aligned} h(x) &= x \cdot (W_{V}^T \otimes Id) \cdot (Id \otimes A) \cdot (W_{O}^T \otimes Id)\\ &= x\cdot (W_{V}^TW_{O}^T \otimes A) \end{aligned}

References

  1. Speech and Language Processing: An Introduction to Natural Language Processing, Computational Linguistics, and Speech Recognition with Language Models, Daniel Jurafsky and James H. Martin
    2025
    https://web.stanford.edu/~jurafsky/slp3/
  2. Mechanistic Interpretability for AI Safety -- A Review, Leonard Bereska and Efstratios Gavves
    2024
    https://arxiv.org/abs/2404.14082
  3. Distributed representations, simple recurrent networks, and grammatical structure, Elman, Jeffrey L.
    Machine Learning, 1991
    https://doi.org/10.1007/BF00114844
  4. Effective Approaches to Attention-based Neural Machine Translation, Minh-Thang Luong and Hieu Pham and Christopher D. Manning
    2015
    https://arxiv.org/abs/1508.04025
  5. Neural Machine Translation by Jointly Learning to Align and Translate, Dzmitry Bahdanau and Kyunghyun Cho and Yoshua Bengio
    2016
    https://arxiv.org/abs/1409.0473
  6. Attention Is All You Need, Ashish Vaswani and Noam Shazeer and Niki Parmar and Jakob Uszkoreit and Llion Jones and Aidan N. Gomez and Lukasz Kaiser and Illia Polosukhin
    2023
    https://arxiv.org/abs/1706.03762
  7. Advancing Transformer Architecture in Long-Context Large Language Models: A Comprehensive Survey, Yunpeng Huang and Jingwei Xu and Junyu Lai and Zixu Jiang and Taolue Chen and Zenan Li and Yuan Yao and Xiaoxing Ma and Lijuan Yang and Hao Chen and Shupeng Li and Penghao Zhao
    2024
    https://arxiv.org/abs/2311.12351
  8. A Mathematical Framework for Transformer Circuits, Elhage, Nelson and Nanda, Neel and Olsson, Catherine and Henighan, Tom and Joseph, Nicholas and Mann, Ben and Askell, Amanda and Bai, Yuntao and Chen, Anna and Conerly, Tom and DasSarma, Nova and Drain, Dawn and Ganguli, Deep and Hatfield-Dodds, Zac and Hernandez, Danny and Jones, Andy and Kernion, Jackson and Lovitt, Liane and Ndousse, Kamal and Amodei, Dario and Brown, Tom and Clark, Jack and Kaplan, Jared and McCandlish, Sam and Olah, Chris
    Transformer Circuits Thread, 2021
    https://transformer-circuits.pub/2021/framework
  9. Zoom In: An Introduction to Circuits, Olah, Chris and Cammarata, Nick and Schubert, Ludwig and Goh, Gabriel and Petrov, Michael and Carter, Shan
    Distill, 2020
    https://distill.pub/2020/circuits/zoom-in

Footnotes

  1. https://transformer-circuits.pub/2021/framework/index.html#def-privileged-basis 2

  2. Ta có thể hiểu một vector AA align (hay thẳng hàng) với vector BB nếu vector AA có thể xấp xỉ hay bằng với αB\alpha B, hay còn gọi là collinear (https://en.wikipedia.org/wiki/Collinearity). Ngoài ra ta còn có 2 trường hợp là α>0\alpha > 0, khi đó AA “nằm cùng hướng” với BB, ngược lại AA “nằm ngược hướng” với BB, thông thường, ta sẽ nghĩ đến trường hợp AA cùng hướng với BB. Vậy làm sao để ta tính được việc xấp xỉ đó, ta sẽ dựa vào cosine similarity, giá trị này càng gần 11, 2 vector càng nằm cùng một hướng với nhau (do đó align với nhau).

  3. Dựa vào 2, việc xoay chính là cố gắng đưa 1 vector nào đó nằm thẳng hàng với vector còn lại. Giả sử ở một hệ toạ độ Oxy, vector AA nằm chếch lên 3030 độ so với vector BB, vì vậy để đưa vector AA thẳng hàng với BB, ta xoay AA một góc 3030 độ (thông qua một phép xoay nào đó).

  4. Một điều nữa đó chính là output của Attention Component (before write) headi\text{head}_irotational invariance (https://en.wikipedia.org/wiki/Rotational_invariance). Bởi vì input của head là xix_i, nếu xix_i được xoay bởi ma trận RR, thì các ma trận WQ,WK,WVW_Q, W_K, W_V sẽ “un-rotate” xix_i trở về ban đầu do đó không ảnh hưởng đến output headi\text{head}_i.

  5. Nếu nói đơn giản thì mỗi head tìm cho mình một chỗ trống, giống như bộ nhớ còn trống vậy, để write thông tin mình lên, do mỗi head chỉ cẩn 64 bytes mà residual stream lại có đến 512 bytes, vì vậy các head không cần phải tranh nhau mà sẽ ghi lên những phân vùng riêng (các không gian con) của mình.

  6. https://transformer-circuits.pub/2021/framework/index.html#d-footnote-6