Skip to content

Commit 1e031a5

Browse files
Add Genie NPU backend support and update dependencies
- Introduced the Genie NPU backend for Android/Snapdragon devices, including model registration and framework integration. - Updated pubspec.yaml to include the runanywhere_genie dependency. - Enhanced AndroidManifest.xml to declare native library requirements for Genie. - Modified GeneratedPluginRegistrant to register Genie and related plugins. - Updated model handling to support Genie in the app's logic and UI. - Improved documentation and changelog to reflect these changes. This commit enhances the SDK's capabilities by integrating support for the Genie NPU, allowing for optimized inference on compatible devices.
1 parent aa8d5f2 commit 1e031a5

39 files changed

Lines changed: 381 additions & 466 deletions

File tree

examples/flutter/RunAnywhereAI/android/app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
<application
88
android:label="RunAnywhere AI"
99
android:name="${applicationName}"
10-
android:icon="@mipmap/ic_launcher">
10+
android:icon="@mipmap/ic_launcher"
11+
android:extractNativeLibs="true">
12+
<!-- Declare vendor public library for Genie NPU (Qualcomm FastRPC DSP communication) -->
13+
<uses-native-library android:name="libcdsprpc.so" android:required="false" />
1114
<activity
1215
android:name=".MainActivity"
1316
android:exported="true"

