OpenHarmony AI框架开发指导

一、概述

1、 功能简介

AI业务子系统是OpenHarmony提供原生的分布式AI能力的子系统。AI业务子系统提供了统一的AI引擎框架,实现算法能力快速插件化集成。

AI引擎框架主要包含插件管理、模块管理和通信管理模块,完成对AI算法能力的生命周期管理和按需部署。插件管理主要实现插件的生命周期管理及插件的按需部署,快速集成AI能力插件;模块管理主要实现任务的调度及管理客户端的实例;通信管理主要实现客户端和服务端之间的跨进程通信管理及AI服务与插件之间的数据传输。后续,会逐步定义统一的AI能力接口,便于AI能力的分布式调用。同时,框架提供适配不同推理框架层级的统一推理接口。

AI引擎框架结构如下图所示。

图1 AI引擎框架

2、 搭建环境
  1. 准备开发板:Hi3516DV300或Hi3518EV300

  2. 下载源码

二、技术规范

1、 代码管理规范

AI引擎框架包含client、server和common三个主要模块,其中client提供server端连接管理功能,OpenHarmony SDK在算法对外接口中需封装调用client提供的公共接口;server提供插件加载以及任务管理等功能,各Plugin实现由server提供的插件接口,完成插件接入;common提供与平台相关的操作方法、引擎协议以及相关工具类,供其他各模块调用。

AI引擎框架各模块之间的代码依赖关系如下图所示:

OpenHarmony AI框架开发指导-鸿蒙开发者社区

图2 AI引擎代码依赖关系

建议:插件与OpenHarmony SDK在AI引擎指定的路径下进行代码开发

在AI引擎框架的整体规划中,OpenHarmony SDK属于client端的一部分,插件由server端调用,属于server端的一部分,因此AI引擎框架为接入的插件与OpenHarmony SDK规划的路径:

SDK代码路径://foundation/ai/engine/services/client/algorithm_sdk

示例1://foundation/ai/engine/services/client/algorithm_sdk/cv

示例2://foundation/ai/engine/services/client/algorithm_sdk/nlu

插件代码路径://foundation/ai/engine/services/server/plugin

示例1://foundation/ai/engine/services/server/plugin/cv

示例2://foundation/ai/engine/services/server/plugin/nlu

规则:插件提供的全部对外接口,统一存放在AI业务子系统interfaces/kits目录

OpenHarmony SDK对外接口是AI业务子系统提供能力的对外暴露方式,按照OpenHarmony的接口管理要求,需统一存放在各子系统的interfaces/kits目录中。当前AI业务子系统插件对外接口路径为//foundation/ai/engine/interfaces/kits,不同插件可在该路径下添加目录,比如增加cv插件,则在路径//foundation/ai/engine/interfaces/kits/cv下面存放接口文件。

规则:插件编译输出路径必须是在/usr/lib

server端加载插件是采用dlopen方式,只支持在/usr/lib路径进行,因此插件在编译so时,需要在编译配置文件中指定输出路径为/usr/lib。

2、命名规范

SDK命名规则:领域_关键词<其他信息1_其他信息2…>_sdk.so

关于领域,建议使用当前主流简称,比如图片视频相关的使用"cv",语音识别相关的使用“asr”,翻译相关的使用“translation”等,存在其他领域的可增加定义;关键词则需要恰当准确的描述所对应插件的算法能力,比如唤醒词识别,则使用keyword_spotting;对于其他信息,比如插件支持的芯片类型、国内海外等信息,可在关键词与“sdk”之间依次添加,信息之间以下划线连接;SDK命名,必须以“_sdk”结尾。

例如:唤醒词识别插件对应的SDK,只支持麒麟9000芯片,适用于中国国内地区适用,则对应的SDK命名为:asr_keyword_spotting_kirin9000_china_sdk.so

插件命名规则:领域_关键词<其他信息1_其他信息2…>.so

插件与SDK存在一一对应的关系,故插件命名的领域、关键词、其他信息等名词解释与要求,均与SDK命名要求保持一致。两者唯一的不同之处在于SDK命名多了个“_sdk”结尾;比如插件命名为“asr_keyword_spotting.so”,则对应SDK命名为“asr_keyword_spotting_sdk.so”。

例如:唤醒词识别插件对应的SDK,只支持麒麟9000芯片,适用于中国国内地区适用,则对应的插件命名为:asr_keyword_spotting_kirin9000_china.so

