跳转到内容

RKLLM 模型部署 API 说明

修改履历

NO版本修改内容修改日期
1Ver1.0新建2026/06/23

本文档信息可能会因文档改进而在未事先通知的情况下变更。最新版请参照本公司网站。

未经株式会社日昇科技书面许可,严禁以任何形式复制本文档。

1. 回调函数定义

回调函数是用于接收模型实时输出的结果。在初始化 RKLLM 时回调函数会被绑定,在模型 推理过程中不断将结果输出至回调函数中,并且每次回调只返回一个 token。 示例代码如下,该回调函数将输出结果实时地打印输出到终端中:

int callback(RKLLMResult* result, void* userdata, LLMCallState state)

{ if(state == LLM_RUN_NORMAL){

printf("%s", result->text);

}

if (state == LLM_RUN_FINISH) {
printf("finish\n");

} else if (state == LLM_RUN_ERROR){

printf("\run error\n");

}

return 0;

}

(1)LLMCallState 是一个状态标志,其具体定义如下:

表 1 LLMCallState 状态标志说明

枚举定义 LLMCallState

描述 用于表示当前 RKLLM 的运行状态。

LLM_RUN_NORMAL:表示 RKLLM 模型当前正在推理中; LLM_RUN_FINISH:表示 RKLLM 模型已完成当前输入的全部推理; 枚举值 LLM_RUN_WAITING:表示当前 RKLLM 解码出的字符不是完整 UTF8 编码, 需等待与下一次解码拼接; LLM_RUN_ERROR:表示 RKLLM 模型推理出现错误; 用户在回调函数的设计过程中,可以根据 LLMCallState 的不同状态设置不同的后处理行 为。 (2)RKLLMResult 是返回值结构体,其具体定义如下:

表 2 RKLLMResult 返回值结构体说明

结构体定义 RKLLMResult

描述 用于返回当前推理生成结果。 const char* text: 表示当前推理生成的文本内容; int32_t token_id: 表示当前推理生成的 token id; RKLLMResultLogits logits: 表示当前推理生成的 logits信息,仅在 字段 RKLLMInferMode 设置为RKLLM_INFER_GET_LOGITS 时返回; RKLLMPerfStat perf: 表示当前推理结束时的性能统计数据,仅在 RKLLM_RUN_FINISH 状态时返回数据; (3)RKLLMResultLogits 是返回值结构体,其具体定义如下:

表 3 RKLLMResultLogits 返回值结构体说明

结构体定义 RKLLMResultLogits

描述 用于返回当前推理生成的 logits。 const float* logits: 表示当前推理生成的 logits;

int vocab_size: 表示词表大小;

字段

int num_tokens: 表示返回的 token 数,用户可根据 vocab_size 与

num_tokens 计算出 logits 大小; 用户在回调函数的设计过程中,可以根据 RKLLMResult 中值设置不同的后处理行为。

2. 参数结构体 RKLLMParam 定义

结构体 RKLLMParam 用于描述、定义 RKLLM 的详细信息,具体的定义如下:

表 4 RKLLMParam 结构体参数说明

结构体定义 RKLLMParam

描述 用于定义 RKLLM 模型的各项细节参数。 字段 const char* model_path: 模型文件的存放路径; int32_t max_context_len: 设置推理时的最大上下文长度; int32_t max_new_tokens: 用于设置模型推理时生成 token 的数量上限; int32_t top_k: top-k 采样是一种文本生成方法,它仅从模型预测的概率最高的 k 个token 中选择下一个 token。该方法有助于降低生成低概率或无意义 token 的风险。更高的值(如 100)将考虑更多的 token 选择,导致文本更加多样 化;而更低的值(如 10)将聚焦于最可能的 token,生成更加保守的文本。默 认值为 40;

