12Tham số, FLOP và bộ nhớ của Transformer#
Khi làm việc với mô hình lớn, nhiều câu hỏi quan trọng có thể trả lời trên giấy trong vài phút, trước khi chạy bất cứ thứ gì: mô hình có vừa bộ nhớ GPU không, huấn luyện mất bao lâu, tăng gấp đôi độ dài ngữ cảnh thì chi phí tăng bao nhiêu. Các công thức để trả lời đều dựng được từ những gì đã học ở Chương 9 và 10. Ta sẽ dựng chúng rồi kiểm chứng với các con số thật của GPT-2 và Llama 2; như sẽ thấy, công thức đếm tham số khớp tới từng tham số.
12.1Mục đích của việc ước lượng#
Câu hỏi thường gặp nhất là mô hình có vừa hay không. Số tham số nhân số byte mỗi tham số cho dung lượng trọng số, và cần cộng thêm KV cache khi suy luận, hoặc gradient, trạng thái của bộ tối ưu và giá trị kích hoạt khi huấn luyện. Câu hỏi thứ hai là tốn bao nhiêu thời gian: số phép tính chia cho tốc độ tính thực tế của phần cứng cho thời gian huấn luyện hoặc độ trễ. Câu hỏi thứ ba là khi thay đổi một cấu hình, như tăng độ dài ngữ cảnh, dùng GQA hay lượng tử hoá trọng số xuống 4 bit, thì chi phí thay đổi thế nào. Cả ba đều bắt đầu từ việc đếm tham số.
12.2Số tham số của một khối Transformer#
Với là số chiều của mô hình và là số chiều ẩn của FFN, bỏ qua hệ số chặn và tham số của các lớp chuẩn hoá, bảng dưới đếm tham số của một khối.
| Thành phần | Số tham số |
|---|---|
| , , | |
| FFN, hai ma trận , | |
| Tổng một khối, với |
Với khối, số tham số không tính embedding là
Đây là công thức Kaplan và cộng sự (2020) dùng trong nghiên cứu về quy luật co giãn. Phần embedding thêm tham số cho bảng embedding từ vựng, cộng nếu dùng embedding vị trí học được. Nếu lớp chiếu ra từ vựng không dùng chung trọng số với bảng embedding, cộng thêm nữa.
12.3Kiểm chứng trên GPT-2 và Llama 2#
Thí nghiệm trong code/models/experiments.py tính đầy đủ số tham số, kể cả hệ số chặn và tham số của LayerNorm, rồi so với số tham số đếm trực tiếp trên các mô hình GPT-2 mà OpenAI đã phát hành.
| Mô hình | Theo công thức | Mô hình phát hành | Chênh lệch | |
|---|---|---|---|---|
| GPT-2 small (, ) | 124 439 808 | 124 439 808 | 0 | 84 934 656 |
| GPT-2 medium (, ) | 354 823 168 | 354 823 168 | 0 | 301 989 888 |
| GPT-2 large (, ) | 774 030 080 | 774 030 080 | 0 | 707 788 800 |
Công thức khớp chính xác tới từng tham số với cả ba kích thước. Các con số trong bài báo GPT-2 lại khác: 117 triệu, 345 triệu và 762 triệu. Kho mã của OpenAI về sau ghi chú rằng các con số ban đầu sai do một lỗi, và tên gọi 124M, 355M, 774M dùng hiện nay đến từ cách đếm trực tiếp như ở bảng trên. Phép đếm tay vì vậy còn có ích để kiểm tra chính các con số được công bố.
Chia nhỏ GPT-2 small cho thấy tham số nằm ở đâu.
| Thành phần | Số tham số | Tỉ lệ |
|---|---|---|
| Embedding từ vựng () | 38 597 376 | 31,0% |
| Embedding vị trí () | 786 432 | 0,6% |
| Attention, 12 khối | 28 348 416 | 22,8% |
| FFN, 12 khối | 56 669 184 | 45,5% |
Bảng chia nhỏ cho thấy hai điều. Embedding chiếm 31% số tham số của GPT-2 small: với mô hình nhỏ và từ vựng lớn, phần embedding chiếm tỉ trọng lớn, nên các nghiên cứu về quy luật co giãn tách riêng số tham số không tính embedding. Còn trong các khối Transformer, FFN chiếm 67% số tham số, đúng tỉ lệ ở Mục 12.2.
Cùng cách đếm áp dụng được cho kiến trúc kiểu Llama, chỉ cần sửa bốn chỗ: FFN dạng SwiGLU có ba ma trận, nên mỗi khối có tham số; RMSNorm chỉ có ; không có hệ số chặn và không có embedding vị trí, vì vị trí được mã hoá bằng RoPE; và lớp chiếu ra không dùng chung trọng số với embedding. Kết quả cho Llama 2 7B là 6 738 415 616 và cho Llama 2 13B là 13 015 864 320, khớp chính xác với số tham số của trọng số đã phát hành. Bài tập 1 yêu cầu tự tính con số của bản 7B.
12.4Số FLOP#
Phép nhân ma trận với tốn FLOP, vì mỗi phần tử kết quả cần phép nhân và phép cộng. Với mỗi token, mỗi tham số của một lớp tuyến tính tham gia đúng một phép nhân và một phép cộng ở lượt xuôi, nên
Lượt ngược tốn khoảng gấp đôi lượt xuôi: một lần cho gradient theo đầu vào của mỗi lớp, để truyền tiếp về phía trước, và một lần cho gradient theo trọng số. Vì vậy huấn luyện tốn khoảng FLOP mỗi token, và toàn bộ quá trình huấn luyện trên token tốn
Với GPT-2 small, , nên suy luận tốn khoảng 170 triệu FLOP mỗi token và huấn luyện khoảng 510 triệu FLOP mỗi token. Đó là con số theo quy ước của Kaplan và cộng sự, chỉ tính các tham số không thuộc embedding. Bảng embedding đầu vào đúng là không tốn phép tính, vì chỉ là phép tra bảng, nhưng lớp chiếu ra từ vựng là một phép nhân ma trận thật. Với GPT-2 small, lớp này tốn thêm triệu FLOP mỗi token ở lượt xuôi, gần một nửa con số 170 triệu, dù ma trận của nó dùng chung với bảng embedding.
Ví dụ 12.1 (Ngân sách huấn luyện Llama 2 7B)
Llama 2 7B có tham số không tính embedding và được huấn luyện trên token, nên FLOP. GPU A100 đạt tối đa 312 TFLOPS với số bf16, nhưng trong thực tế chỉ dùng được một phần; tỉ lệ này gọi là mức sử dụng phần cứng (model FLOPs utilization, MFU), thường 30% tới 50% với mô hình lớn. Với MFU 30%, 37,6% và 40%, ước lượng lần lượt là 230 627, 184 011 và 172 970 giờ-GPU. Meta công bố 184 320 giờ-GPU (Touvron và cộng sự, 2023), ứng với MFU khoảng 37,5%, nằm trong khoảng thông thường. Công thức vì vậy cho đúng bậc độ lớn của chi phí huấn luyện; con số chính xác phụ thuộc hiệu suất của hệ thống.
Con số 37,5% còn phụ thuộc vào cách đếm. Nếu lấy là tổng số tham số, 6 738 415 616, MFU thành khoảng 39%. Nếu cộng thêm phép tính của attention theo quy ước của PaLM (Chowdhery và cộng sự, 2022), tức FLOP mỗi token khi huấn luyện với , MFU thành khoảng 45%. Khi so MFU giữa các báo cáo, cần xem họ đếm những phép tính nào.
Cùng phép tính cho phép trả lời nhanh những câu hỏi mà bài giảng CS336 dùng làm bài tập nhẩm. Huấn luyện một mô hình 70 tỉ tham số trên 15 nghìn tỉ token bằng 1 024 GPU H100 mất bao lâu? Tổng là FLOP. Một H100 đạt khoảng 989 TFLOPS với bf16 khi không dùng tính thưa; với MFU 50%, 1 024 GPU làm được khoảng FLOP mỗi ngày, nên cần khoảng 144 ngày. Karpathy làm phép tính tương tự cho GPT-2 small trong nanoGPT: 124 triệu tham số, 300 tỉ token và 8 GPU A100 với MFU 30% cho khoảng 3,5 ngày, còn lần huấn luyện thật hội tụ sau khoảng 4 ngày.
Công thức dẫn tới một câu hỏi thiết kế: với một ngân sách tính toán cố định, nên chia giữa kích thước mô hình và lượng dữ liệu thế nào? Hoffmann và cộng sự (2022) huấn luyện hơn 400 mô hình và kết luận rằng và nên tăng cùng tỉ lệ khi tăng, với khoảng 20 token dữ liệu cho mỗi tham số; mô hình Chinchilla 70B huấn luyện trên 1,4 nghìn tỉ token theo nguyên tắc này tốt hơn các mô hình lớn hơn nhiều nhưng ít dữ liệu hơn. Kết quả này được gọi là quy luật co giãn tối ưu về tính toán. Trong thực tế, nhiều mô hình được huấn luyện trên lượng dữ liệu vượt xa tỉ lệ 20 token mỗi tham số, vì mô hình nhỏ hơn rẻ hơn khi phục vụ; Llama 2 7B dùng khoảng 300 token mỗi tham số, còn Llama 3 8B dùng hơn 15 nghìn tỉ token, gần 1 900 token mỗi tham số (Llama Team, 2024).
Khi đọc các quy luật co giãn cần để ý được đếm thế nào. Kaplan và cộng sự dùng số tham số không tính embedding, còn Hoffmann và cộng sự dùng tổng số tham số; với GPT-2 small, hai con số là 85 triệu và 124 triệu. Hai nhóm đi tới hai khuyến nghị khác nhau: Kaplan và cộng sự khuyên tăng nhanh hơn nhiều khi ngân sách tăng, còn Chinchilla khuyên tăng như nhau. Pearce và Song (2024) cho thấy phần lớn chênh lệch đó đến từ chính khác biệt trong cách đếm , cộng với việc Kaplan và cộng sự làm thí nghiệm ở quy mô nhỏ, nơi embedding chiếm tỉ trọng lớn.
Công thức chỉ tính các phép nhân với ma trận trọng số, chưa tính hai phép nhân phụ thuộc độ dài ngữ cảnh trong attention: điểm số và tích với . Với mỗi token và mỗi lớp, mỗi phép tốn khoảng FLOP khi tính trên cả ngữ cảnh token, tổng cho cả mô hình. So với , ta có
Với GPT-2 small (, ), tỉ lệ là 0,22, tức attention chiếm phần nhỏ. Với , tỉ lệ là 0,17 ở , nhưng 1,33 ở và 5,33 ở , khi attention trở thành phần chính. Như vậy chi phí tăng theo bình phương độ dài chỉ thực sự chi phối khi vượt khoảng . Nếu cài đặt bỏ qua phần bị mặt nạ nhân quả che, như FlashAttention, chi phí attention giảm khoảng một nửa và ngưỡng thành , là con số mà Kaplan và cộng sự (2020) dùng.
12.5Bộ nhớ#
Bộ nhớ gồm nhiều khoản, mỗi khoản phụ thuộc vào những đại lượng khác nhau, và nhầm lẫn giữa chúng là nguyên nhân của nhiều sự cố hết bộ nhớ. Bảng dưới tách riêng từng khoản.
| Khoản | Công thức | Phụ thuộc vào |
|---|---|---|
| Trọng số | số byte mỗi tham số | số tham số |
| Gradient | số byte | số tham số; chỉ khi huấn luyện |
| Trạng thái của bộ tối ưu | Adam: byte, cộng bản sao FP32 của trọng số khi huấn luyện với độ chính xác hỗn hợp | số tham số; chỉ khi huấn luyện |
| Giá trị kích hoạt | tỉ lệ với , cộng một phần tỉ lệ với nếu lưu ma trận attention | kích thước lô, độ dài chuỗi; chỉ khi huấn luyện |
| KV cache | số byte | độ dài ngữ cảnh, số chuỗi; chỉ khi suy luận |
Khi huấn luyện với độ chính xác hỗn hợp và Adam, mỗi tham số cần khoảng 16 byte (Rajbhandari và cộng sự, 2020): 2 byte cho trọng số 16 bit, 2 byte cho gradient 16 bit, 4 byte cho bản sao trọng số FP32 mà bộ tối ưu cập nhật, và 8 byte cho hai trạng thái , của Adam ở FP32. Với mô hình 7 tỉ tham số, con số là 112 GB, chưa tính giá trị kích hoạt, nên không vừa một GPU 80 GB. Các kỹ thuật như ZeRO (Rajbhandari và cộng sự, 2020) chia gradient và trạng thái bộ tối ưu cho nhiều GPU để giải quyết vấn đề này. Huấn luyện hoàn toàn bằng FP32 cũng tốn đúng 16 byte mỗi tham số, gồm 4 cho trọng số, 4 cho gradient và 8 cho Adam, nên độ chính xác hỗn hợp không giảm các khoản này; lợi ích của nó nằm ở tốc độ tính và ở bộ nhớ cho giá trị kích hoạt, vốn được lưu ở 16 bit. Phép tính theo chiều ngược lại cũng hữu ích, và CS336 dùng nó làm bài tập nhẩm thứ hai: 8 GPU 80 GB, với 16 byte mỗi tham số và mọi khoản được chia đều cho các GPU, chứa được khoảng tham số, tức 40 tỉ, trước khi tính giá trị kích hoạt.
Giá trị kích hoạt có thể còn lớn hơn thế. Korthikanti và cộng sự (2022) ước lượng mỗi khối Transformer huấn luyện với số 16 bit cần khoảng byte cho giá trị kích hoạt, với là độ dài chuỗi, là kích thước lô và là số đầu attention. Với cấu hình của Llama 2 7B (, , 32 khối), một chuỗi 4 096 token cần khoảng 97 GiB, trong đó 80 GiB là số hạng đến từ các ma trận attention . FlashAttention (Mục 10.7) không lưu các ma trận này, đưa con số xuống khoảng 17 GiB, và gradient checkpointing (Mục 5.3) giảm tiếp bằng cách tính lại.
Khi suy luận, trọng số và KV cache là hai khoản chính. Với Llama 2 7B dùng MHA (32 lớp, 32 đầu, ) ở FP16, KV cache tốn byte, tức 0,5 MiB mỗi token; một chuỗi 4 096 token cần 2 GiB, bằng khoảng 16% dung lượng trọng số 13,5 GB. Với nhiều chuỗi và ngữ cảnh dài, KV cache có thể vượt dung lượng trọng số. Mục 3.3 của Ứng dụng LLM dùng các con số này để ước lượng bộ nhớ khi tự triển khai mô hình.
Giảm số byte mỗi số là cách tác động trực tiếp lên mọi dòng của bảng trên, và là chủ đề của giáo trình Quantization.
12.6Tóm tắt#
Các công thức của chương được gom trong bảng dưới.
| Đại lượng | Công thức | Dùng để |
|---|---|---|
| Số tham số không tính embedding | (FFN hai ma trận, ) | ước lượng kích thước mô hình |
| FLOP suy luận mỗi token | , cộng cho attention | ước lượng độ trễ |
| FLOP huấn luyện | ước lượng ngân sách tính toán | |
| Ngưỡng attention chi phối chi phí | (tính đủ ma trận), (bỏ phần bị che) | quyết định có cần attention hiệu quả hơn không |
| KV cache mỗi token | số byte | ước lượng bộ nhớ khi suy luận |
| Bộ nhớ huấn luyện với Adam | khoảng 16 byte mỗi tham số, cộng giá trị kích hoạt | ước lượng bộ nhớ khi huấn luyện |
Công thức đếm tham số khớp tới từng tham số với GPT-2 và Llama 2, còn công thức cho đúng bậc độ lớn của 184 320 giờ-GPU mà Meta công bố cho Llama 2 7B khi mức sử dụng phần cứng khoảng 37,5%. Khi dùng cần nói rõ và các phép tính được đếm gồm những gì: cùng số giờ-GPU đó ứng với MFU 37,5%, 39% hay 45% tuỳ cách đếm, và hai quy luật co giãn của Kaplan và của Chinchilla khác nhau phần lớn vì đếm khác nhau. Attention chỉ chi phối chi phí tính toán khi độ dài ngữ cảnh vượt khoảng . Về bộ nhớ, huấn luyện tốn khoảng 16 byte mỗi tham số cộng giá trị kích hoạt, còn suy luận tốn trọng số cộng KV cache, và mỗi khoản phụ thuộc vào những đại lượng khác nhau.
Chương này khép lại phần kiến trúc của giáo trình. Đi từ các họ mô hình qua cây, mạng nhiều lớp, mạng tích chập, mạng hồi quy tới Transformer, ta đã thấy cùng một câu hỏi lặp lại dưới nhiều dạng: giả định nào của mô hình khớp với cấu trúc của dữ liệu, và làm sao để gradient đi được qua một mạng sâu. Hai giáo trình tiếp theo dùng trực tiếp các kết quả ở đây: Biểu diễn & Căn chỉnh xét những gì một mô hình như vậy học được và cách căn chỉnh nó theo ý người dùng, còn Quantization giảm số byte mỗi số trong mọi dòng của bảng bộ nhớ ở Mục 12.5. Chương 13 gồm các bài tập để luyện các phép tính của giáo trình, và Chương 14 gom các câu hỏi phỏng vấn thường gặp.
Tự kiểm tra
6 câu. Chọn đáp án để xem ngay lời giải thích.
1Số tham số không tính embedding của một Transformer lớp, số chiều , với là bao nhiêu?
2Trong GPT-2 small, embedding chiếm khoảng bao nhiêu phần tổng số tham số?
Vì sao: Bảng embedding có tham số. Với mô hình nhỏ và từ vựng lớn, embedding chiếm tỉ trọng lớn; tỉ lệ này giảm khi mô hình lớn hơn.3Công thức phân bổ chi phí cho mỗi token thế nào?
Vì sao: Lượt ngược tính gradient theo cả đầu vào và trọng số của mỗi lớp, nên tốn gấp đôi lượt xuôi. Với Llama 2 7B, con số 184 320 giờ-GPU đã công bố ứng với mức sử dụng phần cứng khoảng 37,5% (Ví dụ 12.1).4Khi tính đủ ma trận điểm số, phần tính toán của attention lớn hơn phần còn lại khi nào?
Vì sao: Tỉ số giữa hai phần là . Nếu cài đặt bỏ qua phần bị mặt nạ nhân quả che, ngưỡng thành khoảng (Mục 12.4).5Huấn luyện với Adam và độ chính xác hỗn hợp cần khoảng bao nhiêu byte cho mỗi tham số, chưa tính giá trị kích hoạt?
Vì sao: 2 byte trọng số 16 bit, 2 byte gradient, 4 byte bản sao FP32 của trọng số và 8 byte cho hai trạng thái của Adam. Mô hình 7 tỉ tham số cần 112 GB (Mục 12.5).6Khi huấn luyện bị hết bộ nhớ, cách xử lý đầu tiên thường là gì, và vì sao?
Đã trả lời 0/6