3、 接口开发规范

规则:SDK需按算法调用顺序,封装client对外提供接口;对于异步插件对应的SDK,需要实现client提供的回调接口IClientCb

AI引擎的client端对外提供的接口包括AieClientInit、AieClientPrepare、AieClientSyncProcess、AieClientAsyncProcess、AieClientRelease、AieClientDestroy、AieClientSetOption、AieClientGetOption,SDK需要根据插件的接口按照顺序至少封装AieClientInit、AieClientPrepare、AieClientSyncProcess/AieClientAsyncProcess、AieClientRelease、AieClientDestroy五个接口,否则会出现调用问题或者内存泄漏。比如封装过程遗漏了AieClientPrepare接口,则server端无法完成插件加载,故后面的接口都无法调用成功。

对于异步插件,SDK需要实现IClientCb接口,用于接收来自client端的算法推理结果,并将该结果返回给三方调用者。

规则:SDK接口实现中,需要保存与client交互的相关通用数据

AI引擎将的client端采用单例实现,对接多个SDK,因此各SDK需要保存与client交互的通用数据,用于连接server端进行任务推理、结果返回等;需保存数据包含clientInfo、algorithmInfo、configInfo三种数据类型,定义在SDK的成员变量里即可。

建议:SDK实现client定义的IServiceDeadCb接口

Server端是系统常驻进程,以系统能力的形式为多个client提供服务;client定义的IServiceDeadCb接口,是在server端异常死亡后,会被触发调用。这种异常场景,SDK可在死亡通知接口中,实现相关操作,比如停止调用或者再次拉起server端等。

IServiceDeadCb接口实现示例:

class ServiceDeadCb : public IServiceDeadCb {
public:
ServiceDeadCb() = default;
~ServiceDeadCb() override = default;
void OnServiceDead() override
{
printf("[ServiceDeadCb]OnServiceDead Callback happens");
}
};

如上示例,SDK可在OnServiceDead()方法中实现自己的操作,比如停止所有的接口调用等等。

规则:SDK与plugin需要使用编解码模块,将特定算法数据转换成AI引擎的通用数据类型

插件的推理数据,会由三方调用者通过client、server传递到插件中;不同的算法所需要的数据类型是不一致的,比如cv的需要图片数据、asr的需要语音数据;为了适配数据类型的差异,AI引擎对外提供了对基本数据类型的编解码能力,将不同数据类型转换为AI引擎可以使用的通用数据类型。

编码后的数据类型定义:

struct DataInfo {
unsigned char *data;
int length;
} DataInfo;

如上示例,DataInfo数据结构包括指向数据内存的指针和数据长度两个变量组成。

框架接口使用方法:

1.添加依赖的头文件:“utils/encdec/include/encdec.h”。

2.添加build.gn中的依赖项:

include_dirs添加"//foundation/ai/engine/services/common"。

deps添加"//foundation/ai/engine/services/common/utils/encdec:encdec" 。

3.编解码示例:

// 编码调用函数示例:arg1,arg2,arg3等为需编码的变量,dataInfo为编码后的结果
retCode = ProcessEncode(dataInfo, arg1, arg2, arg3) //可以接收任意多个参数
// 解码调用函数示例:dataInfo为需要解码的信息,arg1,arg2,arg3等为解码后的结果
retCode = ProcessDecode(dataInfo, arg1, arg2, arg3) //可以接收任意多个参数

注意:

​ ● 编码和解码调用时的参数顺序需要保证一致。

​ ● 编码后dataInfo的内存需要调用者手动进行释放。

​ ● server端和client端的内存是分开管理和释放的。

​ ● 如果包含共享内存的指针,不需要额外处理。

​ ● 如果其他类型的指针,则需要解引用后使用ProcessEncode/ ProcessDecode。

​ ● 该编解码模块未适配class数据类型,不建议使用。

规则:在SDK中,对以编解码返回的出参数据类型,需要进行内存释放,否则会出现内存泄漏

编码得到的通用数据,本质上是将不同类型数据封装在同一块内存中,然后将这块内存的首地址与长度封装到结构体中。通过编码返回到SDK中的出参数据,在插件中申请了内存,但插件无法释放;因此SDK在拿到数据之后,需要对内存进行释放,否则SDK将无法拿到数据。

内存释放示例:

DataInfo outputInfo = {
.data = nullptr,
.length = 0,
};
AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr);
if (outputInfo.data != nullptr) {
free(outputInfo.data);
outputInfo.data = nullptr;
outputInfo.length = 0;
}

