Skip to content

Commit 82bd939

Browse files
committed
Add Genie NPU models to Flutter and React Native SDKs + example apps
- Update NPUChip in Flutter SDK: new base URL, npuSuffix field, tar.gz format - Update NPUChip in React Native SDK: same changes as Flutter - Update Flutter example: chip-based dynamic model registration with per-chip filtering (Qwen3 4B gen5-only, Llama 3.2 1B both chips) - Update React Native example: same chip-based registration pattern - Update doc comments to reflect new URL format
1 parent c12269d commit 82bd939

5 files changed

Lines changed: 90 additions & 53 deletions

File tree

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

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import 'package:runanywhere_ai/core/design_system/app_spacing.dart';
1010
import 'package:runanywhere_ai/core/services/model_manager.dart';
1111
import 'package:runanywhere_ai/core/utilities/constants.dart';
1212
import 'package:runanywhere_ai/core/utilities/keychain_helper.dart';
13+
import 'package:runanywhere/core/types/npu_chip.dart';
14+
import 'package:runanywhere/public/extensions/runanywhere_device.dart';
1315
import 'package:runanywhere/public/extensions/rag_module.dart';
1416
import 'package:runanywhere_llamacpp/runanywhere_llamacpp.dart';
1517
import 'package:runanywhere_genie/runanywhere_genie.dart';
@@ -208,19 +210,29 @@ class _RunAnywhereAIAppState extends State<RunAnywhereAIApp> {
208210
// --- GENIE NPU MODULE (Android/Snapdragon only) ---
209211
if (Genie.isAvailable) {
210212
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');
213+
final chip = await RunAnywhereDevice.getChip();
214+
if (chip != null) {
215+
// Models with per-chip availability
216+
const genieModels = [
217+
// Qwen3 4B — Gen 5 only
218+
(slug: 'qwen3-4b', name: 'Qwen3 4B', mem: 2800000000, chips: {NPUChip.snapdragon8EliteGen5}),
219+
// Llama 3.2 1B Instruct — both chips
220+
(slug: 'llama-v3.2-1b-instruct', name: 'Llama 3.2 1B Instruct', mem: 1200000000, chips: {NPUChip.snapdragon8Elite, NPUChip.snapdragon8EliteGen5}),
221+
];
222+
for (final m in genieModels) {
223+
if (m.chips.contains(chip)) {
224+
Genie.addModel(
225+
id: '${m.slug}-npu-${chip.identifier}',
226+
name: '${m.name} (NPU - ${chip.displayName})',
227+
url: chip.downloadUrl(m.slug),
228+
memoryRequirement: m.mem,
229+
);
230+
}
231+
}
232+
debugPrint('✅ Genie NPU module registered (chip: ${chip.displayName})');
233+
} else {
234+
debugPrint('ℹ️ Genie available but no supported NPU chip detected');
235+
}
224236
} else {
225237
debugPrint('ℹ️ Genie NPU not available (non-Snapdragon device)');
226238
}

examples/react-native/RunAnywhereAI/App.tsx

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ import {
4242
LLMFramework,
4343
ModelArtifactType,
4444
initializeNitroModulesGlobally,
45+
getChip,
46+
getNPUDownloadUrl,
47+
NPU_CHIPS,
4548
} from '@runanywhere/core';
49+
import type { NPUChip } from '@runanywhere/core';
4650

4751
// Make LlamaCPP optional for ONNX-only builds
4852
let LlamaCPP: any = null;
@@ -244,22 +248,37 @@ async function registerModulesAndModels(): Promise<void> {
244248
if (Platform.OS === 'android' && Genie && Genie.isAvailable) {
245249
Genie.register();
246250

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-
]);
251+
const chip = await getChip();
252+
if (chip) {
253+
// Models with per-chip availability
254+
const genieModels: Array<{
255+
slug: string;
256+
name: string;
257+
mem: number;
258+
chips: string[];
259+
}> = [
260+
// Qwen3 4B — Gen 5 only
261+
{ slug: 'qwen3-4b', name: 'Qwen3 4B', mem: 2_800_000_000, chips: ['8elite-gen5'] },
262+
// Llama 3.2 1B Instruct — both chips
263+
{ slug: 'llama-v3.2-1b-instruct', name: 'Llama 3.2 1B Instruct', mem: 1_200_000_000, chips: ['8elite', '8elite-gen5'] },
264+
];
265+
266+
const registrations = genieModels
267+
.filter((m) => m.chips.includes(chip.identifier))
268+
.map((m) =>
269+
RunAnywhere.registerModel({
270+
id: `${m.slug}-npu-${chip.identifier}`,
271+
name: `${m.name} (NPU - ${chip.displayName})`,
272+
url: getNPUDownloadUrl(chip, m.slug),
273+
framework: LLMFramework.Genie,
274+
memoryRequirement: m.mem,
275+
}),
276+
);
277+
await Promise.all(registrations);
278+
console.log(`✅ Genie NPU models registered (chip: ${chip.displayName})`);
279+
} else {
280+
console.log('ℹ️ Genie available but no supported NPU chip detected');
281+
}
263282
}
264283

