Cải tiến WebAssembly và WebGPU để giúp web AI hoạt động nhanh hơn, phần 1

Tìm hiểu cách các tính năng nâng cao của WebAssembly và WebGPU giúp cải thiện hiệu suất học máy trên web.

Austin Eng
Austin Eng
Deepti Gandluri
Deepti Gandluri
François Beaufort
François Beaufort

Suy luận của AI trên web

Tất cả chúng ta đều nghe câu chuyện: AI đang thay đổi thế giới của chúng ta. Web cũng không ngoại lệ.

Năm nay, Chrome đã bổ sung các tính năng dựa trên AI tạo sinh, bao gồm cả việc tạo giao diện tuỳ chỉnh và/hoặc giúp bạn viết bản nháp văn bản đầu tiên. Tuy nhiên, AI không chỉ dừng lại ở đó, vì AI có thể tự làm phong phú các ứng dụng web.

Các trang web có thể nhúng các thành phần thông minh để phục vụ thị giác, chẳng hạn như chọn khuôn mặt hoặc nhận dạng cử chỉ, để phân loại âm thanh hoặc phát hiện ngôn ngữ. Năm ngoái, chúng tôi nhận thấy AI tạo sinh đã phát triển mạnh mẽ, bao gồm cả một số bản minh hoạ thực sự ấn tượng về các mô hình ngôn ngữ lớn trên web. Hãy nhớ tham khảo bài viết Thực hành về trí tuệ nhân tạo (AI) trên thiết bị dành cho nhà phát triển web.

Khả năng suy luận bằng trí tuệ nhân tạo (AI) trên web hiện có mặt trên một phần lớn thiết bị, và quá trình xử lý bằng trí tuệ nhân tạo (AI) có thể diễn ra trên chính trang web đó, tận dụng phần cứng trên thiết bị của người dùng.

Điều này mạnh mẽ vì một số lý do:

  • Giảm chi phí: Việc chạy suy luận trên máy khách của trình duyệt giúp giảm đáng kể chi phí máy chủ. Điều này có thể đặc biệt hữu ích đối với các truy vấn AI tạo sinh (có thể là những đơn đặt hàng có chi phí cao hơn so với các truy vấn thông thường).
  • Độ trễ: Đối với các ứng dụng đặc biệt nhạy cảm với độ trễ, chẳng hạn như các ứng dụng âm thanh hoặc video, việc xử lý toàn bộ quá trình trên thiết bị sẽ giúp giảm độ trễ.
  • Quyền riêng tư: Chạy ở phía máy khách, cũng có tiềm năng mở khoá một loại ứng dụng mới yêu cầu tăng cường bảo mật, trong đó không thể gửi dữ liệu đến máy chủ.

Cách tải công việc trí tuệ nhân tạo (AI) chạy trên web hiện nay

Hiện nay, các nhà phát triển ứng dụng và nhà nghiên cứu xây dựng mô hình bằng cách sử dụng khung, mô hình thực thi trong trình duyệt thông qua môi trường thời gian chạy như Tensorflow.js hoặc ONNX Runtime Web và thời gian chạy sử dụng API web để thực thi.

Cuối cùng, tất cả các môi trường thời gian chạy đó đều sẽ chạy trên CPU thông qua JavaScript hoặc WebAssembly hoặc trên GPU thông qua WebGL hoặc WebGPU.

Sơ đồ về cách chạy khối lượng công việc AI hiện nay trên web

Khối lượng công việc trong công nghệ học máy

Khối lượng công việc của công nghệ học máy sẽ đẩy tensor thông qua một biểu đồ gồm các nút tính toán. Bộ kéo là dữ liệu đầu vào và đầu ra của các nút này thực hiện một lượng lớn tính toán trên dữ liệu.

Việc này rất quan trọng vì:

  • Tensor là cấu trúc dữ liệu rất lớn, thực hiện phép tính trên các mô hình có thể có hàng tỷ trọng số
  • Việc mở rộng quy mô và dự đoán có thể dẫn đến sự song song dữ liệu. Điều này có nghĩa là các thao tác tương tự được thực hiện trên tất cả các phần tử trong tensor.
  • Công nghệ học máy không đòi hỏi độ chính xác. Có thể bạn cần một số có dấu phẩy động 64 bit để đáp xuống mặt trăng, nhưng để nhận dạng khuôn mặt chỉ cần một biển số từ 8 bit trở xuống.