规则:plugin需要实现server定义的IPlugin接口,并使用宏PLUGIN_INTERFACE_IMPL对外提供插件函数指针

Server端管理的插件内部接口实现逻辑各不相同,为了统一插件的加载流程,AI引擎定义了插件接口IPlugin;在运行态,插件是以动态链接库的形式被AI引擎框架通过dlopen方式加载,各插件需要使用PLUGIN_INTERFACE_IMPL语句对外暴露函数指针,否则插件将无法被正常加载使用。

规则:plugin需要使用AI引擎提供的统一数据通道

AI引擎在server与插件之间,提供了一个统一的数据通道,用来处理来自SDK的推理请求和来自插件的结果返回;plugin在推理接口中,需按数据通道完成请求数据的获取以及推理结果的封装。

数据通道使用示例:

int SyncProcess(IRequest *request, IResponse *&response)
{
HILOGI("[IvpPlugin]Begin SyncProcess");
if (request == nullptr) {
HILOGE("[IvpPlugin]SyncProcess request is nullptr");
return RETCODE_NULL_PARAM;
}
DataInfo inputInfo = request->GetMsg();
if (inputInfo.data == nullptr) {
HILOGE("[IvpPlugin]InputInfo data is nullptr");
return RETCODE_NULL_PARAM;
}...response = IResponse::Create(request);
response->SetResult(outputInfo);
return RETCODE_SUCCESS;
}

示例中request和response是数据通道的内容主体。server端会将数据封装在request中,传递到插件,插件进行算法处理之后,则需要将结果封装成response进行返回。

三、开发指导

1、开发SDK

SDK头文件的功能实现是基于对SDK的调用映射到对客户端的调用。Client端提供的接口如下表所示。

接口名接口说明参数要求
int AieClientInit(const ConfigInfo &configInfo, ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, IServiceDeadCb *cb)作用:链接并初始化引擎服务,激活跨进程调用。返回值:0为成功,其他返回值失败。configInfo(不能为NULL):引擎相关初始化配置数据clientInfo(不能为NULL):引擎客户端信息algorithmInfo(不能为NULL):调用算法信息cb(可为NULL):死亡回调对象
int AieClientPrepare(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo, IClientCb *cb)作用:加载算法插件。返回值: 0为成功,其他返回值失败。clientInfo(不能为NULL):引擎客户端信息algorithmInfo(不能为NULL):调用算法信息inputInfo(可为NULL):加载算法插件时输入所需信息outputInfo(可为NULL):加载算法插件之后如需返回信息则通过此出参返回cb:异步算法通过此回调返回运算结果,因此异步算法此结构体不能为空 若为同步算法,传入空值即可
int AieClientAsyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)作用:执行异步算法。返回值:0为成功,其他返回值失败。clientInfo(不能为NULL):引擎客户端信息algorithmInfo(不能为NULL):调用算法信息inputInfo(可为NULL):算法运算入参
int AieClientSyncProcess(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo, DataInfo &outputInfo)作用:执行同步算法。返回值:0为成功,其他返回值失败。clientInfo(不能为NULL):引擎客户端信息algorithmInfo(不能为NULL):调用算法信息inputInfo(可为NULL):算法运算入参outputInfo(可为NULL):同步算法运算结果出参
int AieClientRelease(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo, const DataInfo &inputInfo)作用:卸载算法插件。返回值:0为成功,其他返回值失败。clientInfo(不能为NULL):引擎客户端信息algorithmInfo(不能为NULL):卸载算法插件的相关信息inputInfo(可为NULL):调用卸载接口时的输入信息
int AieClientDestroy(ClientInfo &clientInfo)作用:断开与服务端的链接,释放相关缓存。返回值:0为成功,其他返回值失败。clientInfo(不能为NULL):所要销毁的引擎客户端信息
int AieClientSetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo)作用:设置配置项,可将一些算法的拓展信息通过此接口传入插件。返回值:0为成功,其他返回值失败。clientInfo(不能为NULL):引擎客户端信息optionType (不能为NULL):算法配置项,算法插件可根据需要利用此状态位inputInfo(可为NULL):插件可根据需要通过此入参设置算法参数信息
int AieClientGetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo, DataInfo &outputInfo)作用:给定特定的optionType和inputInfo,获取其对应的配置项信息。返回值:0为成功,其他返回值失败。clientInfo(不能为NULL):引擎客户端信息optionType(不能为NULL):所获取配置项信息的对应算法状态位inputInfo(可为NULL):所获取配置项信息的对应算法参数信息outputInfo(可为NULL):所要获取的配置项信息返回结果

