ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

RunAnywhere Flutter SDK 实战指南:在 iOS / Android 上端侧运行 LLM、语音与多模态 AI

RunAnywhere Flutter SDK 实战指南:在 iOS / Android 上端侧运行 LLM、语音与多模态 AI RunAnywhere Flutter SDK 实战指南在 iOS / Android 上端侧运行 LLM、语音与多模态 AI【免费下载链接】runanywhere-sdksProduction ready toolkit to run AI locally项目地址: https://gitcode.com/gh_mirrors/ru/runanywhere-sdksRunAnywhere Flutter SDK 是 RunAnywhere 跨平台 SDK 家族Swift / Kotlin / React Native / Web / Flutter中的 Flutter 绑定目标是在 iOS 与 Android 设备上直接运行 LLM、语音识别STT、语音合成TTS、语音活动检测VAD、视觉语言模型VLM乃至完整的语音 Agent 流水线全程不依赖云端推理。本文以仓库内 bindings/flutter/README.md 为核心骨架结合 Flutter 包源码 与 示例应用系统讲解环境要求、安装配置、命名空间式 API、模型管理与错误处理帮助你在一小时内跑通第一个端侧 AI 应用并理解其底层 Dart FFI 与原生 C 核心的协作方式。一、SDK 概览与核心设计RunAnywhere Flutter SDK 以「本地优先、隐私优先」为设计出发点推理完全发生在设备本地用户数据不出设备网络连接仅用于初始模型下载、目录同步与可选的生产遥测。其公共 API 采用命名空间式设计——每一个能力LLM、STT、TTS、VAD、VLM、RAG 等都通过RunAnywhere静态类上的一个静态访问器暴露形如RunAnywhere.capability.method(...)这也是 Swift / Kotlin / React Native 各绑定共享的跨平台一致性约定见 bindings/flutter/docs/Documentation.md。从源码结构看RunAnywhere是一个abstract final class入口文件负责生命周期管理initialize/reset、就绪状态isReady、SDK 版本version、稳定设备标识deviceId、SDK 事件流events以及能力探测capabilities()。底层通过DartBridge走 FFI 调用 native C 核心rac_*C ABI 符号再由各命名空间llm、stt、tts、vad、vlm、voice、models、downloads、rag、tools、embeddings、lora等封装成类型安全的 Dart API。SDK 包本身pubspec.yaml依赖ffi、protobuf由 IDL 生成的 proto 绑定见idl/目录、shared_preferences、path_provider、audioplayers/record音频采集与播放、device_info_plus等构成了一个「核心原生引擎 Dart 薄封装」的分层架构。二、环境要求Requirements在开始之前请先对照以下环境要求确认开发环境达标组件最低版本推荐版本Flutter3.443.44.6见 pubspec.yamlDart3.123.12.2workspace 约束3.12.0 4.0.0iOS17.517.5AndroidAPI 24Android 7.0API 28Xcode2626RAM2 GB4 GB用于更大模型几点需要注意强烈建议使用 ARM64 设备。iOS 上 Metal 加速、Android 上 NEON 指令集都能带来显著性能提升Apple MLX 后端则必须在物理 arm64 iOS 设备上运行模拟器 slice 仅用于编译/链接验证见下文 FAQ。iOS 平台配置是强制的需要静态 CocoaPods 链接和用于语音功能的麦克风权限声明详见 bindings/flutter/docs/DEVELOPMENT.md第三节会给出完整的 Podfile 与 Info.plist 配置。工作区使用 melos 管理多包runanywhere、runanywhere_llamacpp、runanywhere_mlx、runanywhere_onnx、runanywhere_qhexrtmelos bootstrap负责并行pub get见 bindings/flutter/pubspec.yaml。三、安装与平台配置3.1 添加依赖在应用的pubspec.yaml中按需添加包当前仓库锁定版本为0.20.36SDK 包 version 字段Core LlamaCppLLM / VLMGGUF 格式dependencies: runanywhere: 0.20.36 runanywhere_llamacpp: 0.20.36Core ONNXSTT / TTS / VADdependencies: runanywhere: 0.20.36 runanywhere_onnx: 0.20.36Core MLXApple LLM / VLM / 物理 iOS 设备上的语音dependencies: runanywhere: 0.20.36 runanywhere_mlx: 0.20.36可选 NPUSnapdragon Android 上的 Qualcomm Hexagonrunanywhere_qhexrt: 0.20.36随后执行flutter pub get cd ios pod install cd .. # iOS only各包职责一览包用途runanywhere核心 SDK —— 必需runanywhere_llamacppLLM / VLMGGUFrunanywhere_onnxSTT、TTS、VADrunanywhere_mlxApple MLXrunanywhere_qhexrtQualcomm Hexagon NPU可选3.2 iOS 平台配置必需根据 bindings/flutter/docs/DEVELOPMENT.md添加包之后必须更新 iOS Podfile1. 更新ios/Podfileplatform :ios, 17.5 target Runner do use_frameworks! :linkage :static flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| config.build_settings[IPHONEOS_DEPLOYMENT_TARGET] 17.5 config.build_settings[GCC_PREPROCESSOR_DEFINITIONS] || [ $(inherited), PERMISSION_MICROPHONE1, ] end end end重要缺少use_frameworks! :linkage :static会在运行时出现 symbol not found 错误。2. 更新ios/Runner/Info.plist声明麦克风权限keyNSMicrophoneUsageDescription/key stringThis app needs microphone access for speech recognition/string3. 执行 pod installcd ios pod install cd ..3.3 Android 平台配置在android/app/src/main/AndroidManifest.xml中添加录音权限语音功能需要uses-permission android:nameandroid.permission.RECORD_AUDIO /3.4 从源码构建可选如果要从仓库源码构建 native 产物并本地调试工作区采用 melos 引导# 1. 克隆仓库后在仓库根目录构建 native 产物 ./bindings/swift/scripts/build-core-xcframework.sh ./scripts/build/build-core-android.sh arm64-v8a # 2. 引导 Flutter 工作区 cd bindings/flutter melos bootstrapbuild-core-xcframework.sh会把 XCFramework 构建并放置到各包的ios/package/Frameworks/目录build-core-android.sh ABI则生成.so并放置到android/src/main/jniLibs/ABI/。注意发布到 pub.dev 的包不含 native 产物——Android 侧由 Gradle 按 ABI 下载归档并做 SHA-256 校验Apple 侧由 CocoaPods/SwiftPM 下载带固定校验和的插件。本地消费则通过runanywhere.useLocalNativestrueandroid/gradle.properties启用。四、快速开始Quick Start以下是最小可运行示例初始化 SDK、注册 LlamaCpp 后端、下载并加载模型、发起一次对话生成。import package:runanywhere/runanywhere.dart; import package:runanywhere_llamacpp/runanywhere_llamacpp.dart; void main() async { WidgetsFlutterBinding.ensureInitialized(); await RunAnywhere.initialize(); LlamaCpp.register(); await RunAnywhere.downloadModel(smollm2-360m); await RunAnywhere.llm.load(smollm2-360m); final response await RunAnywhere.llm.chat(What is the capital of France?); print(response); }要点解读WidgetsFlutterBinding.ensureInitialized()确保在main()中能安全地等待异步初始化。必须先注册后端模块LlamaCpp.register()、Onnx.register()、Mlx.register()再下载和加载模型。内置目录模型如smollm2-360m会被自动发现无需手动注册自定义模型才需要RunAnywhere.models.register()。downloadModel/loadModel这类扁平别名与 Swift / Kotlin / RN 各绑定保持一致用于跨平台代码迁移时对齐 API 形态见 README。4.1 生产环境初始化默认initialize()以无 API Key 的本地模式运行生产环境可显式传入 API Key、控制面 Base URL 与环境类型await RunAnywhere.initialize( apiKey: YOUR_API_KEY, baseURL: https://api.runanywhere.ai, environment: SDKEnvironment.SDK_ENVIRONMENT_PRODUCTION, );从源码看initialize的执行流程runanywhere.dart包括解析并校验参数 → 获取设备 ID → 挂载遥测 sink → 通过DartBridge初始化原生核心 → 设置模型基础目录 → 启动本地服务HTTP 客户端、遥测、模型注册表→ 异步派发远程服务鉴权、设备注册、assignment 拉取。关键设计是本地推理不会等待网络就绪——远程设置在后台重试因此initialize()返回后即可开始本地工作。若原生核心无法启动或配置被拒绝则抛出SDKException。SDKEnvironmentsdk_environment.dart映射到 C 层的rac_environment_tSDK_ENVIRONMENT_DEVELOPMENT与SDK_ENVIRONMENT_PRODUCTION分别对应本地开发与生产控制面。生产环境默认关闭调试日志LOG_LEVEL_WARNING、允许遥测开发环境则使用LOG_LEVEL_DEBUG。对未知的枚举值采取 fail-closed 策略拒绝静默降级到 DEVELOPMENT那会关闭鉴权与后端同步。五、能力全景CapabilitiesRunAnywhere通过静态访问器暴露全部能力。下表为 README 中能力矩阵的完整版并补充了源码中可确认的方法形态访问器用途示例方法RunAnywhere.llm文本生成llm.chat()、llm.generate()、llm.generateStream()RunAnywhere.stt语音转文字stt.transcribe()、stt.transcribeStream()RunAnywhere.tts文字转语音tts.synthesize()、tts.speak()RunAnywhere.vad语音活动检测vad.detectVoiceActivity()、vad.streamVAD()RunAnywhere.vlm视觉语言模型vlm.processImage()RunAnywhere.voice语音 Agent 流水线voice.initializeWithLoadedModels()RunAnywhere.models模型注册表models.register()、models.available()RunAnywhere.downloads下载生命周期downloads.start()、downloads.delete()RunAnywhere.rag检索增强生成rag.query()RunAnywhere.tools工具 / 函数调用tools.generateWithTools()5.1 LLM文本生成RunAnywhere.llmLLM 命名空间llm.dart提供完整的方法集generate(prompt, {options})单轮补全返回GenerationResultgenerateChat(messages, {options})多轮对话——最后一条消息是当前回合前面的消息作为历史开头的 system 消息作为系统提示词generateStream(prompt)流式生成返回StreamGenerationEvent逐 token 消费await for (final e in RunAnywhere.llm.generateStream(Say hello)) { // 处理流式事件 }当options中挂载了工具定义时generate会自动切换到工具执行会话tool-execution loop回调已注册的 executor 并继续生成llm.dart#L55-L62。5.2 语音三件套STT / TTS / VADSTTstt.darttranscribe(audio, {options})返回TranscriptionopenStream(...)建立持续识别会话支持实时流式转写。TTStts.dartsynthesize(text, {options})返回Audiospeak()直接播放voices()枚举可用音色stop()停止播放。VADdetectVoiceActivity()与streamVAD()用于检测语音端点是语音 Agent 流水线的底层依赖。5.3 语音 AgentRunAnywhere.voicevoice命名空间voice.dart提供语音到语音的 Agent 会话final session await RunAnywhere.voice.createSession(...); await session.start(); // 监听会话事件 await for (final e in session.events) { ... } await session.interrupt(); await session.close();createSession内部会按需确保 VAD 组件就绪必要时自动下载将 STT → LLM → TTS 串成完整的端侧语音对话流水线。5.4 RAG 与工具调用RAGrag.dartsearch(query, {topK})做检索query(question, {options})执行「检索 生成」的完整 RAG 查询返回RagResult。工具调用tools.generateWithTools()支持函数调用function calling与结构化输出可配合 LLM 命名空间的options.tools使用。5.5 模型与下载管理models命名空间models.dart负责模型注册表final llms await RunAnywhere.models.list( const ModelFilter(category: ModelCategory.MODEL_CATEGORY_LANGUAGE)); final model await RunAnywhere.models.get(smollm2-360m); await RunAnywhere.models.refresh( rescanLocal: true, includeRemoteCatalog: false, pruneOrphans: false, );downloads命名空间runanywhere_downloads.dart管理下载与存储生命周期plan(request)预计算下载计划DownloadPlanResultstart(modelId)返回StreamDownloadProgress可实时观察进度直到终态terminal state为止cancel(modelId)/cancelDownload(modelId)取消下载delete(modelId)/deleteAllModels()删除模型与数据clearCache()、getStorageInfo()、list()存储信息与用量统计。5.6 更多能力SDK 还通过RunAnywhere暴露了embeddings文本嵌入、rerank交叉编码器重排、images扩散图像生成、diarization说话人分离、segmentation语义分割、loraLoRA 适配器、cua计算机使用 Agent 脚手架与hybrid端侧/云端语音路由等命名空间。capabilities()会基于当前构建的原生符号导出情况动态报告哪些能力可用、哪些不可用SDKCapabilities.unavailable例如当某个 commons 二进制未导出rac_diarization_diarize_lifecycle_proto符号时diarization会被如实标记为不可用而非虚报runanywhere.dart#L174-L209。agents、wakeword、realtime三个命名空间则明确不属于 v4 公共 API 面不会被宣称支持。六、支持的模型格式与后端格式用途后端包GGUFLLM、部分 VLMrunanywhere_llamacppONNX / Sherpa 归档STT、TTS、VADrunanywhere_onnxMLX bundlesApple silicon 上的 LLM、VLM、语音runanywhere_mlxQHexRT bundlesSnapdragon 上的 NPU 模型runanywhere_qhexrt内置目录模型如smollm2-360m注册后自动发现无需手动注册对于自定义模型通过RunAnywhere.models.register()注册 GGUF、ONNX/Sherpa 或 MLX 模型包即可。后端模块的注册 API 形态可参考 runanywhere_llamacpp 包 READMEawait LlamaCpp.register()之后即可通过核心 SDK 的 API 使用其能力。七、错误处理Error HandlingSDK 所有错误统一抛出SDKException其内部携带 proto 生成的ErrorCodesdk_exception.dart并可从message、code、category三个维度读取错误详情ErrorCode与 C ABI 的rac_result_t负值一一对应正 proto code ↔ 负 C ABI code见源码注释中的 round-trip 逻辑。try { final result await RunAnywhere.llm.generate( Hello!, LLMGenerationOptions(maxTokens: 64), ); } on SDKException catch (error) { print(SDK error [${error.errorCode}]: ${error.message}); }常见工厂构造器包括SDKException.notInitialized()未调用initialize()、validationFailed(...)参数校验失败可携带fieldPath定位到具体字段如STTOptions.sampleRate、invalidConfiguration(...)等便于在业务层做细粒度区分。八、生命周期、事件与状态管理除initialize之外RunAnywhere还提供reset()整体拆卸——卸载模型、关闭会话、清理状态内部按顺序冲刷遥测、重置模型生命周期、关闭模型注册表最后才 shutdown 原生桥以保证 flush 时原生侧仍可用。isReady本地推理可用时为 trueDartBridge.isInitialized _localServicesReady。versionSDK semver 字符串。deviceId稳定设备标识初始化前访问会抛SDKException.notInitialized。events返回StreamSdkEvent订阅生命周期、模型与错误面包屑事件底层由EventBusSdkEventMapper映射runanywhere.dart#L137-L140。九、示例应用Example App仓库自带一个功能完整的跨平台参考应用位于 bindings/flutter/example/覆盖了 LLM 聊天含工具调用与 LoRA 面板、语音STT / TTS / VAD / 语音助手、视觉VLM 相机视图、RAG 文档问答、模型管理下载/选择/状态、基准测试LLM/STT/TTS benchmark、Solutions 面板与 Hexagon NPU 卡片等功能模块见 example/lib/features。其pubspec.yaml通过path:依赖引用本地 SDK 包。运行方式cd bindings/flutter/example flutter pub get cd ios pod install cd .. # iOS flutter run注意由于示例应用依赖本地 SDK 包干净克隆后需先构建并 staging 原生产物Android JNI 库与 iOS XCFramework详见 bindings/flutter/example/README.md。十、常见问题FAQ是否需要联网仅在初次下载模型时需要网络。之后推理完全在设备本地执行。用户数据会被发送到云端吗不会。所有推理均在本地进行。生产模式可能收集匿名遥测可配置见SDKEnvironment的shouldSendTelemetry判定。可以使用自定义模型吗可以。通过RunAnywhere.models.register()注册 GGUF、ONNX/Sherpa 或 MLX 模型包。如何测试 Apple MLXMLX 执行需要物理 arm64 iOS 设备。模拟器 slice 仅用于编译/链接验证无法运行真实推理。更多资料API 参考bindings/flutter/docs/Documentation.md平台配置与构建指南bindings/flutter/docs/DEVELOPMENT.mdFlutter 架构说明bindings/flutter/docs/ARCHITECTURE.md示例应用bindings/flutter/example/许可证LICENSE结语RunAnywhere Flutter SDK 用一个统一的RunAnywhere命名空间把 LLM、语音、视觉、RAG、工具调用与模型管理全部收敛为类型安全的 Dart API配合 LLamaCpp / ONNX / MLX / QHexRT 多后端注册机制让 Flutter 开发者无需接触原生 C 即可在 iOS 与 Android 上构建离线优先、隐私安全的端侧 AI 应用。本文覆盖的安装配置、平台设置、命名空间 API、模型管理与错误处理已经足够支撑你从零开始接入更深层的原生桥接与 IDL 生成细节可从 bindings/flutter/packages/runanywhere/ 源码与 idl/ 协议定义继续深入。【免费下载链接】runanywhere-sdksProduction ready toolkit to run AI locally项目地址: https://gitcode.com/gh_mirrors/ru/runanywhere-sdks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表