diff --git a/lib/generated/intl/messages_zh.dart b/lib/generated/intl/messages_zh.dart index a4a8bc3ba..ecf65f05e 100644 --- a/lib/generated/intl/messages_zh.dart +++ b/lib/generated/intl/messages_zh.dart @@ -338,8 +338,8 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("无法删除共享文件"), "centerPoint": MessageLookupByLibrary.simpleMessage("中心点"), "changeEmail": MessageLookupByLibrary.simpleMessage("修改邮箱"), - "changeLocationOfSelectedItems": MessageLookupByLibrary.simpleMessage( - "Change location of selected items?"), + "changeLocationOfSelectedItems": + MessageLookupByLibrary.simpleMessage("确定要更改所选项目的位置吗?"), "changePassword": MessageLookupByLibrary.simpleMessage("修改密码"), "changePasswordTitle": MessageLookupByLibrary.simpleMessage("修改密码"), "changePermissions": MessageLookupByLibrary.simpleMessage("要修改权限吗?"), @@ -353,6 +353,7 @@ class MessageLookup extends MessageLookupByLibrary { "claimedStorageSoFar": m8, "cleanUncategorized": MessageLookupByLibrary.simpleMessage("清除未分类的"), "clearCaches": MessageLookupByLibrary.simpleMessage("清除缓存"), + "clearIndexes": MessageLookupByLibrary.simpleMessage("清空索引"), "click": MessageLookupByLibrary.simpleMessage("• 点击"), "clickOnTheOverflowMenu": MessageLookupByLibrary.simpleMessage("• 点击溢出菜单"), @@ -498,12 +499,11 @@ class MessageLookup extends MessageLookupByLibrary { "duplicateFileCountWithStorageSaved": m16, "duplicateItemsGroup": m17, "edit": MessageLookupByLibrary.simpleMessage("编辑"), - "editLocation": MessageLookupByLibrary.simpleMessage("Edit location"), + "editLocation": MessageLookupByLibrary.simpleMessage("编辑位置"), "editLocationTagTitle": MessageLookupByLibrary.simpleMessage("编辑位置"), "editsSaved": MessageLookupByLibrary.simpleMessage("已保存编辑"), "editsToLocationWillOnlyBeSeenWithinEnte": - MessageLookupByLibrary.simpleMessage( - "Edits to location will only be seen within Ente"), + MessageLookupByLibrary.simpleMessage("对位置的编辑只能在 Ente 内看到"), "eligible": MessageLookupByLibrary.simpleMessage("符合资格"), "email": MessageLookupByLibrary.simpleMessage("电子邮件地址"), "emailChangedTo": m18, @@ -641,6 +641,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("您输入的恢复密钥不正确"), "incorrectRecoveryKeyTitle": MessageLookupByLibrary.simpleMessage("不正确的恢复密钥"), + "indexedItems": MessageLookupByLibrary.simpleMessage("已索引项目"), "insecureDevice": MessageLookupByLibrary.simpleMessage("设备不安全"), "installManually": MessageLookupByLibrary.simpleMessage("手动安装"), "invalidEmailAddress": @@ -722,6 +723,10 @@ class MessageLookup extends MessageLookupByLibrary { "longpressOnAnItemToViewInFullscreen": MessageLookupByLibrary.simpleMessage("长按一个项目来全屏查看"), "lostDevice": MessageLookupByLibrary.simpleMessage("丢失了设备吗?"), + "machineLearning": MessageLookupByLibrary.simpleMessage("机器学习"), + "magicSearch": MessageLookupByLibrary.simpleMessage("魔法搜索"), + "magicSearchDescription": MessageLookupByLibrary.simpleMessage( + "请使用我们的桌面应用程序来为您库中的待处理项目建立索引。"), "manage": MessageLookupByLibrary.simpleMessage("管理"), "manageDeviceStorage": MessageLookupByLibrary.simpleMessage("管理设备存储"), "manageFamily": MessageLookupByLibrary.simpleMessage("管理家庭计划"), @@ -810,6 +815,7 @@ class MessageLookup extends MessageLookupByLibrary { "paymentFailed": MessageLookupByLibrary.simpleMessage("支付失败"), "paymentFailedTalkToProvider": m35, "paymentFailedWithReason": m36, + "pendingItems": MessageLookupByLibrary.simpleMessage("待处理项目"), "pendingSync": MessageLookupByLibrary.simpleMessage("正在等待同步"), "peopleUsingYourCode": MessageLookupByLibrary.simpleMessage("使用您的代码的人"), "permDeleteWarning": @@ -969,10 +975,9 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("邀请他人,您将在此看到他们分享的所有照片"), "searchResultCount": m44, "security": MessageLookupByLibrary.simpleMessage("安全"), - "selectALocation": - MessageLookupByLibrary.simpleMessage("Select a location"), + "selectALocation": MessageLookupByLibrary.simpleMessage("选择一个位置"), "selectALocationFirst": - MessageLookupByLibrary.simpleMessage("Select a location first"), + MessageLookupByLibrary.simpleMessage("首先选择一个位置"), "selectAlbum": MessageLookupByLibrary.simpleMessage("选择相册"), "selectAll": MessageLookupByLibrary.simpleMessage("全选"), "selectFoldersForBackup": @@ -1071,6 +1076,7 @@ class MessageLookup extends MessageLookupByLibrary { "sortOldestFirst": MessageLookupByLibrary.simpleMessage("最旧在前"), "sparkleSuccess": MessageLookupByLibrary.simpleMessage("✨ 成功"), "startBackup": MessageLookupByLibrary.simpleMessage("开始备份"), + "status": MessageLookupByLibrary.simpleMessage("状态"), "storage": MessageLookupByLibrary.simpleMessage("存储空间"), "storageBreakupFamily": MessageLookupByLibrary.simpleMessage("家庭"), "storageBreakupYou": MessageLookupByLibrary.simpleMessage("您"), diff --git a/lib/services/semantic_search/frameworks/onnx/onnx.dart b/lib/services/semantic_search/frameworks/onnx/onnx.dart index 41f8bb3a5..061de2c3a 100644 --- a/lib/services/semantic_search/frameworks/onnx/onnx.dart +++ b/lib/services/semantic_search/frameworks/onnx/onnx.dart @@ -35,6 +35,7 @@ class ONNX extends MLFramework { @override Future loadImageModel(String path) async { final startTime = DateTime.now(); + await _clipImage.init(); _imageEncoderAddress = await _computer.compute( _clipImage.loadModel, param: { @@ -50,7 +51,9 @@ class ONNX extends MLFramework { @override Future loadTextModel(String path) async { final startTime = DateTime.now(); - await _clipText.init(); + await _computer.compute(_clipText.init); + // Doing this from main isolate since `rootBundle` cannot be accessed outside it + await _clipText.initTokenizer(); _textEncoderAddress = await _computer.compute( _clipText.loadModel, param: { diff --git a/lib/services/semantic_search/frameworks/onnx/onnx_image_encoder.dart b/lib/services/semantic_search/frameworks/onnx/onnx_image_encoder.dart index 842fce7ba..2336ba0c1 100644 --- a/lib/services/semantic_search/frameworks/onnx/onnx_image_encoder.dart +++ b/lib/services/semantic_search/frameworks/onnx/onnx_image_encoder.dart @@ -9,7 +9,7 @@ import "package:onnxruntime/onnxruntime.dart"; class OnnxImageEncoder { final _logger = Logger("OnnxImageEncoder"); - OnnxImageEncoder() { + Future init() async { OrtEnv.instance.init(); } @@ -96,14 +96,14 @@ class OnnxImageEncoder { final int ny = rgb.height; final int inputSize = 3 * nx * ny; final inputImage = List.filled(inputSize, 0.toDouble()); - + const int nx2 = 224; const int ny2 = 224; const int totalSize = 3 * nx2 * ny2; // Load image into List inputImage for (int y = 0; y < ny; y++) { - for (int x = 0; x < nx; x ++) { + for (int x = 0; x < nx; x++) { final int i = 3 * (y * nx + x); inputImage[i] = rgb.getPixel(x, y).r.toDouble(); inputImage[i + 1] = rgb.getPixel(x, y).g.toDouble(); @@ -121,7 +121,7 @@ class OnnxImageEncoder { final std = [0.26862954, 0.26130258, 0.27577711]; for (int y = 0; y < ny3; y++) { - for (int x = 0; x < nx3; x ++) { + for (int x = 0; x < nx3; x++) { for (int c = 0; c < 3; c++) { //linear interpolation final double sx = (x + 0.5) * scale - 0.5; @@ -146,24 +146,23 @@ class OnnxImageEncoder { final double v10 = inputImage[j10]; final double v11 = inputImage[j11]; - final double v0 = v00 + (1 - dx) + v01 * dx; - final double v1 = v10 + (1 - dx) + v11 * dx; + final double v0 = v00 * (1 - dx) + v01 * dx; + final double v1 = v10 * (1 - dx) + v11 * dx; final double v = v0 * (1 - dy) + v1 * dy; final int v2 = min(max(v.round(), 0), 255); - + final int i = 3 * (y * nx3 + x) + c; result[i] = ((v2 / 255) - mean[c]) / std[c]; - } } } final floatList = Float32List.fromList(result); - - final inputOrt = OrtValueTensor.createTensorWithDataList(floatList, [1, 3, 224, 224]); + final inputOrt = + OrtValueTensor.createTensorWithDataList(floatList, [1, 3, 224, 224]); final inputs = {'input': inputOrt}; final session = OrtSession.fromAddress(args["address"]); final outputs = session.run(runOptions, inputs); diff --git a/lib/services/semantic_search/frameworks/onnx/onnx_text_encoder.dart b/lib/services/semantic_search/frameworks/onnx/onnx_text_encoder.dart index bd8a0559b..6a8bb3b74 100644 --- a/lib/services/semantic_search/frameworks/onnx/onnx_text_encoder.dart +++ b/lib/services/semantic_search/frameworks/onnx/onnx_text_encoder.dart @@ -8,19 +8,17 @@ import "package:onnxruntime/onnxruntime.dart"; import "package:photos/services/semantic_search/frameworks/onnx/onnx_text_tokenizer.dart"; class OnnxTextEncoder { - static const vocabFilePath = "assets/models/clip/bpe_simple_vocab_16e6.txt"; + static const kVocabFilePath = "assets/models/clip/bpe_simple_vocab_16e6.txt"; final _logger = Logger("OnnxTextEncoder"); final OnnxTextTokenizer _tokenizer = OnnxTextTokenizer(); - OnnxTextEncoder() { + Future init() async { OrtEnv.instance.init(); - OrtEnv.instance.availableProviders().forEach((element) { - _logger.info('onnx provider=$element'); - }); } - Future init() async { - final vocab = await rootBundle.loadString(vocabFilePath); + // Do not run in an isolate since rootBundle can only be accessed in the main isolate + Future initTokenizer() async { + final vocab = await rootBundle.loadString(kVocabFilePath); await _tokenizer.init(vocab); } diff --git a/pubspec.yaml b/pubspec.yaml index 993450bb0..40f2e3163 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,7 @@ description: ente photos application # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.8.18+538 +version: 0.8.20+540 environment: sdk: ">=3.0.0 <4.0.0"