Chuyển tới nội dung chính

Mô hình này chạy được trên máy nào

Cộng ba khoảnKết luận nhị phânGiải ngược ra số token

Mô hình này chạy được trên máy nào

Câu hỏi thực dụng nhất của cả chương, và nó chỉ cần ba phép nhân với một phép so sánh. Phần thú vị nằm ở chiều ngược lại: máy này chịu được ngữ cảnh dài bao nhiêu?

Cả chương này bạn đã đếm từng khoản riêng lẻ. Bộ đệm KV lớn lên tuyến tính theo ngữ cảnh và theo cỡ lô. Chú ý theo nhóm cắt số đầu KV nên cắt thẳng vào cái bộ đệm đó. Cửa sổ trượt làm nó thôi lớn lên. Định dạng số đổi số byte mỗi phần tử. Bộ nhớ khi huấn luyện cho thấy huấn luyện là một hoá đơn khác hẳn. Còn hai bài đầu chương này thì dạy bạn đọc tệp cấu hìnhcác tệp trọng số để lấy đúng những con số ấy.

Bài này gộp chúng lại để trả lời một câu rất đời: mô hình này chạy được trên máy nào. Câu trả lời là ba phép nhân, một phép cộng và một phép so sánh. Nhưng có một con số thứ hai quan trọng hơn chữ vừa hay không vừa, và hầu như không ai chịu tính: với máy này thì ngữ cảnh dài nhất còn nhét được là bao nhiêu token. Sim dưới đây tính cả hai, và mọi tham số bạn sửa được.

Mô hình này chạy được trên máy nào · cộng ba khoản rồi giải ngược
Cần 34,0 GiB24,0 GiB✘ không vừa
Đang xét Llama 3.1 8B · thẻ 24 GiB trên thẻ 24 GiB lớp RTX 4090. Cái bẫy kinh điển: trọng số vừa dễ dàng, nhưng ngữ cảnh 131.072 token thì không. Đây là chỗ để đọc con số ngữ cảnh tối đa.
Nguồn số mô hình: config.json công bố trên Hugging Face: num_hidden_layers 32, num_key_value_heads 8, head_dim 128, max_position_embeddings 131072. Số tham số làm tròn về 8 tỉ, đúng con số mô hình được gọi tên.
Nguồn dung lượng: 24 GiB là dung lượng công bố của thiết bị, quy về GiB nhị phân; phần thật sự dùng được luôn nhỏ hơn vì trình điều khiển và ngữ cảnh CUDA đã lấy một ít trước khi tiến trình của bạn thấy byte nào.
Mô hình này có 32 đầu truy vấn và 8 đầu KV, tức tỉ lệ nhóm là 4. Chỉ số đầu KV vào phép tính bộ đệm, và đó là lý do của bài chú ý theo nhóm.
Số kiến trúc và dung lượng chép vào bài ngày 28/07/2026 và có thể đã lạc hậu. Preset mang mô hình cộng thiết bị cộng cách nạp số; còn cỡ lô và phần dôi là quyết định của bạn nên bấm preset không đụng vào chúng.

1 · Mô hình ✎ sửa được

2 · Máy, và phần dôi khi chạy ✎ sửa được

Phần dôi 10% là ước lượng, không phải phép đo: vùng làm việc tạm của các nhân tính, phân mảnh bộ cấp phát, đệm thừa, ngữ cảnh CUDA. Sim lấy nó bằng tỉ lệ của hai khoản đếm được rồi làm tròn lên, và đó là một quy ước chứ không phải chân lý. Hạ về 0 thì bảng dưới chỉ còn số học.

3 · Hoá đơn

khoảnbytephần của tổngcách tính
trọng số14,9 GiB43,8%số tham số × 2 byte
bộ đệm KV16,0 GiB47,1%2 × lớp × đầu KV × chiều × byte × token × lô
phần dôi khi chạy (ước lượng)3,1 GiB9,1%10% của hai dòng trên, làm tròn lên
tổng phải có34,0 GiB100,0%141,6% của dung lượng đang có

trọng số: 8.000.000.000 tham số × 2 byte = 16.000.000.000 byte

