Rockchip · AI & Linux Hub

AI-инференс

RKNN-Toolkit2 API: конфигурация, преобразование, квантование и инференс

Полная справка V2.3.2: зависимости фреймворков, все параметры API, смешанное квантование, оценка точности/производительности/памяти и пользовательские операторы.

· ArmSoM Editorial · Rockchip source documentation · 32 мин чтения

Применимость к ArmSoM и источник

Это справка по платформе Rockchip, не отчёт испытаний ArmSoM. Источники: RK-YH-YF-412, V2.3.2, 22 китайские и 25 английских страниц. Китайская статья следует китайскому оригиналу; английская — английскому, полностью переведённому на русский и немецкий. Технических рисунков в PDF нет: весь материал представлен редактируемым текстом, таблицами и кодом, без вымышленных английских изображений. Источник охватывает RV1103/RV1103B/RV1106/RV1106B/RV1126B, RK2118, RK3562 и серии RK3566/3568/3576/3588, но не задаёт SDK/BSP и ядро конкретной платы ArmSoM. Сверяйте NPU-драйвер, Toolkit2/Runtime/Server, систему и архитектуру хоста, Python, фреймворк и формат модели. Возможности x64 нельзя автоматически переносить на ARM64. Версии, top-5, память и вывод SDK — примеры оригинала, не тесты ArmSoM. V2.3.2 обозначает исходный срез, не новейший выпуск.

Примечание сверки: тексты одной версии различаются. Для Ubuntu20.04 китайская ячейка Python содержит 3.8/3.9, английская — 3.8/3.8; в разделе ARM64 Debian помечен x64. Значения сохранены без предположений о совместимости. Все сомнения перечислены в редакционных примечаниях; API/код не являются проверенной адаптацией ArmSoM.

EDITORIAL-NOTES · ArmSoM Docs

1 Требования

1.1 Поддерживаемые модели чипов

RV1103

RV1103B

RV1106

RV1106B

RV1126B

RK2118

RK3562

RK3566 (серия)

RK3568 (серия)

RK3576 (серия)

RK3588 (серия)

Примечание: далее RK3566 / RK3568 / RK3576 / RK3588 обозначают соответствующие серии RK3566 / RK3568 / RK3576 / RK3588.

1.2 Требования к среде и зависимостям

Рекомендуется следующая среда операционной системы:

Версия операционной
системы
Ubuntu18.04
(x64)
Ubuntu20.04
(x64)
Ubuntu22.04
(x64)
Ubuntu24.04
(x64)
Версия Python 3.6 / 3.7 3.8 / 3.8 3.10 / 3.11 3.12

Для ARM64:

Версия операционной системы Debian10 (x64) Debian11 (x64) Debian12 (x64)
Версия Python 3.6 / 3.7 3.8 / 3.8 3.10 / 3.11 / 3.12

Примечания:

1. Подробные зависимости библиотек Python указаны в doc/requirements*.txt.

2. Примеры документа в основном используют Ubuntu 20.04 / Python3.8.

1.3 Поддерживаемые фреймворки глубокого обучения

RKNN-Toolkit2 поддерживает Caffe, TensorFlow, TensorFlow Lite, ONNX, DarkNet и PyTorch.

Соответствие версий RKNN-Toolkit2 и фреймворков приведено ниже:

RKNN-Toolkit2 Caffe TensorFlow TF Lite ONNX DarkNet PyTorch
1.4.0
1.4.2
1.5.0
1.5.2
1.0 1.12.0
~2.8.0
Версия
схемы=3
1.7.0
~1.10.0
Идентификатор коммита:
810d7f7
1.6.0
~1.10.1
1.6.0 1.0 1.12.0
~2.14.0
Версия
схемы=3
1.7.0
~1.14.0
Идентификатор коммита:
810d7f7
1.6.0
~1.13.1
2.0.0
2.1.0
2.2.0
1.0 1.12.0
~2.14.0
Версия
схемы=3
1.7.0
~1.14.1
Идентификатор коммита:
810d7f7
1.10.1
~2.1.0
2.3.0
2.3.2
1.0 1.12.0
~2.14.0
Версия
схемы=3
1.7.0
~1.17.0
Идентификатор коммита:
810d7f7
1.10.1
~2.4.0

Примечания:

1. Благодаря совместимости версий TensorFlow теоретически поддерживаются и pb-файлы, экспортированные версиями до TensorFlow 1.12.0. Подробности совместимости разных версий приведены в официальной документации: https://www.tensorflow.org/guide/versions

2. Схемы разных версий TFLite несовместимы. Если схема экспортированной модели отличается от версии схемы, используемой RKNN-Toolkit2, загрузка модели может завершиться ошибкой.

3. Протокол Caffe в RKNN-Toolkit2 основан на официальном Berkeley-протоколе с модификациями. Источник: https://github.com/BVLC/caffe/tree/master/src/caffe/proto, commit 828dd10. RKNN-Toolkit2 добавляет на этой основе некоторые операторы.

4. Соответствие выпусков ONNX версиям opset и IR описано в документации onnxruntime: https://github.com/microsoft/onnxruntime/blob/v1.10.0/docs/Versioning.md

5. Официальный репозиторий DarkNet: https://github.com/pjreddie/darknet. Правила преобразования RKNN-Toolkit2 в исходном документе основаны на последнем для его состояния коммите ветки master — 810d7f7; это не утверждение о текущем HEAD.

