Trang này cung cấp thông tin tổng quan về cách triển khai trình điều khiển Neural Networks API (NNAPI). Để biết thêm thông tin chi tiết, hãy xem tài liệu có trong các tệp định nghĩa HAL trong hardware/interfaces/neuralnetworks
.
Quá trình triển khai trình điều khiển mẫu nằm trong frameworks/ml/nn/driver/sample
.
Để biết thêm thông tin về Neural Networks API, hãy xem bài viết về Neural Networks API.
HAL mạng nơron
HAL Mạng nơron (NN) định nghĩa khái quát hoá nhiều thiết bị, chẳng hạn như đơn vị xử lý đồ hoạ (GPU) và bộ xử lý tín hiệu kỹ thuật số (DSP) có trong một sản phẩm (ví dụ: điện thoại hoặc máy tính bảng). Trình điều khiển cho các thiết bị này phải tuân thủ NN HAL. Giao diện được chỉ định trong các tệp định nghĩa HAL trong hardware/interfaces/neuralnetworks
.
Quy trình chung của giao diện giữa khung và trình điều khiển được mô tả trong hình 1.
Hình 1. Luồng mạng nơron
Khởi chạy
Khi khởi chạy, khung này sẽ truy vấn trình điều khiển về các chức năng của khung bằng cách sử dụng IDevice::getCapabilities_1_3
.
Cấu trúc @1.3::Capabilities
bao gồm tất cả các loại dữ liệu và biểu thị hiệu suất không thư giãn bằng một vectơ.
Để xác định cách phân bổ các phép tính cho các thiết bị có sẵn, khung này sử dụng các chức năng để hiểu tốc độ và mức tiết kiệm năng lượng của từng trình điều khiển khi thực thi. Để cung cấp thông tin này, trình điều khiển phải cung cấp các con số hiệu suất được chuẩn hoá dựa trên việc thực thi khối lượng công việc tham chiếu.
Để xác định các giá trị mà trình điều khiển trả về để phản hồi IDevice::getCapabilities_1_3
, hãy sử dụng ứng dụng điểm chuẩn NNAPI để đo lường hiệu suất cho các loại dữ liệu tương ứng. Bạn nên sử dụng các mô hình MobileNet v1 và v2, asr_float
và tts_float
để đo lường hiệu suất cho các giá trị dấu phẩy động 32 bit và các mô hình lượng tử hoá MobileNet v1 và v2 cho các giá trị lượng tử hoá 8 bit. Để biết thêm thông tin, hãy xem bài viết Bộ kiểm thử học máy Android.
Trong Android 9 trở xuống, cấu trúc Capabilities
chỉ bao gồm thông tin về hiệu suất trình điều khiển cho tensor dấu phẩy động và lượng tử hoá, đồng thời không bao gồm các loại dữ liệu vô hướng.
Trong quá trình khởi chạy, khung có thể truy vấn thêm thông tin, bằng cách sử dụng IDevice::getType
, IDevice::getVersionString
, IDevice:getSupportedExtensions
và IDevice::getNumberOfCacheFilesNeeded
.
Giữa các lần khởi động lại sản phẩm, khung sẽ yêu cầu tất cả các truy vấn được mô tả trong phần này luôn báo cáo cùng một giá trị cho một trình điều khiển nhất định. Nếu không, một ứng dụng dùng trình điều khiển đó có thể bị giảm hiệu suất hoặc có hành vi không chính xác.
Biên dịch
Khung này xác định sẽ sử dụng thiết bị nào khi nhận được yêu cầu từ một ứng dụng. Trong Android 10, các ứng dụng có thể khám phá và chỉ định các thiết bị mà khung này chọn. Để biết thêm thông tin, hãy xem bài viết Khám phá và chỉ định thiết bị.
Tại thời điểm biên dịch mô hình, khung sẽ gửi mô hình cho từng trình điều khiển đề xuất bằng cách gọi IDevice::getSupportedOperations_1_3
.
Mỗi trình điều khiển trả về một mảng boolean cho biết toán tử nào của mô hình được hỗ trợ. Trình điều khiển có thể xác định rằng không thể hỗ trợ một thao tác nhất định vì một số lý do. Ví dụ:
- Trình điều khiển không hỗ trợ loại dữ liệu.
- Trình điều khiển chỉ hỗ trợ các thao tác có tham số đầu vào cụ thể. Ví dụ: trình điều khiển có thể hỗ trợ các phép toán tích chập 3x3 và 5x5, nhưng không hỗ trợ các phép toán tích chập 7x7.
- Trình điều khiển có các quy tắc ràng buộc về bộ nhớ khiến trình điều khiển không thể xử lý các biểu đồ hoặc dữ liệu đầu vào lớn.
Trong quá trình biên dịch, toán hạng đầu vào, đầu ra và nội bộ của mô hình, như mô tả trong OperandLifeTime
, có thể có kích thước hoặc thứ hạng không xác định. Để biết thêm thông tin, hãy xem phần Hình dạng đầu ra.
Khung này sẽ hướng dẫn từng trình điều khiển đã chọn chuẩn bị thực thi một tập hợp con của mô hình bằng cách gọi IDevice::prepareModel_1_3
.
Sau đó, mỗi trình điều khiển sẽ biên dịch tập hợp con của trình điều khiển đó. Ví dụ: trình điều khiển có thể tạo mã hoặc tạo bản sao trọng số được sắp xếp lại. Vì có thể có một khoảng thời gian đáng kể từ lúc biên dịch mô hình đến khi thực thi yêu cầu, nên bạn không nên chỉ định các tài nguyên như các phần lớn bộ nhớ thiết bị trong quá trình biên dịch.
Nếu thành công, trình điều khiển sẽ trả về một tay điều khiển @1.3::IPreparedModel
. Nếu trình điều khiển trả về mã lỗi khi chuẩn bị tập hợp con của mô hình, thì khung sẽ chạy toàn bộ mô hình trên CPU.
Để giảm thời gian biên dịch khi một ứng dụng khởi động, trình điều khiển có thể lưu các cấu phần phần mềm biên dịch vào bộ nhớ đệm. Để biết thêm thông tin, hãy xem phần Lưu vào bộ nhớ đệm biên dịch.
Thực thi
Khi một ứng dụng yêu cầu khung thực thi một yêu cầu, theo mặc định, khung này sẽ gọi phương thức HAL IPreparedModel::executeSynchronously_1_3
để thực hiện quá trình thực thi đồng bộ trên một mô hình đã chuẩn bị.
Bạn cũng có thể thực thi không đồng bộ yêu cầu bằng phương thức execute_1_3
, phương thức executeFenced
(xem phần Thực thi được bảo vệ) hoặc được thực thi bằng cách sử dụng thực thi hàng loạt.
Lệnh gọi thực thi đồng bộ cải thiện hiệu suất và giảm hao tổn khi tạo luồng so với lệnh gọi không đồng bộ vì quyền kiểm soát chỉ được trả về cho quy trình ứng dụng sau khi quá trình thực thi hoàn tất. Điều này có nghĩa là trình điều khiển không cần một cơ chế riêng để thông báo cho quy trình ứng dụng rằng quá trình thực thi đã hoàn tất.
Với phương thức execute_1_3
không đồng bộ, quyền kiểm soát sẽ quay lại quy trình ứng dụng sau khi quá trình thực thi bắt đầu và trình điều khiển phải thông báo cho khung khi quá trình thực thi hoàn tất bằng cách sử dụng @1.3::IExecutionCallback
.
Tham số Request
được truyền đến phương thức thực thi liệt kê các toán hạng đầu vào và đầu ra được dùng để thực thi. Bộ nhớ lưu trữ dữ liệu toán hạng phải sử dụng thứ tự hàng chính với phương diện đầu tiên lặp lại chậm nhất và không có khoảng đệm ở cuối bất kỳ hàng nào. Để biết thêm thông tin về các loại toán hạng, hãy xem phần Toán hạng.
Đối với trình điều khiển NN HAL 1.2 trở lên, khi một yêu cầu hoàn tất, trạng thái lỗi, hình dạng đầu ra và thông tin về thời gian sẽ được trả về khung. Trong quá trình thực thi, các toán hạng đầu ra hoặc nội bộ của mô hình có thể có một hoặc nhiều chiều chưa biết hoặc thứ hạng không xác định. Khi ít nhất một toán hạng đầu ra có thứ hạng hoặc phương diện không xác định, trình điều khiển phải trả về thông tin đầu ra có kích thước động.
Đối với trình điều khiển có NN HAL 1.1 trở xuống, hệ thống chỉ trả về trạng thái lỗi khi một yêu cầu hoàn tất. Kích thước cho các toán hạng đầu vào và đầu ra phải được chỉ định đầy đủ để quá trình thực thi hoàn tất thành công. Toán hạng nội bộ có thể có một hoặc nhiều chiều chưa biết, nhưng phải chỉ định thứ hạng.
Đối với các yêu cầu của người dùng trải rộng trên nhiều trình điều khiển, khung chịu trách nhiệm dành riêng bộ nhớ trung gian và sắp xếp trình tự các lệnh gọi đến từng trình điều khiển.
Bạn có thể khởi tạo nhiều yêu cầu song song trên cùng một @1.3::IPreparedModel
.
Trình điều khiển có thể thực thi các yêu cầu song song hoặc tuần tự hoá các lần thực thi.
Khung này có thể yêu cầu người lái xe giữ lại nhiều mô hình đã chuẩn bị. Ví dụ: chuẩn bị mô hình m1
, chuẩn bị m2
, thực thi yêu cầu r1
trên m1
, thực thi r2
trên m2
, thực thi r3
trên m1
, thực thi r4
trên m2
, phát hành (được mô tả trong phần Dọn dẹp) m1
và phát hành m2
.
Để tránh việc thực thi lần đầu bị chậm có thể dẫn đến trải nghiệm người dùng kém (ví dụ: kết xuất khung hình đầu tiên bị gián đoạn), trình điều khiển nên thực hiện hầu hết các thao tác khởi chạy trong giai đoạn biên dịch. Việc khởi chạy trong lần thực thi đầu tiên phải được giới hạn ở các thao tác ảnh hưởng tiêu cực đến tình trạng hệ thống khi được thực hiện sớm, chẳng hạn như đặt trước bộ đệm tạm thời lớn hoặc tăng tốc độ xung nhịp của thiết bị. Các trình điều khiển chỉ có thể chuẩn bị một số lượng mô hình đồng thời có hạn có thể phải khởi chạy lần đầu.
Trong Android 10 trở lên, trong trường hợp nhiều quá trình thực thi với cùng một mô hình đã chuẩn bị được thực thi liên tiếp nhanh chóng, ứng dụng có thể chọn sử dụng đối tượng luồng thực thi để giao tiếp giữa các quy trình ứng dụng và trình điều khiển. Để biết thêm thông tin, hãy xem phần Thực thi theo đợt và hàng đợi thông báo nhanh.
Để cải thiện hiệu suất cho nhiều lần thực thi liên tiếp, trình điều khiển có thể giữ lại vùng đệm tạm thời hoặc tăng tốc độ xung nhịp. Bạn nên tạo luồng theo dõi để giải phóng tài nguyên nếu không có yêu cầu mới nào được tạo sau một khoảng thời gian cố định.
Hình dạng đầu ra
Đối với các yêu cầu mà một hoặc nhiều toán hạng đầu ra không có tất cả các kích thước được chỉ định, trình điều khiển phải cung cấp danh sách các hình dạng đầu ra chứa thông tin kích thước cho mỗi toán hạng đầu ra sau khi thực thi. Để biết thêm thông tin về các phương diện, hãy xem OutputShape
.
Nếu quá trình thực thi không thành công do bộ đệm đầu ra có kích thước nhỏ, thì trình điều khiển phải cho biết những toán hạng đầu ra nào có kích thước bộ đệm không đủ trong danh sách hình dạng đầu ra và phải báo cáo nhiều thông tin kích thước nhất có thể, sử dụng giá trị 0 cho các kích thước không xác định.
Thời gian
Trong Android 10, ứng dụng có thể yêu cầu thời gian thực thi nếu ứng dụng đã chỉ định một thiết bị duy nhất để sử dụng trong quá trình biên dịch. Để biết thông tin chi tiết, hãy xem MeasureTiming
và Khám phá và chỉ định thiết bị.
Trong trường hợp này, trình điều khiển NN HAL 1.2 phải đo lường thời lượng thực thi hoặc báo cáo UINT64_MAX
(để cho biết rằng không có thời lượng) khi thực thi một yêu cầu. Trình điều khiển sẽ giảm thiểu mọi mức ảnh hưởng về hiệu suất do việc đo lường thời lượng thực thi.
Trình điều khiển báo cáo các thời lượng sau đây tính bằng micrô giây trong cấu trúc Timing
:
- Thời gian thực thi trên thiết bị: Không bao gồm thời gian thực thi trong trình điều khiển chạy trên bộ xử lý máy chủ.
- Thời gian thực thi trong trình điều khiển: Bao gồm thời gian thực thi trên thiết bị.
Các khoảng thời gian này phải bao gồm thời gian thực thi bị tạm ngưng, ví dụ: khi thực thi bị các tác vụ khác chiếm quyền hoặc khi đang chờ tài nguyên có sẵn.
Khi chưa được yêu cầu đo lường thời lượng thực thi hoặc khi có lỗi thực thi thì trình điều khiển phải báo cáo thời lượng là UINT64_MAX
. Ngay cả khi được yêu cầu đo thời lượng thực thi, trình điều khiển vẫn có thể báo cáo UINT64_MAX
về thời gian trên thiết bị, thời gian trong trình điều khiển hoặc cả hai. Khi trình điều khiển báo cáo cả hai khoảng thời gian dưới dạng một giá trị khác với UINT64_MAX
, thời gian thực thi trong trình điều khiển phải bằng hoặc lớn hơn thời gian trên thiết bị.
Thực thi có bảo vệ
Trong Android 11, NNAPI cho phép các quá trình thực thi chờ danh sách các ô điều khiển sync_fence
và tuỳ ý trả về một đối tượng sync_fence
. Đối tượng này được báo hiệu khi quá trình thực thi hoàn tất. Điều này làm giảm mức hao tổn cho các mô hình trình tự nhỏ và trường hợp sử dụng truyền trực tuyến. Quá trình thực thi có bảo vệ cũng cho phép khả năng tương tác hiệu quả hơn với các thành phần khác có thể báo hiệu hoặc chờ sync_fence
. Để biết thêm thông tin về sync_fence
, hãy xem Khung đồng bộ hoá.
Trong quá trình thực thi có hàng rào, khung này sẽ gọi phương thức IPreparedModel::executeFenced
để khởi chạy quá trình thực thi không đồng bộ, có hàng rào trên một mô hình đã chuẩn bị với một vectơ hàng rào đồng bộ hoá để chờ. Nếu tác vụ không đồng bộ hoàn tất trước khi lệnh gọi trả về, thì hệ thống có thể trả về một tên người dùng trống cho sync_fence
. Bạn cũng phải trả về một đối tượng IFencedExecutionCallback
để cho phép khung truy vấn trạng thái lỗi và thông tin về thời lượng.
Sau khi quá trình thực thi hoàn tất, hệ thống có thể truy vấn hai giá trị thời gian sau đây để đo lường thời lượng thực thi thông qua IFencedExecutionCallback::getExecutionInfo
.
timingLaunched
: Thời lượng từ khiexecuteFenced
được gọi đến khiexecuteFenced
báo hiệu chosyncFence
được trả về.timingFenced
: Thời lượng từ khi tất cả hàng rào đồng bộ hoá mà quá trình thực thi đang chờ được báo hiệu khiexecuteFenced
báo hiệusyncFence
được trả về.
Luồng điều khiển
Đối với các thiết bị chạy Android 11 trở lên, NNAPI bao gồm hai toán tử luồng điều khiển, IF
và WHILE
, lấy các mô hình khác làm đối số và thực thi các mô hình đó theo điều kiện (IF
) hoặc lặp lại (WHILE
). Để biết thêm thông tin về cách triển khai điều này, hãy xem phần Luồng điều khiển.
Chất lượng dịch vụ
Trong Android 11, NNAPI giúp nâng cao chất lượng dịch vụ (QoS) bằng cách cho phép ứng dụng cho biết các mức độ ưu tiên tương đối của các mô hình, khoảng thời gian tối đa dự kiến cần để chuẩn bị một mô hình nhất định và thời lượng tối đa dự kiến cần để hoàn tất một phép tính nhất định. Để biết thêm thông tin, hãy xem bài viết Chất lượng dịch vụ.
Dọn dẹp
Khi một ứng dụng hoàn tất việc sử dụng mô hình đã chuẩn bị, khung sẽ phát hành tham chiếu đến đối tượng @1.3::IPreparedModel
. Khi đối tượng IPreparedModel
không còn được tham chiếu, đối tượng này sẽ tự động bị huỷ trong dịch vụ trình điều khiển đã tạo đối tượng đó. Tại thời điểm này, trong quá trình triển khai hàm huỷ, bạn có thể lấy lại các tài nguyên cụ thể của mô hình. Nếu dịch vụ trình điều khiển muốn đối tượng IPreparedModel
tự động bị huỷ khi không còn cần đến ứng dụng, thì dịch vụ đó không được chứa bất kỳ tham chiếu nào đến đối tượng IPreparedModel
sau khi đối tượng IPreparedeModel
được trả về thông qua IPreparedModelCallback::notify_1_3
.
Mức sử dụng CPU
Trình điều khiển dự kiến sẽ sử dụng CPU để thiết lập các phép tính. Trình điều khiển không nên sử dụng CPU để thực hiện các phép tính biểu đồ vì việc đó ảnh hưởng đến khả năng phân bổ công việc chính xác của khung. Trình điều khiển phải báo cáo các phần mà trình điều khiển không thể xử lý và để khung này xử lý phần còn lại.
Khung này cung cấp cách triển khai CPU cho tất cả các thao tác NNAPI, ngoại trừ các thao tác do nhà cung cấp xác định. Để biết thêm thông tin, hãy xem phần Tiện ích của nhà cung cấp.
Các toán tử được giới thiệu trong Android 10 (API cấp 29) chỉ triển khai CPU tham chiếu để xác minh rằng các kiểm thử CTS và VTS là chính xác. Bạn nên triển khai các phương thức tối ưu hoá có trong khung học máy dành cho thiết bị di động thay vì triển khai CPU NNAPI.
Hàm hiệu dụng
Cơ sở mã NNAPI bao gồm các hàm tiện ích mà các dịch vụ trình điều khiển có thể sử dụng.
Tệp frameworks/ml/nn/common/include/Utils.h
chứa nhiều hàm tiện ích, chẳng hạn như các hàm dùng để ghi nhật ký và chuyển đổi giữa các phiên bản NN HAL khác nhau.
VLogging:
VLOG
là một macro trình bao bọc xung quanhLOG
của Android, chỉ ghi nhật ký thông báo nếu thẻ thích hợp được đặt trong thuộc tínhdebug.nn.vlog
. Phải gọiinitVLogMask()
trước mọi lệnh gọi đếnVLOG
. Bạn có thể sử dụng macroVLOG_IS_ON
để kiểm tra xemVLOG
hiện đã được bật hay chưa, cho phép bỏ qua mã ghi nhật ký phức tạp nếu không cần thiết. Giá trị của thuộc tính phải là một trong những giá trị sau:- Một chuỗi trống cho biết không cần ghi nhật ký.
- Mã thông báo
1
hoặcall
, cho biết rằng đã hoàn tất toàn bộ quá trình ghi nhật ký. - Danh sách các thẻ, được phân tách bằng dấu cách, dấu phẩy hoặc dấu hai chấm, cho biết cần ghi nhật ký nào. Các thẻ đó là
compilation
,cpuexe
,driver
,execution
,manager
vàmodel
.
compliantWithV1_*
: Trả vềtrue
nếu có thể chuyển đổi đối tượng NN HAL sang cùng một loại phiên bản HAL khác mà không làm mất thông tin. Ví dụ: việc gọicompliantWithV1_0
trênV1_2::Model
sẽ trả vềfalse
nếu mô hình bao gồm các loại thao tác được giới thiệu trong NN HAL 1.1 hoặc NN HAL 1.2.convertToV1_*
: Chuyển đổi đối tượng NN HAL từ phiên bản này sang phiên bản khác. Một cảnh báo sẽ được ghi lại nếu lượt chuyển đổi dẫn đến việc mất thông tin (tức là nếu phiên bản mới của loại này không thể thể hiện đầy đủ giá trị).Chức năng: Bạn có thể sử dụng các hàm
nonExtensionOperandPerformance
vàupdate
để giúp tạo trườngCapabilities::operandPerformance
.Truy vấn thuộc tính thuộc các loại:
isExtensionOperandType
,isExtensionOperationType
,nonExtensionSizeOfData
,nonExtensionOperandSizeOfData
,nonExtensionOperandTypeIsScalar
,tensorHasUnspecifiedDimensions
.
Tệp frameworks/ml/nn/common/include/ValidateHal.h
chứa các hàm tiện ích để xác thực rằng đối tượng HAL NN là hợp lệ theo thông số kỹ thuật của phiên bản HAL.
validate*
: Trả vềtrue
nếu đối tượng HAL NN hợp lệ theo thông số kỹ thuật của phiên bản HAL. Các loại OEM và loại tiện ích không được xác thực. Ví dụ:validateModel
trả vềfalse
nếu mô hình chứa một toán tử tham chiếu đến chỉ mục toán hạng không tồn tại hoặc một toán tử không được hỗ trợ ở phiên bản HAL đó.
Tệp frameworks/ml/nn/common/include/Tracing.h
chứa các macro để đơn giản hoá việc thêm thông tin theo dõi hệ thống vào mã Mạng nơron.
Để biết ví dụ, hãy xem các lệnh gọi macro NNTRACE_*
trong trình điều khiển mẫu.
Tệp frameworks/ml/nn/common/include/GraphDump.h
chứa một hàm tiện ích để kết xuất nội dung của Model
ở dạng đồ hoạ cho mục đích gỡ lỗi.
graphDump
: Ghi nội dung đại diện cho mô hình ở định dạng Graphviz (.dot
) vào luồng đã chỉ định (nếu có) hoặc vào logcat (nếu không có luồng nào được cung cấp).
Xác nhận kết quả
Để kiểm thử cách triển khai NNAPI, hãy sử dụng các bài kiểm thử VTS và CTS có trong khung Android. VTS sẽ trực tiếp kiểm tra người lái xe của bạn (không sử dụng khung), trong khi CTS thực thi gián tiếp thông qua khung. Các hàm này kiểm thử từng phương thức API và xác minh rằng tất cả các thao tác do trình điều khiển hỗ trợ đều hoạt động chính xác và cung cấp kết quả đáp ứng các yêu cầu về độ chính xác.
Sau đây là các yêu cầu về độ chính xác trong CTS và VTS đối với NNAPI:
Dấu phẩy động: abs(dự kiến – thực tế) <= atol + rtol * abs(dự kiến); trong đó:
- Đối với fp32, atol = 1e-5f, rtol = 5.0f * 1.1920928955078125e-7
- Đối với fp16, atol = rtol = 5.0f * 0.0009765625f
Được định lượng hoá: song song một (ngoại trừ
mobilenet_quantized
, không theo từng ba)Boolean: khớp chính xác
Một cách CTS kiểm thử NNAPI là tạo các đồ thị giả ngẫu nhiên cố định dùng để kiểm thử và so sánh kết quả thực thi từ mỗi trình điều khiển với phương thức triển khai tham chiếu NNAPI. Đối với trình điều khiển có NN HAL 1.2 trở lên, nếu kết quả không đáp ứng các tiêu chí về độ chính xác, CTS sẽ báo cáo lỗi và kết xuất một tệp thông số kỹ thuật cho mô hình bị lỗi trong /data/local/tmp
để gỡ lỗi.
Để biết thêm thông tin chi tiết về các tiêu chí về độ chính xác, hãy xem TestRandomGraph.cpp
và TestHarness.h
.
Kiểm thử mờ
Mục đích của kiểm thử mờ là tìm các sự cố, câu nhận định, lỗi vi phạm bộ nhớ hoặc hành vi không xác định chung trong mã đang được kiểm thử do các yếu tố như dữ liệu đầu vào không mong muốn. Đối với kiểm thử tìm lỗi ngẫu nhiên NNAPI, Android sử dụng các kiểm thử dựa trên libFuzzer. Các kiểm thử này hiệu quả trong việc tìm lỗi ngẫu nhiên vì sử dụng mức độ bao phủ dòng của các trường hợp kiểm thử trước đó để tạo dữ liệu đầu vào ngẫu nhiên mới. Ví dụ: libFuzzer ưu tiên các trường hợp kiểm thử chạy trên các dòng mã mới. Điều này giúp giảm đáng kể thời gian kiểm thử để tìm mã có vấn đề.
Để kiểm thử tìm lỗi mã nguồn nhằm xác thực việc triển khai trình điều khiển, hãy sửa đổi frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp
trong tiện ích kiểm thử libneuralnetworks_driver_fuzzer
có trong AOSP để đưa mã trình điều khiển vào. Để biết thêm thông tin về kiểm thử tìm lỗi ngẫu nhiên NNAPI, hãy xem frameworks/ml/nn/runtime/test/android_fuzzing/README.md
.
Bảo mật
Vì các quy trình ứng dụng giao tiếp trực tiếp với quy trình của trình điều khiển, nên trình điều khiển phải xác thực các đối số của lệnh gọi mà chúng nhận được. Việc xác thực này được VTS xác minh. Mã xác thực nằm trong frameworks/ml/nn/common/include/ValidateHal.h
.
Trình điều khiển cũng phải đảm bảo rằng ứng dụng không thể làm ảnh hưởng đến các ứng dụng khác khi sử dụng cùng một thiết bị.
Bộ kiểm thử học máy Android
Bộ kiểm thử máy học Android (MLTS) là một điểm chuẩn NNAPI có trong CTS và VTS để xác thực độ chính xác của các mô hình thực trên thiết bị của nhà cung cấp. Điểm chuẩn này đánh giá độ trễ và độ chính xác, đồng thời so sánh kết quả của trình điều khiển với kết quả bằng TF Lite chạy trên CPU, cho cùng một mô hình và tập dữ liệu. Điều này đảm bảo rằng độ chính xác của trình điều khiển không kém hơn so với cách triển khai tham chiếu CPU.
Các nhà phát triển nền tảng Android cũng sử dụng MLTS để đánh giá độ trễ và độ chính xác của các trình điều khiển.
Bạn có thể tìm thấy điểm chuẩn NNAPI trong hai dự án trong AOSP:
platform/test/mlts/benchmark
(ứng dụng đo điểm chuẩn)platform/test/mlts/models
(mô hình và tập dữ liệu)
Mô hình và tập dữ liệu
Điểm chuẩn NNAPI sử dụng các mô hình và tập dữ liệu sau.
- MobileNetV1 độ chính xác đơn và u8 lượng tử hoá ở các kích thước khác nhau, chạy trên một tập hợp con nhỏ (1500 hình ảnh) của Tập dữ liệu hình ảnh mở v4.
- MobileNetV2 có độ chính xác đơn và u8 lượng tử hoá ở nhiều kích thước, chạy trên một tập hợp con nhỏ (1500 hình ảnh) của Tập dữ liệu hình ảnh mở phiên bản 4.
- Mô hình âm thanh dựa trên bộ nhớ ngắn hạn dài (LSTM) để chuyển văn bản sang lời nói, chạy trên một tập hợp con nhỏ của tập hợp CMU Arctic.
- Mô hình âm thanh dựa trên LSTM để nhận dạng lời nói tự động, chạy trên một nhóm nhỏ tập dữ liệu Librispeech.
Để biết thêm thông tin, hãy xem platform/test/mlts/models
.
Kiểm tra căng thẳng
Bộ kiểm thử học máy Android bao gồm một loạt các bài kiểm thử sự cố để xác thực khả năng phục hồi của trình điều khiển trong điều kiện sử dụng nhiều hoặc trong các trường hợp đặc biệt về hành vi của ứng dụng.
Tất cả các thử nghiệm sự cố đều cung cấp các tính năng sau:
- Phát hiện tình trạng treo: Nếu ứng dụng NNAPI bị treo trong quá trình kiểm thử, thì kiểm thử sẽ không thành công với lý do thất bại là
HANG
và bộ kiểm thử sẽ chuyển sang kiểm thử tiếp theo. - Phát hiện sự cố ứng dụng NNAPI: Các hoạt động kiểm thử tiếp tục có hiệu lực sau khi ứng dụng xảy ra sự cố và hoạt động kiểm thử không thành công với lý do không thành công
CRASH
. - Phát hiện sự cố trình điều khiển: Các chương trình kiểm thử có thể phát hiện sự cố trình điều khiển gây ra lỗi trên lệnh gọi NNAPI. Xin lưu ý rằng có thể có sự cố trong các quy trình trình điều khiển không gây ra lỗi NNAPI và không gây ra lỗi kiểm thử. Để khắc phục loại lỗi này, bạn nên chạy lệnh
tail
trên nhật ký hệ thống để tìm lỗi hoặc sự cố liên quan đến trình điều khiển. - Nhắm mục tiêu tất cả trình tăng tốc hiện có: Các chương trình kiểm thử sẽ chạy trên tất cả trình điều khiển hiện có.
Tất cả các thử nghiệm sự cố đều có thể có 4 kết quả sau:
SUCCESS
: Quá trình thực thi đã hoàn tất mà không gặp lỗi.FAILURE
: Thực thi không thành công. Thường xảy ra do lỗi khi kiểm thử một mô hình, cho biết rằng trình điều khiển không thể biên dịch hoặc thực thi mô hình.HANG
: Quy trình kiểm thử không phản hồi.CRASH
: Quy trình kiểm thử gặp sự cố.
Để biết thêm thông tin về quy trình kiểm thử nghiêm ngặt và danh sách đầy đủ các bài kiểm thử sự cố, hãy xem platform/test/mlts/benchmark/README.txt
.
Sử dụng MLTS
Cách sử dụng MLTS:
- Kết nối thiết bị mục tiêu với máy trạm và đảm bảo bạn có thể truy cập thiết bị đó thông qua adb.
Xuất biến môi trường
ANDROID_SERIAL
của thiết bị mục tiêu nếu có nhiều thiết bị được kết nối. cd
vào thư mục nguồn cấp cao nhất của Android.source build/envsetup.sh lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available. ./test/mlts/benchmark/build_and_run_benchmark.sh
Khi kết thúc lần chạy đo điểm chuẩn, kết quả sẽ được trình bày dưới dạng trang HTML và được chuyển đến
xdg-open
.
Để biết thêm thông tin, hãy xem platform/test/mlts/benchmark/README.txt
.
Phiên bản HAL của mạng nơron
Phần này mô tả những thay đổi được giới thiệu trong phiên bản HAL (Lớp trừu tượng phần cứng) cho Android và Mạng Neural.
Android 11
Android 11 ra mắt NN HAL 1.3, bao gồm các thay đổi đáng chú ý sau.
- Hỗ trợ lượng tử hoá 8 bit có dấu trong NNAPI. Thêm loại toán hạng
TENSOR_QUANT8_ASYMM_SIGNED
. Các trình điều khiển có NN HAL 1.3 hỗ trợ các thao tác có lượng tử hoá chưa ký cũng phải hỗ trợ biến thể đã ký của các thao tác đó. Khi chạy các phiên bản đã ký và chưa ký của hầu hết các thao tác được lượng tử hoá, trình điều khiển phải tạo ra cùng một kết quả với độ lệch tối đa là 128. Có 5 trường hợp ngoại lệ đối với yêu cầu này:CAST
,HASHTABLE_LOOKUP
,LSH_PROJECTION
,PAD_V2
vàQUANTIZED_16BIT_LSTM
. Toán tửQUANTIZED_16BIT_LSTM
không hỗ trợ toán hạng đã ký và bốn toán tử còn lại hỗ trợ việc lấy mẫu đã ký nhưng không yêu cầu kết quả phải giống nhau. - Hỗ trợ các quá trình thực thi có hàng rào, trong đó khung gọi phương thức
IPreparedModel::executeFenced
để khởi chạy một quá trình thực thi không đồng bộ, có hàng rào trên một mô hình đã chuẩn bị với một vectơ hàng rào đồng bộ hoá để chờ. Để biết thêm thông tin, hãy xem phần Thực thi có bảo vệ. - Hỗ trợ luồng điều khiển. Thêm các toán tử
IF
vàWHILE
. Các toán tử này lấy các mô hình khác làm đối số và thực thi các mô hình đó theo điều kiện (IF
) hoặc lặp lại (WHILE
). Để biết thêm thông tin, hãy xem phần Luồng điều khiển. - Cải thiện chất lượng dịch vụ (QoS) vì các ứng dụng có thể cho biết các mức độ ưu tiên tương đối của các mô hình, khoảng thời gian tối đa dự kiến cần để chuẩn bị một mô hình nhất định và thời lượng tối đa dự kiến cần để hoàn tất một quá trình thực thi. Để biết thêm thông tin, hãy xem nội dung Chất lượng dịch vụ.
- Hỗ trợ các miền bộ nhớ cung cấp giao diện trình phân bổ cho vùng đệm do người lái xe quản lý. Điều này cho phép truyền bộ nhớ gốc của thiết bị trong các quá trình thực thi, ngăn chặn việc sao chép và chuyển đổi dữ liệu không cần thiết giữa các lần thực thi liên tiếp trên cùng một trình điều khiển. Để biết thêm thông tin, hãy xem phần Miền bộ nhớ.
Android 10
Android 10 ra mắt NN HAL 1.2, trong đó có các thay đổi đáng chú ý sau.
- Cấu trúc
Capabilities
bao gồm tất cả các loại dữ liệu, bao gồm cả loại dữ liệu vô hướng và biểu thị hiệu suất không thư giãn bằng cách sử dụng vectơ thay vì các trường được đặt tên. - Các phương thức
getVersionString
vàgetType
cho phép khung truy xuất loại thiết bị (DeviceType
) và thông tin phiên bản. Xem phần Khám phá và chỉ định thiết bị. - Theo mặc định, phương thức
executeSynchronously
được gọi để thực hiện một quá trình thực thi đồng bộ. Phương thứcexecute_1_2
yêu cầu khung thực hiện một quá trình thực thi một cách không đồng bộ. Hãy xem phần Thực thi. - Thông số
MeasureTiming
choexecuteSynchronously
,execute_1_2
và quá trình thực thi theo đợt chỉ định liệu trình điều khiển có đo lường thời lượng thực thi hay không. Kết quả được báo cáo trong cấu trúcTiming
. Hãy xem phần Thời gian. - Hỗ trợ các quá trình thực thi khi một hoặc nhiều toán hạng đầu ra có kích thước hoặc thứ hạng không xác định. Xem Hình dạng đầu ra.
- Hỗ trợ tiện ích của nhà cung cấp, là tập hợp các thao tác và loại dữ liệu do nhà cung cấp xác định. Trình điều khiển báo cáo các tiện ích được hỗ trợ thông qua phương thức
IDevice::getSupportedExtensions
. Xem phần Tiện ích của nhà cung cấp. - Khả năng một đối tượng hàng loạt kiểm soát một loạt các quá trình thực thi hàng loạt bằng cách sử dụng hàng đợi tin nhắn nhanh (FMQ) để giao tiếp giữa quy trình của ứng dụng và trình điều khiển, giúp giảm độ trễ. Xem bài viết Thực thi hàng loạt và hàng đợi tin nhắn nhanh.
- Hỗ trợ AHardwareBuffer để cho phép trình điều khiển thực thi các quá trình thực thi mà không cần sao chép dữ liệu. Xem AHardwareBuffer.
- Cải thiện tính năng hỗ trợ cho việc lưu các cấu phần phần mềm biên dịch vào bộ nhớ đệm nhằm giảm thời gian biên dịch khi ứng dụng khởi động. Hãy xem phần Lưu nội dung tổng hợp vào bộ nhớ đệm.
Android 10 ra mắt các kiểu toán hạng và toán tử sau.
-
ANEURALNETWORKS_BOOL
ANEURALNETWORKS_FLOAT16
ANEURALNETWORKS_TENSOR_BOOL8
ANEURALNETWORKS_TENSOR_FLOAT16
ANEURALNETWORKS_TENSOR_QUANT16_ASYMM
ANEURALNETWORKS_TENSOR_QUANT16_SYMM
ANEURALNETWORKS_TENSOR_QUANT8_SYMM
ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL
-
ANEURALNETWORKS_ABS
ANEURALNETWORKS_ARGMAX
ANEURALNETWORKS_ARGMIN
ANEURALNETWORKS_AXIS_ALIGNED_BBOX_TRANSFORM
ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM
ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN
ANEURALNETWORKS_BOX_WITH_NMS_LIMIT
ANEURALNETWORKS_CAST
ANEURALNETWORKS_CHANNEL_SHUFFLE
ANEURALNETWORKS_DETECTION_POSTPROCESSING
ANEURALNETWORKS_EQUAL
ANEURALNETWORKS_EXP
ANEURALNETWORKS_EXPAND_DIMS
ANEURALNETWORKS_GATHER
ANEURALNETWORKS_GENERATE_PROPOSALS
ANEURALNETWORKS_GREATER
ANEURALNETWORKS_GREATER_EQUAL
ANEURALNETWORKS_GROUPED_CONV_2D
ANEURALNETWORKS_HEATMAP_MAX_KEYPOINT
ANEURALNETWORKS_INSTANCE_NORMALIZATION
ANEURALNETWORKS_LESS
ANEURALNETWORKS_LESS_EQUAL
ANEURALNETWORKS_LOG
ANEURALNETWORKS_LOGICAL_AND
ANEURALNETWORKS_LOGICAL_NOT
ANEURALNETWORKS_LOGICAL_OR
ANEURALNETWORKS_LOG_SOFTMAX
ANEURALNETWORKS_MAXIMUM
ANEURALNETWORKS_MINIMUM
ANEURALNETWORKS_NEG
ANEURALNETWORKS_NOT_EQUAL
ANEURALNETWORKS_PAD_V2
ANEURALNETWORKS_POW
ANEURALNETWORKS_PRELU
ANEURALNETWORKS_QUANTIZE
ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
ANEURALNETWORKS_RANDOM_MULTINOMIAL
ANEURALNETWORKS_REDUCE_ALL
ANEURALNETWORKS_REDUCE_ANY
ANEURALNETWORKS_REDUCE_MAX
ANEURALNETWORKS_REDUCE_MIN
ANEURALNETWORKS_REDUCE_PROD
ANEURALNETWORKS_REDUCE_SUM
ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR
ANEURALNETWORKS_ROI_ALIGN
ANEURALNETWORKS_ROI_POOLING
ANEURALNETWORKS_RSQRT
ANEURALNETWORKS_SELECT
ANEURALNETWORKS_SIN
ANEURALNETWORKS_SLICE
ANEURALNETWORKS_SPLIT
ANEURALNETWORKS_SQRT
ANEURALNETWORKS_TILE
ANEURALNETWORKS_TOPK_V2
ANEURALNETWORKS_TRANSPOSE_CONV_2D
ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM
ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN
Android 10 đưa ra bản cập nhật cho nhiều thao tác hiện có. Các bản cập nhật này chủ yếu liên quan đến những nội dung sau:
- Hỗ trợ bố cục bộ nhớ NCHW
- Hỗ trợ các tensor có thứ hạng khác 4 trong các hoạt động mềm và chuẩn hoá
- Hỗ trợ các phép tích chập mở rộng
- Hỗ trợ các đầu vào có lượng tử hoá hỗn hợp trong
ANEURALNETWORKS_CONCATENATION
Danh sách dưới đây cho thấy các thao tác được sửa đổi trong Android 10. Để biết đầy đủ thông tin chi tiết về các thay đổi, hãy xem OperationCode trong tài liệu tham khảo của NNAPI.
ANEURALNETWORKS_ADD
ANEURALNETWORKS_AVERAGE_POOL_2D
ANEURALNETWORKS_BATCH_TO_SPACE_ND
ANEURALNETWORKS_CONCATENATION
ANEURALNETWORKS_CONV_2D
ANEURALNETWORKS_DEPTHWISE_CONV_2D
ANEURALNETWORKS_DEPTH_TO_SPACE
ANEURALNETWORKS_DEQUANTIZE
ANEURALNETWORKS_DIV
ANEURALNETWORKS_FLOOR
ANEURALNETWORKS_FULLY_CONNECTED
ANEURALNETWORKS_L2_NORMALIZATION
ANEURALNETWORKS_L2_POOL_2D
ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
ANEURALNETWORKS_LOGISTIC
ANEURALNETWORKS_LSH_PROJECTION
ANEURALNETWORKS_LSTM
ANEURALNETWORKS_MAX_POOL_2D
ANEURALNETWORKS_MEAN
ANEURALNETWORKS_MUL
ANEURALNETWORKS_PAD
ANEURALNETWORKS_RELU
ANEURALNETWORKS_RELU1
ANEURALNETWORKS_RELU6
ANEURALNETWORKS_RESHAPE
ANEURALNETWORKS_RESIZE_BILINEAR
ANEURALNETWORKS_RNN
ANEURALNETWORKS_ROI_ALIGN
ANEURALNETWORKS_SOFTMAX
ANEURALNETWORKS_SPACE_TO_BATCH_ND
ANEURALNETWORKS_SPACE_TO_DEPTH
ANEURALNETWORKS_SQUEEZE
ANEURALNETWORKS_STRIDED_SLICE
ANEURALNETWORKS_SUB
ANEURALNETWORKS_SVDF
ANEURALNETWORKS_TANH
ANEURALNETWORKS_TRANSPOSE
Android 9
NN HAL 1.1 được giới thiệu trong Android 9 và có những thay đổi đáng chú ý sau đây.
IDevice::prepareModel_1_1
bao gồm một tham sốExecutionPreference
. Trình điều khiển có thể sử dụng thông tin này để điều chỉnh quá trình chuẩn bị, vì biết rằng ứng dụng ưu tiên tiết kiệm pin hoặc sẽ thực thi mô hình trong các lệnh gọi liên tiếp nhanh chóng.- 9 toán tử mới đã được thêm vào:
BATCH_TO_SPACE_ND
,DIV
,MEAN
,PAD
,SPACE_TO_BATCH_ND
,SQUEEZE
,STRIDED_SLICE
,SUB
,TRANSPOSE
. - Ứng dụng có thể chỉ định rằng có thể chạy các phép tính có độ chính xác đơn 32 bit bằng cách sử dụng dải số thực 16 bit và/hoặc độ chính xác bằng cách đặt
Model.relaxComputationFloat32toFloat16
thànhtrue
. Cấu trúcCapabilities
có thêm trườngrelaxedFloat32toFloat16Performance
để trình điều khiển có thể báo cáo hiệu suất thư giãn của nó cho khung.
Android 8.1
Neural Networks HAL (1.0) ban đầu được phát hành trong Android 8.1. Để biết thêm thông tin, hãy xem /neuralnetworks/1.0/
.