bộ đệm KV: 2 × 32 × 8 × 128 × 2 × 131.072 × 1 = 17.179.869.184 byte

tổng: 16.000.000.000 + 17.179.869.184 + 3.317.986.919 = 36.497.856.103 byte

trọng số bộ đệm KV phần dôi mốc dung lượng 24,0 GiB
✘ không vừa trên 1 thiết bị 24 GiB, thiếu 10,0 GiB.
Mốc là tổng ≤ dung lượng, và ở đúng chỗ bằng nhau thì kết luận là vừa. Với hoá đơn này, 2 thiết bị 24 GiB là ít nhất mà vẫn vừa, còn 1 thiết bị thì không.

4 · Giải ngược: ngữ cảnh dài nhất còn nhét được

56.664 token
ngữ cảnh dài nhất còn vừa, với đúng trọng số, cỡ lô và phần dôi đang đặt
128,0 KiB
giá của một token ngữ cảnh cho cả lô, tức 128,0 KiB mỗi câu nhân lô 1
4,0 KiB
cho một token ở một lớp, tức 2 × 8 × 128 × 2 = 4.096 byte
43,2%
phần của ngữ cảnh bạn đang đặt mà máy này chịu được

(100 × 25.769.803.776 trừ 16.000.000.000 × 110) ÷ (131.072 × 110) → lấy phần nguyên = 56.664 token

Kiểm lại được cả hai chiều: 56.664 token thì vừa, mà 56.665 token thì không. Chỉ kiểm một chiều thì một công thức lệch một vẫn trông đúng.

5 · Các độ dài ngữ cảnh khác thì sao

ngữ cảnhbộ đệm KVtổng phải cókết luận
4.096 token512,0 MiB16,9 GiB✔ vừa
8.192 token1,0 GiB17,5 GiB✔ vừa
32.768 token4,0 GiB20,8 GiB✔ vừa
131.072 token (đang đặt)16,0 GiB34,0 GiB✘ không vừa
524.288 token64,0 GiB86,8 GiB✘ không vừa
1.048.576 token128,0 GiB157,2 GiB✘ không vừa
Cột kết luận ghi bằng chữ kèm dấu, không chỉ bằng màu, để ai không phân biệt được màu vẫn đọc được. Bảng này luôn chuyển từ vừa sang không vừa đúng một lần, vì giá chỉ tăng theo độ dài ngữ cảnh.
Sim này không chứng minh được gì
  • cộng byte. Nó không nói mô hình chạy nhanh bao nhiêu. Một cấu hình vừa khít có thể chậm tới mức vô dụng, và một cấu hình dư bộ nhớ vẫn có thể nghẽn ở băng thông. Tốc độ phải đo, không suy ra được từ bảng này.
  • Nhiều thiết bị ở đây bị coi như một bể bộ nhớ chung. Thực tế bạn phải chọn cách chia: chia theo lớp thì mỗi thiết bị giữ vài lớp và dữ liệu chạy qua chúng lần lượt, chia theo tensor thì mỗi thiết bị giữ một phần của cùng một phép nhân và phải gộp kết quả liên tục. Mỗi cách có phí liên lạc và phần dôi riêng, sim không tính khoản nào trong đó.
  • Bộ đệm được đếm thẳng, tức đặt trước đủ chỗ cho toàn bộ độ dài ngữ cảnh của mọi câu trong lô. Bộ đệm phân trang chỉ cấp theo khối khi cần, nên nó thường dùng bộ nhớ hiệu quả hơn cách đếm ở đây. Con số này là trường hợp xấu, không phải mức đo được.
  • Dung lượng lấy nguyên con số công bố của thiết bị. Phần thật sự dùng được luôn nhỏ hơn, vì trình điều khiển và ngữ cảnh CUDA đã lấy một ít. Nói cách khác: sim lạc quan ở cả hai phía, đòi hỏi thì đếm thiếu mà cung thì đếm thừa.
  • Phần dôi là một hệ số bạn đặt. Không có con số đúng cho nó. Cách duy nhất biết máy bạn tốn bao nhiêu là chạy rồi đo.
  • Preset chỉ chép lại số công bố kèm nguồn và ngày. Cổng kiểm số canh phép tính, không canh chuyện mô hình hay thiết bị ngoài kia có đúng những con số đó hay không.