表1 Client端提供的接口

其中,ConfigInfo,ClientInfo,AlgorithmInfo,DataInfo的数据结构如下表所示。

结构体名称说明属性
ConfigInfo算法配置项信息。const char *description:配置项信息主体
ClientInfo客户端信息。long long clientVersion:客户端设备版本号(当前还未启用)int clientId:客户端IDint sessionId:会话IDuid_t serverUid:server端UIDuid_t clientUid:client端UIDint extendLen:拓展信息(extendMsg)长度unsigned char *extendMsg:拓展信息主体
AlgorithmInfo算法信息。long long clientVersion:客户端设备版本号(当前还未启用)bool isAsync:是否为异步执行int algorithmType:引擎框架根据插件加载顺序分配的算法类型IDlong long algorithmVersion:算法版本号bool isCloud:是否上云(当前还未启用)int operateId:执行ID(当前还未启用)int requestId:请求ID,标识每次request,以对应执行结果int extendLen:拓展信息(extendMsg)长度unsigned char *extendMsg:拓展信息主体
DataInfo算法数据入参(inputInfo)、接口调用结果出参(outputInfo)。unsigned char *data:数据主体int length:数据(data)长度

表2 ConfigInfo,ClientInfo,AlgorithmInfo,DataInfo的数据结构

具体开发过程可参考唤醒词识别SDK开发示例

2、 开发插件

AI引擎框架规定了一套算法插件接入规范,各插件需实现规定接口以实现获取插件版本信息、算法推理类型、同步执行算法、异步执行算法、加载算法插件、卸载算法插件、设置算法配置信息、获取指定算法配置信息等功能。(同步算法实现SyncProcess接口,异步算法实现AsyncProcess接口)。

算法插件类IPlugin接口设计如下表所示。

接口名接口说明参数要求
const long long GetVersion() const;作用:获取插件版本信息。返回值:版本号(long long)-
const char *GetInferMode() const;作用:获取算法推理类型。返回值:“SYNC” or “ASYNC”;-
int SyncProcess(IRequest *request,IResponse *&response);作用:执行插件同步算法。返回值:0为成功,其他返回值为失败。request(NOT NULL):用于向算法插件传递请求内容;引擎服务端与插件的数据通道。response(NOT NULL):作为出参用于接收算法插件发回的同步算法执行结果,引擎服务端与插件的数据通道。
int AsyncProcess(IRequest *request,IPluginAlgorithmCallback *callback);作用:执行异步算法。返回值:0为成功,其他返回值为失败。request(NOT NULL):用于向算法插件传递请求内容;引擎服务端与插件的数据通道。callback(NOT NULL):算法插件异步执行结果通过此回调返回引擎服务端。
int Prepare(long long transactionId,const DataInfo &inputInfo, DataInfo&outputInfo);作用:加载算法插件。返回值:0为成功,其他返回值为失败。transactionId(NOT NULL):事务ID,用于标记客户端+会话信息。inputInfo(可为NULL):加载算法插件传入的一些信息。outputInfo(可为NULL):调用加载接口时的出参,返回相关执行结果。
int Release(bool isFullUnload, long longtransactionId, const DataInfo &inputInfo);作用:卸载相关算法插件。返回值:0为成功,其他返回值为失败。isFullUnload(NOT NULL):表示此插件是否只剩一个client调用,否则不能直接卸载插件,需等最后一个client来进行卸载。transactionId(NOT NULL):事务ID,用于标记客户端+会话信息。inputInfo(可为NULL):卸载算法插件传入的一些信息。
int SetOption(int optionType, constDataInfo &inputInfo);作用:设置配置项,可将一些算法的拓展信息通过此接口传入插件。返回值:0为成功,其他返回值为失败。optionType (NOT NULL):算法配置项,算法插件可根据需要利用此状态位。inputInfo(可为NULL):插件可根据需要通过此入参设置算法参数信息。
int GetOption(int optionType, constDataInfo &inputInfo, DataInfo&outputInfo);作用:给定特定的optionType和inputInfo,获取其对应的配置项信息。返回值:0为成功,其他返回值为失败。optionType(NOT NULL):所获取配置项信息的对应算法状态位。inputInfo(可为NULL):所获取配置项信息的对应算法参数信息。outputInfo(可为NULL):所要获取的配置项信息返回结果。