6. При загрузке PyTorch-модели (torchscript) рекомендуется использовать одну и ту же версию PyTorch для экспорта модели и преобразования в RKNN. Различие версий может привести к ошибке преобразования.

7. Версия ARM64 поддерживает только PyTorch и ONNX; остальные фреймворки в состоянии источника не поддерживаются.

2 Описание API RKNN-Toolkit2

2.1 Инициализация и освобождение RKNN

Эта группа интерфейсов создаёт и освобождает объект RKNN. Перед использованием любых API RKNN-Toolkit2 вызовите RKNN(); после завершения задачи освободите объект методом release().

При создании объекта RKNN параметры verbose и verbose_file управляют подробным журналом загрузки и построения модели и других операций. verbose имеет тип bool: при True RKNN-Toolkit2 печатает подробный журнал. verbose_file — строка; если она содержит путь к файлу, журнал записывается туда, причём verbose также должен быть True.

Пример кода:

# Print the detailed log information.
rknn = RKNN(verbose=True)

…

rknn.release()

2.2 Настройка модели

Перед построением модели RKNN настройте её через интерфейс config.

API config
Описание Задать параметры преобразования модели.
Параметры mean_values: Средние значения входа. Формат параметра — список, содержащий один или несколько вложенных списков средних значений. Для модели с несколькими входами задаётся несколько вложенных списков. Длина каждого соответствует числу каналов входа. Например, [[128,128,128]] означает вычитание 128 из значений каждого из трёх каналов одного входа.
По умолчанию None: все средние равны нулю.
Параметры std_values: Значения нормализации входа. Формат — список с одним или несколькими вложенными списками значений нормализации. Для модели с несколькими входами используется несколько вложенных списков. Длина каждого соответствует числу каналов входа. Например, [[128,128,128]] означает, что из значений трёх каналов одного входа сначала вычитается среднее, затем результат делится на 128.
По умолчанию None: все значения std равны единице.
Параметры quant_img_RGB2BGR: Указывает, нужно ли сначала выполнить RGB2BGR при загрузке изображения для квантования. При нескольких входах соответствующие параметры разделяются ‘,’, например [True, True, False]. По умолчанию False.
Этот параметр обычно применяется к моделям Caffe. При обучении большинства моделей Caffe изображения набора данных сначала преобразуются RGB2BGR; в таком случае нужно задать True.
Параметр действует только для изображений квантования формата jpg/png/bmp. При чтении npy он игнорируется. Поэтому, если вход модели имеет формат BGR, данные npy также должны быть в BGR.
Параметр применяется только при чтении изображений на этапе квантования (интерфейс build) или анализа точности квантования (accuracy_analysis) и не записывается в итоговую модель RKNN. Поэтому для модели с входом BGR необходимо обеспечить формат BGR входных данных до вызова inference инструментария или функции run C-API.
Параметры quantized_dtype: Тип квантования. Поддерживаются “w8a8”, “w4a16”, “w8a16”, “w4a8”, “w16a16i” и “w16a16i_dfp”. По умолчанию “w8a8”.
- w8a8: веса и активации имеют 8-битную асимметричную точность квантования. (RK2118 не поддерживается.)
- w4a16: веса — 4-битное асимметричное квантование, активации — 16-битная плавающая точка. (Только RK3576/RV1126B.)
- w8a16: веса — 8-битное асимметричное квантование, активации — 16-битная плавающая точка. (Только RK3562.)
- w4a8: веса — 4-битное, активации — 8-битное асимметричное квантование. (Пока не поддерживается.)
- w16a16i: веса и активации — 16-битное асимметричное квантование. (Только RV1103/RV1106.)
- w16a16i_dfp: веса и активации — 16-битное квантование с динамической фиксированной точкой. (Только RV1103/RV1106.)
Параметры quantized_algorithm: Алгоритм вычисления параметров квантования каждого слоя. Поддерживаются normal, mmse, kl_divergence и gdq. По умолчанию normal.
Алгоритм normal отличается быстротой. Обычно рекомендуют примерно 20-100 образцов для квантования; увеличение количества данных не обязательно повышает точность.
Алгоритм mmse медленнее из-за переборного итерационного метода, но обычно точнее normal. Рекомендуется примерно 20-50 образцов. Количество можно увеличить или уменьшить с учётом времени квантования.
Алгоритм kl_divergence требует больше времени, чем normal, но значительно меньше, чем mmse. В некоторых сценариях (при неравномерном распределении признаков) kl_divergence даёт лучший результат. Рекомендуется примерно 20-100 образцов.
Алгоритм gdq действует только для w4a16 и w8a16 и позволяет повысить точность весов этих типов. Рекомендуется более 200 образцов.
Параметры quantized_method: Поддерживаются layer, channel и group{SIZE}. По умолчанию channel.
- layer: для каждого веса используется только один набор параметров квантования.
- channel: каждый канал весов имеет собственный набор параметров квантования. Обычно channel точнее layer.
- group{SIZE}: на основе channel веса каждого выходного канала дополнительно делятся по входному каналу на группы размера {SIZE}. Каждая группа имеет собственный набор параметров квантования. Обычно group{SIZE} точнее channel. {SIZE} — значение, кратное 32, от 32 до 256, например ‘group32’ или ‘group128’. group{SIZE} действует только при quantized_dtype = w4a16.
Параметры float_dtype: Тип данных с плавающей точкой без квантования. Поддерживается float16. По умолчанию float16.
Параметры optimization_level: Уровень оптимизации модели. По умолчанию 3.
Изменение уровня позволяет отключить некоторые или все правила оптимизации при преобразовании. Значение 3 включает все оптимизации. Значение 2 или 1 отключает часть оптимизаций, способных влиять на точность некоторых моделей. Значение 0 отключает все оптимизации.
Параметры target_platform: Целевая платформа чипа для модели RKNN. Поддерживаются ‘rv1103’, ‘rv1103b’, ‘rv1106’, ‘rv1106b’, ‘rv1126b’, ‘rk2118’, ‘rk3562’, ‘rk3566’, ‘rk3568’, ‘rk3576’ и ‘rk3588’. По умолчанию None.
Параметры custom_string: Добавить пользовательскую строку в модель RKNN для последующего запроса во время выполнения. По умолчанию None.
Параметры remove_weight: Удалить веса и создать подчинённую модель RKNN, которая может совместно использовать веса полной модели RKNN, чтобы уменьшить потребление памяти. По умолчанию False.
Параметры compress_weight: Сжать веса модели, чтобы уменьшить размер модели RKNN. По умолчанию False.
Параметры single_core_mode: Генерировать ли только одноядерную модель; это может уменьшить размер модели RKNN и потребление памяти. По умолчанию False. Действует только для RK3588 / RK3576. По умолчанию False.
Параметры model_pruning: Прореживание модели: для моделей с разреженными весами уменьшает размер и вычислительную нагрузку преобразованной модели RKNN. По умолчанию False.
Параметры op_target: Задаёт цель выполнения каждой операции (NPU/CPU/GPU и т. д.). Формат: {‘op0_output_name’:’cpu’, ‘op1_output_name’:’cpu’, …}; либо по op_type: {‘op_type’:’cpu‘, ‘op0_output_name’:’cpu’….}. Допускается смешение обоих способов, например {‘op_type’:’cpu‘, ‘op0_output_name’:’cpu’….}. По умолчанию None.
‘op0_output_name’ и ‘op1_output_name’ — имена выходных тензоров соответствующих OP, получаемые из результатов accuracy_analysis. ‘cpu’ и ‘npu’ означают выполнение соответствующего этому тензору OP на CPU или NPU. Доступны ‘cpu’ / ‘npu’ / ‘gpu’ / ‘auto’; ‘auto’ автоматически выбирает цель.
op_type также получают из результатов accuracy_analysis. Этот способ задаёт цель для всех OP данного типа в модели, например {‘Add’:’cpu’, ‘Expand’:’cpu’,….}.
Параметры dynamic_input: Имитирует динамический вход по нескольким наборам форм входов, заданным пользователем. Формат: [[input0_shapeA, input1_shapeA, …], [input0_shapeB, input1_shapeB, …], …].
По умолчанию None; экспериментальная функция.
Например, исходная форма входа [1,3,224,224], [1,3,height,width] или [1,3,-1,-1], но развёртываемая модель должна поддерживать три формы: [1,3,224,224], [1,3,192,192] и [1,3,160,160]. Можно задать dynamic_input=[[[1,3,224,224]], [[1,3,192,192]], [[1,3,160,160]]]. После преобразования в RKNN для инференса следует передавать входные данные соответствующей формы.
Примечания:
1. Функцию можно включить только тогда, когда сама исходная модель поддерживает динамический вход, иначе возникнет ошибка.
2. Если исходная форма динамическая, разные значения можно задавать только для динамических осей.
Параметры quantize_weight: Если ‘do_quantization’ в rknn.build равно False, уменьшает размер модели rknn квантованием части весов.
По умолчанию False.
Параметры remove_reshape: Удаляет возможные ‘Reshape’ на входах и выходах модели для повышения производительности выполнения. По умолчанию False.
Примечание: включение может изменить форму входных или выходных узлов. Следите за предупреждениями при преобразовании и учитывайте изменение форм при развёртывании.
Параметры sparse_infer: Разреженный инференс для уже разреженных моделей с целью повышения производительности. Только RK3576/RV1126B. По умолчанию False.
Параметры enable_flash_attention: Включать ли Flash Attention. По умолчанию False.
Примечание: FlashAttention основан на https://arxiv.org/abs/2307.08691; использование кэша внутри цикла позволяет ускорить обработку и снизить расход пропускной способности. Однако размер модели может увеличиться. Выбирайте настройку с учётом конкретной модели и сценария. Подробнее см. описание ‘exSDPAttention’ в ‘RKNN Compiler Support Operator List’.
Параметры auto_hybrid_cos_thresh: Порог косинусного расстояния для автоматического смешанного квантования модели. По умолчанию 0.98.
Параметры auto_hybrid_euc_thresh: Порог евклидова расстояния для автоматического смешанного квантования модели. По умолчанию None, то есть не включён.
Возвращаемое значение None.