float top_p: top-p 采样,也被称为核心采样,是另一种文本生成方法,从累计 概率至少为 p 的一组 token 中选择下一个 token。这种方法通过考虑 token 的 概率和采样的 token 数量在多样性和质量之间提供平衡。更高的值(如 0.95) 使得生成的文本更加多样化;而更低的值(如 0.5)将生成更加保守的文本。默 认值为 0.9; float temperature: 控制生成文本随机性的超参数,它通过调整模型输出 token 的概率分布来发挥作用;更高的温度(如 1.5)会使输出更加随机和创造 性,当温度较高时,模型在选择下一个 token 时会考虑更多可能性较低的选项, 从而产生更多样和意想不到的输出;更低的温度(例 0.5)会使输出更加集中、 保守,较低的温度意味着模型在生成文本时更倾向于选择概率高的 token,从而 导致更一致、更可预测的输出;温度为 0 的极端情况下,模型总是选择最有可能 的下一个 token,这会导致每次运行时输出完全相同;为了确保随机性和确定性 之间的平衡,使输出既不过于单一和可预测,也不过于随机和杂乱,默认值为 0.8; float repeat_penalty: 控制生成文本中 token 序列重复的情况,帮助防止模型 生成重复或单调的文本。更高的值(例如 1.5)将更强烈地惩罚重复,而较低的 值(例如 0.9)则更为宽容。默认值为 1.1; float frequency_penalty: 单词/短语重复度惩罚因子,减少总体上使用频率较 高的单词/短语的概率,增加使用频率较低的单词/短语的可能性,这可能会使生 成的文本更加多样化,但也可能导致生成的文本难以理解或不符合预期。设置范 围为[-2.0,2.0],默认为 0; int32_t mirostat: 在文本生成过程中主动维持生成文本的质量在期望的范围内 的算法,它旨在在连贯性和多样性之间找到平衡,避免因过度重复(无聊陷阱) 或不连 贯(混乱陷阱)导致的低质量输出;取值空间为{0, 1, 2}, 0 表示不启动该算法, 1表示使用 mirostat 算法,2 则表示使用 mirostat2.0 算法; float mirostat_tau: 选项设置 mirostat 的目标熵,代表生成文本的期望困惑 度。调整目标熵可以控制生成文本中连贯性与多样性的平衡。较低的值将导致文 本更加集中和连贯,而较高的值将导致文本更加多样化,可能连贯性较差。默认 值是 5.0; float mirostat_eta: 选项设置 mirostat 的学习率,学习率影响算法对生成文本 反馈的响应速度。较低的学习率将导致调整速度较慢,而较高的学习率将使算法 更加灵敏。默认值是 0.1; bool skip_special_token: 是否跳过特殊 token 不输出,例如推理结束符号 <EOS>等; bool is_async: 是否使用异步模式; const char* img_start: 选项设置多模态输入图像编码的起始标志符,在多模态 输入模式下需要配置; const char* img_end: 选项设置多模态输入图像编码的终止标志符,在多模态 输入模式下需要配置; const char* img_content: 选项设置多模态输入图像编码的内容标志符,在多 模态输入模式下需要配置; n_keep: 清除 kv cache 时需要在开头保留的 cache 数量,多轮对话时所设置的 n_keep 值必须不小于 system_prompt 长度; RKLLMExtendParam extend_param: 控制推理的特殊参数;

表 5 RKLLMExtendParam 结构体参数说明

结构体定义 RKLLMExtendParam

描述 控制推理的特殊参数。 int32_t base_domain_id: 控制 RKLLM 模型从哪个 domain 开始初始化,默 认为 0; int8_t embed_flash: 控制是否将模型词表存在 flash 中来节省内存,0 为关 闭,1 为开启 int8_t enabled_cpus_num: 设置推理时使用的 CPU 数量,不同的芯片型号可 设置范围不同。RK3588/3576 的可设置范围为 1~8, RK3562 的可设置范围为 字段

1. ~4,默认设置为 4

uint32_t enabled_cpus_mask: 使用二进制掩码配置具体用哪些 CPU 核进行 推理。在 rkllm.h 中预设了宏表示 CPU 编号,使用 CPU4|CPU5|CPU6|CPU7 方式配置 uint8_t n_batch: 设置并行推理,默认设置为 1 int8_t use_cross_attn: 设置是否启用交叉注意力 在实际的代码构建中,RKLLMParam 需要调用 rkllm_createDefaultParam()函数来初始化 定义,并根据需求设置相应的模型参数。示例代码如下

RKLLMParam param = rkllm_createDefaultParam(); param.model_path = “model.rkllm”; param.top_k = 1; param.max_new_tokens = 256; param.max_context_len = 512;

3. 输入结构体定义