表3 算法插件类IPlugin接口设计

算法插件类接口:Prepare、SyncProcess、AsyncProcess、Release、SetOption、GetOption分别于客户端接口AieClientPrepare、AieClientSyncProcess、AieClientAsyncProcess、AieClientRelease、AieClientSetOption、AieClientGetOption一一对应;GetInferMode接口用于返回算法执行类型——同步或异步。

算法插件回调类IPluginCallback 接口设计如下表所示。

接口名接口说明参数要求
void OnEvent(PluginEvent event,IResponse *response);作用:插件通过此回调返回异步算法执行结果。event:算法执行结果枚举,‘ON_PLUGIN_SUCCEED’或 ‘ON_PLUGIN_FAIL’(成功或者失败)。response:算法执行结果封装。

表4 算法插件回调类IPluginCallback 接口设计

Request、Response是AI引擎服务端与算法插件进行通信的对象。Request封装了调用方的请求、输入数据等,而插件主要通过Response将运算之后的结果返回给AI引擎服务端。

Request类的属性如下表所示。

属性名称属性说明默认值
innerSequenceId_类型:long long作用:暂未启用。0
requestId_类型:int作用:标识请求序列,用于绑定返回运算结果。0
operationId_类型:int作用:暂未启用。0
transactionId_类型:long long作用:事务ID,唯一标识clientId+sessionId。0
algoPluginType_类型:int作用:引擎框架根据插件加载顺序分配的算法类型的ID。0
msg_类型:DataInfo作用:存放调用算法接口的输入数据。.data = nullptr.length = 0

表5 Request类的属性

Response类的属性如下表所示。

属性名称属性说明默认值
innerSequenceId_类型:long long作用:暂未启用。0
requestId_类型:int作用:标识请求序列,用于绑定返回运算结果。0
retCode__类型:int作用:异步执行算法推理结果码。0
retDesc_类型:string作用:暂未启用。-
transactionId_类型:long long作用:事务ID,唯一标识clientId+sessionId。0
algoPluginType_类型:int作用:引擎框架根据插件加载顺序分配的算法类型的ID。INVALID_ALGO_PLUGIN_TYPE(-1)
result_类型:DataInfo作用:存放异步算法推理结果。.data = nullptr.length = 0

表6 Response类的属性

具体开发过程可参考唤醒词识别插件开发示例

3、开发配置文件

开发者开发的SDK通过AlgorithmInfo结构体中algorithmVersion以及algorithmType识别出具体的插件类型,实现插件能力的调用。因此开发者需完成以下步骤:

  1. 代码路径//foundation/ai/engine/services/common/protocol/plugin_config/plugin_config_ini/中添加插件的配置文件。

  2. 代码路径//foundation/ai/engine/services/common/protocol/plugin_config/中的aie_algorithm_type.h文件添加算法类型。

  3. 代码路径//foundation/ai/engine/services/server/plugin_manager/include/中的aie_plugin_info.h文件添加唤醒词识别的算法名称及其在ALGORITHM_TYPE_ID_LIST中的序号。

具体开发过程可参考唤醒词识别配置文件开发示例

四、开发实例

1、唤醒词识别SDK的开发示例
  1. 在//foundation/ai/engine /interfaces/kits目录中添加唤醒词识别SDK的API接口定义,该接口可用三方应用进行调用。如下代码片段即为唤醒词识别定义的API接口示例,其相关代码参考路径为://foundation/ai/engine/interfaces/kits/asr/keyword_spotting。
class KWSSdk {
public:KWSSdk();virtual ~KWSSdk();// 定义创建唤醒词检测工具包的方法int32_t Create();// 定义同步执行唤醒词检测任务的方法int32_t SyncExecute(const Array<int16_t> &audioInput);// 定义设置唤醒词检测回调器的方法。int32_t SetCallback(const std::shared_ptr<KWSCallback> &callback);// 定义销毁唤醒词工具包的方法,释放与插件的会话信息int32_t Destroy();
};
  1. 在//foundation/ai/engine/services/client/algorithm_sdk目录中增加SDK中API接口的具体实现,调用client端提供的接口,实现算法插件能力的使用。如下代码片段即为唤醒词识别的API接口中create方法的具体实现示例,更多详细代码请参考://foundation/ai/engine/services/client/algorithm_sdk/asr/keyword_spotting。