Пример кода:

# model config
rknn.config(mean_values=[[103.94, 116.78, 123.68]],
     std_values=[[58.82, 58.82, 58.82]],
     quant_img_RGB2BGR=True,
     target_platform='rk3566')

2.3 Загрузка модели

RKNN-Toolkit2 поддерживает загрузку исходных моделей Caffe, TensorFlow, TensorFlow Lite, ONNX, DarkNet и PyTorch, ещё не преобразованных в RKNN. Для разных форматов используются разные интерфейсы, описанные ниже.

2.3.1 Загрузка модели Caffe

API load_caffe
Описание Загрузить модель Caffe. (Недоступно на ARM64.)
Параметры model: Путь к файлу структуры модели Caffe (суффикс “.prototxt”).
Параметры blobs: Путь к файлу двоичных данных модели Caffe (суффикс “.caffemodel”).
Параметры input_name: Для модели Caffe с несколькими входами этим параметром можно задать порядок имён входных слоёв, например [‘input1’,’input2’,’input3’]. Имена должны совпадать с именами входов модели. По умолчанию None: порядок автоматически определяется файлом модели Caffe с суффиксом .prototxt.
Возвращаемое значение 0: Импорт выполнен успешно.
Возвращаемое значение -1: Ошибка импорта.

Пример кода:

# Load the mobilenet_v2 Caffe model in the current path
ret = rknn.load_caffe(model='./mobilenet_v2.prototxt',
          blobs='./mobilenet_v2.caffemodel')

2.3.2 Загрузка модели TensorFlow

API load_tensorflow
Описание Загрузить модель TensorFlow. (Недоступно на ARM64.)
Параметры tf_pb: Путь к файлу модели TensorFlow (суффикс “.pb”).
Параметры inputs: Входные узлы модели (имена операндов); поддерживается несколько узлов. Все строки имён входных узлов помещаются в список.
Параметры input_size_list: Формы входных узлов, все формы помещаются в список. Например, для ssd_mobilenet_v1 параметр input_size_list должен быть [[1,300,300,3]].
Параметры outputs: Выходные узлы модели (имена операндов); поддерживается несколько узлов. Все выходные узлы помещаются в список.
Параметры input_is_nchw: Имеет ли вход модели уже раскладку NCHW. По умолчанию False, то есть исходная раскладка NHWC.
Возвращаемое значение 0: Импорт выполнен успешно.
Возвращаемое значение -1: Ошибка импорта.

Пример кода:

# Load ssd_mobilenet_v1_coco_2017_11_17 TF model in the current path
ret = rknn.load_tensorflow(tf_pb='./ssd_mobilenet_v1_coco_2017_11_17.pb',
            inputs=['Preprocessor/sub'],
            outputs=['concat', 'concat_1'],
            input_size_list=[[300, 300, 3]])

2.3.3 Загрузка модели TensorFlow Lite

API load_tflite
Описание Загрузить модель TensorFlow Lite. (Недоступно на ARM64.)
Параметры model: Путь к файлу модели TensorFlow Lite (суффикс “.tflite”).
Параметры input_is_nchw: Имеет ли вход модели уже раскладку NCHW. По умолчанию False, то есть исходная раскладка NHWC.
Возвращаемое значение 0: Импорт выполнен успешно.
Возвращаемое значение -1: Ошибка импорта.

Пример кода:

# Load the mobilenet_v1 TF-Lite model in the current path
ret = rknn.load_tflite(model='./mobilenet_v1.tflite')

2.3.4 Загрузка модели ONNX

API load_onnx
Описание Загрузить модель ONNX.
Параметры model: Путь к файлу модели ONNX (суффикс “.onnx”).
Параметры inputs: Входные узлы модели (имена операндов); поддерживается несколько узлов. Все строки имён входных узлов помещаются в список. По умолчанию None: берутся из модели.
Параметры input_size_list: Формы входных узлов, все формы помещаются в список. Если задан inputs, необходимо задать и input_size_list. По умолчанию None.
Параметры input_initial_val: Начальные значения входов модели в формате списка ndarray. По умолчанию None.
Используется главным образом для фиксации некоторых входов как констант. Для входов, которые не должны быть константами, задаётся None, например [None, np.array([1])].
Параметры outputs: Выходные узлы модели (имена операндов); поддерживается несколько узлов. Все выходные узлы помещаются в список. По умолчанию None: берутся из модели.
Возвращаемое значение 0: Импорт выполнен успешно.
Возвращаемое значение -1: Ошибка импорта.

Пример кода:

# Load the arcface onnx model in the current path
ret = rknn.load_onnx(model='./arcface.onnx')

2.3.5 Загрузка модели DarkNet

API load_darknet
Описание Загрузить модель DarkNet. (Недоступно на ARM64.)
Параметры model: Путь к файлу структуры модели DarkNet (суффикс “.cfg”).
Параметры weight: Путь к файлу весов (суффикс “.weight”).
Возвращаемое значение 0: Импорт выполнен успешно.
Возвращаемое значение -1: Ошибка импорта.

Пример кода:

# Load the yolov3-tiny DarkNet model in the current path
ret = rknn.load_darknet(model='./yolov3-tiny.cfg',
           weight= './yolov3.weights')

2.3.6 Загрузка модели PyTorch

