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

Cửa sổ trượt

Mặt nạ sửa đượcKế toán chính xácTầm nhìn phản trực giác

Cửa sổ trượt

Mỗi token có thật cần đọc lại toàn bộ những gì đứng trước nó? Cắt cho nó chỉ nhìn vài chục token gần nhất thì tiết kiệm được đúng bao nhiêu, và mất gì?

self-attention bạn đã thấy mỗi truy vấn chấm với mọi khoá đứng trước nó. Trong mô hình sinh chữ, mặt nạ nhân quả chỉ chặn phần tương lai, nên trên chuỗi n token vẫn còn n(n+1)/2 ô được phép nhìn: chi phí tính toán bậc hai, và như bài bộ đệm KV đã đếm, bộ nhớ phải giữ lớn lên tuyến tính theo độ dài ngữ cảnh mà không bao giờ nhỏ lại.

Có một cách cắt rất thô: bắt mỗi token chỉ được đọc w token gần nhất, cửa sổ trượt theo vị trí. Nghe như tự làm mô hình kém đi, và điều đó có thể đúng, nhưng hai chuyện sau lại làm nó dùng được thật. Thứ nhất, bộ đệm KV chỉ còn phải giữ đúng cửa sổ, tức nó thôi lớn lên theo ngữ cảnh. Thứ hai, qua nhiều lớp thì tầm nhìn không hề bị khoá ở w. Sim dưới đây tính cả hai bằng số học phổ thông, bạn sửa cấu hình thì nó tính lại.

Cửa sổ trượt · chỉ nhìn gần, và cái giá của nó
Ô mở 105/210Tỉ lệ 50.0%Bộ đệm KV 512.0 MiB
Cửa sổ thật của mô hình là 4096 token, quá rộng để vẽ trên 20 token, nên ma trận minh hoạ dùng cửa sổ 6 còn phần kế toán byte dùng đúng 4096.
Nguồn số: Báo cáo kỹ thuật Mistral 7B (arXiv:2310.06825, 10/2023) và tệp cấu hình công bố kèm mô hình: 32 lớp, 8 đầu KV, 128 chiều mỗi đầu, cửa sổ trượt 4096, ngữ cảnh 32768.
Số chép vào bài ngày 27/07/2026 và có thể đã lạc hậu: lĩnh vực này đổi rất nhanh. Mọi tham số bên dưới đều sửa được, nên có số mới hơn thì gõ vào là tính lại ngay.

1 · Ma trận mặt nạ trên 20 token ✎ sửa được

hàng i \ cột j012345678910111213141516171819ô mở
01
12
23
34
45
56
6×6
7××6
8×××6
9××××6
10×××××6
11××××××6
12×××××××6
13××××××××6
14×××××××××6
15××××××××××6
16×××××××××××6
17××××××××××××6
18×××××××××××××6
19××××××××××××××6
Nhấp một ô bất kỳ trong ma trận để xem vì sao ô đó mở hay bị cắt.
105
ô được phép nhìn, tức số phép chú ý phải tính
50.0%
so với nhân quả đầy đủ (210 ô), tức đã cắt 105 ô
6
token phải giữ trong bộ đệm, đếm đúng bằng số ô mở ở hàng cuối
0
ô chỉ mở được nhờ token neo (bằng 0 khi không bật neo)

2 · Tầm nhìn hiệu dụng qua nhiều lớp ✎ sửa được

Mỗi lớp trộn thêm một cửa sổ nữa, nên qua L lớp thì tầm nhìn là L × (w - 1) + 1 token, xấp xỉ L × w. Trên ma trận đang vẽ: cửa sổ 6 qua 32 lớp muốn tới 161 token, còn chuỗi chỉ có 20 token nên con số bị kẹp về 20.

Ở quy mô thật: cửa sổ 4.096 token, ngữ cảnh 32.768 token
1 lớp4.096 token
2 lớp8.191 token
4 lớp16.381 token
8 lớp32.761 token
16 lớp32.768 tokenđã phủ hết ngữ cảnh
32 lớp32.768 tokenđã phủ hết ngữ cảnh
Đây là giới hạn hình học của đường truyền thông tin: xa nhất thì tín hiệu có thể đi tới đó. Nó không nói rằng mô hình thật dùng hết tầm đó, và cũng không nói tín hiệu đi xa mấy lớp còn mạnh bao nhiêu.

3 · Byte bộ đệm KV ở quy mô thật ✎ sửa được

2 (giữ cả K và V) × 8 đầu KV × 128 chiều × 2 byte = 4.096 byte cho mỗi token ở mỗi lớp. Nhân 32 lớp ra 128.0 KiB cho mỗi token. Phần còn lại chỉ là đếm xem phải giữ bao nhiêu token.

