Multiple local HMS ML Kit translator models in Flutter?

143

Pls check whether you are using the new version of the Flutter plug-in.

Language packs can be used in two-way. For example, en-it can be used for en to it or it to en.

The following are for your reference:

Modify based on the plugin Demo in the official website

The same instance is used for bidirectional translation by invoking multiple times.

//Entry function
_translationMake() async {
  try {
    await _prepareModel_run("it","en","vestiti usati");
    await _prepareModel_run("en","it","application");
  } on Exception catch (e) {
    print(e.toString());
  }
}

_prepareModel_run(String srcLang, String dstLang, String content) async {
  setting.sourceLangCode = srcLang;
  setting.targetLangCode = dstLang;
  try {
    final bool res = await translator.prepareModel(setting: setting); 
    if (res) {
      final String s = await _localTranslate_run(content);
      if (s != null) {
        print("_prepareModel_run " + content + " translate to "+s);
      }
    }else {
      print("_prepareModel_run res false");
    }
  } on Exception catch (e) {
    print(e.toString());
  }
}


Future<String> _localTranslate_run(String Content) async {
  try {
    final String s =
    await translator.syncTranslate(sourceText: Content);
    if (s != null) {
      _stopLocalTranslate();
      
      setState(() => _translateResult = s);
      return s;
    } else {
      print("no Translation");
      setState(() => _translateResult = "no translation");
      return "no translation";
    }
  } on Exception catch (e) {
    print(e.toString());
  }
}

And the log print results are as follows:

_prepareModel_run vestiti usati translate to Used clothes
_prepareModel_run application translate to applicazione
Share:
143
ecorradini
Author by

ecorradini

PhD in Computer Engineering. Android and iOS developer. Currently learning SwiftUI.

Updated on December 01, 2022

Comments

  • ecorradini
    ecorradini over 1 year

    I've defined a class that wraps the HMS ML Kit in-device translator. This class has two translator instances, with two different settings:

    MLLocalTranslator translatorSend = new MLLocalTranslator();
    MLLocalTranslator translatorReceive = new MLLocalTranslator();
    MLTranslateSetting settingSend = new MLTranslateSetting();
    MLTranslateSetting settingReceive = new MLTranslateSetting();
    

    translatorSend translates request from a language (for example it) to English (en). translatorReceive translates the response of the request from en to it.
    However, the prepare method only downloads the model for en_it translation and not the it_en model (if exists).

    HMSTranslator(String languageCode) {
      settingSend.sourceLangCode = languageCode;
      settingSend.targetLangCode = "en";
      settingReceive.sourceLangCode = "en";
      settingReceive.targetLangCode = languageCode;
    }
    
    Future<bool> prepare() async {
      if(settingSend.sourceLangCode != settingSend.targetLangCode) {
        bool isSendPrepared = await translatorSend.prepareModel(setting: settingSend)
        bool isReceivePrepared = await translatorReceive.prepareModel(setting: settingReceive);
        isPrepared = isSendPrepared && isReceivePrepared;
      }
      else {
        isPrepared = false;
      }
      return isPrepared;
    }
    

    The problem comes when I translate a string with translatorSend.

    Future<String> translateString(String stringToTranslate) async {
      if(settingSend.sourceLangCode != settingSend.targetLangCode) {
        String result;
        if (isPrepared) {
          result = await translatorSend.asyncTranslate(sourceText: stringToTranslate);
        }
        else {
          settingSend.sourceTextOnRemote = stringToTranslate;
          result = await sendRemoteTranslator.asyncTranslate(setting: settingSend);
        }
        return result;
      }
      else {
        return stringToTranslate;
      }
    }
    

    This method should translate an it String to an en String. However, it seems to call the en_it model and fails the translation:

    I/flutter (28228): TRANSLATOR: it to en
    I/flutter (28228): TRANSLATOR: PREPARED
    I/MLLocalTranslator(28228): translate sourceLanguage: en targetLanguage: it
    WHAT: vestiti usati -> vestiti usati  - WHERE applicazione -> applicazione 
    

    The translation of the response, from en to it works.
    I've tested other languages and that happens also with fr.
    Further testing showed that the process worked with es:

    WHAT: ropa usada -> Used clothing  - WHERE aplicación -> application 
    
  • ecorradini
    ecorradini about 3 years
    Yes, that’s actually what the docs says for Android. However, I’m developing a Flutter app.
  • Zinna
    Zinna about 3 years
    @ecorradini I added some info. regarding how to use ML kit with Flutter in the answer window.
  • ecorradini
    ecorradini about 3 years
    What you have written works. However, the problem I faced was first with the in-device translation, second with some of the languages supported. I've tried with: - en - it - en - fr - en - de - en - es - en - zh Translating from a language to english (eg it -> en) doesn't work, the translator just gave me back the "it" text, not the "en" one. The online translation worked perfectly, but not the offline one.
  • ecorradini
    ecorradini about 3 years
    That worked, so the solution was actually calling prepareModel each time I needed a translation, changing the order of source and target languages, without mantaining two different instances. Thank you.