API load_pytorch
Описание Загрузить модель PyTorch.
Поддерживается модель Quantization Aware Training (QAT), но для этого нужно обновить torch до версии ‘1.9.0’ или выше.
Параметры model: Путь к файлу структуры модели PyTorch (суффикс “.pt”); модель должна быть в формате torchscript.
Параметры input_size_list: Формы входных узлов, все формы помещаются в список.
Возвращаемое значение 0: Импорт выполнен успешно.
Возвращаемое значение -1: Ошибка импорта.

Пример кода:

# Load the PyTorch model resnet18 in the current path
ret = rknn.load_pytorch(model='./resnet18.pt',
           input_size_list=[[1,3,224,224]])

2.4 Построение модели RKNN

API build
Описание Собрать соответствующую модель RKNN на основе импортированной модели.
Параметры do_quantization: Выполнять ли квантование модели. По умолчанию True.
Параметры dataset: Входной набор данных для калибровки параметров квантования. Поддерживается текстовый файл с путями к изображениям (jpg или png) либо файлам npy для калибровки. На каждой строке один путь, например:
a.jpg
b.jpg
или
a.npy
b.npy
При нескольких входах соответствующие файлы разделяются пробелом, например:
a.jpg a2.jpg
b.jpg b2.jpg
или
a.npy a2.npy
b.npy b2.npy
Примечание: обычно рекомендуются изображения квантования, соответствующие сценарию прогнозирования.
Параметры rknn_batch_size: Изменяет размер пакета входа. По умолчанию None.
При значении больше 1 NPU обрабатывает несколько кадров изображений или входных данных за один инференс. Например, исходный вход MobileNet — [1, 224, 224, 3], выход — [1, 1001]. При rknn_batch_size = 4 вход становится [4, 224, 224, 3], выход — [4, 1001].
Примечания:
1. rknn_batch_size повышает производительность (загрузку ядер) только на многоядерных NPU; рекомендуется выбирать значение по числу ядер NPU.
2. Изменение rknn_batch_size меняет формы входов и выходов. Для inference нужно передавать входы правильного размера и соответственно обрабатывать возвращённые выходы на этапе постобработки.
Параметры auto_hybrid: Включать ли автоматическое смешанное квантование для коррекции точности или переполнения. По умолчанию False: коррекция не выполняется. При квантовании модели auto_hybrid переводит операции, у которых косинусное и евклидово расстояния ниже заданных порогов, в вычисления FP16 (сейчас поддерживается только квантование ‘w8a8’). Если модель не квантуется, auto_hybrid переводит операции, выходящие за диапазон значений FP16, в вычисления INT16.
Примечание:
1. Пороги косинусного и евклидова расстояния задаются через auto_hybrid_cos_thresh и auto_hybrid_euc_thresh интерфейса config.
Возвращаемое значение 0: Сборка выполнена успешно.
Возвращаемое значение -1: Ошибка сборки.

Пример кода:

# Build and quantize RKNN model
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')

2.5 Экспорт модели RKNN

Модель RKNN, созданную через build, можно сохранить в файл для дальнейшего развёртывания.

API export_rknn
Описание Сохранить модель RKNN в указанном файле (суффикс “.rknn”).
Параметры export_path: Путь к создаваемому файлу модели RKNN.
Возвращаемое значение 0: Экспорт выполнен успешно.
Возвращаемое значение -1: Ошибка экспорта.

Пример кода:

# save the built RKNN model as a mobilenet_v1.rknn file in the current path
ret = rknn.export_rknn(export_path='./mobilenet_v1.rknn')

2.6 Загрузка модели RKNN

API load_rknn
Описание Загрузить модель RKNN.
После загрузки не требуется выполнять настройку модели, загрузку исходной модели и сборку RKNN. Загруженную модель можно использовать только при подключении к аппаратной NPU для инференса или получения данных производительности. Симулятор и анализ точности недоступны.
Параметры path: Путь к файлу модели RKNN.
Возвращаемое значение 0: Загрузка выполнена успешно.
Возвращаемое значение -1: Ошибка загрузки.

Пример кода:

# Load the mobilenet_v1 RKNN model in the current path
ret = rknn.load_rknn(path='./mobilenet_v1.rknn')

2.7 Инициализация среды выполнения

Перед инференсом или оценкой производительности инициализируйте среду выполнения. Интерфейс определяет её тип: аппаратная платформа или программный симулятор.

