专栏名称: 谷歌开发者
Google中国官方账号。汇集Android, Chrome, Angular等移动和网络开发技术、Google Play和AdMob等开发者成长、优化和变现平台。
目录
51好读  ›  专栏  ›  谷歌开发者

【GDE 分享】移植 Mediapipe LLM Demo 到 Kotlin Multiplatfo...

谷歌开发者  · 公众号  · 科技媒体  · 2024-12-04 17:30

正文

请到「今天看啥」查看全文


*图片来源 : Android Blog: https://android-developers.googleblog.com/2024/05/android-support-for-kotlin-multiplatform-to-share-business-logic-across-mobile-web-server-desktop.html
尽管 Mediapipe 也支持多个平台,但我们这次主要聚焦在 Android 和 iOS。一方面更贴近现实,各行各业使用 KMP 的公司的用例更多在移动端上;另外一方面也更方便对标其他移动端开发技术栈。



移植流程


初始化


使用 IDEA 或 Android Studio 创建一个 KMP 的基础工程,你可以借助 KMP Wizard 或者第三方 KMP App 的模版。如果你没有 KMP 的相关经验,可以看到它其实就是一个非常类似 Android 工程的结构,只不过这一次我们把 iOS 的壳工程也放到根目录,并且在 app 模块的 build.gradle.kts 内同时配置了 iOS 的相关依赖。


封装和调用 LLM Inference


我们在 commonMain 中,根据 Mediapipe LLM Task SDK 的特征抽象一个简单的接口,使用 Kotlin 编写,用以满足 Android 和 iOS 两端的需要。该接口取代了原有仓库里的 InferenceModel.kt 类。
// app/src/commonMain/.../llm/LLMOperatorinterface LLMOperator {
/** * To load the model into current context. * @return 1. null if it went well 2. an error message in string */ suspend fun initModel(): String?
fun sizeInTokens(text: String): Int
suspend fun generateResponse(inputText: String): String
suspend fun generateResponseAsync(inputText: String): FlowBoolean>>
}
在 Android 上面,因为 LLM Task SDK 原先就是 Kotlin 实现的,所以除了初始化加载模型文件,其余的部分基本就是代理原有的 SDK 功能。
class LLMInferenceAndroidImpl(private val ctx: Context): LLMOperator {
private lateinit var llmInference: LlmInference private val initialized = AtomicBoolean(false) private val partialResultsFlow = MutableSharedFlowBoolean>>(...)
override suspend fun initModel(): String? { if (initialized.get()) { return null } return try { val modelPath = ... if (File(modelPath).exists().not()) { return "Model not found at path: $modelPath" } loadModel(modelPath) initialized.set(true) null } catch (e: Exception) { e.message } } private fun loadModel(modelPath: String) { val options = LlmInference.LlmInferenceOptions.builder() .setModelPath(modelPath) .setMaxTokens(1024) .setResultListener { partialResult, done -> // Transforming the listener to flow, // making it easy on UI integration. partialResultsFlow.tryEmit(partialResult to done) } .build()
llmInference = LlmInference.createFromOptions(ctx, options) }
override fun sizeInTokens(text: String): Int = llmInference.sizeInTokens(text)
override suspend fun generateResponse(inputText: String






请到「今天看啥」查看全文