Giải mã đầu cơ: đoán trước rồi kiểm một lượt
Giải mã đầu cơ: đoán trước rồi kiểm một lượt
Sinh chữ tuần tự chậm vì mỗi token phải chạy hết mô hình. Có một cách né được phần lớn cái chậm đó mà không đổi một chữ nào trong kết quả, và giá phải trả nằm ở chỗ ít ai đoán.
Ở bài KV cache bạn đã thấy sinh chữ là bài toán bộ nhớ. Hệ quả trực tiếp của nó là: một lượt sinh token bị chặn bởi băng thông bộ nhớ, không phải bởi sức tính. Mô hình phải đọc toàn bộ trọng số từ VRAM vào nhân tính chỉ để sinh ra đúng một token, rồi lặp lại y hệt cho token sau. Nghĩa là nếu lượt đó chấm điểm cho một vị trí hay cho năm vị trí thì thời gian gần như bằng nhau: phần đọc trọng số đã chiếm hết, phần tính thêm gần như miễn phí.
Giải mã đầu cơ khai thác đúng chỗ đó. Một mô hình nháp nhỏ và nhanh đoán trước gamma token, rồi mô hình đích chấm cả gamma + 1 vị trí trong một lượt duy nhất, giữ lại tiền tố đoán đúng và vứt phần sau. Đổi một lượt đích lấy nhiều token cùng lúc. Bảng tính dưới đây là toàn bộ phép kế toán đó, cộng thêm phần chứng minh vì sao kết quả không đổi.
gamma + 1 vị trí cùng lúc rẻ ngang sinh một token.| Vòng | Đề xuất | Nhận | Bỏ ở vị trí | Token thu | Cộng dồn token | Lượt nháp | Lượt đích | Chi phí dồn |
|---|---|---|---|---|---|---|---|---|
| 1 | 4 | 4 | không bỏ, được thêm token thưởng | 5 | 5 | 4 | 1 | 1,40 |
| 2 | 4 | 2 | 3 | 3 | 8 | 8 | 2 | 2,80 |
| 3 | 4 | 0 | 1 | 1 | 9 | 12 | 3 | 4,20 |
| 4 | 4 | 3 | 4 | 4 | 13 | 16 | 4 | 5,60 |
| 5 | 4 | 1 | 2 | 2 | 15 | 20 | 5 | 7,00 |
| 6 | 4 | 4 | không bỏ, được thêm token thưởng | 5 | 20 | 24 | 6 | 8,40 |
p và của mô hình nháp q. Luật lấy mẫu đầu cơ: rút từ q, nhận với xác suất min(1, p/q), khi bị từ chối thì rút lại từ phần dư max(0, p - q) đã chuẩn hoá. Cột cuối là phân phối đầu ra thật sự, và nó phải trùng khít cột p.| Token | p (đích) | q (nháp) | min(p, q) | phần dư thô | phần dư chuẩn hoá | đầu ra |
|---|---|---|---|---|---|---|
| mưa | 0,4000 | 0,1000 | 1,0000 | 0,5000 | ||
| nắng | 0,2500 | 0,0000 | 0,0000 | 0,2500 | ||
| gió | 0,1500 | 0,0000 | 0,0000 | 0,1500 | ||
| bão | 0,1000 | 0,0000 | 0,0000 | 0,1000 |
alpha ở trên bằng 90,0% thì phần tính chi phí đang mô tả đúng cặp phân phối này.Vì sao một vòng luôn thu được đúng k + 1 token
Gọi k là số token nháp sống sót qua vòng kiểm. Điều đầu tiên phải nắm là con số +1: nó không bao giờ vắng mặt, dù vòng đó tệ tới đâu.
Có hai trường hợp. Nếu token thứ k + 1 bị từ chối thì chính lượt kiểm đó đã cho ta phân phối của mô hình đích tại vị trí ấy, nên ta lấy luôn một token từ đó: được k token nháp cộng một token sửa. Nếu cả gamma token đều được nhận thì lượt kiểm còn thừa một vị trí nữa, vị trí thứ gamma + 1, và nó cho một token thưởng không mất thêm gì: được gamma cộng một.
Nên trường hợp xấu nhất của một vòng là thu về 1 token, đúng bằng giải mã thường. Giải mã đầu cơ không bao giờ sinh ít token hơn cho mỗi lượt đích. Cái nó có thể làm tệ đi là tổng chi phí, vì các lượt nháp vẫn phải trả tiền dù có được nhận hay không. Toàn bộ bài này xoay quanh chỗ đó.
Token kỳ vọng mỗi vòng
Đặt alpha là xác suất một token nháp bất kỳ được chấp nhận, giả định độc lập giữa các vị trí. Tiền tố đạt tới ít nhất i token khi và chỉ khi i token đầu đều được nhận, tức với xác suất alpha^i. Cộng lại theo i từ 0 tới gamma:
E = alpha^0 + alpha^1 + ... + alpha^gamma = (1 - alpha^(gamma+1)) / (1 - alpha)
Đây là cấp số nhân, nên hai vế bằng nhau. Ô công thức trong sim in cả hai dạng cạnh nhau, và bạn sẽ thấy chúng luôn khớp.
Ba giá trị đáng thuộc lòng, vì chúng là các mốc mà cổng kiểm số của bài khoá lại:
| Trường hợp | E | Vì sao |
|---|---|---|
alpha = 1 | gamma + 1 | công thức đóng chia cho 0, phải lấy giới hạn |
alpha = 0 | 1 | không token nháp nào sống, chỉ còn token sửa |
gamma = 0 | 1 | không đoán gì cả, tức giải mã thường |
Mốc alpha = 1 là chỗ hay làm hỏng chương trình: đặt thẳng công thức đóng vào máy tính thì mẫu số bằng 0 và bạn nhận NaN. Sim này rẽ nhánh tường minh và trả về gamma + 1.
Trần của E khi gamma chạy ra vô cùng là 1 / (1 - alpha). Với alpha = 0,8 trần đó là 5 token một vòng, và đây chính là hạt giống của điểm bất ngờ ở mục sau.
Đọc lại con số ở trạng thái mặc định
Sim mở ra với gamma = 4, alpha = 0,8, chi phí một lượt nháp bằng 0,10 và chi phí một lượt kiểm bằng 1,00. Đơn vị của mọi chi phí là một lượt của mô hình đích, cũng đúng bằng giá của một token dưới giải mã thường.
E = 1 + 0,8 + 0,64 + 0,512 + 0,4096 = 3,362 token
chi phí một vòng = 4 × 0,10 + 1,00 = 1,40
hệ số tăng tốc = 3,362 / 1,40 = 2,40×
Tức mỗi token chỉ còn tốn 0,416 lượt đích thay vì 1. Và chú ý ô phần trần đạt được ghi 67,2%: trong 5 token mà một vòng có thể cho, trung bình ta lấy được hơn hai phần ba. Phần hụt là cái giá của việc đoán trượt.
Đoán càng xa càng tốt? Không, và đây là chỗ trực giác sai
Nếu một vòng đoán 4 token cho 2,40× thì đoán 32 token chắc phải cho nhiều hơn nhiều. Kéo thanh gamma lên 32 và nhìn:
E = 4,997 token chi phí một vòng = 32 × 0,10 + 1,00 = 4,20
hệ số tăng tốc = 4,997 / 4,20 = 1,19×
Tệ đi một nửa. Lý do nằm gọn trong hai con số đó. Tử số bão hoà: nó bị chặn trên bởi 1 / (1 - alpha) = 5, và ở gamma = 32 nó đã đứng ở 4,997, tức gần như không thể nhích thêm. Mẫu số thì tăng tuyến tính mãi, vì mỗi token đoán thêm là thêm một lượt nháp phải trả, bất kể nó có sống sót hay không. Một đại lượng có trần chia cho một đại lượng không có trần thì cuối cùng phải đi về 0.
Giữa hai đầu đó có một đỉnh. Với bộ tham số mặc định, đỉnh nằm ở gamma = 6 với 2,47×, nhỉnh hơn 2,40× ở gamma = 4 một chút, và hơn hẳn 1,19× ở gamma = 32. Đường cong trong sim vẽ đúng con số này cho từng gamma từ 0 tới 32, nên bạn không phải tin lời tôi.
Đây là điều đáng dừng lại. Trong phần lớn các cơ chế bạn gặp ở chương trước, đẩy một tham số lên thì hoặc luôn tốt hơn hoặc luôn xấu đi. Ở đây thì không: có một điểm ngọt, và tìm nó là một quyết định kỹ thuật thật sự của người triển khai.
Đỉnh dịch chỗ khi nào
Đỉnh không phải hằng số. Nó phụ thuộc cả ba tham số còn lại, và mỗi hướng dịch chuyển đều có lý do đọc được ra thành lời.
Alpha lên thì đỉnh sang phải. Giữ nguyên chi phí, chỉ đổi alpha: ở 0,4 đỉnh là gamma = 2, ở 0,8 là 6, ở 0,9 là 10, ở 0,95 là 15. Nháp bám sát đích hơn thì mỗi token đoán thêm có cơ hội sống cao hơn, nên đáng đoán dài hơn. Với alpha = 0,4 mà bạn đặt gamma = 8 thì gần như toàn bộ tiền nháp là ném đi.
Nháp đắt lên thì đỉnh sang trái. Giữ alpha = 0,8, chỉ đổi chi phí nháp: ở 0,01 đỉnh là gamma = 14, ở 0,10 là 6, ở 0,25 là 3, ở 0,99 là 0. Con số cuối đáng nhớ: khi mô hình nháp đắt gần bằng mô hình đích thì không có gamma nào có lãi, tốt nhất là đừng đầu cơ. Bấm preset Nháp đắt ngang đích để thấy trường hợp đó bằng số: hệ số tăng tốc lúc ấy đúng bằng phần trần đạt được, mà phần trần thì không bao giờ vượt 1.
Chi phí nháp bằng 0 đẩy đỉnh ra khỏi khung. Preset Nháp gần như miễn phí đặt chi phí nháp về 0, và khi đó gamma càng lớn càng tốt: sim quét tới 32, báo 5,00× và nói thẳng rằng đỉnh thật có thể còn xa hơn nữa. Đây là giới hạn của phép quét, không phải một con số vật lý.
Kiểm đắt lên thì đỉnh cũng sang phải. Chỗ này ngược trực giác lần hai. Đặt chi phí kiểm lên 1,50 và đỉnh dịch từ 6 sang 7. Lý do: chi phí kiểm là phí cố định của mỗi vòng, không phụ thuộc gamma. Phí cố định càng lớn thì càng đáng chia nó cho nhiều token hơn, tức càng đáng đoán dài hơn một chút.
Nhanh hơn mà kết quả không đổi
Tới đây bạn có thể nghi ngờ: nhanh gấp đôi thì phải đánh đổi cái gì chứ. Với giải mã đầu cơ làm đúng luật thì không, và đây là điểm khiến nó khác hẳn mọi mẹo tăng tốc kiểu lượng tử hoá hay tỉa mô hình.
Luật lấy mẫu đầu cơ như sau. Rút một token x từ phân phối nháp q, nhận nó với xác suất min(1, p(x)/q(x)) trong đó p là phân phối đích. Nếu bị từ chối thì không lấy bừa token của p, mà rút lại từ phần dư max(0, p - q) sau khi chuẩn hoá. Bảng thứ hai trong sim tính từng cột của phép này trên bốn token đồ chơi, và bạn đổi được cả p lẫn q.
Với cặp mặc định, khối lượng sống sót qua phép nhận là min(p, q) cộng lại bằng 0,90, nên xác suất từ chối là 0,10, và phần dư max(0, p - q) cũng có tổng đúng bằng 0,10. Không phải trùng hợp: hai số này luôn bằng nhau, vì tổng của p và của q đều bằng 1. Cho nên với token mưa:
đầu ra = min(p, q) + xác suất từ chối × phần dư chuẩn hoá
= 0,4 + 0,10 × 1 = 0,5 = p
Và cột đầu ra trùng khít cột p ở mọi dòng, không phải trung bình mà là từng dòng một. Nghĩa là văn bản sinh ra được rút từ đúng phân phối của mô hình đích, y như khi không dùng nháp. Cổng kiểm số của bài chạy phép này trên 729 cặp phân phối khác nhau và kiểm rằng đẳng thức đóng lại trong mọi trường hợp.
Một hệ quả đáng chú ý: xác suất chấp nhận tự nhiên của một cặp phân phối chính là tổng min(p, q), tức 1 trừ khoảng cách biến phân toàn phần giữa hai phân phối. Cặp mặc định cho 90,0%. Đây là chỗ duy nhất trong trang mà alpha xuất hiện như một đại lượng tính ra được chứ không phải đặt vào, và nó chỉ tính được vì hai phân phối kia là đồ chơi do bạn gõ.
Nếu bạn muốn xem cách chọn token khi không đầu cơ thì đó là bài temperature, top-k và top-p ở môn NLP. Giải mã đầu cơ nằm một tầng trên: nó không thay cách chọn, nó chỉ thay cách chạy.
Bảng đi từng vòng, và vì sao nó không bốc thăm
Bảng mô phỏng không gọi Math.random ở bất cứ đâu. Thay vào đó bạn viết ra chuỗi chấp nhận: 1 nghĩa là token ở vị trí đó được nhận, 0 nghĩa là bị bỏ. Mỗi vòng đọc lần lượt từng cờ cho tới khi gặp 0 hoặc tới khi đủ gamma cờ, nên một vòng tiêu tối đa gamma cờ.
Chuỗi mặc định 111111001110101111 đọc ở gamma = 4 cho ra sáu vòng: nhận trọn 4 rồi thêm token thưởng, nhận 2 rồi bỏ, bỏ ngay từ vị trí 1, nhận 3 rồi bỏ, nhận 1 rồi bỏ, và cuối cùng nhận trọn 4. Tổng 20 token qua 6 lượt đích, tức 3,333 token một vòng, chi phí 8,40 nên tăng tốc đo được là 2,38×. Con số này gần với 2,40× của phần kỳ vọng, nhưng nó là một mẫu cụ thể, không phải kỳ vọng.
Chuỗi đó tự cho tỉ lệ chấp nhận 14 trên 18, tức 77,8%, gần với alpha = 0,8 mà bạn đang đặt. Sự gần nhau đó là do tôi cố ý viết chuỗi như vậy, không phải bằng chứng gì cả. Sửa chuỗi thành toàn 1 và tỉ lệ nhảy lên 100% trong khi alpha vẫn nằm yên ở 80%: hai con số này độc lập, và nhìn thấy chúng lệch nhau là cách nhanh nhất để hiểu rằng chuỗi là mô hình hoá, không phải đo đạc.
Cái sim này không nói gì
Đây là chỗ phải nói thẳng, vì một mô hình chi phí tính đúng vẫn có thể bị đọc quá xa.
alpha là tham số bạn đặt, không phải số đo được. Tỉ lệ chấp nhận thật phụ thuộc vào cặp mô hình nháp và đích cụ thể, vào dữ liệu đang sinh, vào cả nhiệt độ lấy mẫu, và không có gì trong trang này nói được nó bằng bao nhiêu. Sim cho thấy đúng quan hệ giữa alpha, gamma và hệ số tăng tốc: nếu tỉ lệ chấp nhận là như vậy thì tăng tốc phải là như vậy. Vì lý do đó, cả bảy bộ tham số mẫu đều ghi rõ là bịa ra để minh hoạ, không bộ nào mang tên một mô hình thật.
Mô hình chi phí ở đây là mô hình đơn giản. Nó quy mọi thứ về một con số cho một lượt nháp và một con số cho một lượt kiểm. Nó bỏ qua chuyện gộp lô: khi máy chủ đang phục vụ nhiều yêu cầu cùng lúc, lượt đích đã bị lấp đầy sẵn nên chỗ trống mà đầu cơ khai thác bị thu hẹp, và lợi ích thực tế nhỏ hơn hẳn con số ở đây. Nó cũng bỏ qua bộ nhớ: chạy hai mô hình là hai bộ trọng số và hai KV cache trong cùng một thẻ. Và nó bỏ qua độ trễ mạng lẫn chi phí điều phối. Coi nó là hình dạng của đánh đổi, không phải dự báo thông lượng.
Giả định độc lập giữa các vị trí là một giả định. Công thức alpha^i coi mỗi vị trí như một phép thử riêng với cùng một xác suất. Trong thực tế, khi nháp đã trượt một lần thì nó thường đang lạc ngữ cảnh nên các vị trí sau càng dễ trượt, tức các lần thử tương quan với nhau và tỉ lệ chấp nhận thật giảm dần theo vị trí. Nghĩa là con số E ở đây hơi lạc quan. Đây là quy ước phổ biến trong các phân tích về cơ chế này, không phải một định luật.
Chi phí kiểm bằng 1 là lý tưởng hoá. Đặt nó bằng 1 tức là nói kiểm gamma + 1 vị trí trong một lượt rẻ ngang sinh một token. Điều này gần đúng khi gamma nhỏ và lượt chạy bị chặn bởi băng thông, nhưng sai dần khi gamma lớn. Sim cho bạn kéo con số đó lên tới 3 chính là để thấy giả định ấy ảnh hưởng tới đỉnh ra sao.
Cổng kiểm số canh phép tính, không canh lời khẳng định. Nó bảo đảm rằng với alpha và gamma như vậy thì token kỳ vọng và đỉnh của đường cong phải là như vậy, và rằng đẳng thức phân phối đóng lại. Nó không bảo đảm và không thể bảo đảm rằng một cặp mô hình ngoài kia có tỉ lệ chấp nhận nào.
Một vòng đầu cơ luôn thu về k + 1 token, nên nó không bao giờ tệ hơn giải mã thường về số token mỗi lượt đích. Nhưng token kỳ vọng (1 - alpha^(gamma+1)) / (1 - alpha) bị chặn trên bởi 1 / (1 - alpha), trong khi chi phí nháp tăng tuyến tính theo gamma và không có trần. Một đại lượng bão hoà chia cho một đại lượng tăng mãi thì phải có đỉnh rồi đi xuống, nên gamma tốt nhất là một số hữu hạn cụ thể chứ không phải càng lớn càng tốt. Và nếu vòng kiểm dùng đúng luật lấy mẫu đầu cơ, tức từ chối thì rút lại từ phần dư max(0, p - q), thì phân phối đầu ra trùng khít phân phối của mô hình đích: nhanh hơn mà không mất gì, đổi lại phải nuôi thêm một mô hình nháp trong bộ nhớ.
- 1Với alpha = 0,8 và gamma = 4, một vòng đầu cơ thu về trung bình bao nhiêu token?
- 2Ở bộ tham số mặc định, gamma = 6 cho 2,47× còn gamma = 32 chỉ còn 1,19×. Vì sao đoán xa hơn lại làm hệ số tăng tốc tệ đi?
- 3Vì sao giải mã đầu cơ được coi là nhanh hơn mà không đổi kết quả?