API init_runtime
Описание Инициализировать среду выполнения.
Параметры target: Целевая аппаратная платформа. Поддерживаются ‘rv1103’, ‘rv1103b’, ‘rv1106’, ‘rv1106b’, ‘rv1126b’, ‘rk3562’, ‘rk3566’, ‘rk3568’, ‘rk3576’ и ‘rk3588’. По умолчанию “None”: модель работает в симуляторе.
Примечание: при target = None сначала нужно вызвать build или hybrid_quantization.
Параметры device_id: Идентификатор устройства. При подключении нескольких устройств к ПК нужно указать этот параметр; его можно получить через list_devices. По умолчанию None.
Параметры perf_debug: Режим отладки при оценке производительности. В нём можно получить время выполнения каждого слоя; иначе доступно только полное время выполнения модели. По умолчанию False.
Параметры eval_mem: Включить ли режим оценки памяти. При True затем можно вызвать eval_memory для получения потребления памяти при выполнении модели. По умолчанию False.
Параметры async_mode: Использовать ли асинхронный режим. По умолчанию False.
Вызов inference включает установку входного изображения, выполнение модели и получение результата. В асинхронном режиме установка входа текущего кадра выполняется одновременно с инференсом предыдущего. Поэтому, кроме первого кадра, время установки входа каждого следующего кадра скрывается, что повышает производительность. Каждый возвращаемый результат в этом режиме относится к предыдущему кадру. (Пока не поддерживается.)
Параметры core_mask: Выбирает ядра NPU во время выполнения. Поддерживаются RK3588 / RK3576 и следующие конфигурации:
RKNN.NPU_CORE_AUTO: автоматическое планирование, модель выполняется на свободном ядре NPU.
RKNN.NPU_CORE_0: выполнение на NPU0.
RKNN.NPU_CORE_1: выполнение на NPU1.
RKNN.NPU_CORE_2: выполнение на NPU2.
RKNN.NPU_CORE_0_1: одновременное выполнение на NPU0 и NPU1.
RKNN.NPU_CORE_0_1_2: одновременное выполнение на NPU0, NPU1 и NPU2.
RKNN.NPU_CORE_ALL: число используемых ядер определяется платформой.
По умолчанию “RKNN.NPU_CORE_AUTO”.
Примечание: у RK3576 только 2 ядра, поэтому NPU_CORE_2 и NPU_CORE_0_1_2 задавать нельзя.
Параметры fallback_prior_device: Приоритетное резервное устройство для OP, не поддерживаемого NPU. Поддерживаются ‘gpu’ и ‘cpu’; ‘gpu’ действует только на платформах с аппаратной GPU. По умолчанию ‘cpu’.
Возвращаемое значение 0: Среда выполнения инициализирована успешно.
Возвращаемое значение -1: Ошибка инициализации среды выполнения.

Пример кода:

# Initialize the runtime environment
ret = rknn.init_runtime(target='rk3566')

2.8 Инференс модели RKNN

Интерфейс запускает инференс модели RKNN и получает его результат.

API inference
Описание Выполнить инференс модели с указанными входами и получить результат.
Если при инициализации среды target задан как Rockchip NPU, инференс выполняется на указанной аппаратной платформе. Если target не задан, используется симулятор.
Параметры inputs: Список входов для инференса. Тип объектов — ndarray.
Параметры data_format: Список раскладок входных данных: “nchw” или “nhwc”; действует только для 4-мерных входов. По умолчанию None: все входы имеют раскладку “nhwc”.
Параметры inputs_pass_through: Флаг pass_through. По умолчанию None: все входы передаются без режима pass_through.
Без pass_through инструментарий перед передачей входа драйверу NPU вычитает среднее, делит на дисперсию и т. п.; в режиме pass_through эти операции не выполняются.
Параметр — список. Например, чтобы включить сквозную передачу для input0, но не для input1, задают [1, 0].
Возвращаемое значение results: Результат инференса в формате списка ndarray.

Пример кода:

Для классификационной модели, например mobilenet_v1, пример кода приведён ниже; полный код см. в example/tfilte/mobilenet_v1. Написание tfilte сохранено из исходника.

# Preform inference for a picture with a model and get a top-5 result
outputs = rknn.inference(inputs=[img])
show_outputs(outputs)

Пример результата top-5:

-----TOP 5-----
[ 156] score:0.928223 class:"Shih-Tzu"
[ 155] score:0.063171 class:"Pekinese, Pekingese, Peke"
[ 205] score:0.004299 class:"Lhasa, Lhasa apso"
[ 284] score:0.003096 class:"Persian cat"
[ 285] score:0.000171 class:"Siamese cat, Siamese"

2.9 Оценка производительности модели

API eval_perf
Описание Оценить производительность модели.
Модель должна выполняться на RV1103 / RV1103B / RV1106 / RV1106B / RV1126B / RK3562 / RK3566 / RK3568 / RK3576 / RK3588, подключённом к ПК. Если при init_runtime параметр perf_debug равен False, аппаратная информация о производительности содержит только полное время выполнения модели. При perf_debug = True подробно измеряется и время каждого слоя.
Параметры is_print: Выводить ли информацию о производительности. По умолчанию True.
Параметры fix_freq: Фиксировать ли аппаратную частоту. По умолчанию True.
Возвращаемое значение perf_result: Информация о производительности (строки).

Пример кода:

# Evaluate model performance
perf_detail = rknn.eval_perf()

2.10 Оценка использования памяти

API eval_memory
Описание Получить потребление памяти при выполнении модели на аппаратной платформе.
Модель должна выполняться на подключённом к ПК RV1103 / RV1103B / RV1106 / RV1106B / RV1126B / RK3562 / RK3566 / RK3568 / RK3576 / RK3588.
Параметры is_print: Выводить ли результаты оценки памяти в стандартном формате. По умолчанию True.
Возвращаемое значение memory_detail: Подробные сведения об использовании памяти в формате словаря.
Пример данных:
{
‘weight_memory’: 3698688,
‘internal_memory’: 1756160,
‘other_memory’: 484352,
‘total_memory’: 5939200,
}
- ‘weight_memory’ — объём памяти весов модели.
- ‘internal_memory’ — память внутренних тензоров модели.
- ‘other_memory’ — память других тензоров модели.
- ‘total_memory’ — общий объём памяти модели, сумма памяти весов, внутренних тензоров и прочей памяти.

Пример кода:

