AidGen C++ 接口文档
AidGen C++ 接口文档
AidGen 2.x C++ 接口文档
💡注意
使用 AidGen-SDK 2.x C++ 开发需要了解如下基本事项:
- 编译时需要包含头文件,存放路径
/usr/local/include/aidlux/aidgen/aidgen.hpp - 链接时需要指定库文件,存放路径
/usr/local/lib/libaidgen.so - 所有接口均位于
aplux::aidgen命名空间下 - AidGen 2.x 统一了 LLM 文本生成、多模态推理、Embedding 向量化等能力,提供一致的 API 风格与编程模型
- 相比 1.x 版本,2.x 将
aidllm与aidmlm的功能整合进统一的aidgen命名空间,并提供了 Context → Tokenizer / EmbeddingExtractor / Generator 的分层架构
日志级别.enum LogLevel
AidGen-SDK 提供有设置日志的接口,需要提供给接口当前使用哪个日志级别,所以就需要使用此日志级别枚举。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| INFO | uint8_t | 0 | 消息 |
| WARNING | uint8_t | 1 | 警告 |
| ERROR | uint8_t | 2 | 错误 |
| FATAL | uint8_t | 3 | 致命错误 |
错误码.enum ErrorCode
AidGen-SDK 2.x 的各接口方法统一返回 ErrorCode 枚举值,开发者可根据返回的错误码判断操作是否成功并定位问题。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| SUCCESS | int32_t | 0 | 操作成功 |
| INVALID_PARAM | int32_t | -1 | 无效参数 |
| NOT_INITIALIZED | int32_t | -2 | 尚未初始化 |
| ALREADY_INITIALIZED | int32_t | -3 | 重复初始化 |
| OUT_OF_MEMORY | int32_t | -4 | 内存不足 |
| UNSUPPORTED | int32_t | -5 | 不支持的操作 |
| ABORTED | int32_t | -6 | 操作被中断 |
| FILE_NOT_FOUND | int32_t | -10 | 文件不存在或路径无效 |
| FILE_OPEN_FAILED | int32_t | -11 | 文件无法打开(权限不足或被占用) |
| FILE_EMPTY | int32_t | -12 | 文件存在但内容为空 |
| FILE_READ_ERROR | int32_t | -13 | 文件读取I/O截断或系统级错误 |
| FILE_PARSE_ERROR | int32_t | -14 | 文件内容JSON解析失败 |
| BACKEND_ERROR | int32_t | -20 | 后端运行时通用错误 |
| BACKEND_NOT_FOUND | int32_t | -21 | 找不到后端动态库 |
| INTERNAL_ERROR | int32_t | -99 | 未知异常或系统级崩溃兜底 |
后端类型.enum BackendType
对于 AidGen-SDK 2.x 而言,支持使用不同的推理后端框架来实现大模型的推理任务,涉及到的推理后端如下所示。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| DEFAULT | uint8_t | 0 | 自动选择(优先 QNN248 > QNN240 > QNN236) |
| QNN236 | uint8_t | 1 | 高通 QNN SDK 2.36 推理后端 |
| QNN240 | uint8_t | 2 | 高通 QNN SDK 2.40 推理后端 |
| QNN248 | uint8_t | 3 | 高通 QNN SDK 2.48 推理后端 |
生成状态.enum GenState
Generator 在推理过程中,通过回调函数不断将生成结果返回给开发者。GenState 枚举标识每个回调事件所处的阶段状态,开发者可根据状态码来判断生成进度。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| IDLE | uint8_t | 0 | 空闲,等待新一轮生成 |
| BEGIN | uint8_t | 1 | 句子首个 Token 片段 |
| CONTINUE | uint8_t | 2 | 句子中间延续片段 |
| END | uint8_t | 3 | 句子结束 |
| ABORT | uint8_t | 4 | 用户中断或任务主动放弃 |
| ERROR | uint8_t | 5 | 系统或硬件层面错误 |
全局函数
获取库版本.get_library_version()
获取当前 AidGen 库的版本信息字符串。
| API | get_library_version |
| 描述 | 获取 AidGen 库的版本信息 |
| 参数 | void |
| 返回值 | 包含库版本信息的字符串,格式如 "2.3.0" |
std::string version = aplux::aidgen::get_library_version();
printf("Current aidgen library version: %s\n", version.c_str());获取ABI版本.get_abi_version()
获取 ABI 版本号,用于检测二进制兼容性。
| API | get_abi_version |
| 描述 | 获取 AidGen 库的 ABI 版本号 |
| 参数 | void |
| 返回值 | ABI 版本号(无符号 64 位整数) |
uint64_t abi_ver = aplux::aidgen::get_abi_version();
printf("ABI version: %lu\n", abi_ver);设置日志级别.set_log_level()
设置 AidGen 日志输出的最低级别,低于该级别的日志将不会被输出。
| API | set_log_level |
| 描述 | 设置日志的最低输出级别 |
| 参数 | log_level:LogLevel 枚举值,指定最低日志级别 |
| 返回值 | void |
aplux::aidgen::set_log_level(aplux::aidgen::LogLevel::ERROR);设置日志文件前缀.set_log_file_prefix()
设置日志文件路径前缀,库会自动追加后缀生成实际日志文件,并返回最终完整路径。
| API | set_log_file_prefix |
| 描述 | 设置日志文件路径前缀 |
| 参数 | log_file_prefix:日志文件前缀字符串(不能为空) |
| 返回值 | 最终生成的完整日志文件路径 |
std::string log_path = aplux::aidgen::set_log_file_prefix("./aidgen_log_");
printf("Log file path: %s\n", log_path.c_str());上下文属性.struct ContextProperties
ContextProperties 结构体用于配置 Context 的行为属性,在创建 Context 实例时传入。
成员变量列表
| 成员变量名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| stream | bool | true | 是否启用流式输出 |
| enable_profiler | bool | false | 是否启用性能分析器 |
| enable_prompt_cache | bool | true | 是否启用 Prompt Cache 加速 |
张量.struct Tensor
Tensor 结构体用于承载数据缓冲区及其大小,是 EmbeddingExtractor 的输出容器和 Generator 多模态模式的输入容器。默认 deleter 为 nullptr,此时 unique_ptr 析构时自动调用 delete[] 释放内存;用户也可传入自定义 deleter(如 std::free)来管理外部分配的内存。
成员变量列表
| 成员变量名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| data | std::unique_ptr<uint8_t[], TensorDeleter> | 数据缓冲区指针,支持自定义释放函数 | |
| size | size_t | 0 | 数据字节数 |
生成事件.struct GenEvent
Generator 在推理过程中通过回调函数返回的数据结构,包含当前生成状态和文本内容。
成员变量列表
| 成员变量名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| state | GenState | 当前生成状态码 | |
| text | std::string | 本次回调的文本片段 |
各状态下 text 的含义:
| state | 含义 | text 内容 |
|---|---|---|
| IDLE | 尚未开始 | 为空 |
| BEGIN | 首个 Token | 首个生成的文本 |
| CONTINUE | 中间延续 | 继续生成的文本 |
| END | 生成完毕 | 最终文本 |
| ABORT | 被中断 | 中断前已生成的部分 |
| ERROR | 发生错误 | 可能为空 |
生成回调函数类型.GenCallback
Generator 推理过程中使用的回调函数类型定义。开发者需要实现该类型的回调函数来处理推理结果。
using GenCallback = std::function<void(const GenEvent& event, void* user_data)>;⚠️注意
严禁在回调函数内部调用 Generator::abort(),否则可能导致死锁或未定义行为。
提取器性能数据.struct ExtractorProfileData
EmbeddingExtractor 在推理过程中采集的性能指标数据。
成员变量列表
| 成员变量名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| init_time_us | uint64_t | 0 | 初始化耗时(微秒) |
| prompt_token_count | uint64_t | 0 | Prompt Token 数量 |
| execute_time_us | uint64_t | 0 | 推理耗时(微秒) |
| prompt_processing_tps | float | 0.f | Prompt 处理吞吐(tok/s) |
生成器性能数据.struct GeneratorProfileData
Generator 在推理过程中采集的性能指标数据。
成员变量列表
| 成员变量名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| init_time_us | uint64_t | 0 | 初始化耗时(微秒) |
| prompt_token_count | uint64_t | 0 | Prompt Token 数量 |
| time_to_first_token_time_us | uint64_t | 0 | 首 Token 延迟(微秒) |
| prompt_processing_tps | float | 0.f | Prompt 处理吞吐(tok/s) |
| generated_token_count | uint64_t | 0 | 生成 Token 数量 |
| generate_time_us | uint64_t | 0 | 生成阶段耗时(微秒) |
| generate_tps | float | 0.f | 生成吞吐(tok/s) |
性能数据.struct ProfileData
聚合 EmbeddingExtractor 和 Generator 两个阶段的性能数据。
成员变量列表
| 成员变量名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| extractor | ExtractorProfileData | Embedding 提取器性能数据 | |
| generator | GeneratorProfileData | LLM 生成器性能数据 |
运行上下文类.class Context
Context 是推理上下文类,持有模型配置和后端设置,由 Tokenizer、EmbeddingExtractor 和 Generator 三方共享。Context 采用全局单例模式,同一时刻仅允许存在一个 Context 实例。其生命周期为:create_instance() → initialize() → 使用 → 析构自动清理。Context 不可拷贝、不可移动。
创建实例对象.create_instance()
创建 Context 单例实例。若已有实例存在,返回 nullptr。
| API | create_instance |
| 描述 | 创建 Context 单例实例,同一时刻仅允许存在一个 |
| 参数 | config:模型配置文件路径(JSON),或 JSON 内容字符串本身(首个非空白字符为 `{` 或 `[` 时视为 JSON 内容,否则视为文件路径) |
| properties:ContextProperties 结构体引用,配置流式输出、性能分析、Prompt Cache 等行为 | |
| backend_type:BackendType 枚举值,指定推理后端,默认 BackendType::DEFAULT(自动选择最佳可用后端) | |
| 返回值 | 如果为 nullptr 值,说明已有实例存在或构建失败;否则就是 Context 对象的 shared_ptr |
// 创建上下文属性
aplux::aidgen::ContextProperties props;
props.stream = false;
props.enable_profiler = true;
props.enable_prompt_cache = true;
// 创建 Context 实例
std::shared_ptr<aplux::aidgen::Context> ctx_ptr = aplux::aidgen::Context::create_instance(
"qwen2-7b/qwen2-7b.json", props, aplux::aidgen::BackendType::DEFAULT);
if(ctx_ptr == nullptr){
printf("Context create_instance failed.\n");
return EXIT_FAILURE;
}初始化操作.initialize()
执行完整的初始化流程:license 校验 → 搜索并加载后端插件 → 解析模型配置 JSON → 验证后端版本兼容性(主版本号 + ABI + 最低 minor/patch)→ 初始化后端句柄。
| API | initialize |
| 描述 | 执行 license 校验、后端加载、配置解析等完整初始化 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功。可能返回 BACKEND_NOT_FOUND、FILE_OPEN_FAILED、FILE_EMPTY、FILE_READ_ERROR、FILE_PARSE_ERROR、NOT_INITIALIZED 等错误码 |
💡提示
若初始化时报错 Required QNN backend not found(错误码 BACKEND_NOT_FOUND),说明系统中缺少对应的 QNN 推理后端 SDK。请根据所使用的模型和目标平台安装相应的后端包,例如:
aidgen-qnn236— 适用于高通 QNN SDK 2.36aidgen-qnn240— 适用于高通 QNN SDK 2.40aidgen-qnn248— 适用于高通 QNN SDK 2.48
安装后确保后端动态库(如 libaidgen_qnn240.so)位于 /usr/local/lib 目录下。
// Context 初始化,返回值非 SUCCESS 则报错
if(ctx_ptr->initialize() != aplux::aidgen::ErrorCode::SUCCESS){
printf("Context initialize failed.\n");
return EXIT_FAILURE;
}获取配置.get_config()
查询后端 "context" 作用域下所有可配置参数。必须在 initialize() 之后调用。
| API | get_config |
| 描述 | 查询后端所有 context 级别配置参数 |
| 参数 | void |
| 返回值 | 包含所有 context 配置参数的字符串。未初始化时返回空字符串 |
std::string config = ctx_ptr->get_config();
printf("Context config: %s\n", config.c_str());设置配置.set_config()
通过后端 "context" 作用域设置指定配置项的值。必须在 initialize() 之后调用,且仅在 Tokenizer、Generator 或 EmbeddingExtractor 实例创建之前有效。
| API | set_config |
| 描述 | 设置指定 context 级别配置项的值 |
| 参数 | key:配置项键名 |
| value:配置值 | |
| 返回值 | ErrorCode::SUCCESS 表示成功。未初始化时返回 NOT_INITIALIZED |
if(ctx_ptr->set_config("key", "value") != aplux::aidgen::ErrorCode::SUCCESS){
printf("Context set_config failed.\n");
}分词器类.class Tokenizer
Tokenizer 是文本分词器,负责文本与 Token ID 之间的双向转换。采用全局单例模式,同时仅允许存在一个实例。其生命周期为:create_instance() → initialize() → encode() / decode() → finalize() → 析构。Tokenizer 不可拷贝、不可移动。
创建实例对象.create_instance()
| API | create_instance |
| 描述 | 创建 Tokenizer 单例实例,同一时刻仅允许存在一个 |
| 参数 | context:std::shared_ptr<Context>,共享的已初始化 Context 对象(不能为 nullptr) |
| reserve:保留字段,默认值为 nullptr | |
| 返回值 | 如果为 nullptr 值,说明 context 为空、已有实例存在或构造失败;否则就是 Tokenizer 对象的 unique_ptr |
std::unique_ptr<aplux::aidgen::Tokenizer> tokenizer_ptr = aplux::aidgen::Tokenizer::create_instance(ctx_ptr);
if(tokenizer_ptr == nullptr){
printf("Tokenizer create_instance failed.\n");
return EXIT_FAILURE;
}初始化操作.initialize()
初始化分词器后端,以 "NoEmbedding" 目标加载 tokenizer 模型(仅加载词表,不加载 embedding 权重)。
| API | initialize |
| 描述 | 初始化分词器后端,加载词表模型 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
if(tokenizer_ptr->initialize() != aplux::aidgen::ErrorCode::SUCCESS){
printf("Tokenizer initialize failed.\n");
return EXIT_FAILURE;
}文本编码为Token.encode()
将纯文本字符串编码为 Token ID 序列。必须先调用 initialize()。
| API | encode |
| 描述 | 将文本字符串编码为 Token ID 序列 |
| 参数 | text:待编码的输入文本字符串 |
| token_ids:std::vector<int32_t>&,输出的 Token ID 序列 | |
| 返回值 | ErrorCode::SUCCESS 表示成功。未初始化返回 NOT_INITIALIZED |
std::vector<int32_t> token_ids;
if(tokenizer_ptr->encode("Hello world!", token_ids) != aplux::aidgen::ErrorCode::SUCCESS){
printf("Tokenizer encode failed.\n");
return EXIT_FAILURE;
}
printf("Token count: %zu\n", token_ids.size());Token解码为文本.decode()
将 Token ID 序列解码还原为人类可读的文本。必须先调用 initialize()。
| API | decode |
| 描述 | 将 Token ID 序列解码为文本字符串 |
| 参数 | token_ids:输入的 Token ID 序列 |
| text:std::string&,输出的解码文本 | |
| 返回值 | ErrorCode::SUCCESS 表示成功。未初始化返回 NOT_INITIALIZED |
std::string decoded_text;
if(tokenizer_ptr->decode(token_ids, decoded_text) != aplux::aidgen::ErrorCode::SUCCESS){
printf("Tokenizer decode failed.\n");
return EXIT_FAILURE;
}
printf("Decoded: %s\n", decoded_text.c_str());完结释放操作.finalize()
释放分词器后端资源。必须先调用 initialize()。
| API | finalize |
| 描述 | 释放分词器后端资源 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功。未初始化返回 NOT_INITIALIZED |
if(tokenizer_ptr->finalize() != aplux::aidgen::ErrorCode::SUCCESS){
printf("Tokenizer finalize failed.\n");
return EXIT_FAILURE;
}Embedding提取器类.class EmbeddingExtractor
EmbeddingExtractor 用于将文本编码为单一的 embedding 张量,适用于检索增强生成(RAG)、文本语义相似度计算、特征提取等场景。采用全局单例模式,同时仅允许存在一个实例。其生命周期为:create_instance() → initialize() → encode() / get_profiler() → finalize() → 析构。EmbeddingExtractor 不可拷贝、不可移动。
创建实例对象.create_instance()
| API | create_instance |
| 描述 | 创建 EmbeddingExtractor 单例实例,同一时刻仅允许存在一个 |
| 参数 | context:std::shared_ptr<Context>,共享的已初始化 Context 对象(不能为 nullptr) |
| reserve:保留字段,默认值为 nullptr | |
| 返回值 | 如果为 nullptr 值,说明 context 为空、已有实例存在或构造失败;否则就是 EmbeddingExtractor 对象的 unique_ptr |
std::unique_ptr<aplux::aidgen::EmbeddingExtractor> extractor_ptr =
aplux::aidgen::EmbeddingExtractor::create_instance(ctx_ptr);
if(extractor_ptr == nullptr){
printf("EmbeddingExtractor create_instance failed.\n");
return EXIT_FAILURE;
}初始化操作.initialize()
初始化 embedding 提取器后端并加载 embedding 模型。必须在 Context::initialize() 之后调用。
| API | initialize |
| 描述 | 初始化提取器后端,加载 embedding 模型 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
if(extractor_ptr->initialize() != aplux::aidgen::ErrorCode::SUCCESS){
printf("EmbeddingExtractor initialize failed.\n");
return EXIT_FAILURE;
}完结释放操作.finalize()
释放 embedding 提取器后端资源。必须先调用 initialize()。
| API | finalize |
| 描述 | 释放 embedding 提取器后端资源 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功。未初始化返回 NOT_INITIALIZED |
获取属性.get_property()
查询后端 "extractor" 作用域下所有可配置参数。必须先调用 initialize()。
| API | get_property |
| 描述 | 查询 extractor 作用域下所有可配置参数 |
| 参数 | void |
| 返回值 | 属性值字符串。未初始化时返回空字符串 |
设置属性.set_property()
通过后端 "extractor" 作用域设置指定属性值。必须先调用 initialize()。
| API | set_property |
| 描述 | 设置 extractor 作用域下指定属性值 |
| 参数 | key:属性键名 |
| value:属性值 | |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
编码为Embedding.encode()
将文本字符串编码为 embedding 张量。必须先调用 initialize()。
| API | encode |
| 描述 | 将文本编码为 embedding 张量 |
| 参数 | prompt:待编码的输入文本字符串 |
| embedding:Tensor&,输出的 embedding 张量(data 和 size 由后端填充) | |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
aplux::aidgen::Tensor embedding;
if(extractor_ptr->encode("What is the most popular cookie in the world?", embedding) !=
aplux::aidgen::ErrorCode::SUCCESS){
printf("EmbeddingExtractor encode failed.\n");
return EXIT_FAILURE;
}
printf("Embedding size: %zu bytes\n", embedding.size);获取性能数据.get_profiler()
获取最近一次 embedding 提取的性能分析数据,仅填充 ProfileData::extractor 字段。必须先调用 initialize()。
| API | get_profiler |
| 描述 | 获取最近一次 embedding 提取的性能数据 |
| 参数 | profile_data:ProfileData&,输出的性能数据(仅填充 extractor 字段) |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
aplux::aidgen::ProfileData perf;
if(extractor_ptr->get_profiler(perf) == aplux::aidgen::ErrorCode::SUCCESS){
printf("Extractor TPS: %.2f tok/s\n", perf.extractor.prompt_processing_tps);
}生成器类.class Generator
Generator 是 LLM Token 生成器,支持纯文本和多模态(embedding 输入)两种推理方式。采用全局单例模式,同时仅允许存在一个实例。连续调用 run() 被视为多轮对话,内部自动复用 KV Cache 实现加速;调用 reset() 可清除历史缓存并开始全新对话。其生命周期为:create_instance() → initialize() → run() / reset() / abort() / get_profiler() / get_state() → finalize() → 析构。Generator 不可拷贝、不可移动。
创建实例对象.create_instance()
| API | create_instance |
| 描述 | 创建 Generator 单例实例,同一时刻仅允许存在一个 |
| 参数 | context:std::shared_ptr<Context>,共享的已初始化 Context 对象(不能为 nullptr) |
| reserve:保留字段,默认值为 nullptr | |
| 返回值 | 如果为 nullptr 值,说明 context 为空、已有实例存在或构造失败;否则就是 Generator 对象的 unique_ptr |
std::unique_ptr<aplux::aidgen::Generator> generator_ptr = aplux::aidgen::Generator::create_instance(ctx_ptr);
if(generator_ptr == nullptr){
printf("Generator create_instance failed.\n");
return EXIT_FAILURE;
}初始化操作.initialize()
初始化生成器后端并加载语言模型。必须在 Context::initialize() 之后调用。
| API | initialize |
| 描述 | 初始化生成器后端,加载语言模型 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
if(generator_ptr->initialize() != aplux::aidgen::ErrorCode::SUCCESS){
printf("Generator initialize failed.\n");
return EXIT_FAILURE;
}完结释放操作.finalize()
释放生成器后端资源。必须先调用 initialize()。
| API | finalize |
| 描述 | 释放生成器后端资源 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功。未初始化返回 NOT_INITIALIZED |
获取属性.get_property()
查询后端 "generator" 作用域下所有可配置参数。必须先调用 initialize()。
| API | get_property |
| 描述 | 查询 generator 作用域下所有可配置参数 |
| 参数 | void |
| 返回值 | 属性值字符串。未初始化时返回空字符串 |
设置属性.set_property()
通过后端 "generator" 作用域设置生成参数。必须先调用 initialize()。常用属性包括:"stream"(值为 "0" 或 "1",控制是否流式输出)、采样参数 "temp"、"top-k"、"top-p" 等(值均为字符串格式)。
| API | set_property |
| 描述 | 设置 generator 作用域下指定属性值 |
| 参数 | key:属性键名(如 "stream"、"temp"、"top-k"、"top-p") |
| value:属性值(字符串格式) | |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
// 设置采样参数
generator_ptr->set_property("stream", "1");
generator_ptr->set_property("temp", "0.8");
generator_ptr->set_property("top-k", "20");
generator_ptr->set_property("top-p", "0.9");获取Embedding权重缓冲区.get_embedding_buff()
获取模型 Token Embedding 权重查找表的原始指针及大小。必须先调用 initialize()。
返回的缓冲区按行优先顺序连续存储所有 Token 的 embedding 向量。每个 Token 的 embedding 占用 embedding_size * sizeof(float) 字节,第 i 个 Token 的 embedding 位于偏移量 i * embedding_size * sizeof(float) 处。指针有效期与 Generator 实例生命周期一致,调用者不得释放此缓冲区。
典型用途:手动构建文本 + 视觉的混合 embedding 张量以进行多模态推理。
| API | get_embedding_buff |
| 描述 | 获取模型 Token Embedding 权重缓冲区指针及大小 |
| 参数 | out_ptr:const char*&,输出参数,接收指向 embedding 权重缓冲区的指针,失败时为 nullptr |
| out_size:size_t&,输出参数,接收权重缓冲区的总大小(字节) | |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
const char* embedding_buf = nullptr;
size_t embedding_buf_size = 0;
if(generator_ptr->get_embedding_buff(embedding_buf, embedding_buf_size) !=
aplux::aidgen::ErrorCode::SUCCESS){
printf("get_embedding_buff failed.\n");
}纯文本推理.run()
基于完整 prompt 字符串启动纯文本推理。连续调用 run() 被视为多轮对话,内部自动复用 KV Cache 加速。要开始全新对话,需先调用 reset()。
⚠️注意
严禁在回调函数内部调用 abort(),否则可能导致死锁或未定义行为。
| API | run |
| 描述 | 基于完整 prompt 字符串启动纯文本推理(调用者自行组装 chat template) |
| 参数 | prompt:完整的 prompt 字符串,开发者负责组装 system/user/assistant 角色标记 |
| cb:GenCallback 类型的回调函数,逐个 Token 片段触发 | |
| user_data:用户自定义数据的指针,透传给回调函数,默认值为 nullptr | |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
// 定义回调函数
auto dialog_callback = [](const aplux::aidgen::GenEvent& event, void* user_data){
switch(event.state){
case aplux::aidgen::GenState::BEGIN:
printf("[BEGIN]%s", event.text.c_str());
break;
case aplux::aidgen::GenState::CONTINUE:
printf("%s", event.text.c_str());
fflush(stdout);
break;
case aplux::aidgen::GenState::END:
printf("%s[END]\n", event.text.c_str());
break;
case aplux::aidgen::GenState::ABORT:
printf("\n[ABORT]%s\n", event.text.c_str());
break;
case aplux::aidgen::GenState::ERROR:
printf("\n[ERROR]%s\n", event.text.c_str());
break;
default: break;
}
};
// 执行纯文本推理
std::string prompt = "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n"
"<|im_start|>user\n你好<|im_end|>\n"
"<|im_start|>assistant\n";
if(generator_ptr->run(prompt, dialog_callback) != aplux::aidgen::ErrorCode::SUCCESS){
printf("Generator run failed.\n");
return EXIT_FAILURE;
}多模态推理.run()
基于预计算的 embedding 张量启动多模态推理。开发者自行负责文本 embedding 和图像 embedding 的生成与组装。连续调用 run() 同样复用 KV Cache,使用 reset() 清除。
⚠️注意
严禁在回调函数内部调用 abort(),否则可能导致死锁或未定义行为。
| API | run |
| 描述 | 基于预计算的 embedding 张量启动多模态推理 |
| 参数 | embedding:Tensor&,Embedding 张量(调用者负责生成与组装) |
| cb:GenCallback 类型的回调函数 | |
| user_data:用户自定义数据的指针,透传给回调函数,默认值为 nullptr | |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
重置对话状态.reset()
通过后端 "generator_reset" 操作重置内部 KV Cache 和对话状态。必须在 initialize() 之后调用。在多轮对话中开始全新话题前调用,调用后之前的 KV Cache 加速将失效。
| API | reset |
| 描述 | 重置 KV Cache 和对话状态,准备新一轮对话 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
// 新话题开始前重置
if(generator_ptr->reset() != aplux::aidgen::ErrorCode::SUCCESS){
printf("Generator reset failed.\n");
return EXIT_FAILURE;
}
// 之后可开始全新对话
generator_ptr->run(new_prompt, dialog_callback);中止推理.abort()
通过后端 "generator_abort" 操作主动终止当前推理任务。必须在 initialize() 之后调用。通常在另一个线程中调用,或通过超时机制触发。
⚠️注意
严禁在 GenCallback 回调函数内部调用 abort()。
| API | abort |
| 描述 | 主动终止当前正在运行的推理任务 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
// 在另一个线程中终止推理
if(generator_ptr->abort() != aplux::aidgen::ErrorCode::SUCCESS){
printf("Generator abort failed.\n");
}获取性能数据.get_profiler()
获取最近一次推理的性能分析数据,仅填充 ProfileData::generator 字段。必须先调用 initialize()。
| API | get_profiler |
| 描述 | 获取最近一次生成推理的性能数据 |
| 参数 | profile_data:ProfileData&,输出的性能数据(仅填充 generator 字段) |
| 返回值 | ErrorCode::SUCCESS 表示成功 |
aplux::aidgen::ProfileData perf;
if(generator_ptr->get_profiler(perf) == aplux::aidgen::ErrorCode::SUCCESS){
printf("首Token耗时: %lu us\n", perf.generator.time_to_first_token_time_us);
printf("生成速率: %.2f tok/s\n", perf.generator.generate_tps);
printf("生成Token数: %lu\n", perf.generator.generated_token_count);
}获取当前状态.get_state()
查询生成器当前状态(IDLE / BEGIN / CONTINUE / END / ABORT / ERROR)。必须在 initialize() 之后调用。
| API | get_state |
| 描述 | 查询生成器当前运行状态 |
| 参数 | state:GenState&,输出参数,接收当前状态值 |
| 返回值 | 已初始化时始终返回 ErrorCode::SUCCESS。未初始化返回 NOT_INITIALIZED |
aplux::aidgen::GenState current_state;
if(generator_ptr->get_state(current_state) == aplux::aidgen::ErrorCode::SUCCESS){
printf("Current state: %d\n", static_cast<int>(current_state));
}典型使用流程
纯文本推理完整流程
Context::create_instance(config, props, backend)
→ Context::initialize()
→ Generator::create_instance(ctx) → Generator::initialize()
→ Generator::set_property("stream", "1")
→ Generator::run(prompt, callback)
→ Generator::get_profiler(profile_data)
→ [可选] Generator::reset() → Generator::run(new_prompt, callback)
→ Generator::finalize()完整示例代码:
#include "aidgen.hpp"
using namespace aplux::aidgen;
int main() {
// 1. 创建 Context 并初始化
ContextProperties props;
props.stream = false;
props.enable_profiler = true;
auto ctx = Context::create_instance("/path/to/model.json", props, BackendType::QNN240);
if (!ctx || ctx->initialize() != ErrorCode::SUCCESS) return -1;
// 2. 创建并初始化 Generator
auto generator = Generator::create_instance(ctx);
if (!generator || generator->initialize() != ErrorCode::SUCCESS) return -1;
generator->set_property("stream", "1");
// 3. 执行推理
std::string prompt =
"<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n"
"<|im_start|>user\n你好,介绍一下你自己<|im_end|>\n"
"<|im_start|>assistant\n";
generator->run(prompt, [](const GenEvent& event, void*) {
printf("%s", event.text.c_str());
fflush(stdout);
});
// 4. 获取性能数据并释放
ProfileData perf;
generator->get_profiler(perf);
generator->finalize();
return 0;
}Tokenizer 使用流程
Context::create_instance() → Context::initialize()
→ Tokenizer::create_instance(ctx) → Tokenizer::initialize()
→ Tokenizer::encode(text, token_ids) // 文本 → Token
→ Tokenizer::decode(token_ids, text) // Token → 文本
→ Tokenizer::finalize()auto tokenizer = Tokenizer::create_instance(ctx);
tokenizer->initialize();
// 编码
std::vector<int32_t> tokens;
tokenizer->encode("Hello world!", tokens);
// 解码
std::string decoded;
tokenizer->decode(tokens, decoded);
tokenizer->finalize();Embedding 提取流程
Context::create_instance() → Context::initialize()
→ EmbeddingExtractor::create_instance(ctx) → EmbeddingExtractor::initialize()
→ EmbeddingExtractor::encode(prompt, embedding)
→ EmbeddingExtractor::get_profiler(profile_data)
→ EmbeddingExtractor::finalize()#include "aidgen.hpp"
using namespace aplux::aidgen;
int main() {
ContextProperties props;
props.enable_profiler = true;
auto ctx = Context::create_instance("/path/to/bge-large-htp.json", props, BackendType::QNN240);
if (!ctx || ctx->initialize() != ErrorCode::SUCCESS) return -1;
auto extractor = EmbeddingExtractor::create_instance(ctx);
if (!extractor || extractor->initialize() != ErrorCode::SUCCESS) return -1;
Tensor embedding;
extractor->encode("What is the most popular cookie in the world?", embedding);
ProfileData perf;
extractor->get_profiler(perf);
printf("TPS: %.2f tok/s\n", perf.extractor.prompt_processing_tps);
// 保存 embedding 到文件
std::ofstream out("output.raw", std::ios::binary);
out.write(reinterpret_cast<const char*>(embedding.data.get()), embedding.size);
return 0;
}错误处理模式
所有返回 ErrorCode 的方法都应检查返回值:
if (ctx->initialize() != ErrorCode::SUCCESS) {
fprintf(stderr, "Context initialization failed.\n");
return EXIT_FAILURE;
}常见初始化失败场景:
BACKEND_NOT_FOUND:未找到 QNN 推理后端,请安装对应的后端 SDK(如aidgen-qnn240),详见上文Context::initialize()的提示说明FILE_OPEN_FAILED:模型配置文件路径无效或权限不足FILE_PARSE_ERROR:模型配置文件 JSON 格式有误NOT_INITIALIZED:版本不兼容或 license 校验失败
内存管理原则
| 对象 | 管理方式 | 说明 |
|---|---|---|
| Context | shared_ptr | 共享所有权,应在 Generator / Tokenizer / EmbeddingExtractor 之后析构 |
| Generator | unique_ptr | 独占所有权,析构自动释放单例锁 |
| Tokenizer | unique_ptr | 独占所有权,析构自动释放单例锁 |
| EmbeddingExtractor | unique_ptr | 独占所有权,析构自动释放单例锁 |
| Tensor::data | unique_ptr + 自定义 deleter | 默认 delete[];可传入 std::free 等自定义 deleter |
AidGen 1.x C++ 接口文档 (已废弃)
⚠️注意
以下为 AidGen 1.x 版本的接口文档,包含 aplux::aidllm 和 aplux::aidmlm 两个命名空间。该版本已不再维护更新,建议新项目使用上方的 AidGen 2.x 接口。
AidLLM C++ 接口文档
💡注意
使用 AidGen-SDK C++ 开发需要了解如下基本事项:
- 编译时需要包含头文件,存放路径
/usr/local/include/aidlux/aidgen/aidllm.hpp - 链接时需要指定库文件,存放路径
/usr/local/lib/libaidgen.so - 所有接口均位于
aplux::aidllm命名空间下
推理后端类型.enum LLmBackendType
对于 AidllmSDK 而言,支持使用不同的推理后端框架来实现大模型的推理任务,涉及到的推理后端如下所示。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| TYPE_DEFAULT | uint8_t | 0 | 未知后端类型 |
| TYPE_GENIE | uint8_t | 1 | Genie推理后端 |
推理任务状态.enum LLMSentenceState
Aidllm 在推理任务的完成过程中,针对一次会话,可能会存在各种不同阶段的状态,开发者可以根据这些状态码来了解当前推理任务的运行情况。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| BEGIN | enum class | 0 | 会话开始部分 |
| CONTINUE | enum class | 1 | 会话持续推理中间内容 |
| END | enum class | 2 | 会话结尾部分 |
| COMPLETE | enum class | 3 | 当前会话成功完结 |
| ABORT | enum class | 4 | 当前会话被动终止 |
| ERROR | enum class | 5 | 当前会话推理错误 |
解释器运行状态.enum LLMState
Aidllm 解释器在运行过程中的整体状态,开发者可以通过查询此状态来了解解释器当前的工作情况。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| STANDIDLE | enum class | 0 | 空闲待机状态 |
| BUSYING | enum class | 1 | 正在忙碌推理中 |
| ABORT | enum class | 2 | 推理已被终止 |
| ERROR | enum class | 3 | 推理出现错误 |
日志级别.enum LogLevel
AidllmSDK 提供有设置日志的接口(后续会介绍),需要提供给接口当前使用哪个日志级别,所以就需要使用此日志级别枚举。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| INFO | uint8_t | 0 | 消息 |
| WARNING | uint8_t | 1 | 警告 |
| ERROR | uint8_t | 2 | 错误 |
| FATAL | uint8_t | 3 | 致命错误 |
全局函数
获取库版本.get_library_version()
获取当前 Aidllm 库的版本信息字符串。
| API | get_library_version |
| 描述 | 获取 Aidllm 库的版本信息 |
| 参数 | void |
| 返回值 | 包含库版本信息的字符串 |
std::string version = aplux::aidllm::get_library_version();
printf("Current aidllm library version: %s\n", version.c_str());设置日志级别.set_log_level()
设置 Aidllm 日志输出的最低级别,低于该级别的日志将不会被输出。
| API | set_log_level |
| 描述 | 设置日志的最低输出级别 |
| 参数 | log_level:LogLevel 枚举值,指定最低日志级别 |
| 返回值 | void |
aplux::aidllm::set_log_level(aplux::aidllm::LogLevel::ERROR);设置日志文件前缀.set_log_file_prefix()
设置日志文件名的前缀,用于将日志输出到指定前缀的文件中。
| API | set_log_file_prefix |
| 描述 | 设置日志文件名称的前缀 |
| 参数 | log_file_prefix:日志文件名前缀字符串 |
| 返回值 | void |
aplux::aidllm::set_log_file_prefix("aidllm_log_");推理回调函数类型.LLMCallback
Aidllm 推理过程中使用的回调函数类型定义。开发者需要实现该类型的回调函数来处理推理结果。
using LLMCallback = std::function<int32_t(LLMCallbackData& cb_data, void* user_data)>;💡注意
回调函数返回值类型为 int32_t,返回 0 表示正常继续推理,非 0 可用于控制推理流程。
推理回调函数数据类型.struct LLMCallbackData
Aidllm 在推理任务时,会使用开发者提供的回调函数,此数据类型就是传递给该回调函数的参数,开发者可以在自定义的回调函数中使用推理的结果数据。
成员变量列表
LLMCallbackData 结构体包含如下成员变量:
| 成员变量 | state |
| 类型 | enum LLMSentenceState |
| 默认值 | |
| 描述 | 当前推理会话的状态码 |
| 成员变量 | text |
| 类型 | std::string |
| 默认值 | |
| 描述 | 推理任务的结果字符/特殊状态码对应的提示消息 |
运行上下文类.class LLMContext
Aidllm 在运行过程中,可能需要设置一些配置信息,同时运行时的相关数据也需要传递,使用此运行上下文类型的对象来完成数据流转。
创建实例对象.create_instance()
想要设置运行时的上下文信息,当然就需要先有配置实例对象,此函数用于创建 LLMContext 类型的实例对象。
| API | create_instance |
| 描述 | 用于构造 LLMContext 类的实例对象 |
| 参数 | config_file:初始配置文件,其中可以配置后端类型、模型文件名称等关键信息 |
| 返回值 | 如果为 nullptr 值,说明函数构建对象失败;否则就是 LLMContext 对象的指针 |
// 创建配置实例对象,返回值为空则报错
std::unique_ptr<LLMContext> llm_context_ptr = LLMContext::create_instance("qwen2-7b/qwen2-7b.json");
if(llm_context_ptr == nullptr){
printf("Test sample: LLMContext create_instance failed.\n");
return EXIT_FAILURE;
}成员变量列表
LLMContext 对象用于管理运行时的配置信息,其中包含如下的这些参数:
| 成员变量 | config_file |
| 类型 | std::string |
| 默认值 | |
| 描述 | 初始配置文件,创建对象时传入的配置文件参数 |
| 成员变量 | backend_type |
| 类型 | LLmBackendType |
| 默认值 | LLmBackendType::TYPE_DEFAULT |
| 描述 | 在配置文件中会要求开发者指定推理后端。初始化操作解析配置文件完成之后,会覆写此字段,标识开发者指定的后端类型 |
| 成员变量 | model_file_vec |
| 类型 | std::vector<std::string> |
| 默认值 | |
| 描述 | 在配置文件中会要求开发者指定模型文件。初始化操作解析配置文件完成之后,会覆写此字段,标识开发者指定的模型文件 |
| 成员变量 | config_overwrite_options |
| 类型 | std::string |
| 默认值 | |
| 描述 | 通过设置此字段,可以指定推理过程中的某些关键参数,从而影响推理速度、推理结果等 |
| 成员变量 | android_tmp_directory |
| 类型 | std::string |
| 默认值 | |
| 描述 | 此字段只在 Android 平台下有效。通过设置此字段,可以指定系统用户拥有合法权限的目录,以供推理程序借用 |
解释器类.class LLMInterpreter
LLMInterpreter 类型的对象实例是执行推理操作的主体,用于执行具体的推理过程。
创建实例对象.create_instance()
想要执行推理相关的操作,推理解释器肯定必不可少,此函数就用于构建推理解释器的实例对象。
| API | create_instance |
| 描述 | 利用 LLMContext 对象所管理的各种数据,构造 LLMInterpreter 类型的对象 |
| 参数 | llm_context:LLMContext 实例对象的 unique_ptr 引用(std::unique_ptr<LLMContext>&) |
| reserve:保留字段,默认值为 nullptr | |
| 返回值 | 为 nullptr 值则说明函数构建对象失败;否则就是 LLMInterpreter 对象的 unique_ptr |
// 使用 LLMContext 对象指针来创建解释器对象,返回值为空则报错
std::unique_ptr<LLMInterpreter> llm_interpreter_ptr = LLMInterpreter::create_instance(llm_context_ptr);
if(llm_interpreter_ptr == nullptr){
printf("Test sample: LLMInterpreter create_instance failed.\n");
return EXIT_FAILURE;
}初始化操作.initialize()
解释器对象创建之后,需要执行一些初始化操作,比如环境检查、资源构建等。
| API | initialize |
| 描述 | 完成推理所需的相关初始化工作 |
| 参数 | enable_profiler:是否启用性能分析器,默认值为 false |
| reserve:保留字段,默认值为 nullptr | |
| 返回值 | 0 值则说明初始化操作执行成功,否则非 0 值就说明执行失败 |
// 解释器初始化,返回值非0则报错
int init_result = llm_interpreter_ptr->initialize();
if(init_result != EXIT_SUCCESS){
printf("Test sample: aidllm initialize failed.\n");
return EXIT_FAILURE;
}采样参数设置操作.set_sampler()
成功完成初始化操作之后,可以通过该函数设置采样参数,以控制大模型生成内容的随机性、多样性及质量。
| API | set_sampler |
| 描述 | 设置采样参数,用于控制大模型输出结果的随机性和多样性。 |
| 参数 | key:采样参数的名称,目前支持:
|
value:以字符串格式表示的参数值:
| |
| 返回值 | 0 值说明设置成功,非 0 值说明执行失败(例如 key 不合法或 value 格式不支持)。 |
// 设置采样参数
llm_interpreter_ptr->set_sampler("temp", "0.8");
llm_interpreter_ptr->set_sampler("top-k", "20");
llm_interpreter_ptr->set_sampler("top-p", "0.9");会话推理操作.run()
成功完成初始化操作之后,就可以跟大模型执行对话操作,开发者提供自定义的回调函数,用于处理会话过程中持续的推理结果。
| API | run |
| 描述 | 执行一次会话推理 |
| 参数 | prompt:提示词字符串 |
| cb:LLMCallback 类型的回调函数,用于处理会话过程中持续的推理结果 | |
| user_data:用户数据的指针,方便在自定义回调函数中使用这些数据,默认值为 nullptr | |
| 返回值 | 0 值则说明推理执行成功,否则非 0 值就说明执行失败 |
// 定义回调函数
LLMCallback dialog_callback = [&](LLMCallbackData& cb_data, void* user_data)->int32_t{
if(cb_data.state == LLMSentenceState::BEGIN){
printf("%s", cb_data.text.c_str());
}else if(cb_data.state == LLMSentenceState::CONTINUE){
printf("%s", cb_data.text.c_str());
fflush(stdout);
}else if(cb_data.state == LLMSentenceState::END){
printf("%s\n", cb_data.text.c_str());
}else if(cb_data.state == LLMSentenceState::COMPLETE){
printf("\n[COMPLETE]%s\n", cb_data.text.c_str());
}else if(cb_data.state == LLMSentenceState::ABORT){
printf("\n[ABORT]%s\n", cb_data.text.c_str());
}else if(cb_data.state == LLMSentenceState::ERROR){
printf("\n[ERROR]%s\n", cb_data.text.c_str());
}
return EXIT_SUCCESS;
};
// 执行推理
std::string prompt = "<|im_start|>user\n你好<|im_end|>\n<|im_start|>assistant\n";
int run_result = llm_interpreter_ptr->run(prompt, dialog_callback);
if(run_result != EXIT_SUCCESS){
printf("Test sample: aidllm run failed.\n");
return EXIT_FAILURE;
}查询推理状态.state()
在推理过程中,开发者可能需要查询解释器当前的运行状态,比如判断是否空闲、是否正在推理等。
| API | state |
| 描述 | 获取当前推理任务的运行状态 |
| 参数 | state:LLMState 类型引用,函数调用后会覆写此变量为当前状态 |
| 返回值 | 0 值则说明查询操作执行成功,否则非 0 值就说明执行失败 |
LLMState current_state = LLMState::STANDIDLE;
llm_interpreter_ptr->state(current_state);
printf("Current state: %d\n", (int)current_state);会话终止操作.abort()
用户可能在某些情况下,会想要打断当前正在执行推理的会话,此函数就用于实现推理终止。
⚠️注意
严禁在回调函数(LLMCallback)内部调用 abort 函数,否则可能导致死锁或未定义行为。
| API | abort |
| 描述 | 终止当前正在运行推理的会话 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | 0 值则说明终止操作执行成功,否则非 0 值就说明执行失败 |
// 在另一个线程中终止推理
int abort_result = llm_interpreter_ptr->abort();
if(abort_result != EXIT_SUCCESS){
printf("Test sample: aidllm abort failed.\n");
return EXIT_FAILURE;
}完结释放操作.finalize()
前面提到解释器对象需要执行 initialize() 初始化相关操作,相应的,解释器也会需要执行一些释放操作,将之前创建的资源予以销毁等。
| API | finalize |
| 描述 | 完成必要的反初始化释放操作 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | 0 值则说明执行释放操作成功,否则非 0 值就说明执行失败 |
// 执行解释器反初始化过程,返回值非0则报错
int fin_result = llm_interpreter_ptr->finalize();
if(fin_result != EXIT_SUCCESS){
printf("Test : aidllm finalize failed.\n");
return EXIT_FAILURE;
}获取性能分析器.get_profiler()
当初始化时启用了性能分析器(enable_profiler = true),可以通过此函数获取性能分析器对象指针,用于性能数据的采集与分析。具体用法参见后文「性能分析 (Profiler) C++ 接口文档」章节。
| API | get_profiler |
| 描述 | 获取性能分析器对象的指针 |
| 参数 | void |
| 返回值 | 如果性能分析器已启用,返回 Profiler 对象指针;如果未启用,返回 nullptr |
// 启用性能分析器进行初始化
int init_result = llm_interpreter_ptr->initialize(true);
// 获取性能分析器
aplux::aidgen::Profiler* profiler = llm_interpreter_ptr->get_profiler();AidMLM C++ 接口文档
💡注意
使用 AidMLM-SDK C++ 开发需要了解如下基本事项:
- 编译时需要包含头文件,存放路径
/usr/local/include/aidlux/aidgen/aidmlm.hpp - 链接时需要指定库文件,存放路径
/usr/local/lib/libaidgen.so - 所有接口均位于
aplux::aidmlm命名空间下 - AidMLM 用于多模态大模型(视觉语言模型)的推理,目前支持 Qwen2-VL 和 Qwen2.5-VL 系列模型
推理状态.enum AidLLMState
AidMLM 在推理任务过程中,针对一次会话,可能会存在各种不同阶段的状态,开发者可以根据这些状态码来了解当前推理任务的运行情况。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| STAND | enum class | 0 | 尚未工作 |
| START | enum class | 1 | 推理开始 |
| BUSYING | enum class | 2 | 正在推理中 |
| FINISH | enum class | 3 | 推理结束 |
| COMPLETE | enum class | 4 | 推理过程完整结束或截断结束 |
| WAITING | enum class | 5 | 当前Token解码失败,等待下一次解码 |
| ABORT | enum class | 6 | 当次推理被开发者提前终止 |
| ERROR | enum class | 7 | 异常原因导致的推理失败 |
日志级别.enum LogLevel
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| INFO | uint8_t | 0 | 消息 |
| WARNING | uint8_t | 1 | 警告 |
| ERROR | uint8_t | 2 | 错误 |
| FATAL | uint8_t | 3 | 致命错误 |
模型类型.enum ModelType
指定当前使用的多模态模型类型。
| 成员变量名 | 类型 | 值 | 描述 |
|---|---|---|---|
| RESERVED | enum class | 0 | 保留类型 |
| QWEN2VL | enum class | 1 | Qwen2-VL 模型 |
| QWEN25VL | enum class | 2 | Qwen2.5-VL 模型 |
推理回调函数数据类型.struct AidLLMCBData
AidMLM 在推理任务时,会使用开发者提供的回调函数,此数据类型就是传递给该回调函数的参数。
成员变量列表
| 成员变量 | state |
| 类型 | enum AidLLMState |
| 默认值 | |
| 描述 | 当前推理会话的状态码 |
| 成员变量 | text |
| 类型 | std::string |
| 默认值 | |
| 描述 | 推理任务的结果字符/特殊状态码对应的提示消息 |
推理回调函数类型.AidLLMCB
AidMLM 推理过程中使用的回调函数类型定义。
using AidLLMCB = std::function<void(AidLLMCBData& cb_data, void* user_data)>;图像数据类型.struct ImageData
用于向多模态模型传递图像数据的结构体。
成员变量列表
| 成员变量 | img_pos |
| 类型 | int |
| 默认值 | -1 |
| 描述 | 图像在提示词中的位置索引。如果为 -1,表示图像追加在提示词末尾 |
| 成员变量 | img_data |
| 类型 | uint8_t* |
| 默认值 | nullptr |
| 描述 | 图像数据指针,指向 RGB 格式的图像像素数据,需要开发者预先 resize 到模型要求的宽高 |
初始化参数类型.struct AidmlmInitParam
AidMLM 初始化时需要的各项参数配置。
成员变量列表
| 成员变量名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| vision_model_path | std::string | 视觉编码器模型文件路径 | |
| pos_emb_cos_path | std::string | 位置编码余弦权重文件路径 | |
| pos_emb_sin_path | std::string | 位置编码正弦权重文件路径 | |
| embedding_weights_path | std::string | 词嵌入权重文件路径 | |
| window_attention_mask_path | std::string | 窗口注意力掩码文件路径(仅 Qwen2.5-VL 需要) | |
| full_attention_mask_path | std::string | 全注意力掩码文件路径(仅 Qwen2.5-VL 需要) | |
| llm_model_path_vec | std::vector<std::string> | LLM 模型文件路径列表 | |
| dbg_opt | std::string | 调试选项字符串 | |
| type | ModelType | ModelType::RESERVED | 多模态模型类型 |
| qwen2vl_cfg | Qwen2VLConfig | Qwen2-VL 模型配置 | |
| qwen25vl_cfg | Qwen25VLConfig | Qwen2.5-VL 模型配置 | |
| enable_profiler | bool | false | 是否启用性能分析器 |
| genie_log_level | int | 1 | Genie 后端日志级别(1=ERROR, 2=WARN, 3=INFO, 4=VERBOSE) |
| use_shared_buffer | bool | false | 是否使用共享缓冲区 |
| use_mmap | bool | false | 是否使用内存映射加载模型 |
| use_genie_load_model_ex | bool | false | 是否使用 Genie 扩展模型加载方式 |
模型配置结构体
AidMLM 提供了预定义的模型配置结构体,用于指定不同分辨率和参数规模下的视觉模型配置。开发者可以根据所使用的模型选择对应的配置。
| 配置结构体名 | 模型 | 图像宽高 | 嵌入维度 |
|---|---|---|---|
| Qwen2VLConfig | Qwen2-VL | 644×644 | 1536 |
| Qwen25VLConfig | Qwen2.5-VL 3B | 392×392 | 2048 |
| Qwen25VL3B644Config | Qwen2.5-VL 3B | 644×644 | 2048 |
| Qwen25VL3B672Config | Qwen2.5-VL 3B | 672×672 | 2048 |
| Qwen25VL7B392Config | Qwen2.5-VL 7B | 392×392 | 3584 |
| Qwen25VL7B644Config | Qwen2.5-VL 7B | 644×644 | 3584 |
| Qwen25VL7B672Config | Qwen2.5-VL 7B | 672×672 | 3584 |
全局函数
获取库版本.get_library_version()
| API | get_library_version |
| 描述 | 获取 AidMLM 库的版本信息 |
| 参数 | void |
| 返回值 | 包含库版本信息的字符串 |
std::string version = aplux::aidmlm::get_library_version();
printf("Current aidmlm library version: %s\n", version.c_str());多模态推理类.class Aidmlm
Aidmlm 类型的对象实例是执行多模态推理操作的主体,用于执行视觉语言模型的推理过程。
构造与析构
Aidmlm 对象通过默认构造函数创建。
aplux::aidmlm::Aidmlm mlm_ctx;设置日志级别.set_log_level()
静态方法,设置 AidMLM 日志输出的最低级别。
| API | set_log_level |
| 描述 | 设置日志的最低输出级别(静态方法) |
| 参数 | log_level:LogLevel 枚举值 |
| 返回值 | void |
aplux::aidmlm::Aidmlm::set_log_level(aplux::aidmlm::LogLevel::INFO);设置日志文件前缀.set_log_file_prefix()
静态方法,设置日志文件名的前缀。
| API | set_log_file_prefix |
| 描述 | 设置日志文件名称的前缀(静态方法) |
| 参数 | log_file:日志文件名前缀字符串 |
| 返回值 | void |
aplux::aidmlm::Aidmlm::set_log_file_prefix("./test_mlm");初始化操作.initialize()
完成多模态模型的加载和推理环境初始化。
| API | initialize |
| 描述 | 加载模型并完成推理所需的初始化工作 |
| 参数 | param:AidmlmInitParam 结构体引用,包含模型路径、配置等初始化参数 |
| enable_profiler:是否启用性能分析器,默认值为 false | |
| 返回值 | 0 值则说明初始化操作执行成功,否则非 0 值就说明执行失败 |
aplux::aidmlm::AidmlmInitParam init_param;
init_param.type = aplux::aidmlm::ModelType::QWEN25VL;
init_param.vision_model_path = "/path/to/veg.serialized.bin.aidem";
init_param.pos_emb_cos_path = "/path/to/position_ids_cos.raw";
init_param.pos_emb_sin_path = "/path/to/position_ids_sin.raw";
init_param.embedding_weights_path = "/path/to/embedding_weights.raw";
init_param.window_attention_mask_path = "/path/to/window_attention_mask.raw";
init_param.full_attention_mask_path = "/path/to/full_attention_mask.raw";
init_param.llm_model_path_vec.push_back("/path/to/llm_model.serialized.bin.aidem");
init_param.use_genie_load_model_ex = true;
aplux::aidmlm::Aidmlm mlm_ctx;
if(mlm_ctx.initialize(init_param) < 0){
printf("AidMLM initialize failed.\n");
return EXIT_FAILURE;
}采样参数设置操作.set_sampler()
成功完成初始化操作之后,可以通过该函数设置采样参数,以控制大模型生成内容的随机性、多样性及质量。
| API | set_sampler |
| 描述 | 设置采样参数,用于控制大模型输出结果的随机性和多样性。 |
| 参数 | key:采样参数的名称,目前支持:
|
value:以字符串格式表示的参数值:
| |
| 返回值 | 0 值说明设置成功,非 0 值说明执行失败(例如 key 不合法或 value 格式不支持)。 |
mlm_ctx.set_sampler("top-k", "20");
mlm_ctx.set_sampler("temp", "0.8");会话推理操作.run()
成功完成初始化操作之后,就可以向多模态模型发送图文组合的提示词执行推理。
💡注意
此函数非线程安全,同一时刻只能有一个线程调用 run 方法。
| API | run |
| 描述 | 执行一次多模态会话推理 |
| 参数 | prompt:用户提示词字符串 |
| sys_prompt:系统提示词字符串 | |
| img_vec:ImageData 向量引用,包含需要输入的图像数据 | |
| cb:AidLLMCB 类型的回调函数,用于处理推理结果 | |
| starting_round:是否为新一轮对话的起始(true 为新对话起始) | |
| user_data:用户数据的指针,方便在自定义回调函数中使用这些数据,默认值为 nullptr | |
| 返回值 | 0 值则说明推理执行成功,否则非 0 值就说明执行失败 |
// 定义回调函数
void my_callback(aplux::aidmlm::AidLLMCBData& cb_data, void* user_data){
if(cb_data.state == aplux::aidmlm::AidLLMState::START){
printf("[BOS]%s", cb_data.text.c_str());
}else if(cb_data.state == aplux::aidmlm::AidLLMState::FINISH){
printf("[EOS]%s\n", cb_data.text.c_str());
}else if(cb_data.state == aplux::aidmlm::AidLLMState::ERROR){
printf("[ERROR]%s\n", cb_data.text.c_str());
}else{
printf("%s", cb_data.text.c_str());
}
}
// 准备图像数据(需要预先 resize 到模型要求的尺寸,格式为 RGB)
cv::Mat img = cv::imread("test.jpg");
cv::Mat img_rgb;
cv::cvtColor(img, img_rgb, cv::COLOR_BGR2RGB);
cv::Mat img_resized;
cv::resize(img_rgb, img_resized, cv::Size(392, 392));
aplux::aidmlm::ImageData img_data = {
.img_pos = -1,
.img_data = (uint8_t*)img_resized.data,
};
std::vector<aplux::aidmlm::ImageData> img_vec;
img_vec.push_back(img_data);
// 执行推理
std::string sys_prompt = "You are a helpful assistant.";
std::string user_prompt = "请描述一下图中场景";
int run_result = mlm_ctx.run(user_prompt, sys_prompt, img_vec, my_callback, true);
if(run_result < 0){
printf("AidMLM run failed.\n");
return EXIT_FAILURE;
}会话终止操作.abort()
用于打断当前正在执行推理的会话。
| API | abort |
| 描述 | 终止当前正在运行的推理会话 |
| 参数 | reserve:保留字段,默认值为 nullptr |
| 返回值 | 0 值则说明终止操作执行成功,否则非 0 值就说明执行失败 |
重置操作.reset()
在多轮对话场景中,当需要处理下一张图像或重新开始对话时,需要调用 reset 重置内部状态。
| API | reset |
| 描述 | 重置推理器内部状态,为下一次推理做准备 |
| 参数 | void |
| 返回值 | 0 值则说明重置成功,否则非 0 值就说明执行失败 |
// 处理完一张图像后重置,准备处理下一张
if(mlm_ctx.reset() < 0){
printf("AidMLM reset failed.\n");
return EXIT_FAILURE;
}完结释放操作.finalize()
释放模型资源,完成反初始化。
| API | finalize |
| 描述 | 释放模型资源,完成必要的反初始化操作 |
| 参数 | void |
| 返回值 | 0 值则说明释放成功,否则非 0 值就说明执行失败 |
if(mlm_ctx.finalize() < 0){
printf("AidMLM finalize failed.\n");
return EXIT_FAILURE;
}获取性能分析器.get_profiler()
当初始化时启用了性能分析器,可以通过此函数获取 Profiler 对象指针。具体用法参见后文「性能分析 (Profiler) C++ 接口文档」章节。
| API | get_profiler |
| 描述 | 获取性能分析器对象的指针 |
| 参数 | void |
| 返回值 | 如果性能分析器已启用,返回 Profiler 对象指针;如果未启用,返回 nullptr |
// 启用性能分析器
aplux::aidmlm::AidmlmInitParam init_param;
init_param.enable_profiler = true;
// ... 其他参数设置 ...
mlm_ctx.initialize(init_param, true);
// 执行推理后获取性能数据
aplux::aidgen::Profiler* profiler = mlm_ctx.get_profiler();
aplux::aidgen::ProfileData data = profiler->get_data();
printf("初始化耗时: %lu us\n", data.init_time_us);
printf("首Token耗时: %lu us\n", data.time_to_first_token_us);
printf("生成速率: %.2f tok/s\n", data.generate_rate);
printf("视觉模型执行耗时: %lu us\n", data.vit_execute_time_us);性能分析 (Profiler) C++ 接口文档
💡注意
性能分析相关接口位于 aplux::aidgen 命名空间下(独立于 aplux::aidllm 和 aplux::aidmlm)。
- 头文件路径
/usr/local/include/aidlux/aidgen/profiler.hpp - profiler.hpp 已被 aidllm.hpp 和 aidmlm.hpp 自动包含,无需单独引用
- AidLLM 和 AidMLM 均通过各自的
get_profiler()方法获取 Profiler 对象来使用性能分析功能
性能分析数据类型.struct ProfileData
在推理过程中,开发者可能关注各阶段的性能指标,ProfileData 结构体用于存储推理过程中采集到的性能数据。
成员变量列表
| 成员变量名 | 类型 | 描述 |
|---|---|---|
| init_time_us | uint64_t | 初始化耗时(微秒) |
| prompt_token_num | uint64_t | 输入提示词的 Token 数量 |
| prompt_processing_rate | float | 提示词处理速率(tok/s) |
| time_to_first_token_us | uint64_t | 首个 Token 生成耗时(微秒) |
| generated_token_num | uint64_t | 生成的 Token 数量 |
| generate_rate | float | Token 生成速率(tok/s) |
| generate_time_us | uint64_t | 生成阶段总耗时(微秒) |
| vit_execute_time_us | uint64_t | 视觉模型执行耗时(微秒),仅 AidMLM 有效 |
| vit_init_time_us | uint64_t | 视觉模型初始化耗时(微秒),仅 AidMLM 有效 |
| vit_preprocess_time_us | uint64_t | 视觉模型预处理耗时(微秒),仅 AidMLM 有效 |
| vit_postprocess_time_us | uint64_t | 视觉模型后处理耗时(微秒),仅 AidMLM 有效 |
性能分析器类.class Profiler
Profiler 类用于管理推理过程的性能数据采集,需要在初始化时启用(enable_profiler = true)才能使用。
获取性能数据.get_data()
获取当前已采集的性能数据。
| API | get_data |
| 描述 | 获取当前推理过程中采集的性能分析数据 |
| 参数 | void |
| 返回值 | ProfileData 结构体,包含各阶段的性能指标 |
重置性能数据.reset()
重置已采集的性能数据,通常在开始新一轮推理前调用。
| API | reset |
| 描述 | 清空已采集的性能数据,恢复到初始状态 |
| 参数 | void |
| 返回值 | void |
// 启用性能分析器初始化
int init_result = llm_interpreter_ptr->initialize(true);
// 获取性能分析器
aplux::aidgen::Profiler* profiler = llm_interpreter_ptr->get_profiler();
// 执行推理...
llm_interpreter_ptr->run(prompt, dialog_callback);
// 获取性能数据
aplux::aidgen::ProfileData data = profiler->get_data();
printf("首Token耗时: %lu us\n", data.time_to_first_token_us);
printf("生成速率: %.2f tok/s\n", data.generate_rate);
printf("生成Token数: %lu\n", data.generated_token_num);
// 重置数据,准备下一轮推理
profiler->reset();