265284
// =========================================================================

sdk/runanywhere-flutter/packages/runanywhere/lib/core/types/npu_chip.dart

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
11
/// Supported NPU chipsets for on-device Genie model inference.
22
///
3-
/// Each chip has an [identifier] used to construct dynamic download URLs
4-
/// for chipset-specific NPU model binaries.
3+
/// Each chip has an [identifier] used in model IDs and an [npuSuffix] used
4+
/// to construct download URLs from the HuggingFace model repository.
55
///
66
/// Example:
77
/// ```dart
88
/// final chip = RunAnywhere.getChip();
99
/// if (chip != null) {
10-
/// final url = chip.downloadUrl('qwen');
11-
/// // → https://huggingface.co/Void2377/npu-models/resolve/main/qwen-gen1.zip?download=true
10+
/// final url = chip.downloadUrl('qwen3-4b');
11+
/// // → https://huggingface.co/runanywhere/genie-npu-models/resolve/main/qwen3-4b-genie-w4a16-8elite-gen5.tar.gz
1212
/// }
1313
/// ```
1414
enum NPUChip {
15-
snapdragon8Elite('gen1', 'Snapdragon 8 Elite', 'SM8750'),
16-
snapdragon8EliteGen5('gen2', 'Snapdragon 8 Elite Gen 5', 'SM8850');
15+
snapdragon8Elite('8elite', 'Snapdragon 8 Elite', 'SM8750', '8elite'),
16+
snapdragon8EliteGen5('8elite-gen5', 'Snapdragon 8 Elite Gen 5', 'SM8850', '8elite-gen5');
1717

1818
final String identifier;
1919
final String displayName;
2020
final String socModel;
21+
final String npuSuffix;
2122

22-
const NPUChip(this.identifier, this.displayName, this.socModel);
23+
const NPUChip(this.identifier, this.displayName, this.socModel, this.npuSuffix);
2324

2425
/// Base URL for NPU model downloads on HuggingFace.
2526
static const baseUrl =
26-
'https://huggingface.co/Void2377/npu-models/resolve/main/';
27+
'https://huggingface.co/runanywhere/genie-npu-models/resolve/main/';
2728

2829
/// Build a HuggingFace download URL for this chip.
29-
/// [modelName] is the model prefix (e.g. "qwen") → produces "qwen-gen1.zip"
30-
String downloadUrl(String modelName) =>
31-
'$baseUrl$modelName-$identifier.zip?download=true';
30+
/// [modelSlug] is the model slug (e.g. "qwen3-4b") → produces
31+
/// "qwen3-4b-genie-w4a16-8elite-gen5.tar.gz"
32+
String downloadUrl(String modelSlug) =>
33+
'$baseUrl$modelSlug-genie-w4a16-$npuSuffix.tar.gz';
3234

3335
/// Match an NPU chip from a SoC model string (e.g. "SM8750").
3436
/// Returns null if the SoC is not a supported NPU chipset.

sdk/runanywhere-flutter/packages/runanywhere/lib/public/extensions/runanywhere_device.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ extension RunAnywhereDevice on RunAnywhere {
2525
///
2626
/// Example:
2727
/// ```dart
28-
/// final chip = RunAnywhereDevice.getChip();
28+
/// final chip = await RunAnywhereDevice.getChip();
2929
/// if (chip != null) {
30-
/// final url = chip.downloadUrl('qwen');
31-
/// RunAnywhere.registerModel(id: 'qwen-npu', name: 'Qwen NPU', url: url, ...);
30+
/// final url = chip.downloadUrl('qwen3-4b');
31+
/// RunAnywhere.registerModel(id: 'qwen3-4b-npu', name: 'Qwen3 4B NPU', url: url, ...);
3232
/// }
3333
/// ```
3434
static Future<NPUChip?> getChip() async {

sdk/runanywhere-react-native/packages/core/src/types/NPUChip.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
/**
22
* Supported NPU chipsets for on-device Genie model inference.
33
*
4-
* Each chip has an `identifier` used to construct dynamic download URLs
5-
* for chipset-specific NPU model binaries.
4+
* Each chip has an `identifier` used in model IDs and an `npuSuffix` used
5+
* to construct download URLs from the HuggingFace model repository.
66
*
77
* @example
88
* ```typescript
99
* const chip = await RunAnywhere.getChip();
1010
* if (chip) {
11-
* const url = getNPUDownloadUrl(chip, 'qwen');
12-
* // → https://huggingface.co/Void2377/npu-models/resolve/main/qwen-gen1.zip?download=true
11+
* const url = getNPUDownloadUrl(chip, 'qwen3-4b');
12+
* // → https://huggingface.co/runanywhere/genie-npu-models/resolve/main/qwen3-4b-genie-w4a16-8elite-gen5.tar.gz
1313
* }
1414
* ```
1515
*/
@@ -18,33 +18,37 @@ export interface NPUChip {
1818
identifier: string;
1919
displayName: string;
2020
socModel: string;
21+
npuSuffix: string;
2122
}
2223

2324
/** Base URL for NPU model downloads on HuggingFace. */
2425
export const NPU_BASE_URL =
25-
'https://huggingface.co/Void2377/npu-models/resolve/main/';
26+
'https://huggingface.co/runanywhere/genie-npu-models/resolve/main/';
2627

2728
/** All supported NPU chipsets. */
2829
export const NPU_CHIPS: readonly NPUChip[] = [
2930
{
30-
identifier: 'gen1',
31+
identifier: '8elite',
3132
displayName: 'Snapdragon 8 Elite',
3233
socModel: 'SM8750',
34+
npuSuffix: '8elite',
3335
},
3436
{
35-
identifier: 'gen2',
37+
identifier: '8elite-gen5',
3638
displayName: 'Snapdragon 8 Elite Gen 5',
3739
socModel: 'SM8850',
40+
npuSuffix: '8elite-gen5',
3841
},
3942
] as const;
4043

4144
/**
4245
* Build a HuggingFace download URL for a chip.
4346
* @param chip - The detected NPU chip
44-
* @param modelName - Model prefix (e.g. "qwen") → produces "qwen-gen1.zip"
47+
* @param modelSlug - Model slug (e.g. "qwen3-4b") → produces
48+
* "qwen3-4b-genie-w4a16-8elite-gen5.tar.gz"
4549
*/
46-
export function getNPUDownloadUrl(chip: NPUChip, modelName: string): string {
47-
return `${NPU_BASE_URL}${modelName}-${chip.identifier}.zip?download=true`;
50+
export function getNPUDownloadUrl(chip: NPUChip, modelSlug: string): string {
51+
return `${NPU_BASE_URL}${modelSlug}-genie-w4a16-${chip.npuSuffix}.tar.gz`;
4852
}
4953

5054
/**

0 commit comments

Comments
 (0)