May mắn là các nhà thiết kế chip đã thêm các tính năng để giúp các mô hình chạy nhanh hơn, mát hơn và thậm chí là giúp các mô hình đó chạy được.

Trong khi đó, tại các nhóm WebAssembly và WebGPU, chúng tôi đang nỗ lực để cung cấp những khả năng mới đó cho các nhà phát triển web. Nếu là nhà phát triển ứng dụng web, bạn không thể thường xuyên sử dụng các dữ liệu gốc cấp thấp này. Chúng tôi hy vọng những chuỗi công cụ hoặc khung mà bạn đang sử dụng sẽ hỗ trợ các tính năng và tiện ích mới. Nhờ vậy, bạn có thể nhận được lợi ích từ những thay đổi rất nhỏ đối với cơ sở hạ tầng của mình. Nhưng nếu bạn muốn tinh chỉnh các ứng dụng của mình theo cách thủ công để có hiệu suất thì những tính năng này có liên quan đến công việc của bạn.

WebAssembly

WebAssembly (Wasm) là một định dạng mã byte nhỏ gọn, hiệu quả mà môi trường thời gian chạy có thể hiểu và thực thi. API này được thiết kế để tận dụng các tính năng phần cứng cơ bản, vì vậy nó có thể thực thi ở tốc độ gần với tốc độ gốc. Mã được xác thực và thực thi trong môi trường hộp cát, an toàn đối với bộ nhớ.

Thông tin về mô-đun Wasm được biểu thị bằng mã hoá nhị phân dày đặc. So với định dạng dựa trên văn bản, điều đó có nghĩa là giải mã nhanh hơn, tải nhanh hơn, giảm mức sử dụng bộ nhớ. Đây là cấu trúc linh hoạt vì nó không đưa ra giả định về cấu trúc cơ bản vốn chưa phổ biến trong các kiến trúc hiện đại.

Quy cách WebAssembly có tính lặp lại và được thực hiện trong một nhóm cộng đồng W3C mở.

Định dạng nhị phân không đưa ra giả định về môi trường lưu trữ, vì vậy định dạng này cũng được thiết kế để hoạt động tốt trong các hoạt động nhúng không phải web.

Ứng dụng của bạn có thể được biên dịch một lần và chạy ở mọi nơi: máy tính để bàn, máy tính xách tay, điện thoại hoặc bất kỳ thiết bị nào khác có trình duyệt. Hãy tham khảo bài viết Viết một lần, chạy ở mọi nơi cuối cùng đã được xác định với WebAssembly để tìm hiểu thêm về điều này.

Hình minh hoạ một chiếc máy tính xách tay, máy tính bảng và điện thoại

Hầu hết ứng dụng chính thức chạy suy luận dựa trên AI trên web đều sử dụng WebAssembly, cho cả việc điện toán CPU và giao tiếp với điện toán cho mục đích đặc biệt. Trên ứng dụng gốc, bạn có thể truy cập vào cả điện toán cho mục đích chung và điện toán mục đích đặc biệt, vì ứng dụng có thể truy cập vào các tính năng của thiết bị.

Trên web, để đảm bảo tính di động và bảo mật, chúng tôi đánh giá kỹ lưỡng những tập hợp dữ liệu gốc được hiển thị. Điều này cân bằng khả năng truy cập của web với hiệu suất tối đa do phần cứng cung cấp.

WebAssembly là một trừu tượng di động của CPU, vì vậy, tất cả suy luận của Wasm đều được chạy trên CPU. Mặc dù đây không phải là lựa chọn hiệu quả nhất, nhưng CPU có sẵn rộng rãi và hoạt động trên hầu hết tải công việc, trên hầu hết thiết bị.

Đối với các tải công việc nhỏ hơn, chẳng hạn như khối lượng công việc liên quan đến văn bản hoặc âm thanh, GPU sẽ gây tốn kém. Gần đây, có một số ví dụ mà Wasm là lựa chọn phù hợp:

Bạn có thể khám phá nhiều hơn nữa trong các bản minh hoạ nguồn mở, chẳng hạn như: whisper-tiny, llama.cppGemma2B đang chạy trong trình duyệt.

Áp dụng phương pháp tiếp cận toàn diện cho ứng dụng của bạn

Bạn nên chọn dữ liệu gốc dựa trên mô hình học máy cụ thể, cơ sở hạ tầng ứng dụng và trải nghiệm tổng thể của ứng dụng mà người dùng dự định sử dụng

