Skip to content

Add NPU to manifest #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 6, 2025
42 changes: 28 additions & 14 deletions assets/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"description": "We make it easy to connect with people: Use Whisper to transcribe videos",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "LCM Dreamshaper V7",
Expand All @@ -55,7 +56,8 @@
"description": "Transcribe video with Whisper Large V3",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Large V3",
Expand All @@ -66,7 +68,8 @@
"description": "Transcribe video with Whisper Large V3",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Openai Whisper Large V3",
Expand All @@ -77,7 +80,8 @@
"description": "Transcribe video with Openai Whisper Large V3",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Tiny",
Expand All @@ -88,7 +92,8 @@
"description": "Transcribe video with Whisper Tiny",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Base",
Expand All @@ -99,7 +104,8 @@
"description": "Transcribe video with Whisper Base",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Medium",
Expand All @@ -110,7 +116,8 @@
"description": "Transcribe video with Whisper Medium",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Medium",
Expand All @@ -121,7 +128,8 @@
"description": "Transcribe video with Whisper Medium",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Tiny",
Expand All @@ -132,7 +140,8 @@
"description": "Transcribe video with Whisper Tiny",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Base",
Expand All @@ -143,7 +152,8 @@
"description": "Transcribe video with Whisper Base",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Large V3",
Expand All @@ -154,7 +164,8 @@
"description": "Transcribe video with Whisper Large V3",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Medium",
Expand All @@ -165,7 +176,8 @@
"description": "Transcribe video with Whisper Medium",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Tiny",
Expand All @@ -176,7 +188,8 @@
"description": "Transcribe video with Whisper Tiny",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "Whisper Base",
Expand All @@ -187,7 +200,8 @@
"description": "We make it easy to connect with people: Use Whisper to transcribe videos",
"task": "speech",
"author": "OpenVINO",
"collection": "speech-to-text-672321d5c070537a178a8aeb"
"collection": "speech-to-text-672321d5c070537a178a8aeb",
"npuEnabled": true
},
{
"name": "InternVL2 1B",
Expand Down
31 changes: 24 additions & 7 deletions lib/deployment_processor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:inference/importers/manifest_importer.dart';
import 'package:inference/migration/migration_manager.dart';
import 'package:inference/migration/migrations/migration_1.0.0_to_25.0.1.dart';
import 'package:inference/project.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
Expand All @@ -30,6 +33,15 @@

Future<List<Project>> loadProjectsFromStorage() async {
final directory = await getApplicationSupportDirectory();
final manifest = ManifestImporter("assets/manifest.json");
await manifest.loadManifest();
final migrationManager = MigrationManager(
destinationVersion: currentApplicationVersion,
manifest: manifest.allModels,
migrations: [
MigrationV1ToV2501(),
]
);

return List.from(directory.listSync()
.map((projectFolder) {
Expand All @@ -38,16 +50,21 @@
}
final platformContext = Context(style: Style.platform);
try {
final content = File(platformContext.join(projectFolder.path, "project.json")).readAsStringSync();
final project = Project.fromJson(jsonDecode(content), projectFolder.path);
//if (!project.verify()) {
// throw Exception("project not valid. removing");
//}
final projectFile = File(platformContext.join(projectFolder.path, "project.json"));
final content = projectFile.readAsStringSync();
var jsonContent = jsonDecode(content);
if (migrationManager.eligible((jsonContent))) {
print("Migrating ${projectFolder.path}");
jsonContent = migrationManager.migrate(jsonContent);

Check warning on line 58 in lib/deployment_processor.dart

View check run for this annotation

Codecov / codecov/patch

lib/deployment_processor.dart#L53-L58

Added lines #L53 - L58 were not covered by tests
const encoder = JsonEncoder.withIndent(" ");
projectFile.writeAsStringSync(encoder.convert(jsonContent));

Check warning on line 60 in lib/deployment_processor.dart

View check run for this annotation

Codecov / codecov/patch

lib/deployment_processor.dart#L60

Added line #L60 was not covered by tests
}
final project = Project.fromJson(jsonContent, projectFolder.path);

Check warning on line 62 in lib/deployment_processor.dart

View check run for this annotation

Codecov / codecov/patch

lib/deployment_processor.dart#L62

Added line #L62 was not covered by tests
project.loaded.complete();
return project;
} catch (exception) {
} catch (exception, stack) {
print(exception);
//Directory(projectFolder.path).deleteSync(recursive: true);
print(stack);

Check warning on line 67 in lib/deployment_processor.dart

View check run for this annotation

Codecov / codecov/patch

lib/deployment_processor.dart#L67

Added line #L67 was not covered by tests
return null;
}
})
Expand Down
5 changes: 3 additions & 2 deletions lib/importers/geti_deployment.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
class GetiDeploymentProcessor extends Importer {
final String zipPath;
Archive archive;
Project? project;
GetiProject? project;

GetiDeploymentProcessor(this.zipPath, this.archive);

Expand Down Expand Up @@ -63,6 +63,7 @@
await processTask(task);
}
const encoder = JsonEncoder.withIndent(" ");
project!.size = project!.calculateDiskUsage();

Check warning on line 66 in lib/importers/geti_deployment.dart

View check run for this annotation

Codecov / codecov/patch

lib/importers/geti_deployment.dart#L66

Added line #L66 was not covered by tests
File(platformContext.join(project!.storagePath, "project.json"))
.writeAsString(encoder.convert(project!.toMap()));
project!.loaded.complete();
Expand All @@ -86,7 +87,7 @@
project = GetiProject(
content['id'],
const Uuid().v4().toString(),
"1.0.0",
currentApplicationVersion,
content['name'],
content["creation_time"],
ProjectType.image,
Expand Down
114 changes: 7 additions & 107 deletions lib/importers/manifest_importer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,114 +3,14 @@
// SPDX-License-Identifier: Apache-2.0

import 'dart:convert';
import 'dart:io';

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:inference/project.dart';
import 'package:inference/public_model_info.dart';
import 'package:inference/utils/get_public_thumbnail.dart';
import 'package:inference/utils.dart';
import 'package:path_provider/path_provider.dart';
import 'package:uuid/uuid.dart';

class Model {
final String name;
final String id;
final int fileSize;
final String optimizationPrecision;
final int contextWindow;
final String description;
final String task;

Model({
required this.name,
required this.id,
required this.fileSize,
required this.optimizationPrecision,
required this.contextWindow,
required this.description,
required this.task,
});

Image get thumbnail {
return getThumbnail(id);
}

String get kind {
if (task == 'text-generation'){
return 'llm';
} else if (task == 'speech'){
return 'speech to text';
} else if (task == 'text-to-image'){
return 'image generation';
}
return 'other';
}

String get readableFileSize {
return fileSize.toDouble().readableFileSize();
}

factory Model.fromJson(Map<String, dynamic> json) {
return Model(
name: json['name'],
id: json['id'],
fileSize: json['fileSize'],
optimizationPrecision: json['optimizationPrecision'],
contextWindow: json['contextWindow'],
description: json['description'],
task: json['task'],
);
}

Future<PublicProject> convertToProject() async {
final directory = await getApplicationSupportDirectory();
final projectId = const Uuid().v4();
final storagePath = platformContext.join(directory.path, projectId.toString());
await Directory(storagePath).create(recursive: true);
final projectType = parseProjectType(task);

final project = PublicProject(
projectId,
"OpenVINO/$id",
"1.0.0",
name,
DateTime.now().toIso8601String(),
projectType,
storagePath,
thumbnail,
PublicModelInfo(
id,
DateTime.now().toIso8601String(),
0,
0,
task,
const Collection("https://huggingface.co/api/collections/OpenVINO/llm-6687aaa2abca3bbcec71a9bd", "", "text"),
),
);

project.tasks.add(
Task(
genUUID(),
task,
task,
[],
null,
[],
"",
"",
),
);

return project;
}
}
import 'package:inference/importers/model_manifest.dart';

class ManifestImporter {
final String manifestPath;
List<Model> popularModels = [];
List<Model> allModels = [];
List<ModelManifest> popularModels = [];
List<ModelManifest> allModels = [];

ManifestImporter(this.manifestPath);

Expand All @@ -119,19 +19,19 @@ class ManifestImporter {
final jsonData = jsonDecode(contents);

popularModels = (jsonData['popular_models'] as List)
.map((modelJson) => Model.fromJson(modelJson))
.map((modelJson) => ModelManifest.fromJson(modelJson))
.toList();

allModels = (jsonData['all_models'] as List)
.map((modelJson) => Model.fromJson(modelJson))
.map((modelJson) => ModelManifest.fromJson(modelJson))
.toList();
}

List<Model> getPopularModels() {
List<ModelManifest> getPopularModels() {
return popularModels;
}

List<Model> getAllModels() {
List<ModelManifest> getAllModels() {
return allModels;
}
}
Loading
Loading