为适应不同的输入数据,定义了 RKLLMInput 输入结构体,目前可接受文本、图片和文 本、Token id 以及编码向量四种形式的输入,具体的定义如下:

表 6 RKLLMInput 结构体参数说明

结构体定义 RKLLMInput

描述 用于接收不同形式的输入数据。 RKLLMInputType input_type: 输入模式; const char* role: 输入类型,可选[“user”, “tool”]; bool enable_thinking: Qwen3 模型是否使用 thinking 模式; union: 用于存储不同的输入数据类型,具体包含以下几种形式:

  • const char* prompt_input: 文本提示输入,用于传递自然语言文本; 字段 - RKLLMEmbedInput embed_input: 嵌入向量输入,表示已处理的特征向 量;
  • RKLLMTokenInput token_input: Token 输入,用于传递分词后的 Token 序列;
  • RKLLMMultiModelInput multimodal_input: 多模态输入,可传递多模态 数据,如图片和文本的联合输入。

表 7 RKLLMInputType 输入类型说明

枚举定义 RKLLMInputType

描述 用于表示输入数据类型。

RKLLM_INPUT_PROMPT: 表示输入数据是纯文本; RKLLM_INPUT_TOKEN: 表示输入数据是 Token id; 枚举值 RKLLM_INPUT_EMBED: 表示输入数据是编码向量; RKLLM_INPUT_MULTIMODAL: 表示输入数据是图片和文本; 当输入数据是纯文本时,使用 input_data 直接输入;当输入数据是 Token id、编码向量以 及图 片和文本时,RKLLMInput 需要搭配RKLLMTokenInput, RKLLMEmbedInput 以及 RKLLMMultiModelInput 三个输入结构体使用,具体的介绍如下: (1)RKLLMTokenInput 是接收 Token id 的输入结构体,具体的定义如下:

表 8 RKLLMTokenInput 结构体参数说明

结构体定义 RKLLMTokenInput

描述 用于接收 Token id 数据。

int32_t* input_ids: 输入 token ids 的内存指针; 字段 size_t n_tokens: 输入数据的 token 数量; (2)RKLLMEmbedInput 是接收编码向量的输入结构体,具体的定义如下:

表 9 RKLLMEmbedInput 结构体参数说明

结构体定义 RKLLMEmbedInput

描述 用于接收 Embedding 数据。

float* embed: 输入 token embedding 的内存指针; 字段 size_t n_tokens: 输入数据的 token 数量; (3)RKLLMMultiModelInput 是接收图片和文本的输入结构体,具体的定义如下:

表 10 RKLLMMultiModelInput 结构体参数说明

结构体定义 RKLLMMultiModelInput

描述 用于接收图片和文本多模态数据。 char* prompt: 输入文本的内存指针; float* image_embed: 输入图片 embedding 的内存指针; size_t n_image_tokens: 输入图片 embedding 的 token 数量; size_t n_image: 输入图片数量,支持输入连续多帧图片; 字段 size_t image_width: 输入图片计算 embedding 时的宽度,用于 mrope 计 算参数; size_t image_height: 输入图片计算 embedding 时高度,用于 mrope 计算 参数; RKLLM 支持不同的推理模式,定义了 RKLLMInferParam 结构体,目前可支持在推理过程 与预加载的 LoRA 模型联合推理,或保存 Prompt Cache 用于后续推理加速,具体的定义如 下:

表 11 RKLLMInferParam 结构体参数说明

结构体定义 RKLLMInferParam

描述 用于定义不同的推理模式。

RKLLMInferMode mode: 推理模式,当支持 RKLLM_INFER_GENERATE 普 通推理模式与 RKLLM_INFER_GET_LOGITS 额外获取 logits 值的推理模式; RKLLMLoraParam* lora_params: 推理时使用的 LoRA 的参数配置,用于 在加载多个 LoRA 时选择需要推理的 LoRA,若无需加载 LoRA 则设为 NULL 字段 即可; RKLLMPromptCacheParam* prompt_cache_params: 推理时使用 Prompt Cache 的参数配置,若无需生成 Prompt Cache 则设为 NULL 即 可; keep_history: 推理时是否需要保留历史上下文,当多轮对话时需设置为 1;

表 12 RKLLMLoraParam 结构体参数说明

