docs/cn/run/android/api-reference.mdx
import Feedback from "/snippets/page-feedback.mdx";
通过 runtime_id 选择推理运行环境:
val runtime_id: String? // "llama_cpp" | "qairt" | null
runtime_id | 运行环境 | 模型格式 | 计算单元 |
|---|---|---|---|
"llama_cpp" | llama.cpp + GGML Hexagon 后端 | GGUF | CPU / Adreno GPU / Hexagon NPU |
"qairt" | Qualcomm® AI Engine Direct | Qualcomm AI Hub 预编译 bin | 仅 Hexagon NPU |
null | SDK 根据模型路径自动判断 | — | — |
常量定义见 RuntimeIdValue(LLAMA_CPP、QAIRT)。
给原生 SDK geniex_resolve_device 的计算单元别名。
val compute_unit: String? // "cpu" | "gpu" | "npu" | null
| 别名 | 行为 |
|---|---|
null | 运行环境默认值——llama_cpp 与 qairt 均为 npu。 |
"npu" | Hexagon NPU 加速。骁龙上推荐。 |
"gpu" | 通过 OpenCL 使用 Adreno GPU(仅 llama_cpp)。 |
"cpu" | 纯 CPU。强制 nGpuLayers = 0。 |
模型通过内置的 Rust 模型管理器在设备上拉取。请勿手动 adb push 权重——使用 ModelManagerWrapper。
ModelManagerWrapper// Init (idempotent — safe to call on every Activity.onCreate).
GenieXSdk.getInstance().init(context)
// Pull with streaming progress.
ModelManagerWrapper.pullFlow(
ModelPullInput(
model_name = "unsloth/Qwen3-0.6B-GGUF",
precision = "Q4_0",
hub = HubSource.HUGGINGFACE,
)
).collect { event ->
when (event) {
is ModelManagerWrapper.PullEvent.Progress -> /* update UI */
ModelManagerWrapper.PullEvent.Completed -> /* done */
is ModelManagerWrapper.PullEvent.Error -> /* show error */
}
}
// Resolve on-disk paths for a previously-pulled model.
val paths: ModelPaths? = ModelManagerWrapper.getPaths("unsloth/Qwen3-0.6B-GGUF")
// Inventory / cleanup.
ModelManagerWrapper.list() // List<String>
ModelManagerWrapper.remove("org/repo") // 0 = success
ModelManagerWrapper.clean() // wipe all cached models
ModelPullInputdata class ModelPullInput(
val model_name: String, // "org/repo" or alias
val precision: String? = null, // precision (quantization) e.g. "Q4_0", "Q4_K_M"
val hub: HubSource = HubSource.AUTO, // AUTO routes by model_name
val local_path: String? = null, // only when hub == LOCALFS
val hf_token: String? = null, // falls back to GENIEX_HFTOKEN env
val chipset: String? = null, // required for Qualcomm AI Hub on Android (e.g. "SM8750")
val display_name: String? = null,
)
HubSourceenum class HubSource(val value: Int) {
AUTO(0), // routes by prefix (e.g. ai-hub-models/* → AIHUB)
HUGGINGFACE(1),
MODELSCOPE(2),
AIHUB(3),
VOLCES(4),
LOCALFS(127),
}
ModelPaths由 getPaths() 返回。其字段可直接传入 LlmCreateInput / VlmCreateInput:
data class ModelPaths(
val model_path: String,
val model_dir: String,
val model_name: String,
val runtime_id: String, // authoritative — prefer over UI selection
val mmproj_path: String? = null, // VLM projection weights
val tokenizer_path: String? = null,
val compute_unit: String? = null,
)
LlmCreateInputdata class LlmCreateInput(
val model_name: String,
val model_path: String,
val tokenizer_path: String? = null,
val config: ModelConfig,
val runtime_id: String? = null,
val compute_unit: String? = null,
)
VlmCreateInputdata class VlmCreateInput(
val model_name: String,
val model_path: String,
val mmproj_path: String? = null, // vision projection weights (GGUF VLMs)
val config: ModelConfig,
val runtime_id: String? = null,
val compute_unit: String? = null,
)
ModelConfigdata class ModelConfig(
var nCtx: Int = 2048, // context size; 0 = model default
var nThreads: Int = 8,
var nThreadsBatch: Int = 8,
var nBatch: Int = 2048,
var nUBatch: Int = 512,
var nSeqMax: Int = 1,
var nGpuLayers: Int = -1, // -1 = all layers
val chat_template_path: String = "",
val chat_template_content: String = "",
val max_tokens: Int = 2048,
val enable_thinking: Boolean = false,
val verbose: Boolean = false,
)
ChatMessagedata class ChatMessage(
var role: String, // "system" | "user" | "assistant"
var content: String,
)
VlmChatMessage / VlmContentdata class VlmChatMessage(
val role: String?, // "system" | "user" | "assistant"
val contents: List<VlmContent>,
)
data class VlmContent(
val type: String?, // "text" | "image"
val text: String?, // text content, or absolute file path for image
)
GenerationConfigdata class GenerationConfig(
var maxTokens: Int = 32,
var stopWords: Array<String>? = null,
var stopCount: Int = 0,
var nPast: Int = 0,
var samplerConfig: SamplerConfig? = null,
var imagePaths: Array<String>? = null,
var imageCount: Int = 0,
var audioPaths: Array<String>? = null,
var audioCount: Int = 0,
)
LlmStreamResultsealed class LlmStreamResult {
data class Token(val text: String) : LlmStreamResult()
data class Completed(val profile: ProfilingData) : LlmStreamResult()
data class Error(val throwable: Throwable) : LlmStreamResult()
}
可在 CPU、Adreno GPU 或 Hexagon NPU 上运行任意 GGUF 模型,计算单元由 compute_unit 控制。
val paths = ModelManagerWrapper.getPaths("unsloth/Qwen3-0.6B-GGUF")
?: error("Model not downloaded")
LlmWrapper.builder()
.llmCreateInput(
LlmCreateInput(
model_name = paths.model_name,
model_path = paths.model_path,
config = ModelConfig(nCtx = 4096),
runtime_id = "llama_cpp",
compute_unit = null, // null → npu (recommended on Snapdragon)
)
)
.build()
.onSuccess { llmWrapper = it }
.onFailure { println("Error: ${it.message}") }
val chat = arrayListOf(ChatMessage("user", "What is AI?"))
llmWrapper.applyChatTemplate(chat.toTypedArray(), null, false).onSuccess { t ->
llmWrapper.generateStreamFlow(t.formattedText, GenerationConfig(maxTokens = 2048)).collect { result ->
when (result) {
is LlmStreamResult.Token -> print(result.text)
is LlmStreamResult.Completed -> println("\nDone")
is LlmStreamResult.Error -> println("Error: ${result.throwable}")
}
}
}
| 目标 | compute_unit | 备注 |
|---|---|---|
| 骁龙 NPU(推荐) | "npu" 或 null | Hexagon NPU 加速。 |
| Adreno GPU(OpenCL) | "gpu" | 默认 nGpuLayers = -1 全层卸载。 |
| 纯 CPU | "cpu" | 兼容任意 ARM64 芯片。 |
GGUF VLM 需要两份产物:LLM 权重(model_path)与视觉投影(mmproj_path)。两者均来自 getPaths():
val paths = ModelManagerWrapper.getPaths("unsloth/Qwen3-VL-2B-Instruct-GGUF")
?: error("Model not downloaded")
VlmWrapper.builder()
.vlmCreateInput(
VlmCreateInput(
model_name = paths.model_name,
model_path = paths.model_path,
mmproj_path = paths.mmproj_path,
config = ModelConfig(nCtx = 4096),
runtime_id = "llama_cpp",
compute_unit = null,
)
)
.build()
.onSuccess { vlmWrapper = it }
val msg = VlmChatMessage(
role = "user",
contents = listOf(
VlmContent("image", "/storage/emulated/0/Pictures/example.jpg"),
VlmContent("text", "Describe this image."),
),
)
val chat = arrayListOf(msg)
vlmWrapper.applyChatTemplate(chat.toTypedArray(), null, false).onSuccess { t ->
val gen = vlmWrapper.injectMediaPathsToConfig(chat.toTypedArray(), GenerationConfig(maxTokens = 2048))
vlmWrapper.generateStreamFlow(t.formattedText, gen).collect { result ->
when (result) {
is LlmStreamResult.Token -> print(result.text)
is LlmStreamResult.Completed -> println("\nDone")
is LlmStreamResult.Error -> println("Error: ${result.throwable}")
}
}
}
来自 Qualcomm AI Hub 的预编译模型。仅 NPU,绑定指定芯片(SM8750 = 骁龙 8 至尊版,SM8850 = 骁龙 8 至尊版 Gen 5)。
ModelManagerWrapper.pullFlow(
ModelPullInput(
model_name = "ai-hub-models/Qwen2.5-VL-7B-Instruct",
hub = HubSource.AUTO, // AUTO routes `ai-hub-models/*` to Qualcomm AI Hub
chipset = "SM8750", // REQUIRED on Android
)
).collect { event ->
when (event) {
is ModelManagerWrapper.PullEvent.Progress -> updateProgressBar(event.files)
ModelManagerWrapper.PullEvent.Completed -> println("done")
is ModelManagerWrapper.PullEvent.Error -> println("err ${event.code}: ${event.message}")
}
}
| 模态 | Hub 仓库 |
|---|---|
| LLM | ai-hub-models/Qwen3-4B-Instruct-2507 |
| VLM | ai-hub-models/Qwen2.5-VL-7B-Instruct |
val paths = ModelManagerWrapper.getPaths("ai-hub-models/Qwen3-4B-Instruct-2507")
?: error("Model not downloaded")
LlmWrapper.builder()
.llmCreateInput(
LlmCreateInput(
model_name = paths.model_name,
model_path = paths.model_path,
config = ModelConfig(max_tokens = 2048, enable_thinking = false),
runtime_id = "qairt",
compute_unit = null, // null → NPU (only option for Qualcomm AI Engine Direct)
)
)
.build()
.onSuccess { llmWrapper = it }
.onFailure { println("Error: ${it.message}") }
val chat = arrayListOf(ChatMessage("user", "What is AI?"))
llmWrapper.applyChatTemplate(chat.toTypedArray(), null, false).onSuccess { t ->
llmWrapper.generateStreamFlow(t.formattedText, GenerationConfig()).collect { result ->
when (result) {
is LlmStreamResult.Token -> print(result.text)
is LlmStreamResult.Completed -> println("\nDone")
is LlmStreamResult.Error -> println("Error: ${result.throwable}")
}
}
}
val paths = ModelManagerWrapper.getPaths("ai-hub-models/Qwen2.5-VL-7B-Instruct")
?: error("Model not downloaded")
VlmWrapper.builder()
.vlmCreateInput(
VlmCreateInput(
model_name = paths.model_name,
model_path = paths.model_path,
mmproj_path = paths.mmproj_path,
config = ModelConfig(max_tokens = 2048, enable_thinking = false),
runtime_id = "qairt",
compute_unit = null,
)
)
.build()
.onSuccess { vlmWrapper = it }
val msg = VlmChatMessage(
role = "user",
contents = listOf(
VlmContent("image", "/storage/emulated/0/Pictures/cat.jpg"),
VlmContent("text", "What's in this image?"),
),
)
val chat = arrayListOf(msg)
vlmWrapper.applyChatTemplate(chat.toTypedArray(), null, false).onSuccess { t ->
val gen = vlmWrapper.injectMediaPathsToConfig(chat.toTypedArray(), GenerationConfig(maxTokens = 2048))
vlmWrapper.generateStreamFlow(t.formattedText, gen).collect { result ->
when (result) {
is LlmStreamResult.Token -> print(result.text)
is LlmStreamResult.Completed -> println("\nDone")
is LlmStreamResult.Error -> println("Error: ${result.throwable}")
}
}
}