Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
10990cf
Adds mediapipe_core package (#11)
craiglabenz Nov 13, 2023
7850d32
Add utility to collect headers from google/mediapipe (#10)
craiglabenz Nov 13, 2023
6a7dacb
[FFI] MediaPipe SDKs finder automation (#16)
craiglabenz Jan 12, 2024
8980132
Adds mediapipe_text package (#12)
craiglabenz Mar 11, 2024
4c159a7
Native Assets CI fix (#20)
craiglabenz Mar 12, 2024
4304801
Text Embedding task (#21)
craiglabenz Apr 3, 2024
3fc2d11
updated and re-ran generators
craiglabenz Mar 11, 2024
e01f26b
fixed embedding header file and bindings
craiglabenz Mar 11, 2024
ce42365
adds text embedding classes to text pkg
craiglabenz Mar 11, 2024
d36976b
moved worker dispose method to base class
craiglabenz Mar 25, 2024
f0344b9
class hierarchy improvements
craiglabenz Apr 1, 2024
992332b
cleaned up dispose methods
craiglabenz Apr 1, 2024
4ac6d20
initial commit of language detection task
craiglabenz Apr 1, 2024
b9b6c89
finishes language detection impl
craiglabenz Apr 2, 2024
bed398a
adds language detection demo
craiglabenz Apr 2, 2024
73bada3
backfilling improvements to classification and embedding
craiglabenz Apr 2, 2024
a392f83
adds language detection tests
craiglabenz Apr 2, 2024
4b742a3
add new model download to CI script
craiglabenz Apr 3, 2024
65cc969
fixes stale classification widget test, adds language detection widge…
craiglabenz Apr 3, 2024
daa2eb3
initial inference commit of flutter create -t package
craiglabenz Apr 15, 2024
8a63461
rename inference folder
craiglabenz Apr 15, 2024
a1992b6
adds build tooling for inference headers and ffigen
craiglabenz Apr 15, 2024
e5e76c6
rename "inference" to "genai"
craiglabenz Apr 16, 2024
fdd63eb
adds initial inference impl
craiglabenz Apr 17, 2024
904ee92
flutter creat example for genai
craiglabenz Apr 17, 2024
3dc77e5
sdks crawling update
craiglabenz Apr 19, 2024
9ab9a95
adds android project to genai example
craiglabenz Apr 25, 2024
74275cc
adds ios project to genai example
craiglabenz Apr 25, 2024
6542360
updates to macos project in genai example
craiglabenz Apr 25, 2024
143d6dc
inference impl improvements
craiglabenz Apr 25, 2024
30e813a
inference example - nearly working
craiglabenz Apr 25, 2024
ce5f887
Merge branch 'main' into genai-inference
craiglabenz Apr 25, 2024
40f93a7
various cleanup
craiglabenz Apr 25, 2024
f1b6f39
inference demo updates
craiglabenz Apr 29, 2024
6e39594
model path debugging
craiglabenz Apr 29, 2024
881114e
inference demo improvements
craiglabenz May 1, 2024
a73e36a
improvements to inference demo
craiglabenz May 1, 2024
e3d7c67
genai inference example improvements
craiglabenz May 6, 2024
b1005dc
updates to inference and example
craiglabenz May 10, 2024
d6cad7c
fixed issue with chat screens sometimes not refreshing while the LLM …
craiglabenz May 11, 2024
b05d708
Merge branch 'main' into genai-inference
craiglabenz May 12, 2024
0c648a0
updated SDK manifests
craiglabenz May 12, 2024
bf5bcd8
removed unused ffi utils copy param
craiglabenz May 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ permissions: read-all

on:
pull_request:
branches: [ main ]
branches: [main]
push:
branches: [main, ffi-wrapper, ffi-wrapper-text-pkg]
schedule:
Expand Down
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,17 @@ test_text:
cd packages/mediapipe-task-text/example && flutter test

example_text:
cd packages/mediapipe-task-text/example && flutter run -d macos
cd packages/mediapipe-task-text/example && flutter run -d macos

# GenAI ---
generate_genai:
cd packages/mediapipe-task-genai && dart --enable-experiment=native-assets run ffigen --config=ffigen.yaml

# Example genai invocation.
# Note that `GEMMA_4B_CPU_URI` can either be a local path or web URL. Similar values exist for
# 8B and GPU variants.
#
# For desktop development, standard environment variables like this work great.
# $ GEMMA_4B_CPU_URI=/path/to/gemma-2b-it-cpu-int4.bin flutter run -d [macos, windows, linux]
# For emulator or attached device testing, use `--dart-define` for the same values.
# $ flutter run -d [<device_id>] --dart-define=GEMMA_4B_CPU_URI=https://url/to.com/gemma-2b-it-cpu-int4.bin
9 changes: 6 additions & 3 deletions packages/mediapipe-core/lib/src/interface/task_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import 'dart:typed_data';

import 'package:equatable/equatable.dart';

/// {@template TaskOptions}
/// {@template BaseOptions}
/// Root class for options classes for MediaPipe tasks.
///
/// {@endtemplate}
abstract class Options extends Equatable {}

/// {@template TaskOptions}
/// Implementing classes will contain two [BaseInnerTaskOptions] subclasses,
/// including a descendent of the universal options struct, [BaseBaseOptions].
/// The second field will be task-specific.
Expand All @@ -17,7 +20,7 @@ import 'package:equatable/equatable.dart';
/// This implementation is not immutable to track whether `dispose` has been
/// called. All values used by pkg:equatable are in fact immutable.
// ignore: must_be_immutable
abstract class BaseTaskOptions extends Equatable {
abstract class BaseTaskOptions extends Options {
/// {@macro TaskOptions}
BaseTaskOptions();

Expand Down
4 changes: 2 additions & 2 deletions packages/mediapipe-core/lib/src/io/ffi_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ extension DartAwarePointerChars on Pointer<Pointer<Char>> {
///
/// See also:
/// * [toDartString], for a non-list equivalent.
List<String?> toDartStrings(int length) {
List<String> toDartStrings(int length) {
if (isNullPointer) {
throw Exception('Unexpectedly called `toDartStrings` on nullptr');
}
final dartStrings = <String?>[];
final dartStrings = <String>[];
int counter = 0;
while (counter < length) {
dartStrings.add(this[counter].toDartString());
Expand Down
2 changes: 1 addition & 1 deletion packages/mediapipe-core/lib/src/io/task_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'third_party/mediapipe/generated/mediapipe_common_bindings.dart'
/// should manage their [InnerTaskOptions] fields. The two suggested methods are
/// [copyToNative] and [dispose].
/// {@endtemplate}
mixin TaskOptions<T extends Struct> on BaseTaskOptions {
mixin TaskOptions<T extends Struct> on Options {
/// {@template TaskOptions.copyToNative}
/// Copies these task options into native memory. Any fields of type
/// [InnerTaskOptions] should have their `assignToStruct` method called.
Expand Down
8 changes: 6 additions & 2 deletions packages/mediapipe-core/test/io/task_options_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,17 @@ void main() {
expect(ptr.ref.score_threshold, lessThan(0.90001));
expect(ptr.ref.category_allowlist_count, 3);
expect(
ptr.ref.category_allowlist.toDartStrings(3),
ptr.ref.category_allowlist.toDartStrings(
3,
),
['good', 'great', 'best'],
);

expect(ptr.ref.category_denylist_count, 4);
expect(
ptr.ref.category_denylist.toDartStrings(4),
ptr.ref.category_denylist.toDartStrings(
4,
),
['bad', 'terrible', 'worst', 'honestly come on'],
);
});
Expand Down
4 changes: 3 additions & 1 deletion packages/mediapipe-task-audio/sdk_downloads.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
// Generated file. Do not manually edit.
final Map<String, Map<String, String>> sdkDownloadUrls = {};
// Used by the flutter toolchain (via build.dart) during compilation of any
// Flutter app using this package.
final Map<String, Map<String, Map<String, String>>> sdkDownloadUrls = {};
29 changes: 29 additions & 0 deletions packages/mediapipe-task-genai/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
build/
10 changes: 10 additions & 0 deletions packages/mediapipe-task-genai/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "bd909542a33ab1d5249363a2434ae50ee468094f"
channel: "master"

project_type: package
3 changes: 3 additions & 0 deletions packages/mediapipe-task-genai/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.0.1

* TODO: Describe initial release.
1 change: 1 addition & 0 deletions packages/mediapipe-task-genai/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TODO: Add your license here.
39 changes: 39 additions & 0 deletions packages/mediapipe-task-genai/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!--
This README describes the package. If you publish this package to pub.dev,
this README's contents appear on the landing page for your package.

For information about how to write a good package README, see the guide for
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).

For general information about developing packages, see the Dart guide for
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
and the Flutter guide for
[developing packages and plugins](https://flutter.dev/developing-packages).
-->

TODO: Put a short description of the package here that helps potential users
know whether this package might be useful for them.

## Features

TODO: List what your package can do. Maybe include images, gifs, or videos.

## Getting started

TODO: List prerequisites and provide or point to information on how to
start using the package.

## Usage

TODO: Include short and useful examples for package users. Add longer examples
to `/example` folder.

```dart
const like = 'sample';
```

## Additional information

TODO: Tell users more about the package: where to find more information, how to
contribute to the package, how to file issues, what response they can expect
from the package authors, and more.
9 changes: 9 additions & 0 deletions packages/mediapipe-task-genai/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
include: ../analysis_options.yaml

linter:
rules:
- public_member_api_docs # see https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#documentation-dartdocs-javadocs-etc

analyzer:
exclude:
- "**/mediapipe_genai_bindings.dart"
122 changes: 122 additions & 0 deletions packages/mediapipe-task-genai/build.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import 'dart:io';
import 'package:native_assets_cli/native_assets_cli.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;

import 'sdk_downloads.dart';

late File logFile;

final logs = <(DateTime, String)>[];
void log(String msg) {
logs.add((DateTime.now(), msg));
if (!logFile.parent.existsSync()) {
logFile.parent.createSync();
}

if (logFile.existsSync()) {
logFile.deleteSync();
}
logFile.createSync();
logFile.writeAsStringSync(logs
.map<String>((rec) => '[${rec.$1.toIso8601String()}] ${rec.$2}')
.toList()
.join('\n\n'));
}

Future<void> main(List<String> args) async {
final buildConfig = await BuildConfig.fromArgs(args);
logFile = File(
path.joinAll([
Directory.current.path, // root dir of app using `mediapipe-task-xyz`
'build/${buildConfig.dryRun ? "dryrun" : "live-run"}-build-log.txt',
]),
);

log(args.join(' '));
final String targetOs = buildConfig.targetOs.toString();

log('dir.current: ${Directory.current.absolute.path}');

// Throw if target runtime is unsupported.
if (!sdkDownloadUrls.containsKey(targetOs)) {
throw Exception('Unsupported target OS: $targetOs. '
'Supported values are: ${sdkDownloadUrls.keys.toSet()}');
}

final buildOutput = BuildOutput();
buildOutput.dependencies.dependencies
.add(buildConfig.packageRoot.resolve('build.dart'));
buildOutput.dependencies.dependencies
.add(buildConfig.packageRoot.resolve('sdk_downloads.dart'));

final modelName = 'libllm_inference_engine';
final Iterable<String> archKeys;
if (buildConfig.dryRun) {
archKeys = sdkDownloadUrls[targetOs]![modelName]!.keys;
} else {
archKeys = [buildConfig.targetArchitecture.toString()];
}
for (String arch in archKeys) {
arch = getArchAlias(arch);
log("arch: $arch");
log("sdkDownloadUrls[targetOs]: ${sdkDownloadUrls[targetOs]}");
log("sdkDownloadUrls[targetOs]['$modelName']: ${sdkDownloadUrls[targetOs]![modelName]}");
log("sdkDownloadUrls[targetOs]['$modelName'][$arch]: ${sdkDownloadUrls[targetOs]![modelName]![arch]}");

if (!sdkDownloadUrls[targetOs]!['libllm_inference_engine']!
.containsKey(arch)) {
continue;
}
final assetUrl =
sdkDownloadUrls[targetOs]!['libllm_inference_engine']![arch]!;
final downloadFileLocation = buildConfig.outDir.resolve(
'${arch}_${assetUrl.split('/').last}',
);
log('downloadFileLocation: $downloadFileLocation');
buildOutput.assets.add(
Asset(
id: 'package:mediapipe_genai/src/io/third_party/mediapipe/generated/mediapipe_genai_bindings.dart',
linkMode: LinkMode.dynamic,
target: Target.fromArchitectureAndOs(
Architecture.fromString(arch), buildConfig.targetOs),
path: AssetAbsolutePath(downloadFileLocation),
),
);
if (!buildConfig.dryRun) {
downloadAsset(assetUrl, downloadFileLocation);
}
}

await buildOutput.writeToFile(outDir: buildConfig.outDir);
}

Future<void> downloadAsset(String assetUrl, Uri destinationFile) async {
final downloadUri = Uri.parse(assetUrl);
final downloadedFile = File(destinationFile.toFilePath());
log('Saving file to ${downloadedFile.absolute.path}');

final downloadResponse = await http.get(downloadUri);
log('Download response: ${downloadResponse.statusCode}');

if (downloadResponse.statusCode == 200) {
if (downloadedFile.existsSync()) {
downloadedFile.deleteSync();
}
downloadedFile.createSync();
log('Saved file to ${downloadedFile.absolute.path}\n');
downloadedFile.writeAsBytes(downloadResponse.bodyBytes);
} else {
log('${downloadResponse.statusCode} :: ${downloadResponse.body}');
throw Exception(
'${downloadResponse.statusCode} :: ${downloadResponse.body}');
}
}

/// Translates native-assets architecture names into MediaPipe architecture names
String getArchAlias(String arch) {
return <String, String>{
'arm': 'arm64',
}[arch] ??
arch;
}
43 changes: 43 additions & 0 deletions packages/mediapipe-task-genai/example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
30 changes: 30 additions & 0 deletions packages/mediapipe-task-genai/example/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "86135b7774e32fa7b0ad0d116511471f36048579"
channel: "master"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 86135b7774e32fa7b0ad0d116511471f36048579
base_revision: 86135b7774e32fa7b0ad0d116511471f36048579
- platform: ios
create_revision: 86135b7774e32fa7b0ad0d116511471f36048579
base_revision: 86135b7774e32fa7b0ad0d116511471f36048579

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
Loading