结构体定义 RKLLMLoraParam

描述 用于定义推理时使用 LoRA 的参数;

字段 const char* lora_adapter_name: 推理时使用的 LoRA 名称

表 13 RKLLMPromptCacheParam 结构体参数说明

结构体定义 RKLLMPromptCacheParam

描述 用于定义推理时使用 Prompt Cache 的参数;

int save_prompt_cache: 是否在推理时保存 Prompt Cache, 1 为需要, 0 为

不需要; 字段 const char* prompt_cache_path: Prompt Cache 保存路径, 若未设置则默 认保存到”./prompt_cache.bin”中; 使用 RKLLMPromptCacheParam 的示例如下:

//初始化并设置 Prompt Cache 参数(如果需要使用 prompt cache) RKLLMPromptCacheParam prompt_cache_params; prompt_cache_params.save_prompt_cache = true; // 是否保存 prompt cache prompt_cache_params.prompt_cache_path = ”./prompt_cache.bin”; // 若需要保存 prompt cache, 指定 cache 文件路径

rkllm_infer_params.prompt_cache_params = &prompt_cache_params;

4. 初始化模型

在进行模型的初始化之前,需要提前定义 LLMHandle 句柄,该句柄用于模型的初始化、推 理和资源释放过程。注意,正确的模型推理流程需要统一这 3 个流程中的 LLMHandle 句柄对 象。在模型推理前,用户需要通过 rkllm_init()函数完成模型的初始化,具体函数的定义如下:

表 14 rkllm_init 函数接口说明

函数名 rkllm_init

描述 用于初始化 RKLLM 模型的具体参数及相关推理设置。 参数 LLMHandle* handle: 将模型注册到相应句柄中,用于后续推理、释放调用; RKLLMParam* param: 模型定义的参数结构体;

LLMResultCallback callback: 用于接受处理模型实时输出的回调函数;

返回值 0 表示初始化流程正常;-1 表示初始化失败; 示例代码如下:

LLMHandle llmHandle = nullptr;
rkllm_init(&llmHandle, &param, callback);

5. 模型推理

用户在完成 RKLLM 模型的初始化流程后,即可通过 rkllm_run()函数进行模型推理,并可以 通过初始化时预先定义的回调函数对实时推理结果进行处理;rkllm_run()的具体函数定义如下:

表 15 rkllm_run 函数接口说明

函数名 rkllm_ru

描述 调用完成初始化的 RKLLM 模型进行结果推理;

LLMHandle handle: 模型初始化注册的目标句柄;

RKLLMInput* rkllm_input: 模型推理的输入数据; 参数 RKLLMInferParam* rkllm_infer_params: 模型推理过程中的参数传递; void* userdata: 用户自定义的函数指针,默认设置为 NULL 即可;

返回值 0 表示模型推理正常运行;-1 表示调用模型推理失败;

6. 模型中断

在进行模型推理时,用户可以调用 rkllm_abort()函数中断推理进程,具体的函数定义如 下:

表 16 rkllm_ abort 函数接口说明

函数名 rkllm_ abort

描述 用于中断 RKLLM 模型推理进程。

参数 LLMHandle handle: 模型初始化注册的目标句柄;

返回值 0 表示 RKLLM 模型中断成功;-1 表示模型中断失败; 示例代码如下:

// 其中 llmHandle 为模型初始化时传入的句柄

rkllm_abort(llmHandle);

7. 释放模型资源

在完成全部的模型推理调用后,用户需要调用 rkllm_destroy()函数进行 RKLLM 模型的销 毁,并释放所申请的 CPU、NPU 计算资源,以供其他进程、模型的调用。具体的函数定义如 下:

表 17 rkllm_ destroy 函数接口说明

函数名 rkllm_ destroy

描述 用于销毁 RKLLM 模型并释放所有计算资源。

参数 LLMHandle handle: 模型初始化注册的目标句柄;

返回值 0 表示 RKLLM 模型正常销毁、释放;-1 表示模型释放失败; 示例代码如下:

// 其中 llmHandle 为模型初始化时传入的句柄

rkllm_destroy(llmHandle);

8. LoRA 模型加载

RKLLM 支持在推理基础模型的同时推理 LoRA 模型,可以在调用 rkllm_run接口前通过