ở ngữ cảnh 32.768 tokencửa sổ trượtnhân quả đầy đủtỉ lệ
token phải giữ trong bộ đệm4.09632.76812.5%
byte bộ đệm KV512.0 MiB4.00 GiB12.5%
phép chú ý khi nạp cả ngữ cảnh125.831.168536.887.29623.4%
Tiết kiệm được 3.50 GiB bộ đệm KV so với nhân quả đầy đủ, và đó là chỗ hấp dẫn nhất của cửa sổ trượt: bộ đệm không còn lớn lên theo độ dài ngữ cảnh nữa, nó dừng ở cửa sổ.
Sim này không làm được gì
  • đếm ô nào được nhìn và byte nào phải giữ. Nó không đo chất lượng. Một mặt nạ cắt 90% số ô vẫn hiện ra ở đây đẹp đẽ như nhau, dù mô hình có thể đã hỏng hẳn.
  • Vì sao token neo lại quan trọng tới vậy là một kết quả thực nghiệm của người khác, không phải thứ số học này chứng minh được. Ở đây bạn chỉ thấy chúng tốn thêm bao nhiêu ô và bao nhiêu byte.
  • Số token phải giữ được định nghĩa là số ô mở ở hàng cuối của ma trận, để bạn đếm được bằng mắt. Cách cấp phát thật còn phân trang, còn đệm thừa, còn chỗ cho lô nhiều câu, nên byte thực tế thường nhiều hơn con số này.
  • Preset mang tên mô hình chỉ chép lại tham 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 ngoài kia có đúng cấu hình đó hay không.

Ba con số đáng nhìn kỹ

Cắt cửa sổ là cắt phép tính, và nó đo được chính xác. Ở trạng thái mở bài, ma trận vẽ 20 token với cửa sổ 6. Mặt nạ nhân quả đầy đủ mở 20 × 21 / 2 = 210 ô; cửa sổ 6 mở 6 × 7 / 2 + 14 × 6 = 21 + 84 = 105 ô, đúng một nửa. Công thức đóng ở đây dễ tự dựng lại: hàng i mở min(i + 1, w) ô, nên tổng chia làm hai đoạn, đoạn đầu là cái dốc w(w + 1)/2 cho tới khi cửa sổ đầy, đoạn sau là (n - w) hàng mỗi hàng đúng w ô. Đẩy cửa sổ lên bằng hoặc lớn hơn số token thì tỉ lệ về đúng 1, tức mặt nạ quay lại nhân quả đầy đủ, không phải gần giống mà là từng ô một.

Bộ đệm KV thôi lớn lên theo ngữ cảnh, đây là chỗ ăn tiền nhất. Nhìn bảng số 3. Với cấu hình 32 lớp, 8 đầu KV, 128 chiều mỗi đầu và 2 byte mỗi phần tử, mỗi token ở mỗi lớp tốn 2 × 8 × 128 × 2 = 4096 byte, nhân 32 lớp ra 128.0 KiB cho mỗi token. Ngữ cảnh 32768 token mà giữ hết thì thành 4.00 GiB chỉ riêng bộ đệm. Cửa sổ 4096 chỉ phải giữ 4096 token, tức 512.0 MiB, còn 12,5% và tiết kiệm 3.50 GiB. Quan trọng hơn con số đó: nếu bạn kéo độ dài ngữ cảnh lên nữa thì cột nhân quả đầy đủ tăng theo, còn cột cửa sổ trượt đứng nguyên. Phần phép chú ý khi nạp cả ngữ cảnh cũng tụt về 23,4%, vì bậc hai đã thành gần như tuyến tính.

Cửa sổ hẹp không phải là tầm nhìn hẹp, và đây là điểm phản trực giác nhất của bài. Ở lớp 1, token i trộn được thông tin của token i - (w - 1). Lớp 2 đọc các trạng thái đã trộn đó, nên nó với tới i - 2(w - 1). Cứ mỗi lớp lại vươn thêm một cửa sổ nữa, nên qua L lớp tầm nhìn hiệu dụng là L × (w - 1) + 1 token, xấp xỉ L × w. Kéo núm số lớp mà xem: cửa sổ 4096, một lớp với tới 4096 token, hai lớp 8191, bốn lớp 16.381, tám lớp đã là 32.761 token, tức gần trọn ngữ cảnh 32768. Từ lớp thứ chín trở đi con số bị kẹp ở độ dài chuỗi và sim nói thẳng là đã phủ hết. Trên ma trận nhỏ đang vẽ thì hiện tượng kẹp xảy ra ngay: 32 lớp cửa sổ 6 muốn với tới 161 token, mà chuỗi chỉ có 20.

Nói cho đúng, đó là giới hạn hình học của đường truyền thông tin, không phải lời bảo đảm. Nó cho biết xa nhất thì tín hiệu có thể đi tới đâu, chứ không nói tín hiệu đi qua tám lớp còn mạnh bao nhiêu, cũng không nói mô hình có học được cách dùng đường đi dài đó hay không. Sim này không đo được những chuyện ấy, và bạn nên nghi ngờ bất cứ ai nói L × w là ngữ cảnh hiệu dụng.

Vì sao phải giữ lại vài token đầu chuỗi