# eval memory usage
memory_detail = rknn.eval_memory()

Для примера examples/caffe/mobilenet_v2 ниже показан исходный вывод использования памяти на RK3588. Это данные оригинала, не измерения ArmSoM.

======================================================
     Memory Profile Info Dump
======================================================
NPU model memory detail(bytes):
  Weight Memory: 3.53 MiB
  Internal Tensor Memory: 1.67 MiB
  Other Memory: 473.00 KiB
  Total Memory: 5.66 MiB

INFO: When evaluating memory usage, we need consider
the size of model, current model size is: 4.09 MiB
======================================================

2.11 Получение версии SDK

API get_sdk_version
Описание Получить версии API и драйвера используемого SDK.
Примечание: перед вызовом необходимо загрузить модель и инициализировать среду выполнения. API применяется только на RV1103 / RV1103B / RV1106 / RV1106B / RV1126B / RK3562 / RK3566 / RK3568 / RK3576 / RK3588.
Параметры None.
Возвращаемое значение sdk_version: Версии API и драйвера. Тип данных — строка.

Пример кода:

# Get SDK version
sdk_version = rknn.get_sdk_version()
print(sdk_version)

Пример вывода версии SDK:

==============================================
RKNN VERSION:
  API: 1.5.2 (8babfea build@2023-08-25T02:31:12)
  DRV: rknn_server: 1.5.2 (8babfea build@2023-08-25T10:30:12)
  DRV: rknnrt: 1.5.3b13 (42cbca6f5@2023-10-27T10:13:21)
==============================================

2.12 Смешанное квантование

2.12.1 hybrid_quantization_step1

Первый этап смешанного квантования выполняет hybrid_quantization_step1. Он создаёт временный файл модели (<model_name>.model), файл данных (<model_name>.data) и конфигурацию квантования (<model_name>.quantization.cfg). Описание интерфейса:

API hybrid_quantization_step1
Описание На основе загруженной исходной модели генерируются временные файлы модели, файлы данных и профили квантования.
Параметры dataset: См. 2.4 «Сборка модели RKNN».
Параметры rknn_batch_size: См. 2.4 «Сборка модели RKNN».
Параметры proposal: Генерировать предложения по настройке смешанного квантования. По умолчанию False.
Параметры proposal_dataset_size: Размер набора данных для proposal. По умолчанию 1. Поскольку proposal требует много времени, используется размер 1.
Параметры custom_hybrid: Выбирает подграф смешанного квантования по нескольким наборам имён входов и выходов, заданных пользователем. Формат: [[input0_name, output0_name], [input1_name, output1_name], …]. По умолчанию None.
Примечание: имена входов и выходов следует выбирать по временному файлу модели (<model_name>.model).
Возвращаемое значение 0: Успешно.
Возвращаемое значение -1: Ошибка.

Пример кода:

# Call hybrid_quantization_step1 to generate quantization config
ret = rknn.hybrid_quantization_step1(dataset='./dataset.txt')

2.12.2 hybrid_quantization_step2

Для этапа формирования смешанно-квантованной модели RKNN вызывается hybrid_quantization_step2. Описание интерфейса:

API hybrid_quantization_step2
Описание Принимает временный файл модели, файл данных, профиль квантования и калибровочный набор данных, затем генерирует модель RKNN со смешанным квантованием.
Параметры model_input: Путь к временному файлу модели (<model_name>.model), созданному hybrid_quantization_step1.
Параметры data_input: Путь к файлу данных модели (<model_name>.data), созданному hybrid_quantization_step1.
Параметры model_quantization_cfg: Путь к изменённому файлу конфигурации квантования (<model_name>.quantization.cfg), созданному hybrid_quantization_step1.
Возвращаемое значение 0: Успешно.
Возвращаемое значение -1: Ошибка.

Пример кода:

# Call hybrid_quantization_step2 to generate hybrid quantized RKNN model
ret = rknn.hybrid_quantization_step2(
       model_input='./ssd_mobilenet_v2.model',
       data_input='./ssd_mobilenet_v2.data',
       model_quantization_cfg='./ssd_mobilenet_v2.quantization.cfg')

2.13 Анализ точности квантования

Интерфейс выполняет инференс квантованной модели и формирует выходы каждого слоя для анализа точности квантования.

