Zoom-in: Tokenizer

Nếu bạn hỏi một mô hình ngôn ngữ lớn thế hệ mới rằng từ "strawberry" có bao nhiêu chữ "r", có khả năng nó sẽ tự tin trả lời là 2 chữ thay vì 3. Đây là một lỗi kinh điển khiến nhiều người bật cười: tại sao một AI có thể phân tích các lỗi lập trình phức tạp hay làm toán cao cấp lại thất bại trước một câu hỏi cấp tiểu học?
Hãy phóng to vào bộ phận dịch thuật của mô hình.
Layer 1 — Vấn đề gốc: Máy tính không hiểu chữ viết
Các LLM thực chất là các mạng thần kinh (neural network) chỉ làm việc với số và ma trận toán học. Chúng không thể trực tiếp đọc các ký tự a, b, c hay các từ tiếng Việt như chúng ta.
Do đó, chúng ta cần một bộ phận trung gian gọi là Tokenizer (bộ tách từ) để chuyển đổi văn bản thành danh sách các con số trước khi đưa vào mô hình.
graph TD
Text["📝 Văn bản gốc: 'đường'"] --> Tokenizer["⚙️ Tokenizer"]
Tokenizer --> Tokens["🔢 Danh sách Token ID: [14209, 874]"]
style Text fill:#1e293b,stroke:#475569,color:#cbd5e1
style Tokenizer fill:#1e293b,stroke:#475569,color:#cbd5e1
style Tokens fill:#1e293b,stroke:#475569,color:#cbd5e1
Cách đơn giản nhất là gán mỗi từ hoặc mỗi ký tự cho một mã số. Tuy nhiên:
- Nếu chia theo từng ký tự: Mô hình sẽ mất rất nhiều bước tính toán để xử lý một câu dài, đồng thời khó nắm bắt ngữ nghĩa của từ.
- Nếu chia theo từng từ: Vocabulary (từ điển từ vựng) của mô hình sẽ phình to vô hạn vì ngôn ngữ liên tục xuất hiện từ mới hoặc các biến thể chia thì, tiền tố, hậu tố.
Layer 2 — Cơ chế Byte Pair Encoding (BPE)
Thuật toán phổ biến nhất hiện nay để phân tách từ là Byte Pair Encoding (BPE). Thuật toán này hoạt động bằng cách:
- Bắt đầu từ việc coi mỗi ký tự đơn lẻ là một token.
- Quét qua tập dữ liệu văn bản huấn luyện khổng lồ và tìm cặp token nào thường xuất hiện cạnh nhau nhất.
- Gộp cặp đó lại thành một token mới và thêm vào từ điển.
- Lặp lại quá trình này cho đến khi vocabulary đạt quy mô mong muốn (ví dụ: 100,000 token).
Khi từ "strawberry" được đưa qua Tokenizer, nó thường được tách thành hai phần:
- Token 1:
straw(ID: 4123) - Token 2:
berry(ID: 8912)
Đối với mô hình, từ này chỉ đơn thuần là hai con số đầu vào: [4123, 8912]. Vì mô hình chỉ nhận diện hai mã số này chứ không hề nhìn thấy các chữ cái cấu thành bên trong, việc đếm chữ "r" đối với nó giống như việc bạn phải đoán xem trong hai chiếc hộp đóng kín chứa bao nhiêu viên bi màu đỏ mà không được phép mở nắp.
Layer 3 — Sự thiệt thòi của ngôn ngữ phi tiếng Anh (như tiếng Việt)
Hầu hết các Tokenizer của các tập đoàn công nghệ lớn đều được huấn luyện chủ yếu trên dữ liệu tiếng Anh. Do đó, cách chúng chia token được tối ưu tốt nhất cho tiếng Anh và gây bất lợi lớn cho các ngôn ngữ khác, đặc biệt là tiếng Việt với hệ thống dấu thanh phức tạp.
Chuẩn Unicode của tiếng Việt chứa các ký tự đặc biệt có dấu (như ư, ờ, đ). Khi Tokenizer gặp những ký tự này, do không có sẵn trong vocabulary tối ưu, nó buộc phải rã từ tiếng Việt ra thành nhiều mảnh token rất nhỏ.
Tiếng Anh: "information" ───> [1 token]
Tiếng Việt: "thông tin" ───> [3 đến 4 tokens]
graph TD
subgraph Tiếng Anh
A[information] --> B([1 token])
end
subgraph Tiếng Việt
C[đường] --> D([đư])
C --> E([ờng])
end
Sự chênh lệch này dẫn đến hai hậu quả thực tế:
- Chi phí cao hơn: Các nhà cung cấp tính phí API dựa trên số lượng token. Người dùng tiếng Việt phải trả tiền nhiều hơn gấp 2 đến 3 lần so với người dùng tiếng Anh để truyền tải cùng một lượng thông tin.
- Giới hạn bộ nhớ nhanh hơn: Mọi mô hình đều có giới hạn Context Window (cửa sổ ngữ cảnh) – số lượng token tối đa mà nó có thể đọc và nhớ trong một session. Tiếng Việt tốn nhiều token hơn đồng nghĩa với việc mô hình sẽ nhanh quên ngữ cảnh hơn khi trò chuyện.
Hiểu về Tokenizer giúp bạn viết các prompt hiệu quả hơn, tiết kiệm chi phí và biết cách cấu trúc dữ liệu đầu vào sao cho mô hình dễ xử lý nhất.
Full picture
graph TD
Input["Văn bản: 'strawberry'"] -->|Quá trình Tokenization| Tokenizer[Tokenizer: Thuật toán BPE]
Tokenizer -->|1. Tách từ thành các sub-word| Subwords["Mảnh từ: ['straw', 'berry']"]
Subwords -->|2. Ánh xạ thành mã số| Tokens["Token IDs: [4123, 8912]"]
Tokens -->|3. Đưa vào mô hình| Model[LLM Neural Network]
style Input fill:#1e293b,stroke:#475569,color:#cbd5e1
style Tokenizer fill:#1e293b,stroke:#475569,color:#cbd5e1
style Subwords fill:#1e293b,stroke:#475569,color:#cbd5e1
style Tokens fill:#1e293b,stroke:#475569,color:#cbd5e1
style Model fill:#1e293b,stroke:#475569,color:#cbd5e1
Takeaway
Tokenizer đóng vai trò như một bộ dịch thuật từ ngôn ngữ tự nhiên sang ngôn ngữ số học của LLM. Do sử dụng thuật toán BPE (Byte Pair Encoding) chia văn bản thành các sub-word thay vì ký tự đơn lẻ, mô hình không có khái niệm trực tiếp về mặt chữ cái (dẫn đến lỗi đếm chữ trong từ strawberry). Ngoài ra, do Tokenizer của các mô hình lớn thường tối ưu cho tiếng Anh, văn bản tiếng Việt sẽ bị chia nhỏ thành nhiều token hơn, dẫn đến chi phí sử dụng API cao hơn và làm cạn kiệt cửa sổ ngữ cảnh (Context Window) nhanh hơn.
Related Posts
Zoom-in: Rate Limiter
Gửi quá nhiều request liên tiếp lên API và nhận về mã lỗi 429 Too Many Requests. Người gác cổng Rate Limiter bảo vệ hệ thống như thế nào?
Zoom-in: WebSocket
Chat app cập nhật tin nhắn tức thời mà không cần reload trang. Cách WebSocket giải thoát ứng dụng khỏi giới hạn một chiều của HTTP.
Zoom-in: Virtual Memory
Chạy nhiều ứng dụng cùng lúc, mỗi ứng dụng đều nghĩ mình đang sở hữu toàn bộ RAM hệ thống. Phép thuật nào giúp cô lập bộ nhớ an toàn như vậy?