
Tại sao quá trình giải mã của các mô hình ngôn ngữ lớn (LLM) bị giới hạn bởi bộ nhớ, không phải bởi năng lực tính toán
Điểm: 2 Bình luận: 0
Module 0.1: Tại sao suy luận LLM lại khác biệt
Điều đầu tiên cần hiểu về suy luận LLM là hầu hết mọi thứ bạn biết về suy luận ML đều không đúng – hoặc ít nhất là không áp dụng được.
Mục tiêu học tập
Sau khi hoàn thành module này, bạn sẽ:
Hiểu tại sao chi phí suy luận LLM cao gấp 100 lần so với suy luận ML truyền thống.
Nắm được sự khác biệt cơ bản giữa ML truyền thống và tạo sinh tự hồi quy.
Biết hai giai đoạn của suy luận LLM (prefill và decode) ở cấp độ cao.
Hiểu về giới hạn băng thông bộ nhớ (memory bandwidth wall) làm hạn chế tốc độ giải mã (decode speed).
Sự thật khó chấp nhận
Đây là điều không ai nói với bạn khi bắt đầu làm việc với suy luận LLM:
Suy luận ML truyền thống là một vấn đề đã được giải quyết. Suy luận LLM thì không.
Khía cạnh | ML truyền thống | Suy luận LLM
---|---|---
Độ trễ | Có thể dự đoán (5-20ms) | Không thể dự đoán (100ms-10s)
Bộ nhớ | Cố định cho mỗi yêu cầu | Tăng lên trong quá trình yêu cầu
Xử lý theo lô (Batching) | Đơn giản | Yêu cầu xử lý theo lô liên tục
Mở rộng quy mô (Scaling) | Tuyến tính với GPU | Dưới tuyến tính, bị giới hạn bởi giao tiếp
Chi phí | 0,001 USD cho mỗi yêu cầu | 0,01-0,10 USD cho mỗi yêu cầu
Sự khác biệt không phải là 2 lần hay 5 lần – mà là 100 lần. Và những lý do này là cơ bản, không phải ngẫu nhiên.
Tại sao LLM lại khác biệt về cơ bản
Bản chất tuần tự của việc tạo văn bản
Sự khác biệt cốt lõi nằm ở một từ: tự hồi quy (autoregressive).
Trong ML truyền thống, suy luận là một lần truyền tiến (forward pass) duy nhất. Bạn đưa một hình ảnh vào ResNet, dữ liệu chảy qua mạng một lần, và bạn nhận được kết quả phân loại. Hoàn tất.
Suy luận ML truyền thống: một đầu vào, một lần truyền tiến, một đầu ra. Thời gian cố định, bộ nhớ không đổi và xử lý theo lô đơn giản.
LLM hoạt động hoàn toàn khác. Khi bạn hỏi "Thủ đô của Pháp là gì?", mô hình không đưa ra câu trả lời trong một lần. Nó tạo ra từng token một: "Thủ" → "đô" → "của" → "Pháp" → "là" → "Paris". Mỗi token yêu cầu một lần truyền tiến riêng biệt qua toàn bộ mô hình.
Suy luận LLM: mỗi token đầu ra yêu cầu một lần truyền tiến riêng. Token N không thể được tạo ra cho đến khi các token từ 1 đến N-1 tồn tại.
Đây không phải là một hạn chế cần được khắc phục bằng kỹ thuật – đây là cách các mô hình ngôn ngữ tự hồi quy hoạt động theo thiết kế. Phân phối xác suất cho token thứ 5 phụ thuộc vào các token từ 1-4 thực sự là gì.
Bạn đọc toàn bộ mô hình cho mỗi token
Đây là nhận định thay đổi cách bạn nghĩ về suy luận LLM:
Llama 3.1 8B tạo 100 token:
Mỗi lần tạo token yêu cầu một lần truyền tiến đầy đủ qua mô hình.
Một lần truyền tiến có nghĩa là đọc TẤT CẢ 8 tỷ tham số từ bộ nhớ.
- Token 1: Đọc 16 GB trọng số
- Token 2: Đọc lại 16 GB trọng số
- Token 3: Đọc lại 16 GB trọng số
- ...
- Token 100: Đọc lại 16 GB trọng số
Tổng số lần đọc bộ nhớ: 16 GB × 100 = 1,6 TB
Các mạng thần kinh không "ghi nhớ" trọng số của chúng giữa các hoạt động. Mỗi phép nhân ma trận yêu cầu tải ma trận trọng số từ bộ nhớ GPU (HBM) vào các đơn vị tính toán. Tạo 100 token, tải trọng số 100 lần.
Giới hạn băng thông bộ nhớ (Memory Bandwidth Wall)
Điều này dẫn đến một giới hạn vật lý cứng:
Băng thông bộ nhớ A100: 2 TB/s
Kích thước mô hình (FP16): 16 GB
Thời gian đọc mô hình: 16 GB / 2 TB/s = 8 ms
Tốc độ giải mã tối đa = 1 token / 8 ms = 125 token/giây
Đây là một giới hạn cứng. Không có tối ưu hóa phần mềm nào có thể vượt qua nó. Các cách duy nhất để vượt qua giới hạn này là:
Giảm kích thước mô hình (lượng tử hóa - quantization)
Tăng băng thông bộ nhớ (phần cứng tốt hơn hoặc nhiều GPU hơn)
Tạo nhiều token cho mỗi lần đọc trọng số (giải mã suy đoán - speculative decoding)
Hai giai đoạn: Prefill và Decode
Mỗi yêu cầu LLM trải qua hai giai đoạn riêng biệt với các đặc điểm hoàn toàn khác nhau:
Giai đoạn
Hoạt động
Nút thắt
Thời điểm thực hiện
Prefill (Tiền xử lý)
Xử lý toàn bộ lời nhắc (prompt) cùng lúc
Tính toán (TFLOPS)
Một lần cho mỗi yêu cầu
Decode (Giải mã)
Tạo ra từng token một
Băng thông bộ nhớ (TB/s)
Một lần cho mỗi token đầu ra
Prefill: Giai đoạn bị giới hạn bởi tính toán
Trong giai đoạn prefill, tất cả các token của lời nhắc được xử lý song song thông qua mô hình. Đây là lúc bộ nhớ đệm KV (KV cache) được xây dựng.
Lý do prefill bị giới hạn bởi tính toán: Bộ xử lý đồ họa (GPU) xử lý các ma trận lớn (ví dụ: [1000, 4096] × [4096, 4096] cho lời nhắc 1000 token). Có đủ công việc song song để giữ cho các đơn vị tính toán hoạt động. Nút thắt là số lượng phép tính dấu phẩy động (FLOPs) mà GPU có thể thực hiện mỗi giây.
Decode: Giai đoạn bị giới hạn bởi bộ nhớ
Trong giai đoạn decode, các token được tạo ra từng cái một. Mỗi token yêu cầu đọc toàn bộ mô hình từ bộ nhớ.
Lý do decode bị giới hạn bởi bộ nhớ: GPU xử lý các ma trận nhỏ (ví dụ: [1, 4096] × [4096, 4096]). Không có đủ công việc song song để giữ cho các đơn vị tính toán hoạt động. GPU dành phần lớn thời gian chờ dữ liệu từ bộ nhớ.
┌─────────────────────────────────────────────────────────────────────┐
│ NÚT THẮT DECODE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Khả năng của GPU: 312 TFLOPS (312 nghìn tỷ phép tính/giây) │
│ Hoạt động thực tế của GPU: ~16 GFLOPS (bị giới hạn bởi băng thông bộ nhớ) │
│ │
│ Mức độ sử dụng GPU trong quá trình decode: 16 / 312.000 ≈ 0,005% │
│ │
│ GPU NHÀN RỖI 99,995% trong quá trình decode! │
│ │
│ Đây là lý do: │
│ • Decode chậm mặc dù "ít công việc hơn" │
│ • GPU nhanh hơn không giúp ích nhiều (băng thông bộ nhớ tương tự) │
│ • Xử lý theo lô (batching) rất quan trọng (phân bổ việc đọc trọng số cho nhiều yêu cầu) │
│ • Lượng tử hóa (quantization) có ích (trọng số nhỏ hơn = đọc nhanh hơn) │
│ │
└─────────────────────────────────────────────────────────────────────┘
Minh họa sự khác biệt về tính song song
PREFILL: Song song hóa dễ dàng
GPU xử lý các ma trận lớn → Mức độ sử dụng cao
┌─────────────────────────────────────────────────────────────┐
│ Xử lý 1000 token đồng thời: │
│ │
│ Ma trận Q: [1000, 4096] Ma trận K: [1000, 4096] │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │█████████████████████│ │█████████████████████│ │
│ │█████████████████████│ │█████████████████████│ │
│ │█████████████████████│ │█████████████████████│ │
│ │█████████████████████│ × │█████████████████████│ │
│ │█████████████████████│ │█████████████████████│ │
│ │█████████████████████│ │█████████████████████│ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ → Hàng triệu phép nhân-cộng diễn ra song song │
│ → Các lõi GPU được sử dụng tối đa │
│ → Bị giới hạn bởi tính toán: giới hạn bởi


Nguồn tin: Hacker News LLM — Tác giả: harshuljain13. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.