OpenArchLabOpen Architecture — From Models to Systems

E · Training Architecture

MQA · Multi-Query Attention, một đầu KV dùng chung và giới hạn Tensor Parallel

Multi-Query Attention (MQA) giữ nguyên nhiều đầu Query nhưng rút gọn toàn bộ lớp xuống chỉ còn duy nhất 1 đầu Key và 1 đầu Value dùng chung, giúp thu nhỏ KV cache tới mức tối đa.

LESSON ID arch-mqa GROUP Bản đồ nền tảng LLM
Mục lục bài học

1Định nghĩa

Multi-Query Attention (MQA, do Noam Shazeer đề xuất) là biến thể Attention cắt giảm bộ nhớ đệm mạnh tay nhất theo hướng chia sẻ đầu: mô hình vẫn giữ nguyên H_Q đầu truy vấn (Query heads) để đặt nhiều câu hỏi khác nhau, nhưng toàn bộ H_Q đầu đó đều tra cứu trên duy nhất 1 đầu Key và 1 đầu Value dùng chung (H_KV = 1). Có thể xem MQA là trường hợp cực hạn của GQA khi số nhóm bằng 1, đối lập hoàn toàn với MHA nơi mỗi đầu Query có một cặp Key/Value riêng.

Nhờ rút H_KV về 1, MQA giảm dung lượng KV cache và băng thông đọc bộ nhớ HBM ở pha decode đi đúng H_Q lần (ví dụ giảm 32 lần nếu có 32 đầu Query). Tuy nhiên, việc ép mọi đầu Query đọc chung 1 không gian Key/Value duy nhất có thể làm giảm nhẹ chất lượng mô hình lớn và khiến đầu KV duy nhất đó phải nhân bản (replicate) trên mọi GPU khi chạy Tensor Parallelism — lý do khiến nhiều mô hình sau này ưu tiên chọn điểm cân bằng GQA hoặc MLA.

Ví dụ đời thường: MQA giống như việc một phòng ban có 32 chuyên viên nhưng chỉ in đúng 1 cuốn tài liệu tham khảo duy nhất đặt ở bàn giữa phòng cho tất cả 32 người cùng nhìn chung (thay vì 32 cuốn riêng như MHA hay 8 cuốn theo tổ như GQA) — cách này tiết kiệm giấy và diện tích bàn tới mức tối đa, nhưng mọi người chỉ có chung một bản tóm tắt duy nhất để tra cứu.

2Luồng

Sơ đồ luồng (3 bước)
  1. Chiếu H_Q đầu Query và duy nhất 1 đầu Key/Value

    Ma trận W_K và W_V chỉ có chiều rộng bằng 1 head (d_h).

  2. Lưu 1 cặp Key/Value duy nhất vào KV cache

    Dung lượng KV cache giảm H_Q lần so với MHA cùng kích thước.

  3. Tái sử dụng 1 đầu KV cho mọi đầu Query trên SRAM

    Kernel nạp 1 vector K/V và nhân với toàn bộ H_Q vector Query.

Mã Mermaid
flowchart TD
  step1["Chiếu H_Q đầu Query và duy nhất 1 đầu Key/Value"]
  step2["Lưu 1 cặp Key/Value duy nhất vào KV cache"]
  step3["Tái sử dụng 1 đầu KV cho mọi đầu Query trên SRAM"]
  step1 --> step2
  step2 --> step3

Luồng mô tả cách MQA dùng duy nhất 1 đầu Key/Value cho toàn bộ H_Q đầu Query nhằm tối thiểu hóa băng thông đọc KV cache.

3Giải pháp

Dung lượng KV cache lý tưởng của MQA chỉ còn 2 × L × T × d_h × bytes_per_element (vì H_KV = 1), nhỏ hơn MHA đúng H_Q lần. Điều này giúp biến bước decode từ chỗ bị nghẽn nặng ở băng thông đọc HBM trở nên nhẹ nhàng hơn rất nhiều ở cỡ batch lớn.

