Cách khắc phục tính bất định trong suy luận LLM
(thinkingmachines.ai)- Trong suy luận LLM (mô hình ngôn ngữ lớn), có thể xuất hiện vấn đề tính bất định (nondeterminism) khi cùng một đầu vào và điều kiện nhưng kết quả lại khác nhau
- Trước đây, đồng thời hóa (concurrency) và tính không kết hợp (non-associativity) của phép toán dấu chấm động (floating-point) thường được xem là nguyên nhân chính gây ra tính bất định
- Trên thực tế, nguyên nhân mang tính quyết định lại đến từ sự thay đổi thứ tự tính toán bên trong kernel (mã tính toán) khi kích thước batch (batch size) thay đổi
- Nếu mọi phép toán trong kernel đều được triển khai để có tính bất biến theo batch (batch invariance), thì có thể bảo đảm hoàn toàn khả năng tái lập (reproducibility)
- Có thể tạo kernel bất biến theo batch cho các phép toán chính như RMSNorm, matmul, attention bằng tính toán song song theo dữ liệu, split reduction, chiến lược split kích thước cố định
Giới thiệu và tổng quan vấn đề
- Khả năng tái lập (reproducibility), một yếu tố cốt lõi của tiến bộ khoa học, lại không được đảm bảo tốt trong suy luận LLM (mô hình ngôn ngữ lớn)
- Ngay cả khi hỏi ChatGPT cùng một câu nhiều lần, thường vẫn có trường hợp tạo ra các câu trả lời khác nhau
- Điều này là do quá trình sampling kết quả trong LLM là một lựa chọn ngẫu nhiên dựa trên phân phối xác suất
- Tuy nhiên, ngay cả khi đặt temperature về 0, trên thực tế API của LLM cũng không nhất thiết mang tính xác định (tức là không phải lúc nào cũng cho cùng một kết quả với cùng đầu vào)
- Vấn đề tính bất định vẫn tồn tại ngay cả khi chạy trên thư viện suy luận mã nguồn mở (vLLM, SGLang, v.v.) và phần cứng tự quản lý
Giả thuyết trước đây và giới hạn
- Giả thuyết được biết đến rộng rãi: tính bất định xảy ra do đồng thời hóa + tính không kết hợp của dấu chấm động
- Trong GPU, phép toán dấu chấm động có thể cho kết quả hơi khác nhau tùy theo thứ tự tính toán và thứ tự hoàn thành của luồng
- Nhưng trên thực tế, ngay cả khi lặp lại phép nhân ma trận theo cùng cách với cùng dữ liệu, vẫn luôn thu được kết quả giống hệt từng bit (bw=bitwise equal)
- Để xác định nguyên nhân thực sự, cần phân tích sâu hơn
Phân tích sâu nguyên nhân gây bất định trong suy luận LLM
Bản chất của tính không kết hợp trong dấu chấm động
- Phép toán dấu chấm động có quan hệ (a+b)+c ≠ a+(b+c)
- Khi tính toán giữa các giá trị có độ lớn khác nhau (exponent khác nhau), sẽ xảy ra mất độ chính xác, mất thông tin, và kết quả thay đổi tùy theo thứ tự tính toán
- Vì thứ tự tính toán có thể thay đổi, nên nếu thực hiện nhiều phép cộng tổng theo cách ngẫu nhiên, sẽ cho ra nhiều kết quả khác nhau (đã được xác nhận qua thực nghiệm)
Sự thay đổi thứ tự tính toán trong kernel và đồng thời hóa
- Thông thường, vấn đề đồng thời trong các phép như atomic add được xem là nguyên nhân chính của tính bất định
- Nhưng phần lớn các kernel dùng trong suy luận LLM (đặc biệt là forward pass) vẫn hoạt động mà không cần atomic add
- Với chiến lược song song hóa phù hợp từ trước, split (reduction), v.v., có thể đảm bảo cùng một thứ tự tính toán
Nguyên nhân cốt lõi trên thực tế: thiếu "tính bất biến theo batch (batch invariance)"
- Mỗi kernel riêng lẻ, nếu đầu vào giống nhau, thì luôn trả về cùng một kết quả (run-to-run deterministic)
- Nhưng vì các yêu cầu đồng thời của nhiều người dùng làm batch size thay đổi một cách bất định, nên trên thực tế kết quả cho từng yêu cầu lại không ổn định
- Tùy theo kích thước batch, thứ tự tách hoặc gộp tính toán bên trong sẽ thay đổi, từ đó phát sinh tính bất định
- Nói cách khác, tải máy chủ và mức độ song song hóa (kích thước batch) mang tính bất định mới là nguyên nhân cốt lõi
Thiết kế kernel bất biến theo batch và các ví dụ phép toán chính
RMSNorm
- Áp dụng chiến lược song song hóa theo dữ liệu (data-parallel): mỗi phần tử batch được một lõi xử lý độc lập
- Khi kích thước batch lớn, vẫn duy trì đủ mức song song hóa, tức là chiến lược song song ổn định nên tính bất biến theo batch được đảm bảo
- Khi kích thước batch rất nhỏ, có thể dùng chiến lược thay thế như split reduction, nhưng trong trường hợp này sẽ phải hy sinh một phần tính bất biến theo batch
Nhân ma trận (matmul)
- Song song hóa theo từng tile để áp dụng chiến lược song song theo dữ liệu
- Để tối ưu việc dùng tensor core, cần chia theo tile 2D; với batch rất nhỏ thì cần các chiến lược đặc biệt như split-K
- Khi dùng chiến lược split-K, tính bất biến theo batch có thể bị phá vỡ
- Dù phải đánh đổi một phần hiệu năng, vẫn có thể ép dùng cùng một cấu hình kernel để đảm bảo thứ tự tính toán ổn định (reproducible)
Attention
- Trong FlashAttention2, v.v., có thể đảm bảo tính bất biến theo batch bằng chiến lược song song hóa theo hướng query, reduction đồng thời cho Key/Value
- Nếu thứ tự reduction thay đổi theo kích thước batch hoặc cách chia chuỗi (chunked prefill, prefix caching, v.v.) thì tính bất biến sẽ bị phá vỡ
- Với các chiến lược split-reduction như split-KV (FlashDecoding), có thể giữ nguyên thứ tự tính toán bằng cách cố định kích thước split (fixed split-size)
- Xét theo hoạt động nội bộ, không nên xử lý riêng key/value cache và token mới, mà phải giữ layout key/value nhất quán trong mọi phép toán
Triển khai
- Cung cấp bản demo suy luận xác định áp dụng kernel bất biến theo batch bằng vLLM và torch.Library
- Có thể xem các kernel thay thế cho các phép toán liên quan tại GitHub repo (thinking-machines-lab/batch-invariant-ops)
Thực nghiệm và hiệu năng
Thí nghiệm đo tính bất định
- Dùng mô hình Qwen/Qwen3-235B-A22B-Instruct-2507 để sinh 1000 lần với cùng prompt (“Tell me about Richard Feynman”) trong điều kiện temperature 0
- Tạo ra 80 phần hoàn thành khác nhau (cùng prompt nhưng vẫn tồn tại tính bất định)
- 102 token đầu tiên giống nhau, và nhánh tách đầu tiên xuất hiện ở token thứ 103 (“Queens, New York” so với “New York City”)
- Khi dùng kernel bất biến theo batch, cả 1000 lần đều cho kết quả giống hệt nhau, đạt được khả năng tái lập hoàn toàn
Đánh giá hiệu năng
- Chạy Qwen-3-8B trên 1 GPU, với 1000 yêu cầu, mỗi yêu cầu có chuỗi dài khoảng 90~110
- vLLM mặc định: 26 giây
- deterministic vLLM chưa tối ưu: 55 giây
- áp dụng kernel attention đã cải tiến: 42 giây
- Dù chưa tối ưu đầy đủ, hiệu năng vẫn ở mức có thể sử dụng trong thực tế
Giá trị trong On-policy RL
- Trước đây, do chênh lệch số học rất nhỏ giữa training và inference nên on-policy RL không thể được triển khai chính xác
- Nếu suy luận mang tính xác định, có thể làm cho cả sampling và training đều bitwise identical, từ đó triển khai on-policy RL đúng nghĩa
- Đã xác nhận kết quả trùng khớp hoàn toàn ở các metric chính như KL-divergence, reward, v.v.
Kết luận
- Trong các hệ thống suy luận LLM, rất dễ xem nhẹ tính bất định và sai số số học, nhưng nếu xác định và khắc phục nguyên nhân gốc rễ (thiếu tính bất biến theo batch) thì có thể đạt được khả năng tái lập và tính xác định hoàn toàn
- Nghiên cứu này chỉ ra cách giải quyết vấn đề tính bất định trong suy luận LLM, giúp các nhà phát triển có thể bảo đảm khả năng tái lập hoàn toàn trong hệ thống của chính họ
Thông tin trích dẫn
- Khi trích dẫn nghiên cứu này, hãy dùng thông tin sau
He, Horace and Thinking Machines Lab, "Defeating Nondeterminism in LLM Inference",
Thinking Machines Lab: Connectionism, Sep 2025.
hoặc
@article{he2025nondeterminism,
author = {Horace He and Thinking Machines Lab},
title = {Defeating Nondeterminism in LLM Inference},
journal = {Thinking Machines Lab: Connectionism},
year = {2025},
note = {https://thinkingmachines.ai/blog/…},
doi = {10.64434/tml.20250910}
}
1 bình luận
Ý kiến trên Hacker News
Ngay cả khi giải quyết được tính phi quyết định mang tính “lý thuyết” trong một cặp đầu vào-đầu ra cá biệt hoàn toàn khép kín, vẫn còn hai vấn đề phi quyết định thực tế: cùng một đầu vào nhưng cho ra kết quả khác nhau tùy ngữ cảnh trước đó, và đầu vào chỉ biến đổi nhẹ nhưng không cho ra kết quả được biến đổi đúng tương ứng. Chừng nào các vấn đề này chưa được giải quyết, tính phi quyết định trong hệ thống khép kín thực ra không giúp ích nhiều, trừ những trường hợp mà bảng tra cứu cũng đã là đủ. Rất khó dùng unit test hay tập đánh giá “chính xác” để chứng minh điều gì đó đối với các đầu vào chưa được kiểm thử
Thực ra không tồn tại tình huống “chính xác cùng một đầu vào nhưng kết quả thay đổi theo ngữ cảnh trước đó khác nhau”. Bản thân ngữ cảnh trước đó cũng là đầu vào. Nếu một prompt đầu vào luôn cho ra cùng một kết quả, có thể xem như ngữ cảnh đang bị bỏ qua. Tức là tương đương với việc luôn bắt đầu từ ngữ cảnh rỗng, bất kể trạng thái trong phiên là gì. Điều một số người muốn là,
Tại sao việc “ngữ cảnh trước đó” tạo ra kết quả khác lại là vấn đề? Nếu ngữ cảnh không ảnh hưởng đến kết quả thì cứ bỏ ngữ cảnh đi là được. Tại sao lại phải cố muốn hành vi như vậy? Trên thực tế, với một công cụ, ta mong nó phản ứng khác nhau tùy theo ý định hay việc chuyển mode của mình (ví dụ trong vim, hành vi thay đổi sau khi chuyển sang insert mode). Tôi cũng muốn trí tuệ vận hành theo kiểu đó. Việc bỏ qua ngữ cảnh thậm chí còn giống một dạng thiên kiến xác nhận cực đoan hơn
Rất hữu ích khi tái hiện lỗi
Tôi từng đồng ý đến đoạn nói rằng nó “không giúp ích nhiều”. Có lẽ ý là “nó không giải quyết triệt để toàn bộ vấn đề”
Tôi thắc mắc vì sao lại quá quan tâm đến tính quyết định trong một hệ thống xác suất. Từ góc nhìn người dùng, kể cả nếu đầu vào "How do I X?" luôn cho ra đúng một câu trả lời mang tính quyết định như nhau, thì điều đó cũng chẳng có nhiều ý nghĩa nếu các đầu vào cùng nghĩa như "how do i x?", "how do I x", "how do I X??" lại cho ra những kết quả hoàn toàn khác nhau. Điều thực sự cần ở LLM là khả năng bảo đảm rằng đầu vào tương đương về mặt ngữ nghĩa thì luôn tạo ra đầu ra tương đương về mặt ngữ nghĩa. Đây là một khái niệm hoàn toàn khác với tính quyết định mà ta thường nói trong thuật toán
Không phải mọi ứng dụng dựa trên LLM đều chỉ có giao diện chat nơi người dùng gõ tự do. Nếu bạn đang gọi công cụ 10 lần liên tiếp để đánh giá, hoặc liên tục kiểm thử prompt bằng các công cụ như DSPy Optimizer link, thì khi bạn có thể kiểm soát hoàn toàn đầu vào đến tận cấp token, việc giảm tính khó đoán là rất quan trọng. Trong những môi trường như vậy, nếu có thể loại bỏ biến động ở mức token để chỉ còn phải xử lý sự mơ hồ của chính đầu vào, bạn có thể ánh xạ hành vi của hệ thống vào các cấu trúc cây hoặc đồ thị đáng tin cậy hơn nhiều
Bạn nói không sai, nhưng điều đó không có nghĩa mức độ quyết định này là vô dụng. Nếu ngay cả khi đưa vào cùng một chuỗi token đầu vào mà kết quả vẫn luôn khác nhau, thì sẽ rất khó tái hiện và chia sẻ kết quả với đồng nghiệp, hoặc kiểm thử các tình huống LLM tạo ra đầu ra cực hiếm và khó dự đoán (ví dụ red teaming)
Tôi đang làm một dự án giấu thông tin bằng steganography trong đầu ra của LLM: innocuous. Vì chỉ lấy khoảng 10 token hàng đầu của mô hình để sử dụng, và chủ yếu thử nghiệm trên các mô hình 8B chạy CPU, nên tôi không quá lo việc thứ tự token thay đổi do ảnh hưởng phần cứng, nhưng tôi vẫn định cuối cùng sẽ thêm điều kiện guard để tránh việc các lựa chọn thay đổi vì mất mát độ chính xác rất nhỏ
Điều này có thể rất hữu ích cho khách hàng của các nền tảng AI. Họ có thể chạy cùng một prompt với temperature 0 nhiều lần để kiểm tra xem kết quả có luôn giống nhau không, từ đó xác minh liệu nhà cung cấp AI có đang lén thay mô hình PRO bằng một mô hình rẻ hơn hay không
Với mục đích tái hiện “bug” thì đây là điều bắt buộc. Nếu có thể tái hiện y hệt cùng đầu ra sai hoặc kỳ lạ mỗi lần đưa vào cùng một chuỗi đầu vào, việc debug sẽ dễ hơn nhiều. Nếu kết quả chỉ thay đổi 1 lần trong 100 lần chạy thì sẽ khó hơn rất nhiều
(Có kinh nghiệm làm với JAX/XLA) Đây là chuyện khá nổi tiếng. Tôi cũng đã nhiều lần gặp hiện tượng này (biến thiên theo batch) và được giải thích trong các issue dưới đây: penzai issue #82, jax issue comment
Đôi khi nguyên nhân của tính phi quyết định nằm ở chi tiết triển khai. Ví dụ, trong mã nguồn GPT-2, kể cả khi đặt temperature về 0 trong GUI thì thực tế vẫn truyền vào một giá trị “epsilon” (một số rất nhỏ) khác 0. Điều này cũng hợp lý vì nhằm tránh lỗi division by zero. Tính phi quyết định là “vô dụng” trong nhiều ứng dụng. Đây cũng là một vấn đề cũ trong mô hình chủ đề LDA. Đặc biệt trong các lĩnh vực pháp lý, tài chính và tuân thủ quy định, việc dùng phương pháp không mang tính quyết định thậm chí có thể là bất hợp pháp. Hoặc nó có thể kéo theo những nghĩa vụ bổ sung không mong muốn (phải lưu toàn bộ bản ghi màn hình để sau này có thể phục dựng từng chuyện đã xảy ra)
Có nhắc đến chuyện “làm việc cùng người khác tại Thinking Machines”. Nó làm tôi nhớ thời xưa từng đứng trước MIT AI Lab nhìn cỗ máy với các khối LED đỏ phát sáng. Richard Feynman đã làm những điều thực sự tuyệt vời, và có một bài viết liên quan Feynman and the Connection Machine. Tại Mỹ, nhãn hiệu “THINKING MACHINES” không được đăng ký dưới tên Hillis mà dưới tên công ty do ông sáng lập, và đã bị hủy trong giai đoạn 1998–1999. Công ty phá sản năm 1994, và tài sản được chuyển cho Sun Microsystems (sau này là Oracle) cùng các bên khác. Thinking Machines Lab Inc. do Amira Murati thành lập đang tiến hành nộp đơn nhãn hiệu mới cho “THINKING MACHINES” trong năm 2025
Tôi rất mừng khi gần đây xuất hiện nhiều thảo luận nghiên cứu kiểu blog có chất lượng cao. Anthropic đang dẫn dắt văn hóa này và xu hướng đó ngày càng lan rộng nên rất đáng kỳ vọng. Trước đây vào thời nghiên cứu RL, OpenAI cũng từng như vậy
Bản thân ngôn ngữ tự nhiên vốn đã mơ hồ. Nó phải mơ hồ như thế. Tôi nghĩ cách tiếp cận kiểu “biến hình tròn thành hình vuông rồi giải thích vì sao phải làm thế” đang được thử ở đây là sai. Những cuộc thảo luận như thế này rồi sẽ phát triển thành các tranh luận về việc chấp nhận tốt hơn bản chất của ngôn ngữ và tính ngẫu nhiên, và diễn giải ngôn ngữ vượt lên trên những mẫu con ngữ pháp tí hon như QKV projection matrix
Tôi vẫn không thích tên công ty này. Tôi tự hỏi vì sao kiểu đặt tên này cứ lặp lại. Có lẽ là mong khí chất của một tổ chức huyền thoại nào đó sẽ thấm sang cả startup mới. Nhưng tôi không nghĩ chỉ cần đặt tên startup tiếp theo là PARC thì tự động cũng sẽ kế thừa được đổi mới về mạng máy tính đâu
Ý bạn là công ty “Thinking Machines” đã biến mất từ năm 1994 ấy à? Tôi phải tra mới biết, và có vẻ nó không nổi tiếng đến mức đó nên chắc không hẳn là cố tình như vậy. Tôi chỉ thấy đây là một cái tên vừa ngầu vừa trực quan
Chỉ riêng việc đặt tên như vậy đã có sẵn marketing miễn phí đi kèm, cũng giống như lý do hệ thống nhãn hiệu ra đời
Nội dung thật sự thú vị. Nói cho những ai chưa biết thì đây là công ty do cựu CTO OpenAI Mira Murati khởi xướng