Skip to content

Commit 538575f

Browse files
authored
Android App with MediaTek Mode
Differential Revision: D64776199 Pull Request resolved: #6304
1 parent 74e6c1f commit 538575f

File tree

8 files changed

+207
-14
lines changed

8 files changed

+207
-14
lines changed

examples/demo-apps/android/LlamaDemo/app/src/main/AndroidManifest.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,30 @@
3636
android:name="libcdsprpc.so"
3737
android:required="false" />
3838

39+
<uses-native-library
40+
android:name="libapuwareutils_v2.mtk.so"
41+
android:required="false" />
42+
43+
<uses-native-library
44+
android:name="libapuwareapusys_v2.mtk.so"
45+
android:required="false" />
46+
47+
<uses-native-library
48+
android:name="libnir_neon_driver_ndk.mtk.so"
49+
android:required="false" />
50+
51+
<uses-native-library
52+
android:name="libnir_neon_driver_ndk.mtk.vndk.so"
53+
android:required="false" />
54+
55+
<uses-native-library
56+
android:name="libcmdl_ndk.mtk.vndk.so"
57+
android:required="false" />
58+
59+
<uses-native-library
60+
android:name="libcmdl_ndk.mtk.so"
61+
android:required="false" />
62+
3963
<activity
4064
android:name=".MainActivity"
4165
android:exported="true"

