Платформа и источник
Статья подготовлена по PDF производителя RKNN V2.5.0 и относится только к перечисленным в нём чипам и интерфейсам. Для платы ArmSoM сначала проверьте SoC, драйвер NPU, Toolkit/Runtime, SDK/BSP и версию ядра. Проверки на оборудовании ArmSoM не проводились; примеры и измерения оригинала не являются тестами ArmSoM.
Навигация по серии
- Платформы, заголовки и компоновка
- Владение памятью и общий/zero-copy процессы
- Устройство, контекст и флаги инициализации
- Запросы модели, тензоров и динамических форм
- Вход, выполнение, выход и динамические формы
- Тензоры, выделение памяти и синхронизация
- Матричное умножение и динамические формы
- Регистрация и атрибуты пользовательских операторов
- Коды состояния, тензоры, память и расширения
- Структуры матричного умножения
- Структуры операторов и миграция устаревших API
5.3. Выполнение инференса
Настройка входов, инференс, получение выходов и динамические формы.
rknn_inputs_set
rknn_inputs_set задаёт входные данные модели. Поддерживается несколько входов, каждый представлен объектом rknn_input. До вызова rknn_inputs_set пользователь должен заполнить поля этих объектов. Недоступно на RV1106/RV1103/RV1103B/RV1106B/RK2118.
| API | rknn_inputs_set |
|---|---|
| Описание | Задаёт входные данные модели. |
| Параметр | rknn_context context: объект rknn_contex (написание источника). |
| Параметр | uint32_t n_inputs: число входов. |
| Параметр | rknn_input inputs[]: массив rknn_input. |
| Возвращаемое значение | int: Код ошибки (см. коды состояния). |
Пример кода:
rknn_input inputs[1];
memset(inputs, 0, sizeof(inputs));
inputs[0].index = 0;
inputs[0].type = RKNN_TENSOR_UINT8;
inputs[0].size = img_width*img_height*img_channels;
inputs[0].fmt = RKNN_TENSOR_NHWC;
inputs[0].buf = in_data;
inputs[0].pass_through = 0;
ret = rknn_inputs_set(ctx, 1, inputs);
rknn_run
rknn_run выполняет инференс модели. До вызова входные данные следует настроить через rknn_inputs_set или интерфейс без копирования.
| API | rknn_run |
|---|---|
| Описание | Выполняет инференс модели. |
| Параметр | rknn_context context: объект rknn_contex (написание источника). |
| Параметр | rknn_run_extend* extend: резерв расширения; в описываемой версии не используется, допускается только NULL. |
| Возвращаемое значение | int: Код ошибки (см. коды состояния). |
Пример кода:
ret = rknn_run(ctx, NULL);
rknn_outputs_get
rknn_outputs_get получает выходные данные модели. Можно получить несколько выходов, каждый представлен объектом rknn_output, который необходимо создать и инициализировать перед вызовом. RV1106/RV1103/RV1106B/RV1103B/RK2118 не поддерживаются.
Есть два способа предоставления буферов выходных данных:
- Пользователь сам выделяет и освобождает буферы. Тогда rknn_output.is_prealloc=1, а rknn_output.buf указывает на выделенный пользователем буфер.
- Память выделяет rknn. Тогда rknn_output.is_prealloc=0. После выполнения функции создаётся rknn_output.buf с выходными данными.
| API | rknn_outputs_get |
|---|---|
| Описание | Получает выходные данные инференса. |
| Параметр | rknn_context context: объект rknn_context. |
| Параметр | uint32_t n_outputs: число выходов. |
| Параметр | rknn_output outputs[]: массив rknn_output. |
| Параметр | rknn_run_extend* extend: резерв расширения; пока не используется, допускается только NULL. Тип сохранён по источнику. |
| Возвращаемое значение | int: Код ошибки (см. коды состояния). |
Пример кода:
rknn_output outputs[io_num.n_output];
memset(outputs, 0, sizeof(outputs));
for (int i = 0; i < io_num.n_output; i++) {
outputs[i].index = i;
outputs[i].is_prealloc = 0;
outputs[i].want_float = 1;
}
ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);
rknn_outputs_release
rknn_outputs_release освобождает ресурсы объекта rknn_output.
| API | rknn_outputs_release |
|---|---|
| Описание | Освобождает объект rknn_output. |
| Параметр | rknn_context context: объект rknn_context. |
| Параметр | uint32_t n_outputs: число выходов. |
| Параметр | rknn_output outputs[]: массив освобождаемых rknn_output. |
| Возвращаемое значение | int: Код ошибки (см. коды состояния). |
Пример кода:
ret = rknn_outputs_release(ctx, io_num.n_output, outputs);
rknn_set_input_shape (устаревший интерфейс)
Интерфейс устарел. Для привязки форм входа используйте rknn_set_input_shapes. В текущей версии старый интерфейс недоступен. Для продолжения его использования нужен SDK 1.5.0 и руководство версии 1.5.0.
rknn_set_input_shapes
Для модели с динамическим входом перед инференсом укажите текущую форму. Передаются число входов и массив rknn_tensor_attr с формами и компоновками. Заполните index, name, dims и fmt каждого элемента; остальные поля не требуются. Через rknn_query можно заранее получить число входных форм и список поддерживаемых динамических форм. Форма входа должна входить в этот список. Вызов необходим при первом запуске и каждом переключении формы; иначе повторять его не нужно.
| API | rknn_set_input_shapes |
|---|---|
| Описание | Задаёт текущую форму входа модели. |
| Параметр | rknn_context context: объект rknn_context. |
| Параметр | uint32_t n_inputs: число входных тензоров. |
| Параметр | rknn_tensor_attr *: указатель массива атрибутов со всеми формами входов. Для каждого входа задаются index, name, dims, fmt и n_dims; остальные поля не требуются. |
| Возвращаемое значение | int: Код ошибки (см. коды состояния). |
Пример кода:
for (int i = 0; i < io_num.n_input; i++) {
for (int j = 0; j < input_attrs[i].n_dims; ++j) {
input_attrs[i].dims[j] = dyn_range[i].dyn_range[0][j];
}
}
ret = rknn_set_input_shapes(ctx, io_num.n_input, input_attrs);
if (ret < 0) {
fprintf(stderr, "rknn_set_input_shapes error! ret=%d\n", ret);
return -1;
}
Источник и редакционные примечания
Технические главы разделены по назначению. Код, идентификаторы и параметры сохранены. Китайская версия следует китайскому оригиналу; английская, русская и немецкая — английскому. В главы без иллюстраций вымышленные изображения не добавлены.
Оговорки оригинала: номера глав и примерные журналы сохранены; ранние версии SDK в журналах не являются версией этой статьи. Runtime переходит от главы 3 к 5 и повторяет номера запросов. Таблица rknn_init называет extend отключённым, но далее описывает user_key и общие веса. Текст о нативном динамическом выходе указывает RKNN_QUERY_CURRENT_OUTPUT_ATTR, пример — RKNN_QUERY_CURRENT_NATIVE_OUTPUT_ATTR. Некоторые описания native NHWC/NC1HWC2 смешивают вход и выход. Проверяйте фактические заголовки V2.5.0 и целевой SDK: поведение не подтверждено тестами. Ссылка RK2118 в оригинале называется RKNN3_RK2118_Quick_Start.pdf, а в текущем каталоге находится руководство RKNN2.
