Giải mã, ba núm chỉnh cách mô hình chọn chữ
Giải mã, ba núm chỉnh cách mô hình chọn chữ
Mô hình chỉ đưa ra một danh sách điểm số. Việc biến danh sách đó thành một chữ cụ thể là do bạn quyết định, qua ba núm tên là nhiệt, top-k và top-p.
Một mô hình ngôn ngữ không trả về chữ. Nó trả về một logit cho mỗi ứng viên trong từ vựng, tức một điểm số thô chưa phải xác suất. Muốn có xác suất thì đem cả danh sách qua softmax, muốn có chữ thì phải bốc một ứng viên ra khỏi phân phối đó. Chính bước bốc này, gọi là giải mã (decoding), quyết định văn bản của bạn nghe nhàm chán hay nghe lảm nhảm, dù trọng số mô hình không đổi một chút nào.
Sim dưới đây giữ một danh sách mười ứng viên cho ô trống trong Hôm nay trời ___. Bạn sửa được logit của từng ứng viên, và ba thanh trượt sẽ tính lại toàn bộ phân phối ngay lập tức. Ở trạng thái mặc định, nhiệt bằng 1, k bằng 5 và p bằng 0.90.
Hôm nay trời ___mười ứng viên cho ô trống, kèm điểm thô (logit) của chúng+ - hoặc cuộn chuột, bước 0.1chia nhiệt: logit / 1.00 rồi softmax›giữ 5 từ điểm cao nhất›giữ tới khi tích luỹ đạt 0.90›chuẩn hoá lại| Từ | logit | p gốc (T=1) | sau nhiệt | sau top-k | tích luỹ | sau lọc | đếm trong chuỗi | độ lớn cuối |
|---|---|---|---|---|---|---|---|---|
| đẹp | 3.2 | 35.58% | 35.58% | 38.84% | 38.84% | 40.99% | 5 (42%) | |
| mưa | 2.8 | 23.85% | 23.85% | 26.03% | 64.87% | 27.48% | 2 (17%) | |
| nắng | 2.5 | 17.67% | 17.67% | 19.29% | 84.16% | 20.36% | 1 (8%) | |
| lạnh | 1.9 | 9.70% | 9.70% | 10.58% | 94.74% | 11.17% | 4 (33%) | |
| secắt bởi p | 1.2 | 4.82% | 4.82% | 5.26% | 100.00% | 0.00% | 0 (0%) | |
| âmcắt bởi k | 0.8 | 3.23% | 3.23% | 0% | · | 0.00% | 0 (0%) | |
| rấtcắt bởi k | 0.4 | 2.16% | 2.16% | 0% | · | 0.00% | 0 (0%) | |
| xanhcắt bởi k | 0.1 | 1.60% | 1.60% | 0% | · | 0.00% | 0 (0%) | |
| buồncắt bởi k | -0.3 | 1.07% | 1.07% | 0% | · | 0.00% | 0 (0%) | |
| sậpcắt bởi k | -1.5 | 0.32% | 0.32% | 0% | · | 0.00% | 0 (0%) |
top-k loại5 từtop-p loại (sau khi top-k đã cắt)1 từtop-k giữ đúng 5 dòng đầu bất kể phân phối nhọn hay phẳng. top-p thì nhìn cột tích luỹ: nó dừng ở dòng đầu tiên đưa tổng lên tới 0.90, nên số dòng nó giữ đổi theo độ nhọn. Kéo T qua lại với k để nguyên và nhìn ô còn lại ở trên: k không nhúc nhích, p thì có. Còn đây là lý do kéo p vài nấc mà chẳng thấy gì đổi: cột tích luỹ nhảy bậc, nên mọi giá trị p lớn hơn 84.16% và không quá 94.74% đều cho đúng 4 dòng này. Ngưỡng vốn là bậc thang chứ không phải núm hỏng. Muốn thêm một dòng nữa thì phải vượt hẳn 94.74%.seed = 7 và cùng ba thanh trượt thì chuỗi trên luôn y hệt, đổi seed là đổi chuỗi: bộ sinh số ở đây là một hàm thuần viết tay trong engine, không dùng Math.random. Chỉ 12 lần lấy mẫu thì tần suất còn lệch xa xác suất lý thuyết ở cột sau lọc, đó là chuyện bình thường của mẫu nhỏ chứ không phải lỗi; cổng kiểm trong repo rút 40000 lần để so cho tử tế.Nhiệt đổi hình dáng phân phối
Nhiệt là một số dương T chen vào giữa logit và softmax: thay vì tính softmax(logit), ta tính softmax(logit / T). Phép chia này kéo giãn hoặc nén mọi khoảng cách giữa các logit cùng một lúc.
Tnhỏ hơn 1 chia mọi khoảng cách cho một số nhỏ, tức làm chúng lớn ra, nên phân phối nhọn lại: từ đang dẫn đầu càng dẫn đầu hơn. ĐẩyTtiến về 0 thì toàn bộ khối lượng dồn về từ điểm cao nhất, và giải mã trở thành chọn tham lam (greedy), tức luôn lấy từ đứng đầu.Tlớn hơn 1 nén mọi khoảng cách lại, nên phân phối phẳng ra, tiến dần về đều. Ứng viên tệ cũng có cơ hội thật sự.
Ô độ hỗn loạn trên thanh công cụ là entropy của phân phối sau khi chia nhiệt, đo bằng nat. Ở trạng thái mặc định nó là 1.715 trên trần 2.303, tức ln 10, là entropy của phân phối đều trên mười ứng viên. Kéo T xuống thì số này tụt về 0, kéo lên thì nó bò dần lên trần.
Điều quan trọng cần nhìn cho rõ: nhiệt không loại ai cả. Từ tệ nhất vẫn còn trong bảng, chỉ là xác suất của nó bị bóp nhỏ hoặc thổi to. Muốn loại hẳn thì phải dùng hai núm còn lại.
top-k và top-p cắt đuôi, theo hai kiểu khác nhau
top-k là luật đơn giản nhất: sắp xếp giảm dần, giữ đúng k dòng đầu, vứt phần còn lại, rồi chia lại cho tổng để phần giữ được cộng lại bằng 1. Ở mặc định k bằng 5 nên năm dòng cuối bảng bị gạch với nhãn cắt bởi k.
top-p, còn gọi là nhân mẫu (nucleus sampling), không đếm số dòng mà đếm khối lượng xác suất. Nó lấy tập nhỏ nhất có tổng xác suất từ p trở lên. Cột tích luỹ trong bảng chính là để bạn thấy đường cắt nằm ở đâu: cộng dồn từ trên xuống, dòng đầu tiên đưa tổng chạm ngưỡng là dòng cuối cùng được giữ. Ở mặc định, tích luỹ sau bốn dòng là 94.74%, đã vượt 0.90, nên bốn dòng đó sống và từ se ở dòng thứ năm bị gạch với nhãn cắt bởi p.
Vì cột tích luỹ nhảy bậc chứ không chạy liên tục, p cũng chỉ đổi kết quả theo bậc. Ở trạng thái mặc định, mọi p lớn hơn 84.16% và không quá 94.74% đều cho đúng bốn dòng ấy, nên kéo p từ 0.90 lên 0.91 thì không có gì nhúc nhích. Đó là bản chất của một ngưỡng chứ không phải thanh trượt hỏng, và sim in sẵn hai đầu của khoảng ngay dưới bảng để bạn biết phải vượt mốc nào thì dòng thứ năm mới sống lại.
Có một ca rất dễ cài sai, và bạn nên thử ngay trong sim: khi từ đầu bảng đã chiếm ít nhất p khối lượng thì tập giữ lại phải có đúng một từ, dù các từ sau đó bám sát đến đâu. Kéo p xuống dưới xác suất của dòng đầu, tức xuống 0.38 hoặc thấp hơn, rồi nhìn ô còn lại trên thanh công cụ: nó phải về 1, không phải 2.
Khác biệt cốt lõi giữa hai núm nằm ở chỗ top-p thích nghi còn top-k thì không. Thử làm chính xác thế này trong sim:
- Kéo
klên hết mức, tức bằng 10, đểtop-kkhông can thiệp gì. Giữpở0.90. - Kéo
Txuống0.20: ô còn lại hiện 2 từ. Về1.00: hiện 5 từ. Lên2.00: hiện 8 từ. - Bây giờ kéo
plên1.00và đặtkbằng 5. VặnTtừ đầu này sang đầu kia của thanh trượt, tức cả dải0.05tới3.00: ô còn lại đứng im ở 5 từ, không nhúc nhích.
Đó là toàn bộ luận điểm. Khi mô hình rất chắc chắn, phân phối nhọn, top-p tự thu hẹp lại còn vài từ. Khi mô hình phân vân, phân phối phẳng, top-p tự nới ra. top-k thì cắt đúng một số dòng cố định bất kể mô hình đang chắc hay đang mù mờ, nên ở chỗ nhọn nó giữ thừa rác, còn ở chỗ phẳng nó chặn mất lựa chọn hợp lý.
Thứ tự áp dụng là một quy ước
Sim này chạy đúng thứ tự sau, và dải nhãn ngay trên bảng nhắc lại thứ tự đó:
- chia nhiệt rồi
softmax - lọc
top-k - lọc
top-p - chuẩn hoá lại
Cần nói thẳng: đây là quy ước, không phải chân lý. Nó khớp với cách các bộ lọc của thư viện transformers xếp hàng, nhưng thư viện khác có thể xếp khác, và thứ tự thì đổi được kết quả thật chứ không chỉ đổi cách trình bày. Lý do là bước 2 đã chuẩn hoá lại trước khi bước 3 nhìn vào cột tích luỹ, nên các con số mà top-p đọc là số sau khi top-k cắt.
Ví dụ nhỏ để thấy rõ, với ba logit 2, 1, 0 và nhiệt bằng 1. Xác suất là 66.52%, 24.47%, 9.00%. Đặt p bằng 0.72:
- Với
kbằng 3, tức không cắt gì, tích luỹ dòng đầu là66.52%, chưa tới0.72, nên giữ hai từ. - Với
kbằng 2, hai từ còn lại được chuẩn hoá thành73.11%và26.89%, nên tích luỹ dòng đầu đã là73.11%, vượt0.72, và chỉ giữ một từ.
Cùng một p, cùng một danh sách logit, hai kết quả khác nhau chỉ vì k khác nhau. Đây là loại chi tiết mà hai bài báo báo cáo cùng cấu hình vẫn ra số khác nhau, nên khi so sánh hệ thống thì phải nói rõ mình chạy thứ tự nào.
Lấy mẫu có seed, để kết quả lặp lại được
Phần cuối sim bốc chữ ra từ phân phối cuối cùng bằng số ngẫu nhiên thật, chứ không in sẵn một dãy có trước. Trước khi nhìn kết quả, phải nói rõ một điều quyết định cách đọc nó: sim không sinh văn bản tự hồi quy. Nó chỉ giữ đúng một danh sách mười ứng viên và không bao giờ chạy lại mô hình, nên dãy chữ dưới đây là nhiều lần rút thăm độc lập từ cùng một phân phối cố định, không phải một câu mà mô hình viết dần ra. Mô hình thật dựng lại toàn bộ bảng sau từng chữ, dựa trên cả những chữ vừa sinh. Hãy đọc dãy đó như kết quả tung xúc xắc nhiều lần, đừng đọc như tiếng Việt.
Bộ sinh số ngẫu nhiên ở đây là một hàm thuần tự viết trong engine theo kiểu đồng dư tuyến tính (LCG), chứ không phải Math.random. Có hai lý do. Thứ nhất, trang này được dựng sẵn trên máy chủ rồi mới chạy tiếp trong trình duyệt, nếu số ngẫu nhiên không lặp lại được thì hai bên sẽ vẽ ra hai chuỗi khác nhau. Thứ hai, một kết quả không lặp lại được thì không kiểm được, mà cổng kiểm số của bài này cần so tần suất thực nghiệm với xác suất lý thuyết.
Ở seed 7 và 12 lần lấy mẫu, chuỗi mặc định là đẹp lạnh mưa lạnh đẹp nắng đẹp đẹp đẹp lạnh lạnh mưa. Gõ seed khác thì chuỗi đổi, gõ 7 trở lại thì chuỗi cũ quay về nguyên vẹn.
Hãy thử đối chiếu hai trạng thái, cả hai đều để k bằng 10 và p bằng 1.00 cho top-k với top-p đứng ngoài, cùng seed 7:
Tbằng0.20chođẹp mưa đẹp mưa đẹp đẹp đẹp đẹp đẹp nắng nắng đẹp, vỏn vẹn 3 từ khác nhau.Tbằng1.60chođẹp rất nắng xanh đẹp âm mưa đẹp đẹp buồn buồn nắng, 7 từ khác nhau.
Đây chính là cái giá của sự an toàn. Hạ nhiệt và cắt đuôi đều đẩy văn bản về phía những từ mà mô hình tự tin, nên ít khi bậy, nhưng cũng nhạt và lặp. Nới ra thì đa dạng hơn và cũng dễ trượt hơn. Không có cấu hình đúng phổ quát, chỉ có cấu hình hợp với việc bạn đang làm: trích xuất dữ liệu thì nên lạnh, viết nháp sáng tạo thì nên ấm.
Nhắc lại giới hạn đã nêu ở đầu mục, vì đây đúng là chỗ dễ quên nhất: hai dòng trên không phải hai câu mà mô hình viết ra, chúng là mười hai lần rút thăm độc lập từ hai phân phối cố định khác nhau. Thứ đổi giữa hai dòng là phân phối, không phải ngữ cảnh. Và với 12 lần rút thì tần suất còn lệch xa xác suất ở cột sau lọc, đó là chuyện bình thường của mẫu nhỏ; cổng kiểm trong repo rút 40000 lần mới đủ để so cho tử tế.
Nhiệt đổi hình dáng phân phối mà không loại ai, còn top-k với top-p cắt đuôi. Hạ nhiệt và cắt đuôi đều làm văn bản an toàn hơn nhưng nhạt hơn. Giữa hai kiểu cắt, top-p tự co giãn theo độ nhọn của phân phối còn top-k thì luôn giữ đúng một số dòng. Và thứ tự áp dụng ba núm là quy ước của từng thư viện, phải ghi rõ khi báo cáo kết quả.
- 1Đẩy nhiệt T tiến dần về 0 thì cách chọn chữ trở thành gì?
- 2Khác biệt cốt lõi giữa top-k và top-p là gì?
- 3Phân phối có xác suất giảm dần 66.52 phần trăm, 24.47 phần trăm, 9.00 phần trăm. Đặt p bằng 0.6 và không cắt bằng k thì top-p giữ lại mấy từ?