Đại diện GPU cho TensorFlow Lite

Việc sử dụng đơn vị xử lý đồ hoạ (GPU) để chạy các mô hình học máy (ML) có thể cải thiện đáng kể hiệu suất của mô hình và trải nghiệm người dùng của các ứng dụng hỗ trợ ML. TensorFlow Lite cho phép sử dụng GPU và các bộ xử lý chuyên biệt khác thông qua trình điều khiển phần cứng có tên là uỷ quyền. Việc cho phép sử dụng GPU với ứng dụng học máy TensorFlow Lite có thể mang lại những lợi ích sau:

  • Tốc độ – GPU được xây dựng cho thông lượng cao của các tải công việc song song cực lớn. Thiết kế này khiến chúng phù hợp với mạng nơron sâu, bao gồm một số lượng lớn toán tử, mỗi toán tử hoạt động trên các tensor đầu vào có thể được xử lý song song, thường dẫn đến độ trễ thấp hơn. Trong trường hợp tốt nhất, việc chạy mô hình của bạn trên GPU có thể chạy đủ nhanh để bật các ứng dụng theo thời gian thực mà trước đây không làm được.
  • Hiệu suất năng lượng – GPU thực hiện các phép tính học máy theo cách rất hiệu quả và tối ưu hoá, thường tiêu thụ ít năng lượng hơn và tạo ít nhiệt hơn so với cùng một tác vụ chạy trên CPU.

Tài liệu này trình bày thông tin tổng quan về việc hỗ trợ GPU trong TensorFlow Lite và một số cách sử dụng nâng cao cho bộ xử lý GPU. Để biết thông tin cụ thể hơn về cách triển khai tính năng hỗ trợ GPU trên các nền tảng cụ thể, hãy xem các hướng dẫn sau:

Hỗ trợ hoạt động GPU ML

Có một số giới hạn đối với những thao tác học máy TensorFlow, hay hoạt động, có thể được tăng tốc bằng uỷ quyền GPU TensorFlow Lite. Phương thức uỷ quyền hỗ trợ các hoạt động sau với độ chính xác của độ chính xác đơn 16 bit và 32 bit:

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • LOGISTIC
  • LSTM v2 (Basic LSTM only)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

Theo mặc định, tất cả hoạt động chỉ được hỗ trợ ở phiên bản 1. Việc bật tính năng hỗ trợ lượng tử hoá sẽ kích hoạt các phiên bản phù hợp, ví dụ: ADD phiên bản 2.

Khắc phục sự cố khi hỗ trợ GPU

Nếu một số hoạt động không được tính năng uỷ quyền GPU hỗ trợ, thì khung sẽ chỉ chạy một phần của biểu đồ trên GPU và phần còn lại trên CPU. Do chi phí đồng bộ hoá CPU/GPU cao, chế độ thực thi phân tách như thế này thường dẫn đến hiệu suất chậm hơn so với khi toàn bộ mạng chỉ chạy trên CPU. Trong trường hợp này, ứng dụng sẽ tạo cảnh báo, chẳng hạn như:

WARNING: op code #42 cannot be handled by this delegate.

Không có lệnh gọi lại cho các lỗi thuộc loại này vì đây không phải là lỗi thời gian chạy thực tế. Khi kiểm thử việc thực thi mô hình bằng tính năng uỷ quyền GPU, bạn nên cảnh báo về những cảnh báo này. Một số lượng lớn các cảnh báo như vậy có thể cho biết rằng mô hình của bạn không phải là lựa chọn phù hợp nhất để sử dụng tính năng tăng tốc GPU, và có thể cần phải tái cấu trúc mô hình.

Mô hình mẫu

Các mô hình mẫu sau đây được xây dựng để tận dụng tính năng tăng tốc GPU bằng TensorFlow Lite và được cung cấp để tham khảo và kiểm thử:

Tối ưu hoá cho GPU