Lưu ý quan trọng khi chạy Tensor Parallelism (TP) trên N GPU: vì chỉ có 1 đầu Key/Value duy nhất (H_KV = 1), engine không thể chia đầu KV theo chiều head cho N GPU mà phải nhân bản (replicate) đầu KV đó trên cả N thiết bị (hoặc phải phân mảnh theo chiều sequence). Do đó trên cụm TP = 8 GPU, dung lượng KV cache trên mỗi GPU của MQA thực tế bằng với GQA có H_KV = 8.

Để bù phần tham số bị giảm ở ma trận chiếu W_K và W_V khi dùng MQA, các kiến trúc thực tế (như PaLM, Falcon hay StarCoder) thường tăng nhẹ chiều rộng của mạng truyền thẳng FFN để giữ nguyên tổng ngân sách tham số.

4Profiling

  • Tốc độ decode và băng thông HBM tiết kiệm được

    So sánh thời gian bước decode (TPOT) và lượng byte đọc từ HBM mỗi token giữa MQA (H_KV = 1), GQA và MHA ở cùng độ dài ngữ cảnh.

  • Chi phí nhân bản KV cache khi bật Tensor Parallelism

    Kiểm tra bộ nhớ KV cache trên từng GPU khi TP > 1: với MQA, mỗi GPU đều giữ nguyên 1 đầu KV nên tổng KV cache toàn cụm tăng theo TP_size.

Mẹo đo lường: ghim số liệu trên workload thật, ghi cả p50/p95/p99 thay vì chỉ trung bình, và luôn ghi lại điều kiện chạy (batch, cache, đồng thời, phần cứng) trước và sau khi tối ưu. Số đo thiếu điều kiện chạy thì không so sánh được.

5Ví dụ

Giảm 32 lần KV cache trên một GPU đơn lẻ

Trên mô hình 32 lớp, H_Q = 32, d_h = 128 ở BF16: trong khi MHA tốn 524.288 byte/token thì MQA (H_KV = 1) chỉ tốn 2 × 32 × 1 × 128 × 2 = 16.384 byte (16 KiB) mỗi token — giảm đúng 32 lần trên một GPU.

Vì sao trên cụm 8 GPU chạy TP, GQA-8 chiếm KV cache ngang MQA

Khi chạy Tensor Parallelism trên 8 GPU, MQA phải nhân bản 1 đầu KV ra cả 8 GPU (mỗi GPU giữ 1 đầu KV), còn GQA với H_KV = 8 chia đều 8 đầu KV cho 8 GPU (mỗi GPU cũng giữ đúng 1 đầu KV) nhưng GQA-8 lại giữ được chất lượng biểu diễn cao hơn.

6Thuật ngữ

Multi-Query Attention (MQA)
Cơ chế chú ý giữ H_Q đầu Query nhưng chỉ dùng duy nhất 1 đầu Key và 1 đầu Value (H_KV = 1) cho toàn bộ lớp.
KV head replication under TP
Khi chia Tensor Parallelism trên nhiều GPU, vì MQA chỉ có 1 đầu KV không thể cắt nhỏ theo head, mọi GPU đều phải giữ bản sao của đầu KV duy nhất này.
Arithmetic intensity gain
Nhờ đọc 1 đầu KV từ HBM rồi nhân với cả H_Q đầu Query trong SRAM, MQA tăng mạnh tỷ số phép tính trên mỗi byte bộ nhớ đọc vào.
Glossary (5)
Cache
Bộ nhớ giữ kết quả có thể dùng lại; trong attention thường giữ key/value vectors.
Tensor
Mảng số nhiều chiều, như một vector, ma trận hoặc nhóm ma trận.
Kernel
Hàm tính toán chạy trên thiết bị; thường xử lý nhiều phần tử song song.
Latency
Thời gian chờ để nhận một kết quả hoặc một bước kết quả.
Batch
Nhóm công việc hoặc mẫu được xử lý trong một lượt tính.

7Bài liên quan

8Nguồn