int32_t KWSSdk::KWSSdkImpl::Create()
{if (kwsHandle_ != INVALID_KWS_HANDLE) {HILOGE("[KWSSdkImpl]The SDK has been created");return KWS_RETCODE_FAILURE;}if (InitComponents() != RETCODE_SUCCESS) {HILOGE("[KWSSdkImpl]Fail to init sdk components");return KWS_RETCODE_FAILURE;}// 调用client端提供的AieClientInit接口,实现初始化引擎服务,激活跨进程调用int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr);if (retCode != RETCODE_SUCCESS) {HILOGE("[KWSSdkImpl]AieClientInit failed. Error code[%d]", retCode);return KWS_RETCODE_FAILURE;}if (clientInfo_.clientId == INVALID_CLIENT_ID) {HILOGE("[KWSSdkImpl]Fail to allocate client id");return KWS_RETCODE_FAILURE;}DataInfo inputInfo = {.data = nullptr,.length = 0,};DataInfo outputInfo = {.data = nullptr,.length = 0,};// 调用client端提供的AieClientPrepare接口,实现加载算法插件retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr);if (retCode != RETCODE_SUCCESS) {HILOGE("[KWSSdkImpl]AieclientPrepare failed. Error code[%d]", retCode);return KWS_RETCODE_FAILURE;}if (outputInfo.data == nullptr || outputInfo.length <= 0) {HILOGE("[KWSSdkImpl]The data or length of output info is invalid");return KWS_RETCODE_FAILURE;}MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data);retCode = PluginHelper::UnSerializeHandle(outputInfo, kwsHandle_);if (retCode != RETCODE_SUCCESS) {HILOGE("[KWSSdkImpl]Get handle from inputInfo failed");return KWS_RETCODE_FAILURE;}return KWS_RETCODE_SUCCESS;
}

上述代码为API接口的具体实现。在示例代码中,SDK中create接口的具体实现即为上述示例代码中create方法,该方法调用了AI引擎框架client端提供的AieClientInit及AieClientPrepare接口,从而实现与server端建立连接及加载算法模型的能力。

说明:

SDK调用AI引擎client端接口应遵循AieClientInit->AieClientPrepare->AieClientSyncProcess/AieClientAsyncProcess->AieClientRelease->AieClientDestroy顺序,否则调用接口会返回错误码。

2、 唤醒词识别插件的开发示例

在代码路径//foundation/ai/engine/services/server/plugin中添加唤醒词识别插件的接口定义(IPlugin),并实现AI能力的调用。如下代码片段即实现唤醒词识别的算法插件的接口定义。更多插件开发的相关代码参考路径如下://foundation/ai/engine/services/server/plugin/asr/keyword_spotting

#include "plugin/i_plugin.h
class KWSPlugin : public IPlugin {
public:KWSPlugin();~KWSPlugin();const long long GetVersion() const override;const char* GetName() const override;const char* GetInferMode() const override;int32_t Prepare(long long transactionId, const DataInfo &amp;amp;inputInfo, DataInfo &amp;amp;outputInfo) override;int32_t SetOption(int optionType, const DataInfo &amp;amp;inputInfo) override;int32_t GetOption(int optionType, const DataInfo &amp;amp;inputInfo, DataInfo &amp;amp;outputInfo) override;int32_t SyncProcess(IRequest *request, IResponse *&amp;amp;response) override;int32_t AsyncProcess(IRequest *request, IPluginCallback*callback) override;int32_t Release(bool isFullUnload, long long transactionId, const DataInfo &amp;amp;inputInfo) override;
};

上述代码实现server提供的IPlugin接口。唤醒词识别的sample中调用的client端接口与插件中的接口对应关系及其实现功能如下表所示。

client端定义的接口插件中定义的接口功能
AieClientPreparePrepare提供推理算法插件初始化功能,例如:加载唤醒词识别模型,将固定位置(/sdcard/wenwen_inst.wk)模型加载至内存。
AieClientSyncProcessSyncProcess提供同步执行推理算法的能力,例如:实现同步执行音频推理算法,判断音频中是否存在唤醒词。
AieClientAsyncProcessAsyncProcess提供异步执行推理算法的能力,当前唤醒词识别场景不涉及,但开发者可根据具体场景自行实现。
AieClientSetOptionSetOption提供手动设置算法相关配置项,如置信度阈值、时延等超参数的能力。当前唤醒词识别场景未涉及,开发者可视具体场景自行实现。
AieClientGetOptionGetOption提供获取算法相关配置项,以唤醒词识别为例:获取唤醒词模型中输入输出的规模,输入规模即为唤醒词识别模型要求输入的MFCC特征的维度(固定值:4000),输出规模即为结果的置信度得分维度(固定值:2)。
AieClientReleaseRelease提供卸载算法模型功能,以唤醒词识别为例:实现卸载相关模型,并清理特征处理器中的动态内存。