Ví dụ: trong tính năng phát hiện mốc khuôn mặt của MediaPipe, suy luận về CPU và dự đoán GPU là tương đương (chạy trên thiết bị Apple M1), nhưng có những mô hình mà phương sai có thể cao hơn đáng kể.

Đối với tải công việc học máy, chúng tôi cân nhắc góc nhìn tổng quan về ứng dụng, đồng thời lắng nghe ý kiến của các tác giả khung và đối tác ứng dụng để phát triển và đưa các tính năng nâng cao được yêu cầu nhiều nhất. Các chính sách này thường được chia thành ba danh mục:

  • Hiển thị các tiện ích CPU quan trọng đối với hiệu suất
  • Cho phép chạy các mô hình lớn hơn
  • Cho phép tương tác liền mạch với các API web khác

Tính toán nhanh hơn

Hiện tại, thông số kỹ thuật WebAssembly chỉ bao gồm một tập hợp các lệnh nhất định mà chúng tôi hiển thị trên web. Tuy nhiên, phần cứng tiếp tục bổ sung các hướng dẫn mới hơn để tăng khoảng cách giữa hiệu suất gốc và hiệu suất WebAssembly.

Xin lưu ý rằng các mô hình học máy không phải lúc nào cũng yêu cầu độ chính xác cao. SIMD được nới lỏng là một đề xuất giúp giảm một số yêu cầu nghiêm ngặt và không mang tính xác định, giúp tạo mã nhanh hơn cho một số toán tử vectơ vốn là điểm nóng về hiệu suất. Ngoài ra, SIMD thoải mái giới thiệu sản phẩm chấm và hướng dẫn FMA mới giúp tăng tốc khối lượng công việc hiện có từ 1,5 đến 3 lần. Tính năng này được phát hành trong Chrome 114.

Định dạng dấu phẩy động có độ bán chính xác sử dụng 16 bit cho IEEE FP16 thay vì 32 bit dùng cho các giá trị có độ chính xác đơn. So với các giá trị có độ chính xác đơn, có một số ưu điểm trong việc sử dụng giá trị bán chính xác, giảm yêu cầu về bộ nhớ, cho phép huấn luyện và triển khai mạng nơron lớn hơn, giảm băng thông bộ nhớ. Độ chính xác giảm giúp tăng tốc độ truyền dữ liệu và các phép toán.

Mô hình lớn hơn

Con trỏ vào bộ nhớ tuyến tính Wasm được biểu thị dưới dạng số nguyên 32 bit. Điều này dẫn đến hai hệ quả: kích thước vùng nhớ khối xếp được giới hạn ở mức 4GB (khi máy tính có RAM vật lý nhiều hơn thế) và mã ứng dụng nhắm mục tiêu đến Wasm phải tương thích với kích thước con trỏ 32 bit (trong đó).

Đặc biệt là với các mô hình lớn như chúng ta hiện nay, việc tải các mô hình này vào WebAssembly có thể bị hạn chế. Đề xuất Memory64 loại bỏ những hạn chế này theo dung lượng bộ nhớ tuyến tính lớn hơn 4GB và phù hợp với không gian địa chỉ của nền tảng gốc.

Chúng tôi hiện đã triển khai đầy đủ chính sách trong Chrome và dự kiến sẽ giao hàng vào cuối năm nay. Hiện tại, bạn có thể chạy thử nghiệm có cờ chrome://flags/#enable-experimental-webassembly-features và gửi ý kiến phản hồi cho chúng tôi.

Khả năng tương tác tốt hơn trên web

WebAssembly có thể là điểm truy cập cho mục đích tính toán đặc biệt trên web.

Có thể sử dụng WebAssembly để đưa các ứng dụng GPU lên web. Điều đó có nghĩa là ứng dụng C++ có thể chạy trên thiết bị cũng có thể chạy trên web, với một số sửa đổi nhỏ.

Emscripten, chuỗi công cụ trình biên dịch Wasm, đã có các liên kết cho WebGPU. Đây là điểm bắt đầu cho hoạt động suy luận bằng AI trên web. Vì vậy, điều quan trọng là Wasm có thể tương tác liền mạch với phần còn lại của nền tảng web. Chúng tôi đang làm việc trên một số đề xuất khác nhau trong lĩnh vực này.