rkllm_load_lora接口加载LoRA模型。RKLLM支持加载多个LoRA 模 型,每调用一次
rkllm_load_lora 可加载一个 LoRA 模型。具体的函数定义如下:

表 18 rkllm_load_lora 函数接口说明

函数名 rkllm_load_lora

描述 用于加载 LoRA 模型。

LLMHandle handle: 模型初始化注册的目标句柄;

参数 RKLLMLoraAdapter* lora_adapter: 加载 LoRA 模型时的参数配置;

返回值 0 表示 LoRA 模型正常加载;-1 表示模型加载失败;

表 19 RKLLMLoraAdapter 结构体参数说明

结构体定义 RKLLMLoraAdapter

描述 用于配置加载 LoRA 时的参数。 const char* lora_adapter_path: 待加载 LoRA 模型的路径; const char* lora_adapter_name: 待加载 LoRA 模型的名称, 由用户自定义, 字段 用于后续推理时选择指定 LoRA; float scale: LoRA 模型在推理过程中对基础模型参数进行调整的幅度; 加载 LoRA 的示例代码如下:

RKLLMLoraAdapter lora_adapter; memset(&lora_adapter, 0, sizeof(RKLLMLoraAdapter)); lora_adapter.lora_adapter_path = “lora.rkllm”; lora_adapter.lora_adapter_name = “lora_name”; lora_adapter.scale = 1.0;

ret = rkllm_load_lora(llmHandle, &lora_adapter);
if (ret != 0) {
printf("\nload lora failed\n");

}

9. Prompt Cache 管理

在模型推理过程中,Prefill 阶段通常消耗大量的计算资源和时间,特别是在 Prompt 很长的 情况下。为了加速这一过程,RKLLM 支持文件加载 Prompt Cache,通过复用缓存中的内容, 可以显著减少 Prefill 阶段的耗时,从而提升整体推理效率。在调用 rkllm_run 接口进行推理之 前,请确保正确配置 prompt_cache_params 参数。这一步骤允许模型在推理结束后生成对应的 Prompt Cache 文件。当首次运行推理时,系统会自动生成一个 Prompt Cache 文件。该文件包 含了 Prefill 阶段所需的中间结果,以便后续使用。在后续的推理任务中,可以通过调用

rkllm_load_prompt_cache 接口加载之前生成的 Prompt Cache 文件。

具体的函数定义如下:

表 20 rkllm_load_prompt_cache 函数接口说明

函数名 rkllm_load_prompt_cache

描述 用于加载 Prompt Cache。

LLMHandle handle: 模型初始化注册的目标句柄,可见 4. 初始化模型;

参数 const char* prompt_cache_path: 待加载 Prompt Cache 文件的路径;

返回值 0 表示 Prompt Cache 模型正常加载;-1 表示模型加载失败;

表 21 rkllm_release_prompt_cache 函数接口说明

函数名 rkllm_release_prompt_cache

描述 用于释放 Prompt Cache。

参数 LLMHandle handle: 模型初始化注册的目标句柄,可见 4. 初始化模型;

返回值 0 表示 Prompt Cache 模型正常释放;-1 表示模型释放失败; 注意: RKLLM 会从头开始检测输入与 prompt_cache 中相同的部分,假设您的输入格式固定为 PROMPT_PREFIX + text + PROMPT_POSTFIX,您可以仅对 PROMPT_PREFIX 部分生成 Prompt Cache,加载后在后续的推理中即可复用这部分结果。 RKLLM 支持生成多个 Prompt Cache 文件。在需要使用不同的 Prompt Cache 时,只需加 载对应的文件即可。当需要切换到另一个 Prompt Cache 文件或不再需要使用加载的 PromptCache 时,请显式调用 rkllm_release_prompt_cache 接口进行释放。 加载 Prompt Cache 的示例代码如下:

// 初始化并设置 Prompt Cache 参数,并调用 run 接口生成 prompt cache 文件 RKLLMPromptCacheParam prompt_cache_params;

// 是否保存 prompt cache prompt_cache_params.save_prompt_cache = true;

// 若需要保存 prompt cache, 指定 cache 文件绝对路径 prompt_cache_params.prompt_cache_path = “/data/prompt_cache.bin”;