表7 唤醒词识别中client端接口与插件中的接口对应关系

注意:

1.接口AieClientInit、AieClientDestroy分别用于与server端建立和断开连接,未调用到插件算法中,因此插件中无需定义与之对应的接口。

2.唤醒词识别插件需要使用PLUGIN_INTERFACE_IMPL语句对外暴露函数指针,否则插件将无法被正常加载使用。

PLUGIN_INTERFACE_IMPL(KWSPlugin);
3、唤醒词识别配置文件的开发示例
  1. 在代码路径//foundation/ai/engine/services/common/protocol/plugin_config/plugin_config_ini/中添加唤醒词识别的配置文件。
[base]
supported_boards = hi3516dv300
related_sessions = asr_keyword_spotting+20001002//[asr_keyword_spotting+20001002]的命名规则为[算法名称+算法version]
[asr_keyword_spotting+20001002]
AID         = asr_keyword_spotting
VersionCode = 20001002
VersionName = 2.00.01.002
XPU         = NNIE
District    = China
// 编译出的插件so文件所在的位置
FullPath    = /usr/lib/libasr_keyword_spotting.so
Chipset     = ALL
ChkSum      = ''
Key         = ''
  1. 在代码路径//foundation/ai/engine/services/common/protocol/plugin_config/中的aie_algorithm_type.h文件添加唤醒词识别算法类型id。
// 唤醒词识别的算法类型id与唤醒词识别在ALGORITHM_TYPE_ID_LIST中的序号一一对应
const int ALGORITHM_TYPE_KWS = 3;

3.在代码路径//foundation/ai/engine/services/server/plugin_manager/include/中的aie_plugin_info.h文件添加唤醒词识别算法名称及在ALGORITHM_TYPE_ID_LIST中的序号。

const std::string ALGORITHM_ID_SAMPLE_1 = "sample_plugin_1";
const std::string ALGORITHM_ID_SAMPLE_2 = "sample_plugin_2";
const std::string ALGORITHM_ID_IVP = "cv_human_detect";
// 添加唤醒词识别的算法名称asr_keyword_spotting
// 算法的变量名称与ALGORITHM_TYPE_ID_LIST中算法typeId命名相同,例如:ALGORITHM_ID_KWS 
const std::string ALGORITHM_ID_KWS = "asr_keyword_spotting";
const std::string ALGORITHM_ID_IC = "cv_image_classification";
const std::string ALGORITHM_ID_INVALID = "invalid algorithm id";const std::vector<std::string> ALGORITHM_TYPE_ID_LIST = {ALGORITHM_ID_SAMPLE_1,ALGORITHM_ID_SAMPLE_2,ALGORITHM_ID_IVP,// 添加唤醒词识别在ALGORITHM_TYPE_ID_LIST中的序号,通过该序号可获得唤醒词识别的算法名称// 唤醒词识别的算法名称和唤醒词识别在ALGORITHM_TYPE_ID_LIST中的序号顺序需保持一致ALGORITHM_ID_KWS,ALGORITHM_ID_IC,
};

为了能让大家更好的学习鸿蒙 (OpenHarmony) 开发技术,这边特意整理了《鸿蒙 (OpenHarmony)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙 (OpenHarmony)开发学习手册》

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. ……

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

如何快速入门?:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. 构建第一个JS应用
  4. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/418484.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

检索增强(RAG)的方式---重排序re-ranking

提升RAG&#xff1a;选择最佳嵌入Embedding&重排序Reranker模型 检索增强生成(RAG)技术创新进展&#xff1a;自我检索、重排序、前瞻检索、系统2注意力、多模态RAG RAG的re-ranking指的是对初步检索出来的候选段落或者文章&#xff0c;通过重新排序的方式来提升检索质量。…

红包封面免费送1000个,你设计,我出额度

