Đây là hướng dẫn toàn diện về LiteRT.js, bao gồm quy trình chuyển đổi một mô hình PyTorch để chạy trong trình duyệt bằng tính năng tăng tốc WebGPU. Ví dụ này sử dụng ResNet18 cho mô hình thị giác và TensorFlow.js để xử lý trước và sau.
Hướng dẫn này sẽ đề cập đến các bước sau:
- Chuyển đổi mô hình PyTorch của bạn sang LiteRT bằng AI Edge Torch.
- Thêm gói LiteRT vào ứng dụng web của bạn.
- Tải mô hình.
- Viết logic xử lý trước và sau.
Chuyển đổi sang LiteRT
Sử dụng sổ tay PyTorch Converter để chuyển đổi một mô hình PyTorch sang định dạng .tflite
thích hợp. Để xem hướng dẫn chi tiết về các loại lỗi bạn có thể gặp phải và cách khắc phục, hãy xem Trình chuyển đổi Torch AI Edge README.
Mô hình của bạn phải tương thích với torch.export.export
, tức là bạn phải xuất được mô hình bằng TorchDynamo. Do đó, nó không được có bất kỳ nhánh có điều kiện nào của python phụ thuộc vào các giá trị thời gian chạy trong các tensor. Nếu bạn thấy các lỗi sau trong quá trình torch.export.export
, thì mô hình của bạn không thể xuất bằng torch.export.export
. Mô hình của bạn cũng không được có bất kỳ phương diện đầu vào hoặc đầu ra động nào trên các tensor. Điều này bao gồm cả phương diện lô.
Bạn cũng có thể bắt đầu bằng một mô hình PyTorch tương thích với TensorRT hoặc có thể xuất ONNX:
Phiên bản tương thích với TensorRT của một mô hình có thể là một điểm khởi đầu tốt, vì một số loại lượt chuyển đổi TensorRT cũng yêu cầu các mô hình phải xuất được TorchDynamo. Nếu sử dụng bất kỳ hoạt động NVIDIA / CUDA nào trong mô hình, bạn sẽ cần thay thế các hoạt động đó bằng các hoạt động PyTorch tiêu chuẩn.
Mô hình PyTorch có thể xuất sang ONNX có thể là một điểm khởi đầu tốt, mặc dù một số mô hình ONNX sử dụng TorchScript thay vì TorchDynamo để xuất. Trong trường hợp đó, mô hình có thể không xuất được sang TorchDynamo (mặc dù có khả năng gần hơn mã mô hình ban đầu).
Để biết thêm thông tin, hãy xem bài viết Chuyển đổi các mô hình PyTorch sang LiteRT.
Thêm gói LiteRT
Cài đặt gói @litertjs/core
từ npm:
npm install @litertjs/core
Nhập gói và tải các tệp Wasm của gói:
import {loadLiteRt} from '@litertjs/core';
// They are located in node_modules/@litertjs/core/wasm/
// Serve them statically on your server.
await loadLiteRt(`your/path/to/wasm/`);
Tải mô hình
Nhập và khởi chạy LiteRT.js cũng như các tiện ích chuyển đổi LiteRT-TFJS. Bạn cũng cần nhập TensorFlow.js để truyền tensor đến LiteRT.js.
import {CompileOptions, loadAndCompile, loadLiteRt, setWebGpuDevice} from '@litertjs/core';
import {runWithTfjsTensors} from '@litertjs/tfjs-interop';
// TensorFlow.js imports
import * as tf from '@tensorflow/tfjs';
import '@tensorflow/tfjs-backend-webgpu'; // Only WebGPU is supported
import {WebGPUBackend} from '@tensorflow/tfjs-backend-webgpu';
async function main() {
// Initialize TensorFlow.js WebGPU backend
await tf.setBackend('webgpu');
// Initialize LiteRT.js's Wasm files
await loadLiteRt('your/path/to/wasm/');
// Make LiteRt use the same GPU device as TFJS (for tensor conversion)
const backend = tf.backend() as WebGPUBackend;
setWebGpuDevice(backend.device);
// ...
}
main();
Tải mô hình LiteRT đã chuyển đổi:
const model = await loadAndCompile('path_to_model.tflite', {
accelerator: 'webgpu', // or 'wasm'
});
Viết quy trình mô hình
Viết logic xử lý trước và sau kết nối mô hình với ứng dụng của bạn. Bạn nên dùng TensorFlow.js để xử lý trước và sau, nhưng nếu không viết bằng TensorFlow.js, bạn có thể gọi await
tensor.data
để lấy giá trị dưới dạng ArrayBuffer hoặc await
tensor.array
để lấy một mảng JS có cấu trúc.
Sau đây là ví dụ về quy trình từ đầu đến cuối cho ResNet18:
// Wrap in a tf.tidy call to automatically clean up intermediate TensorFlow.js tensors.
// (Note: tidy only supports synchronous functions).
const top5 = tf.tidy(() => {
// Get RGB data values from an image element and convert it to range [0, 1).
const image = tf.browser.fromPixels(dogs, 3).div(255);
// These preprocessing steps come from https://github.com/pytorch/vision/blob/main/torchvision/models/resnet.py#L315
// The mean and standard deviation for the image normalization come from https://github.com/pytorch/vision/blob/main/torchvision/transforms/_presets.py#L38
const imageData = image.resizeBilinear([224, 224])
.sub([0.485, 0.456, 0.406])
.div([0.229, 0.224, 0.225])
.reshape([1, 224, 224, 3])
.transpose([0, 3, 1, 2]);
// You can pass inputs as a single tensor, an array, or a JS Object
// where keys are the tensor names in the TFLite model.
// When passing an Object, the output is also an Object.
// Here, we're passing a single tensor, so the output is an array.
const probabilities = runWithTfjsTensors(model, imageData)[0];
// Get the top five classes.
return tf.topk(probabilities, 5);
});
const values = await top5.values.data();
const indices = await top5.indices.data();
top5.values.dispose(); // Clean up the tfjs tensors.
top5.indices.dispose();
// Print the top five classes.
const classes = ... // Class names are loaded from a JSON file in the demo.
for (let i = 0; i < 5; ++i) {
const text = `${classes[indices[i]]}: ${values[i]}`;
console.log(text);
}
Kiểm tra và khắc phục sự cố
Hãy tham khảo các phần sau đây để biết cách kiểm thử ứng dụng và xử lý lỗi.
Kiểm thử bằng dữ liệu đầu vào giả
Sau khi tải một mô hình, bạn nên kiểm thử mô hình bằng các dữ liệu đầu vào giả trước. Điều này sẽ phát hiện mọi lỗi thời gian chạy trước khi bạn dành thời gian viết logic xử lý trước và sau cho quy trình mô hình của mình. Để kiểm tra điều này, bạn có thể sử dụng Trình kiểm thử mô hình LiteRT.js hoặc kiểm thử theo cách thủ công.
Trình kiểm thử mô hình LiteRT.js
Trình kiểm thử mô hình LiteRT.js chạy mô hình của bạn trên GPU và CPU bằng cách sử dụng các đầu vào ngẫu nhiên để xác minh rằng mô hình chạy chính xác trên GPU. Công cụ này kiểm tra những điều sau:
- Loại dữ liệu đầu vào và đầu ra có được hỗ trợ hay không.
- Liệu tất cả các thao tác có sẵn trên GPU hay không.
- Mức độ trùng khớp giữa đầu ra của GPU và đầu ra của CPU tham chiếu.
- Hiệu suất của suy luận GPU.
Để chạy Trình kiểm thử mô hình LiteRT.js, hãy chạy npm i @litertjs/model-tester
rồi chạy npx model-tester
. Thao tác này sẽ mở một thẻ trình duyệt để bạn chạy mô hình.
Kiểm thử mô hình theo cách thủ công
Nếu muốn kiểm thử mô hình theo cách thủ công thay vì sử dụng trình kiểm thử mô hình LiteRT.js (@litertjs/model-tester
), bạn có thể tạo dữ liệu đầu vào giả và chạy mô hình bằng runWithTfjsTensors
.
Để tạo dữ liệu đầu vào giả, bạn cần biết tên và hình dạng của các tensor đầu vào. Bạn có thể tìm thấy những thông tin này bằng LiteRT.js bằng cách gọi model.getInputDetails
hoặc model.getOutputDetails
. Cách đơn giản để tìm thấy chúng là đặt một điểm ngắt sau khi mô hình được tạo. Hoặc sử dụng Trình khám phá mô hình.
Sau khi biết tên và hình dạng đầu vào và đầu ra, bạn có thể kiểm thử mô hình bằng một đầu vào giả. Điều này giúp bạn tin tưởng rằng mô hình sẽ chạy trước khi bạn viết phần còn lại của quy trình học máy. Thao tác này sẽ kiểm thử để đảm bảo rằng tất cả các thao tác trên mô hình đều được hỗ trợ. Ví dụ:
// Imports, initialization, and model loading...
// Create fake inputs for the model
const fakeInputs = model.getInputDetails().map(
({shape, dtype}) => tf.ones(shape, dtype));
// Run the model
const outputs = runWithTfjsTensors(model, fakeInputs);
console.log(outputs);
Các loại lỗi
LiteRT.js có thể không hỗ trợ một số mô hình LiteRT. Các lỗi thường thuộc các danh mục sau:
- Shape Mismatch (Hình dạng không khớp): Một lỗi đã biết chỉ ảnh hưởng đến GPU.
- Thao tác không được hỗ trợ: Thời gian chạy không hỗ trợ một thao tác trong mô hình. Phần phụ trợ WebGPU có phạm vi hạn chế hơn so với CPU. Vì vậy, nếu gặp lỗi này trên GPU, bạn có thể chạy mô hình trên CPU.
- Loại Tensor không được hỗ trợ: LiteRT.js chỉ hỗ trợ các tensor int32 và float32 cho đầu vào và đầu ra của mô hình.
- Mô hình quá lớn: LiteRT.js có giới hạn về kích thước của các mô hình mà nó có thể tải.
Thao tác không được hỗ trợ
Điều này cho biết rằng phần phụ trợ đang được sử dụng không hỗ trợ một trong các thao tác trong mô hình. Bạn sẽ cần viết lại mô hình PyTorch ban đầu để tránh thao tác này và chuyển đổi lại, hoặc bạn có thể chạy mô hình trên CPU.
Trong trường hợp BROADCAST_TO
, bạn có thể giải quyết vấn đề này bằng cách đặt kích thước lô giống nhau cho mọi tensor đầu vào của mô hình. Các trường hợp khác có thể phức tạp hơn.
Loại tensor không được hỗ trợ
LiteRT.js chỉ hỗ trợ các tensor int32 và float32 cho đầu vào và đầu ra của mô hình.
Mô hình quá lớn
Lỗi này thường xuất hiện dưới dạng lệnh gọi đến Aborted()
hoặc lỗi phân bổ bộ nhớ tại thời điểm tải mô hình. LiteRT.js có giới hạn về kích thước của các mô hình mà nó có thể tải. Vì vậy, nếu bạn thấy thông báo này, thì có thể mô hình của bạn quá lớn. Bạn có thể thử lượng tử hoá các trọng số bằng ai-edge-quantizer, nhưng vẫn giữ các phép tính ở float32 hoặc float16, cũng như đầu vào và đầu ra của mô hình ở float32 hoặc int32.