rkllm_infer_params.prompt_cache_params = &prompt_cache_params;
rkllm_infer_params.mode = RKLLM_INFER_GENERATE;
rkllm_input.input_type = RKLLM_INPUT_PROMPT;
rkllm_input.prompt_input = (char *)prompt.c_str();
rkllm_run(llmHandle, &rkllm_input, &rkllm_infer_params, NULL);

减 // 加载 prompt cache 文件, 少 prefill 耗时

rkllm_load_prompt_cache(llmHandle, "./prompt_cache.bin");
if (ret != 0) {
printf("\nload Prompt Cache failed\n");

}

rkllm_run(llmHandle, &rkllm_input, &rkllm_infer_params, NULL);

10. KV Cache 管理

RKLLM 支持手动清除 KV 缓存,可用于单轮和多轮对话。在调用清除缓存功能时,如果 keep_system_prompt 设置为 1,则会保留系统提示词(如果存在);否则,将清空整个缓存。 函数定义如下:

表 22 rkllm_clear_kv_cache 函数接口说明

函数名 rkllm_clear_kv_cache

描述 用于清除 kv cache。

LLMHandle handle: 模型初始化注册的目标句柄;

keep_system_prompt: 是否保留系统提示词; start_pos: 需要删除的 kv cache 起始位 position id,包含 start_pos 位 置,若无需使用请手动配置为 nullptr; end_pos: 需要删除的 kv cache 结束位 position id,不包含 end_pos 位 参数 置,若无需使用请手动配置为 nullptr; 注意:

  1. 只有在单轮模式中使用暂停推理功能时才支持删除指定位置 kv cache;

2. 如果提供了特定的范围 [start_pos, end_pos),则忽略

keep_system_prompt,改为清 除范围内的 kv cache; 返回值 0 表示 kv cache 清除成功;-1 表示清除失败;

11. Chat Template 设置

当用户使用文本输入时,RKLLM 会对默认文本进行前处理,前处理时会根据 Hugging Face模型 tokenizer_config.json 文件中的 chat_template 字段,自动解析并应用提示词模板。 如需自定义,可使用以下函数进行重置,其中,system_prompt 作为系统提示词,用于指导模 型行为,prompt_prefix 为用户输入前缀,prompt_postfix 为用户输入后缀,具体的函数定义

如下。当用户重置模板后,enable_thinking 选项将失效,用户需要在自定义的 prompt 中进行 配置。

表 23 rkllm_set_chat_template 函数接口说明

函数名 rkllm_set_chat_template

描述 用于设置提示词。

LLMHandle handle: 模型初始化注册的目标句柄;

system_prompt: 系统提示词; 参数 prompt_prefix: 用户输入前缀; prompt_postfix: 用户输入后缀;

返回值 0 表示 chat_template 设置成功;-1 表示设置失败;

12. Function Calling 设置

RKLLM 支持通过 Function Calling 实现模型与外部系统的结构化交互,扩展大模型能力边 界,提升模型在知识补充、数据精确获取等任务中的表现。当启用 Function Calling 模式后,应 用程序可将函数定义传入模型,模型根据用户提问判断是否需要调用函数,并根据设定的格式输 出调用请求。应用程序根据模型意图调用相应函数并将结果返回,模型最终基于结果继续对话。 RKLLM 支持的 Function Calling 设置函数定义如下:

表 24 rkllm_set_function_tools 函数接口说明

函数名 rkllm_set_function_tools

描述 Function Calling 配置,包括系统提示词、工具函数定义和工具响应标识

LLMHandle handle: 模型初始化注册的目标句柄;

system_prompt: 系统提示词; tools: JSON 格式的函数定义字符串,描述可用函数的名称、功能和参数格 参数 式; tool_response_str: 工具函数调用结果的标识标签,用于与普通对话内容进行 区分; 返回值 0 表示设置成功;-1 表示设置失败;

示例代码如下:

首先配置 tools

std::string system_prompt = "You are Qwen, created by Alibaba Cloud.

You are a helpful assistant.\n\nCurrent Date: 2024-09-30”;

std::string tools = R"([