相信最近大家或多或少都知道了吧&#xff0c;腾讯又又又给大家&#xff0c;准确的说是给一年勤奋的公众号/视频号博主一个福利 根据不同博主的粉丝、更新频度以及作品质量&#xff0c;给力博主们免费制作红包封面的福利 比如我这个号&#xff0c;有6000额度 那这6000个&#…

从规则到神经网络:机器翻译技术的演化之路

文章目录 从规则到神经网络&#xff1a;机器翻译技术的演化之路一、概述1. 机器翻译的历史与发展2. 神经机器翻译的兴起3. 技术对现代社会的影响 二、机器翻译的核心技术1. 规则基础的机器翻译&#xff08;Rule-Based Machine Translation, RBMT&#xff09;2. 统计机器翻译&am…

【STM32】STM32学习笔记-I2C通信协议(31)

00. 目录 文章目录 00. 目录01. I2C简介02. I2C主要特点03. I2C硬件电路04. I2C时序基本单元05. I2C时序波形图06. 附录 01. I2C简介 I2C(Inter&#xff0d;Integrated Circuit)总线是一种由NXP&#xff08;原PHILIPS&#xff09;公司开发的两线式串行总线&#xff0c;用于连接…

【高等数学之定积分】

一、什么是定积分? 我们第一次新手司机开车从某一地方到(一数)家&#xff0c;自始至终保持着匀速行驶&#xff0c;那么这个过程所经历的路程是什么呢?用速度-时间函数图像来表示一下&#xff0c;我们发现其实就是其曲线下的面积。 第二次开车我们已经有了一定的经验&#xff…

vivado 定义板文件板

定义板文件板 &#xff1c;board&#xff1e;标记是板文件的根。它包括识别基本信息的属性关于董事会。 <board schema_version"2.1" vendor"xilinx.com" name"kc705" display_name"Kintex-7 KC705 Evaluation Platform" url&qu…

数据结构小项目----通讯录的实现(这里用链表实现) 超详细~~~~૮(˶ᵔ ᵕ ᵔ˶)ა

目录 Contact.h说明&#xff1a; 结构体与头文件的包含&#xff1a; ​编辑 函数在头文件的声明与定义&#xff1a; Contact.c中各个函数的实现&#xff1a; 1.检查链表中的数据是否满了&#xff0c;满了就扩容 2.链表的尾插 3.链表的删除 4.查找名字是否匹配 5.初始化通讯…

代码随想录二刷 |二叉树 | 将有序数组转换为二叉搜索树

代码随想录二刷 |二叉树 | 将有序数组转换为二叉搜索树 题目描述解题思路代码实现 题目描述 109.将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组&#xff0c;转换为一棵高度平衡二叉搜索树。 本题中&#xff0c;一个高度平衡二叉树是指一个二叉树每个节点 的左右…

Zabbix 系统监控详解

1 介绍 1.1 摘要 本文深入浅出&#xff0c;切近实际运维应用&#xff0c;由 zabbix 3.4 版本入手&#xff0c;学习 zabbix 监控告警实现方式&#xff0c;由 zabbix 5.0 浅出实现快速部署、快速应用。本人从业多年&#xff0c;关注 zabbix 开源社区&#xff0c;以及 zabbix 官…

企业邮箱:定义、功能与优势一览

本文将为大家讲解&#xff1a;1、企业邮箱的定义&#xff1b;2、企业邮箱的主要功能特点&#xff1b;3、企业邮箱如何选择和部署&#xff1b;4、企业邮箱的运营与维护&#xff1b;5、企业邮箱在实际工作中的应用与挑战&#xff1b;6、2024年最新五大企业邮箱盘点 下面提到的功能…

【kali后续配置】Kali Linux 换源更新及配置SSH服务一文通(一键换源脚本)

在前面&#xff0c;我们已经下载并安装了Kali Linux 2023版本&#xff0c;因为一些事情的耽误&#xff0c;后面的一些操作教程没有发出来&#xff0c;今天给大家补上。 Kali Linux安装 前置准备&#xff1a; VMware安装kali Linux 镜像下载 kali源 官方源 deb http://htt…

基于JavaWeb+SSM+Vue基于微信小程序的网上商城系统的设计和实现

基于JavaWebSSMVue基于微信小程序的网上商城系统的设计和实现 滑到文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 滑到文末获取源码 Lun文目录 目录 1系统概述 1 1.1 研究背景 1 1.2研究目的 1 1.3系统设计思想…