examples/demo-apps/android/LlamaDemo/app/src/main/BUCK

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fb_android_library(
1414
name = "app_lib",
1515
srcs = [
1616
"java/com/example/executorchllamademo/AppLog.java",
17+
"java/com/example/executorchllamademo/BackendType.java",
1718
"java/com/example/executorchllamademo/DemoSharedPreferences.java",
1819
"java/com/example/executorchllamademo/ETImage.java",
1920
"java/com/example/executorchllamademo/ETLogging.java",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.example.executorchllamademo;
2+
3+
public enum BackendType {
4+
XNNPACK,
5+
QUALCOMM,
6+
MEDIATEK
7+
}

examples/demo-apps/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/MainActivity.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ private void setLocalModel(String modelPath, String tokenizerPath, float tempera
125125
long runStartTime = System.currentTimeMillis();
126126
mModule =
127127
new LlamaModule(
128-
ModelUtils.getModelCategory(mCurrentSettingsFields.getModelType()),
128+
ModelUtils.getModelCategory(
129+
mCurrentSettingsFields.getModelType(), mCurrentSettingsFields.getBackendType()),
129130
modelPath,
130131
tokenizerPath,
131132
temperature);
@@ -174,6 +175,11 @@ private void setLocalModel(String modelPath, String tokenizerPath, float tempera
174175
+ modelPath
175176
+ "\nTokenizer path: "
176177
+ tokenizerPath
178+
+ "\nBackend: "
179+
+ mCurrentSettingsFields.getBackendType().toString()
180+
+ "\nModelType: "
181+
+ ModelUtils.getModelCategory(
182+
mCurrentSettingsFields.getModelType(), mCurrentSettingsFields.getBackendType())
177183
+ "\nTemperature: "
178184
+ temperature
179185
+ "\nModel loaded time: "
@@ -229,6 +235,7 @@ protected void onCreate(Bundle savedInstanceState) {
229235

230236
try {
231237
Os.setenv("ADSP_LIBRARY_PATH", getApplicationInfo().nativeLibraryDir, true);
238+
Os.setenv("LD_LIBRARY_PATH", getApplicationInfo().nativeLibraryDir, true);
232239
} catch (ErrnoException e) {
233240
finish();
234241
}
@@ -285,6 +292,7 @@ protected void onResume() {
285292
}
286293
boolean isUpdated = !mCurrentSettingsFields.equals(updatedSettingsFields);
287294
boolean isLoadModel = updatedSettingsFields.getIsLoadModel();
295+
setBackendMode(updatedSettingsFields.getBackendType());
288296
if (isUpdated) {
289297
if (isLoadModel) {
290298
// If users change the model file, but not pressing loadModelButton, we won't load the new
@@ -293,6 +301,7 @@ protected void onResume() {
293301
} else {
294302
askUserToSelectModel();
295303
}
304+
296305
checkForClearChatHistory(updatedSettingsFields);
297306
// Update current to point to the latest
298307
mCurrentSettingsFields = new SettingsFields(updatedSettingsFields);
@@ -302,6 +311,22 @@ protected void onResume() {
302311
}
303312
}
304313

314+
private void setBackendMode(BackendType backendType) {
315+
if (backendType.equals(BackendType.XNNPACK) || backendType.equals(BackendType.QUALCOMM)) {
316+
setXNNPACKMode();
317+
} else if (backendType.equals(BackendType.MEDIATEK)) {
318+
setMediaTekMode();
319+
}
320+
}
321+
322+
private void setXNNPACKMode() {
323+
requireViewById(R.id.addMediaButton).setVisibility(View.VISIBLE);
324+
}
325+
326+
private void setMediaTekMode() {
327+
requireViewById(R.id.addMediaButton).setVisibility(View.GONE);
328+
}
329+
305330
private void checkForClearChatHistory(SettingsFields updatedSettingsFields) {
306331
if (updatedSettingsFields.getIsClearChatHistory()) {
307332
mMessageAdapter.clear();
@@ -672,7 +697,8 @@ private void onModelRunStopped() {
672697
addSelectedImagesToChatThread(mSelectedImageUri);
673698
String finalPrompt;
674699
String rawPrompt = mEditTextMessage.getText().toString();
675-
if (ModelUtils.getModelCategory(mCurrentSettingsFields.getModelType())
700+
if (ModelUtils.getModelCategory(
701+
mCurrentSettingsFields.getModelType(), mCurrentSettingsFields.getBackendType())
676702
== ModelUtils.VISION_MODEL) {
677703
finalPrompt = mCurrentSettingsFields.getFormattedSystemAndUserPrompt(rawPrompt);
678704
} else {
@@ -705,7 +731,9 @@ public void run() {
705731
}
706732
});
707733
long generateStartTime = System.currentTimeMillis();
708-
if (ModelUtils.getModelCategory(mCurrentSettingsFields.getModelType())
734+
if (ModelUtils.getModelCategory(
735+
mCurrentSettingsFields.getModelType(),
736+
mCurrentSettingsFields.getBackendType())
709737
== ModelUtils.VISION_MODEL) {
710738
mModule.generateFromPos(
711739
finalPrompt,

examples/demo-apps/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ModelUtils.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,33 @@
99
package com.example.executorchllamademo;
1010

1111
public class ModelUtils {
12+
// XNNPACK or QNN
1213
static final int TEXT_MODEL = 1;
14+
15+
// XNNPACK
1316
static final int VISION_MODEL = 2;
1417
static final int VISION_MODEL_IMAGE_CHANNELS = 3;
1518
static final int VISION_MODEL_SEQ_LEN = 768;
1619
static final int TEXT_MODEL_SEQ_LEN = 256;
1720

18-
public static int getModelCategory(ModelType modelType) {
19-
switch (modelType) {
20-
case LLAVA_1_5:
21-
return VISION_MODEL;
22-
case LLAMA_3:
23-
case LLAMA_3_1:
24-
case LLAMA_3_2:
25-
default:
26-
return TEXT_MODEL;
21+
// MediaTek
22+
static final int MEDIATEK_TEXT_MODEL = 3;
23+
24+
public static int getModelCategory(ModelType modelType, BackendType backendType) {
25+
if (backendType.equals(BackendType.XNNPACK)) {
26+
switch (modelType) {
27+
case LLAVA_1_5:
28+
return VISION_MODEL;
29+
case LLAMA_3:
30+
case LLAMA_3_1:
31+
case LLAMA_3_2:
32+
default:
33+
return TEXT_MODEL;
34+
}
35+
} else if (backendType.equals(BackendType.MEDIATEK)) {
36+
return MEDIATEK_TEXT_MODEL;
2737
}
38+
39+
return TEXT_MODEL; // default
2840
}
2941
}

examples/demo-apps/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/SettingsActivity.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import android.os.Bundle;
1515
import android.text.Editable;
1616
import android.text.TextWatcher;
17+
import android.view.View;
1718
import android.widget.Button;
1819
import android.widget.EditText;
1920
import android.widget.ImageButton;
@@ -32,6 +33,7 @@ public class SettingsActivity extends AppCompatActivity {
3233

3334
private String mModelFilePath = "";
3435
private String mTokenizerFilePath = "";
36+
private TextView mBackendTextView;
3537
private TextView mModelTextView;
3638
private TextView mTokenizerTextView;
3739
private TextView mModelTypeTextView;
@@ -41,6 +43,7 @@ public class SettingsActivity extends AppCompatActivity {
4143
private double mSetTemperature;
4244
private String mSystemPrompt;
4345
private String mUserPrompt;
46+
private BackendType mBackendType;
4447
private ModelType mModelType;
4548
public SettingsFields mSettingsFields;
4649

@@ -68,9 +71,11 @@ protected void onCreate(Bundle savedInstanceState) {
6871
}
6972

7073
private void setupSettings() {
74+
mBackendTextView = requireViewById(R.id.backendTextView);
7175
mModelTextView = requireViewById(R.id.modelTextView);
7276
mTokenizerTextView = requireViewById(R.id.tokenizerTextView);
7377
mModelTypeTextView = requireViewById(R.id.modelTypeTextView);
78+
ImageButton backendImageButton = requireViewById(R.id.backendImageButton);
7479
ImageButton modelImageButton = requireViewById(R.id.modelImageButton);
7580
ImageButton tokenizerImageButton = requireViewById(R.id.tokenizerImageButton);
7681
ImageButton modelTypeImageButton = requireViewById(R.id.modelTypeImageButton);
@@ -79,6 +84,10 @@ private void setupSettings() {
7984
loadSettings();
8085

8186
// TODO: The two setOnClickListeners will be removed after file path issue is resolved
87+
backendImageButton.setOnClickListener(
88+
view -> {
89+
setupBackendSelectorDialog();
90+
});
8291
modelImageButton.setOnClickListener(
8392
view -> {
8493
setupModelSelectorDialog();
@@ -104,6 +113,12 @@ private void setupSettings() {
104113
if (mModelType != null) {
105114
mModelTypeTextView.setText(mModelType.toString());
106115
}
116+
mBackendType = mSettingsFields.getBackendType();
117+
ETLogging.getInstance().log("mBackendType from settings " + mBackendType);
118+
if (mBackendType != null) {
119+
mBackendTextView.setText(mBackendType.toString());
120+
setBackendSettingMode();
121+
}
107122

108123
setupParameterSettings();
109124
setupPromptSettings();
@@ -285,6 +300,29 @@ private void showInvalidPromptDialog() {
285300
.show();
286301
}
287302

303+
private void setupBackendSelectorDialog() {
304+
// Convert enum to list
305+
List<String> backendTypesList = new ArrayList<>();
306+
for (BackendType backendType : BackendType.values()) {
307+
backendTypesList.add(backendType.toString());
308+
}
309+
// Alert dialog builder takes in arr of string instead of list
310+
String[] backendTypes = backendTypesList.toArray(new String[0]);
311+
AlertDialog.Builder backendTypeBuilder = new AlertDialog.Builder(this);
312+
backendTypeBuilder.setTitle("Select backend type");
313+
backendTypeBuilder.setSingleChoiceItems(
314+
backendTypes,
315+
-1,
316+
(dialog, item) -> {
317+
mBackendTextView.setText(backendTypes[item]);
318+
mBackendType = BackendType.valueOf(backendTypes[item]);
319+
setBackendSettingMode();
320+
dialog.dismiss();
321+
});
322+
323+
backendTypeBuilder.create().show();
324+
}
325+
288326
private void setupModelSelectorDialog() {
289327
String[] pteFiles = listLocalFile("/data/local/tmp/llama/", ".pte");
290328
AlertDialog.Builder modelPathBuilder = new AlertDialog.Builder(this);
@@ -370,6 +408,32 @@ private String getFilenameFromPath(String uriFilePath) {
370408
return "";
371409
}
372410

411+
private void setBackendSettingMode() {
412+
if (mBackendType.equals(BackendType.XNNPACK) || mBackendType.equals(BackendType.QUALCOMM)) {
413+
setXNNPACKSettingMode();
414+
} else if (mBackendType.equals(BackendType.MEDIATEK)) {
415+
setMediaTekSettingMode();
416+
}
417+
}
418+
419+
private void setXNNPACKSettingMode() {
420+
requireViewById(R.id.modelLayout).setVisibility(View.VISIBLE);
421+
requireViewById(R.id.tokenizerLayout).setVisibility(View.VISIBLE);
422+
requireViewById(R.id.parametersView).setVisibility(View.VISIBLE);
423+
requireViewById(R.id.temperatureLayout).setVisibility(View.VISIBLE);
424+
mModelFilePath = "";
425+
mTokenizerFilePath = "";
426+
}
427+
428+
private void setMediaTekSettingMode() {
429+
requireViewById(R.id.modelLayout).setVisibility(View.GONE);
430+
requireViewById(R.id.tokenizerLayout).setVisibility(View.GONE);
431+
requireViewById(R.id.parametersView).setVisibility(View.GONE);
432+
requireViewById(R.id.temperatureLayout).setVisibility(View.GONE);
433+
mModelFilePath = "/in/mtk/llama/runner";
434+
mTokenizerFilePath = "/in/mtk/llama/runner";
435+
}
436+
373437
private void loadSettings() {
374438
Gson gson = new Gson();
375439
String settingsFieldsJSON = mDemoSharedPreferences.getSettings();
@@ -384,6 +448,7 @@ private void saveSettings() {
384448
mSettingsFields.saveParameters(mSetTemperature);
385449
mSettingsFields.savePrompts(mSystemPrompt, mUserPrompt);
386450
mSettingsFields.saveModelType(mModelType);
451+
mSettingsFields.saveBackendType(mBackendType);
387452
mDemoSharedPreferences.addSettings(mSettingsFields);
388453
}
389454

examples/demo-apps/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/SettingsFields.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public ModelType getModelType() {
3030
return modelType;
3131
}
3232

33+
public BackendType getBackendType() {
34+
return backendType;
35+
}
36+
3337
public String getUserPrompt() {
3438
return userPrompt;
3539
}
@@ -63,9 +67,11 @@ public boolean getIsLoadModel() {
6367
private boolean isClearChatHistory;
6468
private boolean isLoadModel;
6569
private ModelType modelType;
70+
private BackendType backendType;
6671

6772
public SettingsFields() {
6873
ModelType DEFAULT_MODEL = ModelType.LLAMA_3;
74+
BackendType DEFAULT_BACKEND = BackendType.XNNPACK;
6975

7076
modelFilePath = "";
7177
tokenizerFilePath = "";
@@ -75,6 +81,7 @@ public SettingsFields() {
7581
isClearChatHistory = false;
7682
isLoadModel = false;
7783
modelType = DEFAULT_MODEL;
84+
backendType = DEFAULT_BACKEND;
7885
}
7986

8087
public SettingsFields(SettingsFields settingsFields) {
@@ -86,6 +93,7 @@ public SettingsFields(SettingsFields settingsFields) {
8693
this.isClearChatHistory = settingsFields.getIsClearChatHistory();
8794
this.isLoadModel = settingsFields.getIsLoadModel();
8895
this.modelType = settingsFields.modelType;
96+
this.backendType = settingsFields.backendType;
8997
}
9098

9199
public void saveModelPath(String modelFilePath) {
@@ -100,6 +108,10 @@ public void saveModelType(ModelType modelType) {
100108
this.modelType = modelType;
101109
}
102110

111+
public void saveBackendType(BackendType backendType) {
112+
this.backendType = backendType;
113+
}
114+
103115
public void saveParameters(Double temperature) {
104116
this.temperature = temperature;
105117
}
@@ -126,6 +138,7 @@ public boolean equals(SettingsFields anotherSettingsFields) {
126138
&& userPrompt.equals(anotherSettingsFields.userPrompt)
127139
&& isClearChatHistory == anotherSettingsFields.isClearChatHistory
128140
&& isLoadModel == anotherSettingsFields.isLoadModel
129-
&& modelType == anotherSettingsFields.modelType;
141+
&& modelType == anotherSettingsFields.modelType
142+
&& backendType == anotherSettingsFields.backendType;
130143
}
131144
}

0 commit comments

Comments
 (0)