Hoá đơn gồm đúng ba khoản

Khoản một, trọng số, bằng số tham số nhân số byte mỗi tham số. Ở trạng thái mở bài là 8 tỉ tham số ở 2 byte, tức 8.000.000.000 × 2 = 16.000.000.000 byte, hiện là 14,9 GiB. Khoản này là hằng số: nó không quan tâm câu nhắc dài một trăm hay một trăm nghìn token. Đổi sang 1 byte thì nó còn một nửa, đổi sang 4 bit thì còn một phần tư, và đó là toàn bộ lý do người ta lượng tử hoá trọng số.

Khoản hai, bộ đệm KV, đúng công thức bài bộ đệm KV đã dựng: 2 × số lớp × số đầu KV × chiều mỗi đầu × số byte × số token × cỡ lô. Số 2 đứng đầu là vì mỗi token để lại một vectơ khoá và một vectơ giá trị, không có gì khác nấp trong đó. Với 32 lớp, 8 đầu KV, 128 chiều mỗi đầu và 2 byte, một token ở một lớp tốn 2 × 8 × 128 × 2 = 4096 byte, nhân 32 lớp thành 131.072 byte tức 128,0 KiB cho mỗi token. Ngữ cảnh 131.072 token với lô 1 thì thành 17.179.869.184 byte, đúng 16,0 GiB. Khoản này lớn hơn khoản trọng số ngay ở trạng thái mở bài: 47,1% của tổng so với 43,8%.

Khoản ba, phần dôi khi chạy, là ước lượng chứ không phải phép đo. Vùng làm việc tạm của các nhân tính, phân mảnh bộ cấp phát, đệm thừa, ngữ cảnh CUDA: những thứ này có thật, chúng tốn bộ nhớ thật, và không phép nhân nào trên trang này đoán được chúng. Nên sim để chúng thành một hệ số bạn đặt, mặc định 10% của hai khoản trên, làm tròn lên. Ở trạng thái mở bài đó là 3.317.986.919 byte tức 3,1 GiB. Hãy coi con số 10% là một quy ước để có cái mà bàn, không phải một hằng số của tự nhiên. Kéo nó về 0 thì cả trang chỉ còn số học thuần, và đó là cách kiểm tra xem kết luận của bạn có phụ thuộc vào phần đoán hay không.

Cộng lại: 16.000.000.000 + 17.179.869.184 + 3.317.986.919 = 36.497.856.103 byte, tức 34,0 GiB.

Kết luận nhị phân, và cái mốc bằng nhau

Thiết bị mở bài là một thẻ 24 GiB, tức 25.769.803.776 byte. Tổng đang là 141,6% của con số đó, nên kết luận là không vừa, thiếu 10.728.052.327 byte tức 10,0 GiB. Sim còn nói luôn: cần 2 thiết bị 24 GiB mới vừa, và với 2 thiết bị thì còn dư 14,0 GiB.

Mốc được định nghĩa là tổng ≤ dung lượng, và ở đúng chỗ bằng nhau thì kết luận là vừa. Nghe như chi li thừa thãi, nhưng đây là loại lỗi không con số nào trên màn hình tố cáo được: viết nhầm thành tổng < dung lượng thì mọi cấu hình vẫn hiện đúng byte, chỉ riêng cấu hình rơi trúng mốc bị kết luận sai, và không ai đứng đúng vào chỗ đó để phát hiện. Cổng kiểm số của bài vì vậy khẳng định cả ba điểm: đúng trên mốc, thấp hơn mốc một byte, cao hơn mốc một byte.

Nói cho công bằng: trong thực tế bạn sẽ không muốn chạy ở đúng 100% dung lượng. Nhưng chỗ để cài cái thận trọng đó là núm phần dôi, không phải phép so sánh. Trộn hai thứ vào nhau là cách chắc chắn để sau này không biết mình đang đo cái gì.