Các kỹ thuật sau đây có thể giúp bạn đạt được hiệu suất tốt hơn khi chạy các mô hình trên phần cứng GPU bằng cách sử dụng uỷ quyền GPU TensorFlow Lite:

  • Định hình lại các thao tác – Một số thao tác diễn ra nhanh trên CPU có thể tiêu tốn nhiều tài nguyên cho GPU trên thiết bị di động. Các thao tác đổi hình dạng sẽ đặc biệt tốn kém khi chạy, bao gồm cả BATCH_TO_SPACE, SPACE_TO_BATCH, SPACE_TO_DEPTH, v.v. Bạn nên kiểm tra kỹ việc sử dụng các thao tác định hình lại và xem xét rằng thao tác này có thể chỉ được áp dụng để khám phá dữ liệu hoặc cho các lần lặp lại đầu tiên của mô hình. Việc xoá các bộ lọc đó có thể cải thiện đáng kể hiệu suất.

  • Kênh dữ liệu hình ảnh – Trên GPU, dữ liệu tensor được chia thành 4 kênh, do đó, một phép tính trên tensor có hình dạng [B,H,W,5] hoạt động tương tự như trên một tensor có hình dạng [B,H,W,8], nhưng kém hơn đáng kể so với [B,H,W,4]. Nếu phần cứng máy ảnh bạn đang sử dụng hỗ trợ khung hình ảnh trong RGBA, thì việc cấp dữ liệu đầu vào 4 kênh đó sẽ nhanh hơn đáng kể vì phần cứng này giúp tránh việc sao chép bộ nhớ từ RGB 3 kênh sang RGBX 4 kênh.

  • Mô hình được tối ưu hoá cho thiết bị di động – Để có hiệu suất tốt nhất, bạn nên cân nhắc huấn luyện lại thuật toán phân loại bằng kiến trúc mạng được tối ưu hoá cho thiết bị di động. Hoạt động tối ưu hoá cho tính năng dự đoán trên thiết bị có thể giúp giảm đáng kể độ trễ và mức tiêu thụ pin bằng cách tận dụng các tính năng phần cứng dành cho thiết bị di động.

Hỗ trợ GPU nâng cao

Bạn có thể sử dụng các kỹ thuật bổ sung, nâng cao có xử lý GPU để mang lại hiệu suất tốt hơn nữa cho các mô hình, bao gồm cả việc lượng tử hoá và chuyển đổi tuần tự. Các phần sau đây sẽ mô tả chi tiết hơn về những kỹ thuật này.

Sử dụng mô hình lượng tử hoá

Phần này giải thích cách tính năng uỷ quyền GPU tăng tốc các mô hình lượng tử hoá 8 bit, bao gồm:

Để tối ưu hoá hiệu suất, hãy sử dụng các mô hình có cả tensor đầu vào và đầu ra dạng dấu phẩy động.

Cơ chế này hoạt động như thế nào?

Vì phần phụ trợ GPU chỉ hỗ trợ thực thi dấu phẩy động, nên chúng tôi chạy các mô hình lượng tử hoá bằng cách cho nó "khung hiển thị dấu phẩy động" của mô hình gốc. Ở cấp độ cao, bạn cần thực hiện các bước sau:

  • Các tensor hằng số (chẳng hạn như trọng số/độ lệch) được khử lượng tử một lần vào bộ nhớ GPU. Thao tác này xảy ra khi bạn bật tính năng uỷ quyền cho TensorFlow Lite.

  • Các đầu vào và đầu ra cho chương trình GPU, nếu được lượng tử hoá 8 bit, sẽ được khử lượng tử và lượng tử hoá (tương ứng) cho mỗi lần suy luận. Thao tác này được thực hiện trên CPU bằng cách sử dụng các nhân được tối ưu hoá của TensorFlow Lite.

  • Trình mô phỏng lượng tử hoá được chèn giữa các thao tác để bắt chước hành vi lượng tử hoá. Phương pháp này là cần thiết đối với các mô hình mà hoạt động dự kiến sẽ kích hoạt theo các giới hạn đã học được trong quá trình lượng tử hoá.

Để biết thông tin về cách bật tính năng này bằng tính năng uỷ quyền GPU, hãy xem các nội dung sau:

Giảm thời gian khởi chạy bằng tính năng chuyển đổi tuần tự

Tính năng uỷ quyền GPU cho phép bạn tải từ mã nhân hệ điều hành được biên dịch trước và dữ liệu mô hình được chuyển đổi tuần tự cũng như lưu trên ổ đĩa từ các lần chạy trước. Phương pháp này giúp tránh biên dịch lại và có thể giảm tới 90% thời gian khởi động. Cải tiến này được thực hiện bằng cách trao đổi dung lượng ổ đĩa để tiết kiệm thời gian. Bạn có thể bật tính năng này bằng một số lựa chọn cấu hình, như trong các mã ví dụ sau đây:

C++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Java

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

Khi sử dụng tính năng chuyển đổi tuần tự, hãy đảm bảo mã của bạn tuân thủ các quy tắc triển khai sau:

  • Lưu trữ dữ liệu chuyển đổi tuần tự trong một thư mục mà các ứng dụng khác không thể truy cập được. Trên thiết bị Android, hãy sử dụng getCodeCacheDir() trỏ đến một vị trí riêng tư của ứng dụng hiện tại.
  • Mã thông báo kiểu máy phải là mã duy nhất cho thiết bị của kiểu máy cụ thể. Bạn có thể tính toán mã thông báo mô hình bằng cách tạo vân tay số từ dữ liệu mô hình thông qua các thư viện như farmhash::Fingerprint64.