Token, chi phí và chọn mô hình
Tới đây bạn đã biết viết prompt cho rõ. Còn một mặt thực dụng nữa người dùng AI nên nắm
sớm: prompt không chỉ "tốn chữ" mà còn tốn tài nguyên và đôi khi tốn tiền. Hiểu một chút
về token, chi phí và cách chọn mô hình giúp bạn dùng AI vừa hiệu quả vừa tiết kiệm.
Ba tình huống rất quen mà bài này giải thích được hết. Bạn dán cả một file mã nguồn dài vào
chat, công cụ báo vượt giới hạn. Bạn trò chuyện tới lượt thứ ba mươi, mô hình bỗng "quên"
cái ràng buộc bạn nêu ngay từ đầu. Bạn viết một chương trình nhỏ gọi mô hình qua API,
chạy vài trăm lần thử, rồi giật mình khi nhìn bảng sử dụng. Cả ba đều quy về một đơn vị
đếm duy nhất.
Thử ngay: đo token và chi phí
Token là mẩu chữ nhỏ mà mô hình dùng để đếm văn bản, cả phần bạn gửi lẫn phần nó viết ra;
mục ngay sau sẽ nói kỹ. Trước hết hãy lấy cảm giác về con số. Bấm qua lại hai câu mẫu đầu
để thấy bản tiếng Việt có dấu tốn nhiều token hơn bản tiếng Anh cùng nghĩa, chỉnh thanh
trượt số token đầu ra và đơn giá
tương đối để xem thanh chi phí dài ra, rồi kéo số lượt hội thoại để thấy vì sao gửi lại cả
lịch sử làm chi phí từng lượt tăng dần. Các con số chỉ là ước lượng thô và đơn giá là đơn
vị tương đối bạn tự đặt, không phải giá tiền thật của mô hình nào.
Token và độ dài
Mô hình không đọc theo từ hay theo ký tự, mà theo token: những mẩu chữ nhỏ, mỗi mẩu cỡ
vài ký tự. Một từ tiếng Việt thường tách thành vài token; một câu ngắn có thể là vài
chục token. Điều quan trọng: cả prompt bạn gửi đi lẫn câu trả lời mô hình viết ra đều
được tính bằng token. Prompt càng dài, câu trả lời càng dài thì tổng số token càng
lớn.
Vì sao lại cắt chữ thành mẩu như vậy? Vì hai thái cực đều dở. Nếu mỗi từ là một đơn vị, từ
điển phình to vô tận và mô hình chịu chết trước tên riêng hay lỗi gõ phím. Nếu mỗi ký tự là
một đơn vị, chuỗi trở nên quá dài. Cách tách token là lối đi ở giữa: mẩu chữ hay gặp thì
gộp thành một token, chữ hiếm thì bị bẻ nhỏ. Hệ quả thực tế: văn bản càng thông thường
thì càng ít token. Một tên biến kỳ quặc, một chuỗi mã băm, một đoạn JSON đầy dấu ngoặc
đều bị bẻ vụn. Bộ tách token của các mô hình phổ biến được xây chủ yếu trên dữ liệu tiếng
Anh, nên chữ tiếng Việt hay bị bẻ thành nhiều mẩu hơn: cùng một ý, bản tiếng Việt thường
tốn nhiều token hơn bản tiếng Anh.
Số token này gắn với hai thứ. Thứ nhất là cửa sổ ngữ cảnh ở bài trước: nó có hạn, nên
một prompt quá dài lan man có thể chiếm chỗ một cách lãng phí, thậm chí đẩy thông tin cũ
trôi ra ngoài. Thứ hai là tốc độ và chi phí: nhiều token hơn nghĩa là mô hình phải xử
lý lâu hơn và, nếu bạn gọi mô hình qua dịch vụ trả phí, tốn tiền hơn.
Chỗ này đáng dừng lại, vì nó ảnh hưởng trực tiếp tới túi tiền và tới trần ngữ cảnh của bạn.
Một token không phải là một từ. Trong tiếng Anh, từ thông dụng thường vừa gọn trong một
token nên số token xấp xỉ số từ. Tiếng Việt thì khác: chữ có dấu được biểu diễn tốn kém
hơn, và âm tiết tiếng Việt ít nằm trong bộ từ vựng mà bộ tách token học được, nên một chữ
quen thuộc vẫn có thể bị bẻ thành mấy mẩu. Cùng một nội dung, bản tiếng Việt tiêu tốn nhiều
token hơn bản tiếng Anh. Hệ quả cần nhớ: ngân sách token khi làm việc bằng tiếng Việt
eo hẹp hơn bạn tưởng.
Vài điều rút ra. Một tài liệu tiếng Việt sẽ chạm trần ngữ cảnh sớm hơn một tài liệu tiếng Anh
trông dài tương đương. Nếu chi phí API cao hơn dự tính, nguyên nhân có thể chỉ là bạn đang
tính nhẩm theo số từ tiếng Anh. Và trong việc thuần kỹ thuật, nơi ngôn ngữ của lời nhắc không
quan trọng, viết phần chỉ dẫn bằng tiếng Anh rồi yêu cầu trả lời bằng tiếng Việt là một cách
tiết kiệm hợp lệ. Đây là lựa chọn chứ không phải luật: việc nào cần diễn đạt tinh tế bằng
tiếng Việt thì cứ viết tiếng Việt.
Cửa sổ ngữ cảnh: cái trần cứng
Nói cho chính xác, cửa sổ ngữ cảnh là số token tối đa mô hình xử lý được trong một
lượt, tính cả phần vào lẫn phần ra. Trong một cuộc trò chuyện, mỗi lượt mới thường phải
mang theo toàn bộ lịch sử trước đó thì mô hình mới nhớ được câu chuyện, nên trò chuyện càng
dài thì mỗi lượt càng nặng.
Khi chạm trần có hai kiểu hành xử. Một là công cụ báo lỗi và từ chối, thường gặp khi bạn dán một file quá lớn. Hai là nó tự cắt bớt phần cũ nhất để nhét vừa, và đây mới là kiểu nguy hiểm vì nó im lặng: mô hình vẫn trả lời trôi chảy nhưng ràng buộc bạn nêu ở lượt đầu đã rơi ra ngoài. Bạn thấy nó "quên", thật ra nó không còn thấy. Cách xử lý: chỉ đưa phần liên quan thay vì cả file, mở cuộc trò chuyện mới kèm tóm tắt ngắn khi đổi chủ đề, và nhắc lại ràng buộc then chốt ở lượt hiện tại.
Vì sao lại phải có trần
Sao không cho mô hình đọc bao nhiêu tuỳ thích? Khi đoán chữ tiếp theo, mỗi token đều được
đối chiếu với những token khác trong ngữ cảnh để biết cái nào đáng chú ý; chính cơ chế ấy
cho phép nó biết "biến i" ở dòng ba là cùng biến với "biến i" ở dòng bốn mươi. Nhưng số
cặp cần đối chiếu tăng nhanh hơn nhiều so với độ dài văn bản, và toàn bộ ngữ cảnh còn phải
nằm trong bộ nhớ của phần cứng đang chạy mô hình. Vậy nên trần ngữ cảnh là một ranh giới kỹ
thuật và kinh tế, không phải hạn chế tuỳ tiện. Nó cũng giải thích chuyện bạn cảm nhận được:
ngữ cảnh càng dài thì mỗi lượt càng chậm và càng đắt, chứ không phải cứ đầy trần mới có vấn
đề.
Một hiểu lầm nữa: trần lớn hơn không có nghĩa là dùng thoải mái hơn. Nhồi thật nhiều tài liệu với hy vọng "cứ đưa hết cho chắc" thường phản tác dụng, vì thông tin then chốt bị pha loãng giữa hàng chục trang không liên quan. Ngữ cảnh là mặt bàn làm việc, không phải cái kho.
Hội thoại dài: bạn trả tiền lại cho quá khứ
Đây là cơ chế giải thích phần lớn những hoá đơn gây bất ngờ. Mô hình không có trí nhớ giữa các lượt và không lưu cuộc trò chuyện ở đâu cả. Cái tạo ra cảm giác nó "nhớ" chuyện lúc nãy là công cụ chat đã âm thầm gửi lại toàn bộ lịch sử kèm câu hỏi mới, mỗi lượt.
Hệ quả: lượt đầu bạn trả tiền cho một câu hỏi; lượt hai, phần vào gồm câu hỏi một, câu trả lời một và câu hỏi hai; lượt ba lại gồm tất cả những gì trước đó cộng câu mới. Mỗi lượt bạn trả tiền lại cho toàn bộ quá khứ, nên càng về cuối, một câu hỏi ngắn cỡ một dòng vẫn kéo theo phần vào rất nặng, và tổng chi phí tăng nhanh hơn nhiều so với tổng số chữ bạn đã gõ.
Cùng cơ chế ấy giải thích chuyện "mô hình quên": khi lịch sử phình tới sát trần, công cụ buộc phải cắt bớt phần cũ nhất, và nó cắt trong im lặng. Từ đó ra một thói quen tiết kiệm rất nhiều: đổi việc thì đổi phiên. Xong bài tập tuần này, đừng hỏi tiếp bài tuần sau trong cùng cuộc trò chuyện; mở phiên mới, và nếu cần mang theo bối cảnh thì viết một đoạn tóm tắt ngắn gồm những gì còn thật sự liên quan.
Đánh đổi: đầy đủ hay tiết kiệm
Tới đây có vẻ hai lời khuyên đang kéo về hai phía: bài trước bảo cấp đủ ngữ cảnh và dữ liệu,
bài này bảo token tốn tiền và làm chậm. Không mâu thuẫn, chỉ là một đánh đổi cần biết cân.
Ba tình huống thật.
Gỡ một lỗi trong dự án. Cám dỗ là dán cả kho mã nguồn cho chắc ăn. Cách đúng là dán hàm bị lỗi, nguyên văn thông báo lỗi, và định nghĩa những kiểu dữ liệu mà hàm đó dùng tới; phần còn lại chỉ làm loãng. Phép thử: nếu bỏ đoạn này ra mà mô hình vẫn đủ dữ kiện để chỉ đúng dòng sai, thì đoạn đó là chữ thừa.
Viết báo cáo từ một tài liệu dài. Đừng dán cả tài liệu ở mỗi lượt. Hãy dán một lần, yêu cầu rút ra bản tóm tắt có cấu trúc, kiểm lại bằng mắt, rồi làm việc tiếp trên bản tóm tắt ấy trong một phiên mới.
Chạy cùng một lời nhắc nhiều lần bằng chương trình. Đây là chỗ mọi lãng phí bị nhân lên: một đoạn hướng dẫn dài dòng dùng một lần thì không sao, nhưng lặp cho từng bài chấm thì bị nhân theo số lần gọi. Với việc lặp, hãy rút gọn phần chỉ dẫn chung và chốt chặt độ dài đầu ra.
Nguyên tắc cân đo: mỗi token phải mua về một thông tin mà mô hình không thể tự suy ra.
Ngữ cảnh người đọc, ràng buộc đề bài, dữ liệu cụ thể đều không suy ra được nên luôn đáng giữ.
Chi phí ở mức ý niệm
Khi dùng AI qua giao diện chat miễn phí, bạn không thấy hoá đơn, nhưng giới hạn vẫn tồn
tại dưới dạng số lượt hay tốc độ. Khi gọi mô hình bằng lập trình (qua API), nhà cung
cấp thường tính tiền theo token: một mức cho token đầu vào (prompt bạn gửi) và một
mức cho token đầu ra (câu trả lời sinh ra). Bạn chưa cần nhớ con số; chỉ cần nắm nguyên
tắc: prompt gọn và rõ thường vừa rẻ vừa nhanh hơn, vì nó dùng ít token mà vẫn đủ
thông tin để mô hình làm đúng.
# bản dài lan man (tốn token, loãng ý)
Chào bạn, mình đang học lập trình và hôm nay mình có một
chút thắc mắc nho nhỏ, không biết bạn có thể giúp mình
được không, là về cái vòng lặp ấy, mình nghe nói có nhiều
loại lắm, bạn giải thích giúp mình với nhé, cảm ơn nhiều...
# bản gọn (ít token, rõ việc)
Giải thích khác nhau giữa for và while trong C, cho sinh
viên năm nhất, kèm 1 ví dụ ngắn cho mỗi loại.
Hai prompt cùng nhắm một việc, nhưng bản gọn dùng ít token hơn nhiều mà lại nói rõ hơn:
ngôn ngữ (C), người đọc (năm nhất), thứ cần so sánh và định dạng (mỗi loại một ví dụ).
Lời chào hỏi, rào đón "nho nhỏ", "không biết có được không" không thêm thông tin cho mô
hình, chỉ thêm token.
Vì sao prompt dài lại chậm
Thời gian trả lời gồm hai phần. Phần đầu là đọc lời nhắc: mô hình phải xử lý toàn bộ
token đầu vào trước khi viết được chữ đầu tiên, nên bạn thấy một khoảng lặng dài hơn hẳn
sau khi dán một file lớn. Phần sau là viết câu trả lời: mô hình sinh từng token một theo
trình tự, token sau phụ thuộc token trước, nên câu trả lời dài gấp đôi thì thời gian
sinh cũng dài gần gấp đôi.
Từ đó rút ra một mẹo nhiều người bỏ qua: giới hạn độ dài đầu ra cũng quan trọng không kém việc rút gọn đầu vào. Nếu chỉ cần một câu trả lời, hãy nói "tối đa ba câu, không giải thích thêm". Bạn vừa đỡ chờ, vừa đỡ tốn, vừa khỏi đọc lướt một bài dài để tìm một dòng.
Mẹo tiết kiệm token
Tiết kiệm không có nghĩa là viết cụt lủn. Nó nghĩa là mỗi token bạn bỏ ra phải mua về
một thông tin. Năm thói quen sau gần như luôn có lợi.
- Bỏ nghi thức xã giao. Chào hỏi, rào đón dài dòng không thêm thông tin nào.
- Cắt dữ liệu về đúng phần liên quan. Dán hàm bị lỗi, không dán cả module.
- Chốt độ dài đầu ra. Đây thường là chỗ tiết kiệm nhiều nhất.
- Đừng lặp lại cái mô hình đã có. Trong cùng cuộc trò chuyện, chỉ dán phần đã thay đổi.
- Đừng ép mô hình viết lại toàn bộ. Yêu cầu "chỉ đưa phần cần sửa" thay vì "viết lại cả file".
Có thứ token nhìn thì thừa mà thật ra rất đáng tiền.
- Cắt mất ngữ cảnh. Bỏ câu "cho sinh viên năm nhất, đề cấm dùng đệ quy" tiết kiệm được
vài chục
token, nhưng đổi lại một câu trả lời không dùng được. Hỏi lại hai lần thì tổngtokenđã cao hơn ngay từ đầu. - Cắt mất dữ liệu. Tả lỗi bằng lời thay vì dán thông báo lỗi là cách nhanh nhất đẩy mô hình vào chỗ phải đoán, mà đoán thì dễ bịa.
- Viết tắt tới mức tối nghĩa. Câu cụt gây mơ hồ, mà mơ hồ thì tốn nhiều lượt hơn.
Nguyên tắc chốt: cắt chữ thừa, đừng cắt thông tin. Phép thử là hỏi từng câu "bỏ câu này thì mô hình có thể hiểu sai không?". Nếu có, hãy giữ.
- Dùng một cuộc trò chuyện duy nhất cho cả học kỳ. Lịch sử phình ra, mỗi lượt gửi lại toàn bộ quá khứ, mà quá khứ đó phần lớn chẳng liên quan gì tới câu hỏi hôm nay. Vừa đắt, vừa chậm, vừa dễ bị cắt mất ràng buộc quan trọng trong im lặng.
- Hỏi lại cho may rủi thay vì sửa lời nhắc. Bấm "trả lời lại" ba lần tốn nhiều
tokenhơn hẳn việc bỏ ra một phút thêm ngữ cảnh và định dạng vào lời nhắc gốc, mà xác suất trúng thì vẫn thấp vì lời nhắc vẫn thiếu đúng thông tin đã thiếu. - Bắt mô hình in lại cả file chỉ để sửa một dòng. Phần đầu ra dài đó bạn phải trả tiền, phải chờ, rồi phải đọc dò xem nó có lặng lẽ đổi gì khác không. Hãy yêu cầu chỉ đưa phần cần sửa kèm vị trí.
Chọn mô hình theo việc
Không phải lúc nào cũng cần mô hình mạnh nhất. Các nhà cung cấp thường có vài cỡ mô hình: loại nhỏ chạy nhanh, rẻ, hợp việc đơn giản; loại lớn suy luận sâu hơn nhưng chậm hơn và đắt hơn. Chọn đúng cỡ cho việc cũng là một kỹ năng dùng AI.
- Việc đơn giản, lặp lại, cần nhanh (tóm tắt ngắn, đổi định dạng, sửa lỗi chính tả): ưu tiên mô hình nhỏ, rẻ.
- Việc khó, cần suy luận nhiều bước (gỡ một lỗi rối, thiết kế giải thuật, phân tích dài): chọn mô hình mạnh hơn, chấp nhận chậm và tốn hơn.
- Khi chưa chắc: thử mô hình nhỏ trước; nếu kết quả chưa đạt mới nâng lên mô hình mạnh.
Hai giới hạn cần nhớ
Cuối cùng, dù prompt có gọn và mô hình có mạnh tới đâu, có hai giới hạn cố hữu bạn phải luôn nhớ khi tin vào câu trả lời.
- Mốc kiến thức (cutoff): mô hình được huấn luyện tới một thời điểm rồi "đóng băng". Nó thường không biết sự kiện xảy ra sau ngày đó (phiên bản thư viện mới, tin tức gần đây). Hỏi chuyện mới mà không cung cấp dữ liệu thì câu trả lời dễ lỗi thời.
- Thiên kiến (bias): mô hình có khuynh hướng nói theo cái phổ biến trong dữ liệu, và đôi khi "nịnh" theo ý người hỏi, đồng tình cho xuôi thay vì phản biện. Nếu bạn hỏi gài theo hướng sai, nó có thể hùa theo.
Vì hai lẽ đó, hãy luôn kiểm chứng thông tin quan trọng từ nguồn đáng tin, đừng tin chỉ vì câu trả lời nghe trôi chảy và tự tin. Với code, hãy biên dịch và chạy thử trước khi tin.
Bài tập nhỏ
Bài tập: chẩn đoán ba tình huống
Giải thích mỗi tình huống bằng kiến thức về token và cửa sổ ngữ cảnh, kèm cách xử lý. (a)
Bạn dán cả file 2000 dòng, công cụ báo vượt giới hạn. (b) Tới lượt thứ ba mươi, mô hình
quên ràng buộc "không dùng thư viện ngoài" bạn nêu từ đầu. (c) Chương trình của bạn gọi mô
hình 500 lần để chấm bài, chi phí cao hơn dự tính nhiều.
Lời giải. (a) File vượt quá cửa sổ ngữ cảnh. Xử lý: chỉ đưa phần liên quan, hoặc chia
nhỏ và xử lý lần lượt. (b) Hội thoại đã dài tới mức phần đầu bị đẩy ra ngoài cửa sổ, mô
hình không còn thấy ràng buộc đó. Xử lý: mở cuộc trò chuyện mới kèm tóm tắt ràng buộc, hoặc
nhắc lại ngay trong lượt hiện tại. (c) Mỗi lần gọi đều tính cả token vào lẫn ra; phần
hướng dẫn dài lặp lại ở cả 500 lần thì bị nhân lên 500. Xử lý: rút gọn phần hướng dẫn
chung, giới hạn độ dài đầu ra, và cân nhắc mô hình nhỏ hơn cho việc chấm theo tiêu chí rõ.
Bài tập: cắt gì và giữ gì
Bạn đang gỡ một lỗi trong đồ án. Lời nhắc hiện tại gồm sáu phần. Với mỗi phần, quyết định giữ
hay cắt, và giải thích bằng nguyên tắc "mỗi token phải mua về một thông tin mà mô hình không
thể tự suy ra". (a) Một đoạn chào hỏi và xin lỗi vì làm phiền. (b) Nguyên văn thông báo lỗi.
(c) Toàn bộ mã nguồn của dự án, gồm cả những tệp không liên quan. (d) Câu "đề bài cấm dùng thư
viện ngoài". (e) Định nghĩa của cấu trúc dữ liệu mà hàm bị lỗi đang dùng. (f) Câu "hãy giải
thích thật chi tiết và đầy đủ mọi khía cạnh".
Lời giải. (a) Cắt: không mang thông tin nào. (b) Giữ: dữ kiện quan trọng nhất và tuyệt
đối không suy ra được; tả lại bằng lời là tự đẩy mô hình vào chỗ phải đoán. (c) Cắt phần lớn,
chỉ giữ hàm bị lỗi và những gì nó gọi tới; dán cả dự án vừa đắt, vừa chậm, vừa pha loãng chỗ
đáng chú ý. (d) Giữ: ràng buộc mô hình không có cách nào biết, thiếu nó thì bạn dễ nhận về
một lời khuyên không được phép dùng, tức mất trắng cả lượt hỏi. (e) Giữ: không có định nghĩa
cấu trúc thì mô hình phải đoán các trường, mà đoán thì dễ bịa. (f) Cắt, thay bằng ràng buộc
đo được, chẳng hạn "nêu nguyên nhân trong một câu, chỉ ra dòng sai, đưa bản sửa ngắn". Ba
phần a, c và f bị cắt vì cùng một lý do: tốn token mà không mua về thông tin nào mô hình
chưa có.
Tự kiểm Buổi 1
- 1Cốt lõi cách một LLM tạo câu trả lời là gì?
- 2Cửa sổ ngữ cảnh nghĩa là gì?
- 3Temperature cao thì câu trả lời có xu hướng?
- 4Bốn thành phần cơ bản của một prompt là gì?
- 5Vì sao nên viết prompt gọn và rõ thay vì dài lan man?
Tóm tắt bài
Cả bài quy về một đơn vị đếm và ba hệ quả. Đơn vị đếm là token, và tiếng Việt có dấu tốn
nhiều token hơn tiếng Anh cho cùng một ý. Hệ quả thứ nhất là cửa sổ ngữ cảnh, một trần cứng
tính cả phần vào lẫn phần ra, tồn tại vì khối lượng tính toán tăng nhanh hơn độ dài văn bản.
Hệ quả thứ hai là chi phí: mô hình không có trí nhớ giữa các lượt nên mỗi lượt mới phải gửi
lại toàn bộ lịch sử, khiến chi phí một cuộc trò chuyện dài tăng nhanh hơn nhiều so với lượng
chữ bạn gõ. Hệ quả thứ ba là độ trễ, và đó là lý do chốt độ dài đầu ra thường tiết kiệm nhiều
nhất. Đường ranh không đổi: cắt chữ thừa, đừng cắt thông tin.
Tóm tắt buổi
- Một LLM là bộ máy đoán chữ tiếp theo: nó nối tiếp lời nhắc của bạn dựa trên các mẫu đã học, không tra cứu và không đọc được ý bạn.
- Mô hình chỉ nhìn thấy những gì nằm trong cửa sổ ngữ cảnh; thông tin quan trọng phải được đưa vào lời nhắc.
- Có một chút ngẫu nhiên (
temperatureở mức ý niệm), nên cùng một prompt có thể cho các câu trả lời hơi khác nhau giữa các lần. - Bốn thành phần cơ bản: chỉ dẫn + ngữ cảnh + dữ liệu vào + chỉ báo định dạng. Công thức gọn RTF: vai trò + nhiệm vụ + định dạng.
- Prompt và câu trả lời đều tính bằng
token: viết gọn, rõ thì vừa rẻ vừa nhanh; chọn cỡ mô hình theo độ khó của việc. - Cửa sổ ngữ cảnh là trần cứng tính bằng
token, tính cả phần vào lẫn phần ra; hội thoại quá dài làm phần đầu trôi ra ngoài và mô hình "quên" trong im lặng. - Tiết kiệm
tokennghĩa là cắt chữ thừa, không cắt thông tin: bỏ nghi thức xã giao và chốt độ dài đầu ra, nhưng luôn giữ ngữ cảnh và dữ liệu. - Mọi mô hình đều có mốc kiến thức và thiên kiến; đầu ra luôn cần được kiểm lại, đặc biệt với code và thông tin mới.