Con số ít ai tính: ngữ cảnh dài nhất còn nhét được

Chữ vừa hay không vừa chỉ trả lời một bit. Câu hỏi có ích hơn là: giữ nguyên máy và trọng số, ngữ cảnh dài nhất mà bộ đệm còn nhét được là bao nhiêu. Phép giải ngược khá gọn. Gọi W là byte trọng số, c là giá một token ngữ cảnh cho cả lô, p là phần dôi tính theo phần trăm, C là dung lượng. Hoá đơn ở ngữ cảnh TW + cT cộng thêm phần dôi của chính nó, nên điều kiện vừa rút gọn được thành

(W + cT) × (100 + p) ≤ 100 × C

và số token tối đa là phần nguyên của (100C - W(100 + p)) ÷ (c(100 + p)).

Ở trạng thái mở bài, phép đó cho 56.664 token. Tức mô hình 8 tỉ tham số ở 2 byte đúng là chạy được trên một thẻ 24 GiB, nhưng chỉ với khoảng 43% ngữ cảnh mà nó được huấn luyện để dùng. Con số này chính xác tới từng byte: ở 56.664 token thì hoá đơn là 25.769.770.189 byte, còn dư 33.587 byte; thêm đúng một token nữa thành 25.769.914.368 byte và vượt thẻ. Cổng kiểm số khẳng định cả hai chiều, vì chỉ khẳng định một chiều thì một công thức lệch một đơn vị vẫn xanh mãi mãi.

Bấm sang preset Llama 3.1 8B ở 4 bit: cùng mô hình, cùng thẻ, chỉ đổi hai ô byte. Hoá đơn tụt xuống 12,9 GiB, kết luận thành vừa, và ngữ cảnh tối đa lên 296.433 token, tức vượt xa cái 131.072 mà mô hình được huấn luyện. Đây là toàn bộ nội dung của câu "lượng tử hoá để chạy trên máy cá nhân", viết bằng số.

Khi cắt ngữ cảnh không cứu được gì

Preset Llama 3.1 70B trên một thẻ 80 GiB là ca đáng nhìn kỹ nhất. Trọng số ở 2 byte là 140.000.000.000 byte tức 130,4 GiB, trong khi thẻ chỉ có 85.899.345.920 byte tức 80,0 GiB. Ngữ cảnh tối đa ra 0 token, và đó là số 0 thật chứ không phải một số âm bị che đi: ngay cả khi bộ đệm rỗng hoàn toàn thì trọng số một mình đã không nạp nổi.

Điều này nghe hiển nhiên khi viết ra, nhưng nó đổi hẳn việc cần làm. Khi ngữ cảnh tối đa bằng 0 thì cắt ngữ cảnh là vô nghĩa, dù cắt bao nhiêu: bạn phải hạ số byte mỗi trọng số hoặc thêm thiết bị. Sim nói luôn cần 3 thiết bị 80 GiB mới vừa cho cấu hình đó, và 2 thiết bị thì không.

Có một biến thể tinh vi hơn mà sim cũng phân biệt: trọng số vừa, nhưng cộng phần dôi lên chúng thì đã vượt. Lúc đó ngữ cảnh tối đa cũng bằng 0, mà lý do khác hẳn, nên sim ghi hai câu giải thích khác nhau chứ không dùng chung một câu cho tiện.

Đọc preset và đọc dung lượng cho đúng

Preset ở đây là một cặp: một mô hình và một thiết bị, vì câu hỏi của bài là cặp đó chứ không phải riêng cái nào. Mỗi vế mang tên, ngày chép và nguồn riêng, và ngày hiện ngay dưới hàng preset. Preset thứ nhất ghi rõ cả mô hình lẫn thiết bị đều là số minh hoạ, không phải cấu hình của ai cả, vì thà nói là minh hoạ còn hơn dán một cái tên lên những con số mình không kiểm được.