examples/flutter/RunAnywhereAI/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,26 @@ public static void registerWith(@NonNull FlutterEngine flutterEngine) {
2020
} catch (Exception e) {
2121
Log.e(TAG, "Error registering plugin audioplayers_android, xyz.luan.audioplayers.AudioplayersPlugin", e);
2222
}
23+
try {
24+
flutterEngine.getPlugins().add(new io.flutter.plugins.camerax.CameraAndroidCameraxPlugin());
25+
} catch (Exception e) {
26+
Log.e(TAG, "Error registering plugin camera_android_camerax, io.flutter.plugins.camerax.CameraAndroidCameraxPlugin", e);
27+
}
2328
try {
2429
flutterEngine.getPlugins().add(new dev.fluttercommunity.plus.device_info.DeviceInfoPlusPlugin());
2530
} catch (Exception e) {
2631
Log.e(TAG, "Error registering plugin device_info_plus, dev.fluttercommunity.plus.device_info.DeviceInfoPlusPlugin", e);
2732
}
33+
try {
34+
flutterEngine.getPlugins().add(new com.mr.flutter.plugin.filepicker.FilePickerPlugin());
35+
} catch (Exception e) {
36+
Log.e(TAG, "Error registering plugin file_picker, com.mr.flutter.plugin.filepicker.FilePickerPlugin", e);
37+
}
38+
try {
39+
flutterEngine.getPlugins().add(new io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin());
40+
} catch (Exception e) {
41+
Log.e(TAG, "Error registering plugin flutter_plugin_android_lifecycle, io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin", e);
42+
}
2843
try {
2944
flutterEngine.getPlugins().add(new com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin());
3045
} catch (Exception e) {
@@ -35,6 +50,11 @@ public static void registerWith(@NonNull FlutterEngine flutterEngine) {
3550
} catch (Exception e) {
3651
Log.e(TAG, "Error registering plugin flutter_tts, com.tundralabs.fluttertts.FlutterTtsPlugin", e);
3752
}
53+
try {
54+
flutterEngine.getPlugins().add(new io.flutter.plugins.imagepicker.ImagePickerPlugin());
55+
} catch (Exception e) {
56+
Log.e(TAG, "Error registering plugin image_picker_android, io.flutter.plugins.imagepicker.ImagePickerPlugin", e);
57+
}
3858
try {
3959
flutterEngine.getPlugins().add(new dev.fluttercommunity.plus.packageinfo.PackageInfoPlugin());
4060
} catch (Exception e) {
@@ -61,14 +81,14 @@ public static void registerWith(@NonNull FlutterEngine flutterEngine) {
6181
Log.e(TAG, "Error registering plugin runanywhere, ai.runanywhere.sdk.RunAnywherePlugin", e);
6282
}
6383
try {
64-
flutterEngine.getPlugins().add(new ai.runanywhere.sdk.llamacpp.LlamaCppPlugin());
84+
flutterEngine.getPlugins().add(new ai.runanywhere.sdk.genie.GeniePlugin());
6585
} catch (Exception e) {
66-
Log.e(TAG, "Error registering plugin runanywhere_llamacpp, ai.runanywhere.sdk.llamacpp.LlamaCppPlugin", e);
86+
Log.e(TAG, "Error registering plugin runanywhere_genie, ai.runanywhere.sdk.genie.GeniePlugin", e);
6787
}
6888
try {
69-
flutterEngine.getPlugins().add(new ai.runanywhere.sdk.onnx.OnnxPlugin());
89+
flutterEngine.getPlugins().add(new ai.runanywhere.sdk.llamacpp.LlamaCppPlugin());
7090
} catch (Exception e) {
71-
Log.e(TAG, "Error registering plugin runanywhere_onnx, ai.runanywhere.sdk.onnx.OnnxPlugin", e);
91+
Log.e(TAG, "Error registering plugin runanywhere_llamacpp, ai.runanywhere.sdk.llamacpp.LlamaCppPlugin", e);
7292
}
7393
try {
7494
flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());

examples/flutter/RunAnywhereAI/ios/Runner/GeneratedPluginRegistrant.m

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,24 @@
1212
@import audioplayers_darwin;
1313
#endif
1414

15+
#if __has_include(<camera_avfoundation/CameraPlugin.h>)
16+
#import <camera_avfoundation/CameraPlugin.h>
17+
#else
18+
@import camera_avfoundation;
19+
#endif
20+
1521
#if __has_include(<device_info_plus/FPPDeviceInfoPlusPlugin.h>)
1622
#import <device_info_plus/FPPDeviceInfoPlusPlugin.h>
1723
#else
1824
@import device_info_plus;
1925
#endif
2026

27+
#if __has_include(<file_picker/FilePickerPlugin.h>)
28+
#import <file_picker/FilePickerPlugin.h>
29+
#else
30+
@import file_picker;
31+
#endif
32+
2133
#if __has_include(<flutter_secure_storage/FlutterSecureStoragePlugin.h>)
2234
#import <flutter_secure_storage/FlutterSecureStoragePlugin.h>
2335
#else
@@ -30,6 +42,12 @@
3042
@import flutter_tts;
3143
#endif
3244

45+
#if __has_include(<image_picker_ios/FLTImagePickerPlugin.h>)
46+
#import <image_picker_ios/FLTImagePickerPlugin.h>
47+
#else
48+
@import image_picker_ios;
49+
#endif
50+
3351
#if __has_include(<package_info_plus/FPPPackageInfoPlusPlugin.h>)
3452
#import <package_info_plus/FPPPackageInfoPlusPlugin.h>
3553
#else
@@ -60,16 +78,16 @@
6078
@import runanywhere;
6179
#endif
6280

63-
#if __has_include(<runanywhere_llamacpp/LlamaCppPlugin.h>)
64-
#import <runanywhere_llamacpp/LlamaCppPlugin.h>
81+
#if __has_include(<runanywhere_genie/GeniePlugin.h>)
82+
#import <runanywhere_genie/GeniePlugin.h>
6583
#else
66-
@import runanywhere_llamacpp;
84+
@import runanywhere_genie;
6785
#endif
6886

69-
#if __has_include(<runanywhere_onnx/OnnxPlugin.h>)
70-
#import <runanywhere_onnx/OnnxPlugin.h>
87+
#if __has_include(<runanywhere_llamacpp/LlamaCppPlugin.h>)
88+
#import <runanywhere_llamacpp/LlamaCppPlugin.h>
7189
#else
72-
@import runanywhere_onnx;
90+
@import runanywhere_llamacpp;
7391
#endif
7492

7593
#if __has_include(<shared_preferences_foundation/SharedPreferencesPlugin.h>)
@@ -94,16 +112,19 @@ @implementation GeneratedPluginRegistrant
94112

95113
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
96114
[AudioplayersDarwinPlugin registerWithRegistrar:[registry registrarForPlugin:@"AudioplayersDarwinPlugin"]];
115+
[CameraPlugin registerWithRegistrar:[registry registrarForPlugin:@"CameraPlugin"]];
97116
[FPPDeviceInfoPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"FPPDeviceInfoPlusPlugin"]];
117+
[FilePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FilePickerPlugin"]];
98118
[FlutterSecureStoragePlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterSecureStoragePlugin"]];
99119
[FlutterTtsPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterTtsPlugin"]];
120+
[FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]];
100121
[FPPPackageInfoPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"FPPPackageInfoPlusPlugin"]];
101122
[PathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"PathProviderPlugin"]];
102123
[PermissionHandlerPlugin registerWithRegistrar:[registry registrarForPlugin:@"PermissionHandlerPlugin"]];
103124
[RecordIosPlugin registerWithRegistrar:[registry registrarForPlugin:@"RecordIosPlugin"]];
104125
[RunAnywherePlugin registerWithRegistrar:[registry registrarForPlugin:@"RunAnywherePlugin"]];
126+
[GeniePlugin registerWithRegistrar:[registry registrarForPlugin:@"GeniePlugin"]];
105127
[LlamaCppPlugin registerWithRegistrar:[registry registrarForPlugin:@"LlamaCppPlugin"]];
106-
[OnnxPlugin registerWithRegistrar:[registry registrarForPlugin:@"OnnxPlugin"]];
107128
[SharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"SharedPreferencesPlugin"]];
108129
[SqflitePlugin registerWithRegistrar:[registry registrarForPlugin:@"SqflitePlugin"]];
109130
[URLLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"URLLauncherPlugin"]];

