Token là đơn vị chữ nhỏ nhất mà mô hình ngôn ngữ đọc vào và viết ra — có khi là cả một từ, có khi chỉ là một âm tiết, một phần của từ, một dấu câu hay một khoảng trắng. Trước khi chatbot "đọc" câu bạn gõ, câu đó đã bị cắt thành dãy token và đổi thành dãy số. Mọi thứ mô hình làm sau đó đều diễn ra trên dãy số này.
Chữ token xuất hiện khắp nơi khi người ta nói về AI: giới hạn bao nhiêu nghìn token, câu trả lời dài bao nhiêu token, tiếng nào tốn nhiều token hơn. Bài này giải thích token theo cách người không học kỹ thuật cũng nắm được, kèm những hệ quả rất đời thường: vì sao chatbot đếm sai số chữ cái, vì sao đôi khi nó viết sai chính tả một tên riêng, và vì sao văn bản tiếng Việt thường đầy cửa sổ ngữ cảnh nhanh hơn tiếng Anh.
Vì sao máy không đọc thẳng từng chữ cái hay từng từ
Có hai cách cắt văn bản đơn giản nhất mà người mới thường nghĩ tới. Cách thứ nhất là cắt theo từng chữ cái. Làm vậy thì bảng chữ cần nhớ rất nhỏ, nhưng một câu ngắn biến thành dãy dài hàng trăm phần tử, mô hình phải làm việc vất vả hơn nhiều để ghép lại thành nghĩa, và sức chứa mỗi lần xử lý bị tiêu hao rất nhanh.
Cách thứ hai là cắt theo từng từ trọn vẹn. Dãy ngắn hơn hẳn, nhưng bảng từ vựng phải chứa mọi từ có thể gặp trong mọi ngôn ngữ, mọi cách viết sai, mọi tên riêng, mọi biến thể như số nhiều, chia thì, viết hoa. Bảng đó sẽ phình ra vô tận, và gặp một từ chưa từng thấy là mô hình bó tay.
Token là giải pháp ở giữa. Bảng từ vựng của mô hình có kích thước cố định, thường từ vài chục nghìn tới vài trăm nghìn mảnh, gồm những chuỗi ký tự xuất hiện nhiều nhất trong dữ liệu. Từ phổ biến được giữ nguyên thành một mảnh. Từ hiếm được ghép từ vài mảnh nhỏ hơn. Và vì bảng luôn có cả những mảnh nhỏ tới mức từng ký tự hay từng byte, mô hình không bao giờ gặp chữ mà nó hoàn toàn không ghi lại được.
Một hình ảnh dễ nhớ là bộ đồ chơi xếp hình. Những khối lớn có sẵn hình mái nhà, cánh cửa giúp xếp nhanh các công trình quen thuộc. Khi cần một hình lạ, bạn vẫn dùng được những khối nhỏ vuông vức để ghép. Bảng token chính là bộ khối đó, được thiết kế sao cho văn bản thường gặp xếp bằng ít khối nhất.
Bộ tách chữ được dựng ra như thế nào
Bộ tách chữ không phải do người ngồi soạn từng mảnh. Phần lớn được dựng tự động theo một quy trình gộp dần, thường được nhắc tới với tên mã hoá cặp byte. Ở mức nguyên lý, quy trình đi như sau:
- Bắt đầu với bảng chỉ gồm các đơn vị nhỏ nhất, như từng ký tự hoặc từng byte.
- Quét qua một lượng văn bản mẫu rất lớn, đếm xem cặp đơn vị nào đứng cạnh nhau nhiều nhất.
- Gộp cặp hay gặp nhất thành một mảnh mới và thêm vào bảng. Chẳng hạn trong tiếng Anh, chữ t và chữ h đứng cạnh nhau rất nhiều nên sớm được gộp.
- Lặp lại việc đếm và gộp. Các mảnh vừa tạo lại có thể ghép tiếp với mảnh khác thành mảnh dài hơn, dần dần thành cả từ hoặc cụm thường gặp.
- Dừng khi bảng đạt kích thước định trước. Từ đó bảng được giữ cố định và dùng cho cả quá trình huấn luyện lẫn lúc trò chuyện với người dùng.
Điều quan trọng rút ra từ quy trình này: cách cắt phản ánh đúng thành phần của văn bản mẫu. Ngôn ngữ nào chiếm nhiều trong văn bản mẫu thì chữ của ngôn ngữ đó được gộp thành mảnh dài, đọc tiết kiệm. Ngôn ngữ nào ít thì bị chẻ vụn hơn. Mỗi hãng, mỗi thế hệ mô hình có bộ tách chữ riêng, nên cùng một câu có thể ra số mảnh khác nhau tuỳ mô hình.
Bộ tách chữ cũng không biết gì về nghĩa. Nó cắt theo tần suất xuất hiện, nên ranh giới mảnh không nhất thiết trùng ranh giới từ hay âm tiết mà người đọc cảm nhận.
Tiếng Việt bị cắt ra sao
Tiếng Việt có một đặc điểm khiến chuyện cắt mảnh thú vị: chữ viết dùng dấu cách giữa các âm tiết chứ không giữa các từ. "Học sinh" là một từ nhưng viết thành hai âm tiết. Bộ tách chữ không biết điều này, nó chỉ thấy chuỗi ký tự. Với những âm tiết rất phổ biến như "của", "và", "không", nhiều bộ tách hiện đại giữ được trọn một mảnh. Với âm tiết ít gặp hơn, đặc biệt là những âm tiết mang dấu thanh kết hợp với dấu mũ như "ưởng" hay "ượt", chuỗi có thể bị chẻ thành hai ba mảnh.
Lý do kỹ thuật nằm ở chỗ chữ có dấu tiếng Việt khi lưu trong máy chiếm nhiều byte hơn chữ Latinh trơn, và trong văn bản mẫu của nhiều mô hình, tiếng Việt chiếm tỉ lệ nhỏ hơn hẳn tiếng Anh. Hai điều đó cộng lại khiến một đoạn tiếng Việt thường cần nhiều mảnh hơn đoạn tiếng Anh cùng ý. Mức chênh lệch khác nhau giữa các bộ tách chữ, và các thế hệ mô hình gần đây đã cải thiện đáng kể cho các ngôn ngữ ngoài tiếng Anh, nên bạn đừng tin một con số cố định nào.
Còn một chi tiết ít người biết: cùng một chữ "ế" có thể được máy lưu theo hai cách, một ký tự dựng sẵn hoặc chữ "e" cộng các dấu ghép riêng. Nhìn trên màn hình y hệt nhau, nhưng bộ tách chữ thấy hai chuỗi khác nhau và có thể cắt khác nhau. Văn bản chép từ một số phần mềm cũ hay gặp chuyện này. Hầu hết hệ thống hiện nay có bước chuẩn hoá trước khi tách, nhưng đây vẫn là một nguồn khác biệt nhỏ.
Việc tốn mảnh hơn không có nghĩa là mô hình hiểu tiếng Việt kém tương ứng. Chất lượng tiếng Việt phụ thuộc nhiều hơn vào lượng và chất của dữ liệu tiếng Việt mà mô hình được học. Bài riêng về tiếng Việt trong chuyên mục này bàn kỹ chuyện đó.
Những lỗi kỳ lạ bắt nguồn từ token
Đếm chữ cái sai. Hỏi "từ strawberry có mấy chữ r" từng là phép thử nổi tiếng làm nhiều chatbot trả lời sai. Mô hình thấy từ đó dưới dạng hai ba mảnh đã gộp, không thấy từng chữ r. Các mô hình mới hơn làm tốt hơn nhờ được huấn luyện thêm hoặc tự viết ra từng chữ trước khi đếm, nhưng gốc rễ của khó khăn vẫn là cách cắt mảnh.
Đảo ngược chữ, ghép vần, chơi chữ. Các trò như viết ngược một từ, tìm từ có vần "anh", làm câu đối chữ đều đòi hỏi nhìn vào bên trong mảnh. Mô hình có thể làm được nhưng dễ trượt hơn những việc làm trên cả từ hoặc cả câu.
Tên riêng hiếm bị viết sai. Một tên làng, tên người ít xuất hiện bị cắt thành nhiều mảnh vụn. Khi viết lại, mô hình phải chọn đúng từng mảnh theo đúng thứ tự, mỗi bước là một lần đoán, nên chỉ cần lệch một mảnh là sai một dấu hoặc một chữ.
Tính toán với số dài. Số cũng bị cắt mảnh, và tuỳ bộ tách chữ, một số dài như 1234567 có thể bị chia thành những cụm không khớp với hàng nghìn, hàng triệu. Đó là một phần lý do mô hình làm phép tính nhiều chữ số dễ sai nếu không dùng công cụ tính riêng.
Khoảng trắng và dấu câu cũng tính. Hai dấu cách thay vì một, dấu chấm lửng gõ bằng ba dấu chấm, xuống dòng nhiều lần đều tạo ra mảnh. Chúng hiếm khi gây lỗi lớn, nhưng làm văn bản tốn chỗ hơn bạn nghĩ.
Token, từ và độ dài: nên hình dung thế nào
Vì token không trùng với từ, người ta hay quy đổi gần đúng để hình dung. Bảng dưới là cách nghĩ ở mức trực giác, không phải số đo của một mô hình cụ thể.
| Câu hỏi | Cách nghĩ gần đúng | Lưu ý |
|---|---|---|
| Một token dài bao nhiêu? | Với tiếng Anh, hay được ước khoảng ba phần tư một từ, tức trung bình chừng bốn ký tự | Đây là ước lượng phổ biến do các nhà cung cấp đưa ra cho tiếng Anh, không áp nguyên cho tiếng Việt |
| Tiếng Việt thì sao? | Một âm tiết tiếng Việt thường là một mảnh hoặc hơn, tuỳ âm tiết và tuỳ bộ tách | Kiểm bằng công cụ đếm token của chính hãng nếu bạn cần số chính xác |
| Giới hạn "nghìn token" nghĩa là gì? | Là tổng số mảnh mô hình xử lý được một lần, gồm cả đầu vào lẫn câu trả lời | Giới hạn khác nhau giữa các mô hình và thay đổi theo thời gian |
| Câu trả lời bị cắt ngang giữa chừng? | Thường là vì chạm mức tối đa số mảnh cho phép viết ra trong một lượt | Ứng dụng có thể đặt giới hạn này thấp hơn khả năng thật của mô hình |
Với người dùng thường, token quan trọng chủ yếu ở hai chỗ: nó quyết định văn bản dài tới đâu thì mô hình còn ôm được trong một lần, và nó là đơn vị mà các dịch vụ dùng để đo lượng sử dụng. Chuyện tính phí theo token là chuyện của người làm sản phẩm, có ở các trang về lập trình với AI; ở đây chỉ cần biết đơn vị đo là mảnh chứ không phải từ hay ký tự.
Từ mảnh chữ đến nghĩa: con số không mang nghĩa, vị trí trong không gian mới mang
Một câu hỏi tự nhiên: nếu mỗi mảnh chỉ là một con số trong bảng tra, thì mô hình lấy đâu ra nghĩa? Con số thứ tự trong bảng quả thật không mang nghĩa gì. Mảnh số 500 không gần nghĩa với mảnh số 501 hơn mảnh số 30.000. Bước đầu tiên bên trong mô hình là đổi mỗi số thứ tự thành một dãy dài các con số khác, gọi là vectơ nhúng, có thể hình dung như toạ độ của mảnh đó trong một không gian có rất nhiều chiều.
Các toạ độ này không được ai gán tay; chúng được học trong lúc huấn luyện. Kết quả là những mảnh hay dùng trong ngữ cảnh giống nhau sẽ nằm gần nhau: "mèo" gần "chó" hơn gần "bàn", "Hà Nội" gần "Huế" hơn gần "hôm qua". Nghĩa không nằm trong một mảnh đơn lẻ, mà nằm trong quan hệ giữa các mảnh, và được tinh chỉnh tiếp khi mô hình xét cả câu.
Vì vậy, dù tiếng Việt bị cắt vụn hơn, mô hình vẫn có thể hiểu và viết tiếng Việt tốt nếu được học đủ nhiều: các mảnh vụn của "trường" ghép lại vẫn được đặt vào đúng vị trí nghĩa sau vài lớp xử lý. Cắt vụn làm tốn sức và dễ trượt ở những chi tiết chữ, nhưng không tự động làm mất nghĩa. Thuật ngữ nhúng và việc tìm theo nghĩa được giải thích riêng ở chuyên mục thuật ngữ của trang.
Câu hỏi thường gặp
Một token bằng bao nhiêu chữ tiếng Việt?
Không có tỉ lệ cố định. Âm tiết phổ biến thường gọn trong một mảnh, âm tiết ít gặp có dấu phức tạp có thể thành hai ba mảnh. Tỉ lệ còn khác nhau giữa các mô hình, nên muốn biết chính xác hãy dùng công cụ đếm token của đúng mô hình đó.
Vì sao chatbot hay đếm sai số chữ cái trong một từ?
Vì mô hình nhìn từ đó dưới dạng vài mảnh đã gộp sẵn chứ không thấy từng chữ cái. Muốn đếm, nó phải suy ra bên trong mảnh có những chữ nào, việc này dễ sai hơn nhiều so với hiểu nghĩa cả câu.
Mọi chatbot có dùng chung một cách cắt token không?
Không. Mỗi hãng và mỗi thế hệ mô hình thường có bộ tách chữ riêng, dựng từ văn bản mẫu riêng. Cùng một đoạn văn có thể ra số mảnh khác nhau khi đưa vào các mô hình khác nhau.
Viết tiếng Việt không dấu có giúp tiết kiệm token không?
Có thể tốn ít mảnh hơn, nhưng đổi lại mô hình phải đoán nghĩa từ chữ mất dấu, dễ hiểu nhầm hơn và câu trả lời có thể kém tự nhiên. Với người dùng thường, viết có dấu đầy đủ vẫn là lựa chọn hợp lý.
Token có liên quan gì đến tiền mã hoá không?
Không. Trong AI, token chỉ mảnh chữ mà mô hình đọc và viết. Trong tiền mã hoá, token là một loại tài sản số. Hai nghĩa dùng chung một từ tiếng Anh nhưng hoàn toàn không liên quan.
Ảnh và giọng nói có được cắt thành token không?
Với các mô hình đa phương thức, ảnh và âm thanh cũng được chia thành những mảnh nhỏ rồi đổi thành dãy số để mô hình xử lý cùng chữ. Cách chia khác với chữ, nhưng ý tưởng cắt nhỏ thành đơn vị đọc được là tương tự.