Bấm sang chế độ cửa sổ trượt cộng token neo. Bốn cột sát mép trái mở ở mọi hàng, và từ hàng 6 trở đi chúng đổi màu, vì lúc đó chúng đã nằm ngoài cửa sổ và chỉ còn neo giữ lại. Với 20 token, cửa sổ 6 và 4 token neo, số ô mở đi từ 105 lên 155, trong đó 50 ô có được là nhờ neo, và bộ đệm phải giữ 10 token thay vì 6. Ở quy mô thật thì 4 token neo thêm vào 4096 token cửa sổ chỉ đội bộ đệm từ 512.0 MiB lên 512.5 MiB, tức thêm nửa MiB.

Nửa MiB để làm gì? Đây là chỗ phải nói thật rõ ranh giới. Người ta phát hiện ra rằng nếu bỏ hẳn các token đầu chuỗi ra khỏi bộ đệm, chất lượng sinh chữ sụp một cách bất thường, sụp mạnh hơn nhiều so với mức mà việc mất vài token ở xa đáng gây ra. Cách giải thích thường gặp là softmax buộc tổng trọng số bằng 1, nên khi không có ô nào đáng để ý thật thì mô hình phải đổ phần trọng số dư đó vào đâu đó, và trong thực tế nó học cách đổ vào mấy token đầu chuỗi. Bỏ mất chỗ trút ấy thì phân bố chú ý méo hẳn. Giữ lại vài token neo là cách vá rất rẻ, và cái rẻ đó thì sim đo được.

Nhưng phần chất lượng thì sim không đo được. Nó đếm ô và đếm byte. Kết luận rằng 4 token neo cứu được chất lượng là kết quả thực nghiệm của người khác, đo bằng perplexity trên chuỗi rất dài, không phải thứ mà số học ở đây chứng minh. Cổng kiểm số của bài này canh phép tính: nếu cấu hình là như vậy thì số ô và số byte phải là như vậy. Nó không canh, và không thể canh, những khẳng định về mô hình ngoài kia.

Đọc preset cho đúng

Preset mang tên mô hình chỉ chép lại tham số đã công bố, kèm nguồn và ngày chép, và ngày đó hiện ngay dưới hàng preset. Lĩnh vực này đổi rất nhanh: một bản v0.2 có thể bỏ hẳn cửa sổ trượt, một mô hình mới có thể xen kẽ lớp cửa sổ với lớp toàn cục theo tỉ lệ riêng của nó. Nên hãy coi preset là ví dụ đã đóng băng thời điểm. Preset thứ tư ghi rõ là số minh hoạ cho một lớp kích thước, không phải cấu hình của mô hình nào cả, vì thà nói là minh hoạ còn hơn dán tên một mô hình lên những con số mình không kiểm được.

Vài điểm nhỏ nhưng hay bị bỏ qua:

  • Cửa sổ trượt là chuyện của mặt nạ, không phải chuyện của trọng số. Cùng một mô hình có thể chạy với cửa sổ ở lúc suy luận dù nó không được huấn luyện như vậy, và ngược lại. Điều đó ảnh hưởng tới chất lượng, nhưng không ảnh hưởng tới phép đếm ở đây.
  • Số token phải giữ trong sim được định nghĩa là số ô mở ở hàng cuối của ma trận, để bạn đếm được bằng mắt. Bộ nhớ thật còn phân trang, còn đệm thừa, còn phải chứa nhiều câu trong một lô, nên con số thực tế thường lớn hơn.
  • Cửa sổ bằng 0 bị chặn. Cửa sổ 0 nghĩa là token không đọc được cả chính nó, hàng mặt nạ rỗng và softmax chia cho 0. Sim kẹp về 1 và báo cho bạn biết là nó đã kẹp, thay vì âm thầm sửa.
Điều rút ra

Cửa sổ trượt đổi tầm nhìn trực tiếp lấy hai thứ rất cụ thể: số phép chú ý tụt từ bậc hai về gần tuyến tính, và bộ đệm KV thôi lớn lên theo ngữ cảnh vì chỉ còn phải giữ đúng cửa sổ. Cái làm nó dùng được thật là chuyện xếp lớp: qua L lớp, tầm nhìn hiệu dụng lên tới khoảng L × w, nên cửa sổ 4096 với 32 lớp về mặt hình học đã phủ trọn ngữ cảnh 32768. Chỗ nó gãy là các token đầu chuỗi, nên người ta giữ lại vài token neo, và cái giá của mấy token đó nhỏ tới mức gần như miễn phí. Đếm được ô và byte không có nghĩa là đo được chất lượng: phần đó phải chạy thực nghiệm mới biết.

Câu hỏi tự kiểm0/3 đúngchưa trả lời
  1. 1Một chuỗi 8 token với mặt nạ nhân quả đầy đủ. Có bao nhiêu ô được phép nhìn, tức bao nhiêu phép chú ý phải tính?
  2. 2Mô hình có 32 lớp, mỗi lớp dùng cửa sổ trượt rộng 4096, ngữ cảnh 32768 token. Về mặt hình học, thông tin từ token đầu chuỗi có thể đi tới token cuối chuỗi hay không?
  3. 3Đang ở cửa sổ trượt 4096 trên ngữ cảnh 32768 với bộ đệm 512.0 MiB. Bật thêm 4 token neo đầu chuỗi thì chuyện gì xảy ra, và sim chứng minh được điều gì?