Cấu hình TensorFlow Lite với Backend NPU cho Raspberry Pi CM5
Để khai thác sức mạnh của Neural Processing Unit (NPU) trên Raspberry Pi CM5, chúng ta cần biên dịch TensorFlow Lite (TFLite) từ nguồn với các delegate (trình xử lý) cụ thể cho kiến trúc Arm. Thư viện mặc định của TFLite chỉ chạy trên CPU, do đó bước này là bắt buộc để đạt hiệu suất Edge.
Trước tiên, hãy clone repository chính thức của TensorFlow và cấu hình để hỗ trợ Arm Compute Library (ACL) backend, đây là backend chuẩn cho NPU trên các dòng Raspberry Pi mới.
cd ~
git clone --recursive https://github.com/tensorflow/tensorflow.git
cd tensorflow
git checkout v2.15.0
Phía sau: Bạn sẽ thấy thư mục tensorflow được tải về với đầy đủ các submodule cần thiết cho việc build cross-compile.
Tiếp theo, ta cần thiết lập môi trường build toolchain cho kiến trúc ARM64 (aarch64) của CM5. Sử dụng Docker container hoặc toolchain đã cài đặt sẵn từ Phần 1 để tránh xung đột thư viện trên host.
export TF_ENABLE_XLA=1
export TF_LITE_ENABLE_NPU=1
export TARGET_ARCH=aarch64
export CROSS_COMPILE=arm-linux-gnueabihf-
# Nếu dùng cross-compile toolchain từ Phần 1, đảm bảo nó nằm trong $PATH
Phía sau: Các biến môi trường này sẽ báo cho script build của TensorFlow biết rằng chúng ta đang biên dịch cho kiến trúc ARM và cần bật tính năng NPU.
Bắt đầu quá trình build TFLite runtime với các flag tối ưu cho Edge. Chúng ta sẽ dùng Bazel để biên dịch static library để giảm kích thước binary và tăng tốc độ khởi tạo.
bazel build -c opt \
--config=rpi4 \
--define tflite_with_xla=true \
--define tflite_with_npu=true \
--copt=-O3 \
//tensorflow/lite/tools/make:libtensorflowlite_c \
//tensorflow/lite/tools/make:libtensorflowlite_c_with_xnnpack
Phía sau: Bazel sẽ thực hiện biên dịch. Nếu thành công, bạn sẽ thấy thông báo "INFO: Build succeeded" và các file .a (static library) nằm trong thư mục bazel-bin.
Copy các thư viện đã biên dịch sang thư mục hệ thống để ứng dụng có thể link vào.
cp bazel-bin/tensorflow/lite/tools/make/libtensorflowlite_c.a /usr/local/lib/
cp bazel-bin/tensorflow/lite/tools/make/libtensorflowlite_c_with_xnnpack.a /usr/local/lib/
cp tensorflow/lite/c/c_api.h /usr/local/include/
cp tensorflow/lite/c/c_api_experimental.h /usr/local/include/
ldconfig
Phía sau: Thư viện TFLite đã được cài đặt toàn cục. Command `ldconfig` cập nhật cache của linker để hệ thống nhận diện thư viện mới ngay lập tức.
Verify kết quả phần 1
Để xác minh TFLite đã được build đúng với hỗ trợ NPU, hãy kiểm tra xem symbol của NPU delegate có tồn tại trong binary không.
nm /usr/local/lib/libtensorflowlite_c.a | grep -i "npu"
Phía sau: Nếu thấy các dòng symbol liên quan đến "npu_delegate" hoặc "acl", chứng tỏ backend NPU đã được tích hợp thành công.
Cài đặt và Cấu hình ONNX Runtime cho GPU/NPU
Build ONNX Runtime từ Source cho Edge
ONNX Runtime cung cấp khả năng chạy các model đa dạng hơn so với TFLite. Để tận dụng GPU (Mali) hoặc NPU trên CM5, ta không thể dùng wheel package từ PyPI mà phải biên dịch từ source với các backend cụ thể.
cd ~
git clone --recursive https://github.com/microsoft/onnxruntime.git
cd onnxruntime
git checkout v1.16.0
Phía sau: Repository ONNX Runtime được tải về. Phiên bản v1.16.0 là bản ổn định hỗ trợ tốt cho các kiến trúc Arm mới.
Cấu hình CMake để build ONNX Runtime với các tùy chọn: sử dụng Arm Compute Library (ACL) cho NPU và GPU, đồng thời tắt các backend không cần thiết để giảm kích thước.
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release \
-Donnxruntime_build_ai_dnn_provider=ON \
-Donnxruntime_enable_acl=ON \
-Donnxruntime_enable_acl_fp16=ON \
-Donnxruntime_enable_acl_fp32=ON \
-Donnxruntime_enable_ep_transformations=ON \
-Donnxruntime_minimal_build=ON \
-DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/arm-linux-gnueabihf.cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local \
..
Phía sau: CMake sẽ parse các tùy chọn. Thông báo "Configuring done" và "Generating done" xuất hiện mà không có lỗi là dấu hiệu thành công.
Bắt đầu build và install thư viện ONNX Runtime.
make -j$(nproc)
make install
Phía sau: Quá trình build sẽ tạo ra thư viện C++ và Python wrapper. Sau khi `make install` xong, thư viện sẽ nằm ở /usr/local/lib và /usr/local/include.
Thiết lập Environment Variables cho Delegate
ONNX Runtime cần biết chính xác phần cứng nào được sử dụng thông qua biến môi trường. Trên CM5, ta cần chỉ định sử dụng Arm NN backend (thường là NPU hoặc GPU).
export ORT_ROCM_VISIBLE_DEVICES=""
export ORT_OPENVINO_VISIBLE_DEVICES=""
export ORT_ACCELERATOR="acl"
export ONNXRUNTIME_ENABLE_ARM_NN=1
Phía sau: Các biến này sẽ được hệ thống đọc khi khởi tạo ONNX Runtime session, buộc engine ưu tiên sử dụng NPU/GPU thay vì CPU.
Verify kết quả phần 2
Kiểm tra xem ONNX Runtime có nhận diện được Arm NN backend hay không bằng script Python nhỏ.
python3 -c "import onnxruntime as ort; providers = ort.get_available_providers(); print('Available providers:', providers); print('Has ACL:', 'ACL' in providers or 'ArmNN' in providers)"
Phía sau: Output phải hiển thị 'ACL' hoặc 'ArmNN' trong danh sách available providers. Nếu chỉ thấy 'CPUExecutionProvider', quá trình cấu hình backend chưa thành công.
Biên dịch Model AI sang Định dạng Tối ưu cho Edge
Chuyển đổi Model sang TFLite Flatbuffer
Model huấn luyện sẵn (thường là .pb hoặc .h5) cần được chuyển đổi sang định dạng .tflite (flatbuffer) để giảm overhead khi load và tối ưu hóa inference. Quan trọng nhất là phải bật quantization (lượng tử hóa) để NPU có thể xử lý hiệu quả.
pip3 install tensorflow-lite-model-optimization
Phía sau: Cài đặt công cụ tối ưu hóa model của TensorFlow. Đảm bảo package này tương thích với phiên bản TFLite đã build ở phần 1.
Sử dụng script Python để convert model với tùy chọn `experimental_new_quantized_ops=True` và `per_tensor_quantization` để hỗ trợ NPU tốt hơn.
python3
Phía sau: File `model_quantized_npu.tflite` được tạo ra. Kích thước file thường nhỏ hơn file gốc đáng kể do đã được lượng tử hóa.
Chuyển đổi Model sang ONNX và Tối ưu
Đối với các model phức tạp hơn, định dạng ONNX thường linh hoạt hơn. Ta cần convert từ PyTorch/Keras sang ONNX, sau đó dùng tool `onnx-simplifier` để làm sạch graph trước khi đưa vào runtime.
pip3 install onnx onnx-simplifier torch torchvision
Phía sau: Cài đặt các thư viện cần thiết để export và tối ưu model ONNX.
Script Python để export model PyTorch sang ONNX và tối ưu hóa graph.
python3
Phía sau: File `model_optimized.onnx` được tạo ra. Graph đã được làm sạch, loại bỏ các node không cần thiết, giúp ONNX Runtime load nhanh hơn và giảm memory usage.
Verify kết quả phần 3
Đảm bảo file model mới tạo ra không bị lỗi cú pháp bằng công cụ kiểm tra của ONNX hoặc TFLite.
python3 -c "import onnx; onnx.checker.check_model('model_optimized.onnx'); print('ONNX model is valid')"
python3 -c "import tensorflow as tf; interpreter = tf.lite.Interpreter(model_path='model_quantized_npu.tflite'); print('TFLite model loaded successfully')"
Phía sau: Cả hai lệnh đều chạy không lỗi và in ra thông báo xác nhận. Nếu có lỗi, quá trình conversion cần được kiểm tra lại.
Kiểm tra Khả năng Tải Model và Inference qua API
Test Inference với Python (TFLite)
Viết script Python để load model TFLite đã được tối ưu và chạy inference, đảm bảo rằng backend NPU được kích hoạt đúng cách.
python3
Phía sau: Script chạy và in ra thời gian inference. Nếu NPU hoạt động, thời gian trung bình (latency) sẽ thấp hơn đáng kể so với khi chạy trên CPU thuần. Nếu không load được delegate, script sẽ báo lỗi hoặc chạy chậm (CPU mode).
Test Inference với C++ (ONNX Runtime)
Viết code C++ để test ONNX Runtime, đảm bảo rằng backend ACL (NPU/GPU) được sử dụng. Đây là bước quan trọng cho các ứng dụng embedded performance-critical.
cat > test_onnx.cpp
Phía sau: File `test_onnx.cpp` được tạo sẵn với logic test đầy đủ.
Biên dịch file C++ và link với thư viện ONNX Runtime đã cài đặt.
g++ -std=c++17 -O3 -I/usr/local/include/onnxruntime test_onnx.cpp -L/usr/local/lib -lonnxruntime -lpthread -o test_onnx
Phía sau: Compiler tạo ra file binary `test_onnx` không có lỗi liên quan đến thư viện.
Chạy file binary để kiểm tra hiệu năng thực tế.
LD_LIBRARY_PATH=/usr/local/lib ./test_onnx
Phía sau: Chương trình chạy và in ra thời gian inference. Nếu ArmNN/NPU hoạt động, latency sẽ ở mức thấp (ví dụ: < 5ms tùy model). Nếu thấy thông báo lỗi "Provider not found", cần kiểm tra lại bước cài đặt ONNX Runtime.
Verify kết quả phần 4
So sánh hiệu năng giữa chạy trên CPU và NPU bằng cách tắt delegate trong script Python để có số liệu đối chứng.
python3 -c "import tensorflow as tf; interpreter = tf.lite.Interpreter(model_path='model_quantized_npu.tflite'); interpreter.allocate_tensors(); print('CPU Mode loaded. Run without NPU delegate to compare.' )"
Phía sau: Khi chạy script test không có `experimental_delegates`, thời gian inference sẽ tăng lên đáng kể (có thể gấp 5-10 lần), chứng tỏ việc tích hợp NPU ở các bước trước là thành công.
Điều hướng series:
Mục lục: Series: Tối ưu hóa Linux Kernel cho Raspberry Pi CM5 để chạy AI Edge
« Phần 3: Xây dựng Device Tree và Driver cho CM5
Phần 5: Tối ưu hiệu năng và đo lường thông số thực tế »