examples/flutter/RunAnywhereAI/lib/app/runanywhere_ai_app.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:runanywhere_ai/core/utilities/constants.dart';
1212
import 'package:runanywhere_ai/core/utilities/keychain_helper.dart';
1313
import 'package:runanywhere/public/extensions/rag_module.dart';
1414
import 'package:runanywhere_llamacpp/runanywhere_llamacpp.dart';
15+
import 'package:runanywhere_genie/runanywhere_genie.dart';
1516

1617
/// RunAnywhereAIApp (mirroring iOS RunAnywhereAIApp.swift)
1718
///
@@ -204,6 +205,27 @@ class _RunAnywhereAIAppState extends State<RunAnywhereAIApp> {
204205
debugPrint('✅ LlamaCPP module registered');
205206
await Future<void>.delayed(Duration.zero);
206207

208+
// --- GENIE NPU MODULE (Android/Snapdragon only) ---
209+
if (Genie.isAvailable) {
210+
await Genie.register(priority: 200);
211+
Genie.addModel(
212+
id: 'qwen2_5-7b-instruct-genie',
213+
name: 'Qwen 2.5 7B (NPU)',
214+
url: 'https://huggingface.co/runanywhere/genie-npu-models/resolve/main/qwen2.5-7b-instruct-genie-w8a16.tar.gz',
215+
memoryRequirement: 5000000000,
216+
);
217+
Genie.addModel(
218+
id: 'llama-3.2-1b-instruct-genie',
219+
name: 'Llama 3.2 1B (NPU)',
220+
url: 'https://huggingface.co/runanywhere/genie-npu-models/resolve/main/llama-3.2-1b-instruct-genie-w4.tar.gz',
221+
memoryRequirement: 1500000000,
222+
);
223+
debugPrint('✅ Genie NPU module registered');
224+
} else {
225+
debugPrint('ℹ️ Genie NPU not available (non-Snapdragon device)');
226+
}
227+
await Future<void>.delayed(Duration.zero);
228+
207229
// --- VLM MODULE ---
208230
RunAnywhere.registerModel(
209231
id: 'smolvlm-500m-instruct-q8_0',

examples/flutter/RunAnywhereAI/lib/features/chat/chat_interface_view.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ class _ChatInterfaceViewState extends State<ChatInterfaceView> {
530530

531531
/// Map SDK InferenceFramework enum to app framework enum
532532
LLMFramework _mapInferenceFramework(sdk.InferenceFramework? framework) {
533-
if (framework == null) return LLMFramework.llamaCpp;
533+
if (framework == null) return LLMFramework.unknown;
534534
switch (framework) {
535535
case sdk.InferenceFramework.llamaCpp:
536536
return LLMFramework.llamaCpp;
@@ -540,8 +540,10 @@ class _ChatInterfaceViewState extends State<ChatInterfaceView> {
540540
return LLMFramework.onnxRuntime;
541541
case sdk.InferenceFramework.systemTTS:
542542
return LLMFramework.systemTTS;
543+
case sdk.InferenceFramework.genie:
544+
return LLMFramework.genie;
543545
default:
544-
return LLMFramework.llamaCpp;
546+
return LLMFramework.unknown;
545547
}
546548
}
547549

@@ -769,7 +771,6 @@ class _MessageBubble extends StatefulWidget {
769771

770772
class _MessageBubbleState extends State<_MessageBubble> {
771773
bool _showThinking = false;
772-
bool _showToolCallSheet = false;
773774

774775
@override
775776
Widget build(BuildContext context) {

examples/flutter/RunAnywhereAI/lib/features/models/model_list_view_model.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ class ModelListViewModel extends ChangeNotifier {
137137
return LLMFramework.onnxRuntime;
138138
case sdk.InferenceFramework.systemTTS:
139139
return LLMFramework.systemTTS;
140+
case sdk.InferenceFramework.genie:
141+
return LLMFramework.genie;
140142
default:
141143
return LLMFramework.unknown;
142144
}
@@ -153,6 +155,8 @@ class ModelListViewModel extends ChangeNotifier {
153155
return sdk.InferenceFramework.onnx;
154156
case LLMFramework.systemTTS:
155157
return sdk.InferenceFramework.systemTTS;
158+
case LLMFramework.genie:
159+
return sdk.InferenceFramework.genie;
156160
case LLMFramework.mediaPipe:
157161
case LLMFramework.whisperKit:
158162
case LLMFramework.unknown:

examples/flutter/RunAnywhereAI/lib/features/models/model_types.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ enum LLMFramework {
1010
onnxRuntime,
1111
systemTTS,
1212
whisperKit,
13+
genie,
1314
unknown;
1415

1516
String get displayName {
@@ -26,6 +27,8 @@ enum LLMFramework {
2627
return 'System TTS';
2728
case LLMFramework.whisperKit:
2829
return 'WhisperKit';
30+
case LLMFramework.genie:
31+
return 'Genie NPU';
2932
case LLMFramework.unknown:
3033
return 'Unknown';
3134
}
@@ -45,6 +48,8 @@ enum LLMFramework {
4548
return 'system_tts';
4649
case LLMFramework.whisperKit:
4750
return 'whisperkit';
51+
case LLMFramework.genie:
52+
return 'genie';
4853
case LLMFramework.unknown:
4954
return 'unknown';
5055
}

examples/flutter/RunAnywhereAI/pubspec.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ dependencies:
1717
# RunAnywhere SDK - LlamaCpp Backend (LLM)
1818
runanywhere_llamacpp:
1919
path: ../../../sdk/runanywhere-flutter/packages/runanywhere_llamacpp
20+
21+
# RunAnywhere SDK - Genie NPU Backend (Android/Snapdragon only)
22+
runanywhere_genie: ^0.1.2
2023
provider: ^6.1.0
2124
flutter_markdown: ^0.6.18
2225
record: ^6.1.0

examples/react-native/RunAnywhereAI/App.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
StyleSheet,
2020
ActivityIndicator,
2121
TouchableOpacity,
22+
Platform,
2223
} from 'react-native';
2324
import { NavigationContainer } from '@react-navigation/native';
2425
import Icon from 'react-native-vector-icons/Ionicons';
@@ -50,6 +51,15 @@ try {
5051
} catch (e) {
5152
console.warn('[App] LlamaCPP backend not available - some features disabled');
5253
}
54+
55+
// Make Genie optional (Android/Snapdragon only)
56+
let Genie: any = null;
57+
try {
58+
Genie = require('@runanywhere/genie').Genie;
59+
} catch (e) {
60+
console.warn('[App] Genie NPU backend not available');
61+
}
62+
5363
import { ONNX } from '@runanywhere/onnx';
5464
import { getStoredApiKey, getStoredBaseURL, hasCustomConfiguration } from './src/screens/SettingsScreen';
5565

@@ -228,6 +238,30 @@ async function registerModulesAndModels(): Promise<void> {
228238
]);
229239
}
230240

241+
// =========================================================================
242+
// Genie NPU backend + models (Android/Snapdragon only)
243+
// =========================================================================
244+
if (Platform.OS === 'android' && Genie && Genie.isAvailable) {
245+
Genie.register();
246+
247+
await Promise.all([
248+
RunAnywhere.registerModel({
249+
id: 'qwen2_5-7b-instruct-genie',
250+
name: 'Qwen 2.5 7B (NPU)',
251+
url: 'https://huggingface.co/runanywhere/genie-npu-models/resolve/main/qwen2.5-7b-instruct-genie-w8a16.tar.gz',
252+
framework: LLMFramework.Genie,
253+
memoryRequirement: 5_000_000_000,
254+
}),
255+
RunAnywhere.registerModel({
256+
id: 'llama-3.2-1b-instruct-genie',
257+
name: 'Llama 3.2 1B (NPU)',
258+
url: 'https://huggingface.co/runanywhere/genie-npu-models/resolve/main/llama-3.2-1b-instruct-genie-w4.tar.gz',
259+
framework: LLMFramework.Genie,
260+
memoryRequirement: 1_500_000_000,
261+
}),
262+
]);
263+
}
264+
231265
// =========================================================================
232266
// ONNX backend + STT/TTS models
233267
// =========================================================================

examples/react-native/RunAnywhereAI/android/app/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ android {
174174
"**/libNitroModules.so", // Nitro modules shared by @runanywhere/onnx and react-native-nitro-modules
175175
"**/librac_backend_onnx.so", // ONNX backend duplicated via rag + onnx modules
176176
"**/librac_commons.so",
177-
"**/libomp.so"
177+
"**/libomp.so",
178+
"**/libcdsprpc.so" // Qualcomm FastRPC (shared by Genie and device)
178179
]
179180
}
180181

@@ -199,7 +200,7 @@ dependencies {
199200
implementation project(':runanywhere_core')
200201
implementation project(':runanywhere_llamacpp')
201202
implementation project(':runanywhere_onnx')
202-
implementation project(':runanywhere_rag')
203+
implementation project(':runanywhere_genie')
203204

204205
def isHermesEnabled = project.hasProperty("hermesEnabled") ? project.hermesEnabled.toBoolean() : true
205206
// Expose hermesEnabled for other modules (like react-native-worklets)

0 commit comments

Comments
 (0)