Hai điểm nhỏ nhưng hay làm người ta nhầm:

  • Dung lượng công bố không phải dung lượng dùng được. Trình điều khiển và ngữ cảnh CUDA đã lấy một ít trước khi tiến trình của bạn thấy byte nào. Sim lấy nguyên con số công bố, nên nó lạc quan ở cả hai phía: đòi hỏi thì đếm thiếu, còn cung thì đếm thừa.
  • Cỡ lô và phần dôi không thuộc về preset. Đó là cách bạn phục vụ mô hình, không phải thuộc tính của mô hình hay của thẻ, nên bấm preset không đụng vào hai ô đó. Đổi cỡ lô từ 1 lên 2 là nhân đôi toàn bộ khoản bộ đệm, và bảng sẽ cho bạn thấy ngay.

Sim này không chứng minh được gì

Phần này quan trọng ngang phần trên, nên đọc kỹ.

  • Nó không nói mô hình chạy nhanh bao nhiêu. Nó cộng byte. Một cấu hình vừa khít vẫn có thể chậm tới mức không dùng được, và một cấu hình dư bộ nhớ vẫn có thể nghẽn ở băng thông. Tốc độ phải đo.
  • Nó gộp nhiều thiết bị thành một bể bộ nhớ chung. Thực tế bạn phải chọn cách chia. Chia theo lớp thì mỗi thiết bị giữ một số lớp và dữ liệu đi qua chúng lần lượt. Chia theo tensor thì mỗi thiết bị giữ một phần của cùng một phép nhân và phải gộp kết quả liên tục. Mỗi cách có phí liên lạc và phần dôi riêng, và sim không tính khoản nào trong đó. Đây là chỗ nó yếu nhất.
  • Nó đếm bộ đệm thẳng, tức đặt trước đủ chỗ cho toàn bộ độ dài ngữ cảnh của mọi câu trong lô. Bộ đệm KV phân trang chỉ cấp theo khối khi cần nên thường dùng bộ nhớ hiệu quả hơn hẳn cách đếm ở đây. Con số của sim là trường hợp xấu, không phải mức đo được.
  • Phần dôi là hệ số bạn đặt. Không có con số đúng cho nó. Cách duy nhất biết máy bạn tốn bao nhiêu là chạy rồi đo.

Cổng kiểm số của bài canh phép tính: nếu cấu hình là như vậy thì từng khoản, tổng, kết luận vừa hay không vừa và số token tối đa phải đúng như vậy, kiểm cả ở đúng mốc biên lẫn một byte hai bên. Nó không canh, và không thể canh, những khẳng định về tốc độ hay về việc mô hình ngoài kia có thật sự mang những con số này.

Điều rút ra

Hoá đơn để chạy một mô hình gồm ba khoản: trọng số là hằng số, bộ đệm KV lớn lên theo ngữ cảnh nhân cỡ lô, phần dôi khi chạy là ước lượng nên phải để nó thành một núm chứ đừng giả vờ biết. Cộng lại rồi so với dung lượng nhân số thiết bị, và nhớ rằng mốc bằng nhau thì tính là vừa. Nhưng con số đáng mang đi dùng không phải chữ vừa hay không vừa mà là ngữ cảnh dài nhất còn nhét được: nó chỉ là một phép chia, và nó cho biết bạn phải cắt gì. Khi số đó bằng 0 thì cắt ngữ cảnh không cứu được gì, phải hạ bit hoặc thêm máy. Cuối cùng: phép cộng này nói được cái gì vừa, nó không nói được cái gì nhanh.

Câu hỏi tự kiểm0/3 đúngchưa trả lời
  1. 1Một cấu hình cộng lại ra đúng 25.769.803.776 byte, và thiết bị cũng đúng 25.769.803.776 byte. Sim kết luận thế nào, và vì sao lại phải nói rõ chuyện này?
  2. 2Llama 3.1 8B ở 2 byte trên một thẻ 24 GiB: tổng ra 34,0 GiB nên không vừa, còn ngữ cảnh tối đa là 56.664 token. Con số 56.664 nói cho bạn biết phải làm gì?
  3. 3Llama 3.1 70B ở 2 byte trên một thẻ 80 GiB, sim báo ngữ cảnh tối đa bằng 0 token. Đọc con số 0 đó thế nào cho đúng?