{ “type”: “function”, “function”: { “name”: “get_current_temperature”, “description”: “Get current temperature at a location.”, “parameters”: { “type”: “object”,

“properties”: { “location”: { “type”: “string”, “description”: “The location to get the temperature for, in the format “City, State, Country”.” }, “unit”: { “type”: “string”, “enum”: [“celsius”, “fahrenheit”], “description”: “The unit to return the temperature in. Defaults to “celsius”.” } }, “required”: [“location”] } } }, { “type”: “function”, “function”: { “name”: “get_temperature_date”, “description”: “Get temperature at a location and date.”, “parameters”: { “type”: “object”, “properties”: { “location”: { “type”: “string”, “description”: “The location to get the temperature for, in the format “City, State, Country”.” }, “date”: { “type”: “string”, “description”: “The date to get the temperature for, in the format “Year-Month-Day”.” }, “unit”: { “type”: “string”, “enum”: [“celsius”, “fahrenheit”], “description”: “The unit to return the temperature in. Defaults to “celsius”.” } }, “required”: [“location”, “date”] } } } ])”;

rkllm_set_function_tools(llmHandle, system_prompt.c_str(),

tools.c_str(), “tool_response”);

接下来,在推理过程中配合 rkllm_run 实现调用链:

// 用户提问 RKLLMInferParam rkllm_infer_params; memset(&rkllm_infer_params, 0, sizeof(RKLLMInferParam));

rkllm_infer_params.mode = RKLLM_INFER_GENERATE;
rkllm_infer_params.keep_history = 0;

RKLLMInput rkllm_input;

rkllm_input.input_type = RKLLM_INPUT_PROMPT;
rkllm_input.enable_thinking = false;
rkllm_input.role = "user";
rkllm_input.prompt_input = "What's the temperature in San Francisco

now? How about tomorrow?”;

rkllm_run(llmHandle, &rkllm_input, &rkllm_infer_params, NULL);

// 第一次调用 rkllm_run 会返回需要调用的工具函数名 <tool_call> {“name”: “get_current_temperature”, “arguments”: {“location”: “San Francisco”}} </tool_call> <tool_call> {“name”: “get_temperature_date”, “arguments”: {“location”: “San Francisco”, “date”: “2024-10-01”}} </tool_call>

// 将工具调用结果返回给大模型,role 必须配置为 tool

rkllm_input.role = "tool";
rkllm_input.prompt_input = R"([

{ “temperature”: 26.1, “location”: “San Francisco”, “unit”: “celsius” }, { “temperature”: 25.9, “location”: “San Francisco”, “date”: “2024-09-30”, “unit”: “celsius” } ])”;

rkllm_run(llmHandle, &rkllm_input, &rkllm_infer_params, NULL);

// 最终结果 “The current temperature in San Francisco is 26.1°C. Tomorrow, the temperature is expected to be 25.9°C.”

13. Cross attention 设置

RKLLM 支持 cross attention 推理,用户可以通过如下函数将 encoder 生成的 K/V 缓存、 掩码以及位置信息输入给解码器用于交叉注意力计算。cross attention 只支持自定义模型推理, 模型的转换方式详见 3.1.6 章节。

表 25 rkllm_set_cross_attn_params 函数接口说明

函数名 rkllm_set_cross_attn_params

描述 用于配置交叉注意力参数

LLMHandle handle: 模型初始化注册的目标句柄;

参数 RKLLMCrossAttnParam* cross_attn_params: 交叉注意力参数;

返回值 0 表示设置成功;-1 表示设置失败;

表 26 RKLLMCrossAttnParam 结构体参数说明

结构体定义 RKLLMCrossAttnParam

描述 交叉注意力参数

  • float* encoder_k_cache: encoder 输出的 k 值缓存指针,
  • float* encoder_v_cache: encoder 输出的 v 值缓存指针 字段 - float* encoder mask: encoder 的注意力掩码
  • int32_t* encoder_pos: encoder 输入 token 的位置信息
  • int* num_tokens: encoder 的输入 token 数

14. 多 batch 并行推理

RKLLM 支持同时推理多个 batch(建议 batch 数量不超过 8)。 使用两个 batch 进行推理的示例代码如下,主要为:

模型初始化时需要将 param.extend_param.n_batch 参数设置为 2; 使用多 batch 进行推理时,输入 RLLLMInput 和 callback 中的 RKLLMResult 均为 n_batch 大小的数组; callback 中所有 batch 推理结果同步返回,当某个 batch 返回的 token id 为负数时,表 示该 batch 推理结束,所有 batch 都推理结束时才会终止推理; 在 callback 中处理返回的文本时,必须先判断返回的 text 是否为空指针,再进行赋值操 作。

#include <string.h>
#include <unistd.h>
#include <string>
#include "rkllm.h"
#include <fstream>
#include <iostream>
#include <csignal>
#include <vector>

using namespace std;

LLMHandle llmHandle = nullptr;
std::string output_texts[10];
int callback(RKLLMResult *result, void *userdata, LLMCallState state)

{

if (state == RKLLM_RUN_FINISH)

{

printf("\nrkllm run finish\n");

} else if (state == RKLLM_RUN_ERROR) {

printf("\nrkllm run error\n");

} else if (state == RKLLM_RUN_NORMAL) { RKLLMResult batch1 = result[0]; RKLLMResult batch2 = result[1];

if (batch1.text) {

output_texts[0] += batch1.text;

printf("batch 0 %s\n", output_texts[0].c_str());

}

if (batch2.text) {

output_texts[1] += batch2.text;;

printf("batch 1 %s\n", output_texts[1].c_str());

} }

return 0;

}

int main(int argc, char **argv)

{

if (argc < 4) {
std::cerr << "Usage: " << argv[0] << " model_path

max_new_tokens max_context_len\n”;

return 1;

}

RKLLMParam param = rkllm_createDefaultParam(); param.model_path = argv[1]; param.top_k = 1; param.top_p = 0.95; param.temperature = 0.8; param.repeat_penalty = 1.1; param.frequency_penalty = 0.0; param.presence_penalty = 0.0; param.max_new_tokens = std::atoi(argv[2]); param.max_context_len = std::atoi(argv[3]); param.skip_special_token = true; param.extend_param.base_domain_id = 0; param.extend_param.embed_flash = 1; param.extend_param.n_batch = 2;

int ret = rkllm_init(&llmHandle, &param, callback);
if (ret == 0){
printf("rkllm init success\n");

} else {

printf("rkllm init failed\n");

exit_handler(-1); }

RKLLMInput rkllm_input[2]; memset(&rkllm_input, 0, sizeof(RKLLMInput)*2); RKLLMInferParam rkllm_infer_params; memset(&rkllm_infer_params, 0, sizeof(RKLLMInferParam)); // 将所有内容初始化为 0 output_texts[0].clear(); output_texts[1].clear();

rkllm_infer_params.mode = RKLLM_INFER_GENERATE;
rkllm_infer_params.keep_history = 0;
rkllm_input[0].input_type = RKLLM_INPUT_PROMPT;
rkllm_input[0].role = "user";
rkllm_input[0].enable_thinking = false;
rkllm_input[0].prompt_input = "上联: 江边惯看千帆过";
rkllm_input[1].input_type = RKLLM_INPUT_PROMPT;
rkllm_input[1].role = "user";
rkllm_input[1].enable_thinking = false;
rkllm_input[1].prompt_input = "以咏梅为题目,帮我写一首古诗,要求包含梅花、白雪等元素。";
printf("robot: ");
rkllm_run(llmHandle, &rkllm_input[0], &rkllm_infer_params, NULL);
rkllm_destroy(llmHandle);
return 0;

}

15. 模型暂停推理

RKLLM 支持在单轮模式中暂停推理,具体为在 callback 中 return 1。暂停推理时,kv cache不会被清除,用户可以继续更改输入后,调用 rkllm_run 恢复推理。

16. 模型性能数据回调

RKLLM 支持在推理结束时返回单次推理性能数据,包括 prefill 和 decode 推理总耗时、 token数量和内存占用,返回的结构体定义如下:

表 27 RKLLMPerfStat 结构体参数说明

结构体定义 RKLLMPerfStat

描述 返回模型推理性能数据 字段 - float prefill_time_ms: prefill 阶段总耗时,单位 ms

  • int prefill_tokens: prefill 阶段总 token 数

  • float generate_time_ms: generate 阶段总耗时

  • int generate_tokens: generate 阶段生成的总 token 数

  • float memory_usage_mb: 推理过程 VmHWM 内存大小,单位 MB