API accuracy_analysis
Описание Выполнить инференс квантованной модели и создать снимок, то есть выгрузить данные тензоров каждого слоя. Для вычисления ошибки квантования выгружаются оба типа данных: fp32 и quant.
Примечания:
1. Интерфейс вызывается только после build или hybrid_quantization_step2.
2. Если target равно None, а исходная модель уже квантована (модель QAT), вызов завершится ошибкой.
3. Метод квантования соответствует настройке config.
Параметры inputs: Список путей к изображениям (jpg/png/bmp/npy).
Параметры output_dir: Каталог вывода всех данных снимка. По умолчанию ‘./snapshot’.
Если target не задан, в output_dir создаются:
- Каталог simulator: результаты каждого слоя симулятора при полном выполнении квантованной модели (выход преобразован в float32).
- Каталог golden: результаты каждого слоя симулятора при полном выполнении модели с плавающей точкой.
- error_analysis.txt: косинусное расстояние (entire_error и single_error) между результатом каждого слоя квантованной модели в симуляторе и моделью с плавающей точкой в симуляторе при полном вычислении квантованной модели. Различие entire_error/single_error заключается в том, поступает ли вход каждого слоя из квантованной модели или модели с плавающей точкой. Подробнее см. error_analysis.txt.
Если target задан, в output_dir дополнительно создаются:
- Каталог runtime: результаты каждого слоя при полном выполнении квантованной модели на NPU (выход преобразован в float32).
- error_analysis.txt: дополнительно записывается косинусное расстояние (entire_error) между результатами каждого слоя симулятора и NPU при полном вычислении квантованной модели. Подробнее см. error_analysis.txt.
Параметры target: Целевая аппаратная платформа. Поддерживаются ‘rv1103’, ‘rv1103b’, ‘rv1106’, ‘rv1106b’, ‘rv1126b’, ‘rk3562’, ‘rk3566’, ‘rk3568’, ‘rk3576’ и ‘rk3588’. По умолчанию “None”.
Если target задан, получаются выходы каждого слоя NPU и анализируется их точность.
Параметры device_id: Идентификатор устройства. При подключении нескольких устройств к ПК его необходимо указать; значение получают через list_devices. По умолчанию “None “.
Возвращаемое значение 0: Успешно.
Возвращаемое значение -1: Ошибка.

Пример кода:

# Accuracy analysis
ret = rknn.accuracy_analysis(inputs=['./dog_224x224.jpg'])

2.14 Список устройств

API list_devices
Описание Перечислить подключённые RV1103 / RV1103B / RV1106 / RV1106B / RV1126B / RK3562 / RK3566 / RK3568 / RK3576 / RK3588.
Примечание: поддерживаются два режима подключения устройств — ADB и NTB. При подключении нескольких устройств их режимы должны совпадать.
Параметры None.
Возвращаемое значение Возвращает списки adb_devices и ntb_devices. Если к ПК не подключено ни одного устройства, возвращает два пустых списка.

Пример кода:

rknn.list_devices()

Пример списка устройств:

*************************
all device(s) with adb mode:
VD46C3KM6N
*************************

2.15 Экспорт зашифрованной модели RKNN

Интерфейс шифрует обычную модель RKNN и формирует зашифрованную модель.

API export_encrypted_rknn_model
Описание Шифрует обычную модель RKNN в соответствии с уровнем шифрования, выбранным пользователем.
Примечание: RV1103/RV1103B/RV1106/RV1106B/RK2118 пока не поддерживаются.
Параметры input_model: Путь к модели RKNN для шифрования.
Параметры output_model: Путь сохранения зашифрованной модели. По умолчанию None: используется {original_model_name}.crypt.rknn.
Параметры crypt_level: Уровень шифрования. Поддерживаются 1, 2 или 3; по умолчанию 1.
Чем выше уровень, тем выше безопасность и дольше расшифровка; при более низком уровне безопасность ниже, но расшифровка быстрее.
Возвращаемое значение 0: Успешно.
Возвращаемое значение -1: Ошибка.

Пример кода:

ret = rknn.export_encrypted_rknn_model('test.rknn')

2.16 Регистрация пользовательского оператора

Интерфейс регистрирует пользовательский оператор.

API reg_custom_op
Описание Зарегистрировать пользовательский оператор; поддерживается только для модели ONNX.
Параметры custom_op: Класс пользовательского оператора для создания нового OP вне спецификации операторов ONNX. Рекомендуется начинать op_type нового OP с ‘cst’; пользователь должен реализовать функции shape_infer и compute.
Примечание: класс custom_op используется только при преобразовании модели и генерации моделей RKNN с пользовательскими операторами. Для развёртывания на устройстве также следует обратиться к главе 5.5 ‘RKNN SDK User Guide’.
Возвращаемое значение 0: Успешно.
Возвращаемое значение -1: Ошибка.

Пример кода:

import numpy as np
from rknn.api.custom_op import get_node_attr
class cstSoftmax:
  op_type = 'cstSoftmax'
  def shape_infer(self, node, in_shapes, in_dtypes):
    out_shapes = in_shapes.copy()
    out_dtypes = in_dtypes.copy()
    return out_shapes, out_dtypes
  def compute(self, node, inputs):
    x = inputs[0]
    axis = get_node_attr(node, 'axis')
    x_max = np.max(x, axis=axis, keepdims=True)
    tmp = np.exp(x - x_max)
    s = np.sum(tmp, axis=axis, keepdims=True)
    outputs = [tmp / s]
    return outputs

ret = rknn.reg_custom_op(cstSoftmax)

2.17 Создание примера развёртывания C++

API codegen
Описание Сгенерировать пример развёртывания на C++.
Параметры output_path: Выходной каталог; пользователь может задать его имя.
Параметры inputs: Список путей к входам модели. Допускается оставить пустым. Поддерживаются jpg/png/npy. При использовании npy информация о размерностях данных должна совпадать с размерностями входа модели.
Параметры overwrite: При True файлы в каталоге output_path будут перезаписаны. По умолчанию False.
Возвращаемое значение 0: Успешно.
Возвращаемое значение -1: Ошибка.

Пример кода:

ret = rknn.codegen(output_path='./rknn_app_demo',
        inputs=['./mobilenet_v2/dog_224x224.jpg'],
        overwrite=True)

Другие статьи по теме → · Учебные маршруты →