Tích hợp cam kết JavaScript (JSPI)

Các ứng dụng C và C++ điển hình (cũng như nhiều ngôn ngữ khác) thường được viết dựa trên API đồng bộ. Điều này có nghĩa là ứng dụng sẽ ngừng thực thi cho đến khi thao tác hoàn tất. Các ứng dụng chặn như vậy thường trực quan hơn để ghi so với các ứng dụng không nhận biết được không đồng bộ.

Khi các thao tác tiêu tốn nhiều tài nguyên chặn luồng chính, chúng có thể chặn I/O và người dùng có thể thấy hiện tượng giật. Có sự không phù hợp giữa mô hình lập trình đồng bộ của ứng dụng gốc và mô hình không đồng bộ của web. Điều này đặc biệt khó khăn đối với các ứng dụng cũ do việc chuyển đổi rất tốn kém. Emscripten cung cấp cách để thực hiện việc này bằng tính năng Asyncify, nhưng đây không phải lúc nào cũng là lựa chọn tốt nhất – kích thước mã lớn hơn và không hiệu quả.

Ví dụ sau đây là tính toán fibonacci, sử dụng các hứa hẹn của JavaScript để bổ sung.

long promiseFib(long x) {
 if (x == 0)
   return 0;
 if (x == 1)
   return 1;
 return promiseAdd(promiseFib(x - 1), promiseFib(x - 2));
}
// promise an addition
EM_ASYNC_JS(long, promiseAdd, (long x, long y), {
  return Promise.resolve(x+y);
});
emcc -O3 fib.c -o b.html -s ASYNCIFY=2

Trong ví dụ này, hãy chú ý đến những điều sau:

  • Macro EM_ASYNC_JS tạo tất cả mã kết nối cần thiết để chúng ta có thể sử dụng DEXI để truy cập vào kết quả của lời hứa, tương tự như cách sử dụng với một hàm thông thường.
  • Tuỳ chọn dòng lệnh đặc biệt, -s ASYNCIFY=2. Thao tác này sẽ gọi tuỳ chọn để tạo mã sử dụng DEXI cho giao diện với các lệnh nhập JavaScript trả về lời hứa.

Để biết thêm về IMEI, cách sử dụng và các lợi ích, hãy đọc bài viết Giới thiệu về API tích hợp cam kết JavaScript của WebAssembly trên v8.dev. Tìm hiểu về bản dùng thử theo nguyên gốc hiện tại.

Kiểm soát bộ nhớ

Nhà phát triển có rất ít quyền kiểm soát đối với bộ nhớ Wasm; mô-đun có bộ nhớ riêng. Bất kỳ API nào cần truy cập vào bộ nhớ này đều phải sao chép vào hoặc sao chép ra, và việc sử dụng này có thể thực sự tăng lên. Ví dụ: có thể một ứng dụng đồ hoạ cần sao chép vào và xuất ra cho từng khung hình.

Đề xuất Kiểm soát bộ nhớ nhằm cung cấp khả năng kiểm soát chi tiết hơn đối với bộ nhớ tuyến tính Wasm và giảm số lượng bản sao trên quy trình của ứng dụng. Đề xuất này đang ở Giai đoạn 1, chúng tôi đang tạo nguyên mẫu này trong V8, công cụ JavaScript của Chrome, để cung cấp thông tin cho sự phát triển của tiêu chuẩn này.

Quyết định phần phụ trợ phù hợp với bạn

Mặc dù CPU có mặt ở khắp mọi nơi, nhưng không phải lúc nào CPU cũng là lựa chọn tốt nhất. Tính năng điện toán dùng cho mục đích đặc biệt trên GPU hoặc các trình tăng tốc có thể mang lại hiệu suất theo thứ tự lớn hơn, đặc biệt là đối với các kiểu máy lớn hơn và trên các thiết bị cao cấp. Điều này đúng cho cả ứng dụng gốc và ứng dụng web.

Loại phần phụ trợ mà bạn chọn sẽ phụ thuộc vào ứng dụng, khung hoặc chuỗi công cụ, cũng như các yếu tố khác ảnh hưởng đến hiệu suất. Tuy nhiên, chúng tôi vẫn đang tiếp tục đầu tư vào các đề xuất cho phép Wasm cốt lõi hoạt động tốt với phần còn lại của nền tảng web và cụ thể hơn là với WebGPU.

Đọc tiếp Phần 2