Skip to content

Commit

Permalink
Update torchchat Android app to use latest ET llama demo app (pytorch…
Browse files Browse the repository at this point in the history
  • Loading branch information
kirklandsign authored Oct 14, 2024
1 parent 020da2e commit c867660
Show file tree
Hide file tree
Showing 67 changed files with 3,538 additions and 486 deletions.
2 changes: 1 addition & 1 deletion torchchat/edge/android/torchchat/app/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
/build
/build
116 changes: 84 additions & 32 deletions torchchat/edge/android/torchchat/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,45 +1,97 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

plugins {
id("com.android.application")
id("com.android.application")
id("org.jetbrains.kotlin.android")
}

android {
namespace = "org.pytorch.torchchat"
compileSdk = 33
namespace = "org.pytorch.torchchat"
compileSdk = 34

defaultConfig {
applicationId = "org.pytorch.torchchat"
minSdk = 24
targetSdk = 33
versionCode = 1
versionName = "1.0"
defaultConfig {
applicationId = "org.pytorch.torchchat"
minSdk = 28
targetSdk = 33
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { useSupportLibrary = true }
externalNativeBuild { cmake { cppFlags += "" } }
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions { jvmTarget = "1.8" }
buildFeatures { compose = true }
composeOptions { kotlinCompilerExtensionVersion = "1.4.3" }
packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } }
}

dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.0")
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.camera:camera-core:1.3.0-rc02")
implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha12")
implementation("com.facebook.fbjni:fbjni:0.5.1")
implementation("com.google.code.gson:gson:2.8.6")
implementation(files("libs/executorch-llama.aar"))
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.activity:activity:1.9.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}

tasks.register("setup") {
doFirst {
exec {
commandLine("sh", "examples/demo-apps/android/LlamaDemo/setup.sh")
workingDir("../../../../../")
}
buildFeatures {
viewBinding = true
}
}

tasks.register("setupQnn") {
doFirst {
exec {
commandLine("sh", "examples/demo-apps/android/LlamaDemo/setup-with-qnn.sh")
workingDir("../../../../../")
}
}
}

dependencies {
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("com.facebook.fbjni:fbjni:0.5.1")
implementation(files("libs/executorch.aar"))
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
tasks.register("download_prebuilt_lib") {
doFirst {
exec {
commandLine("sh", "examples/demo-apps/android/LlamaDemo/download_prebuilt_lib.sh")
workingDir("../../../../../")
}
}
}
2 changes: 1 addition & 1 deletion torchchat/edge/android/torchchat/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

package org.pytorch.torchchat;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import android.os.Bundle;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.pytorch.executorch.LlamaCallback;
import org.pytorch.executorch.LlamaModule;

@RunWith(AndroidJUnit4.class)
public class PerfTest implements LlamaCallback {

private static final String RESOURCE_PATH = "/data/local/tmp/llama/";
private static final String TOKENIZER_BIN = "tokenizer.bin";

private final List<String> results = new ArrayList<>();
private final List<Float> tokensPerSecond = new ArrayList<>();

@Test
public void testTokensPerSecond() {
String tokenizerPath = RESOURCE_PATH + TOKENIZER_BIN;
// Find out the model name
File directory = new File(RESOURCE_PATH);
Arrays.stream(directory.listFiles())
.filter(file -> file.getName().endsWith(".pte"))
.forEach(
model -> {
LlamaModule mModule = new LlamaModule(model.getPath(), tokenizerPath, 0.8f);
// Print the model name because there might be more than one of them
report("ModelName", model.getName());

int loadResult = mModule.load();
// Check that the model can be load successfully
assertEquals(0, loadResult);

// Run a testing prompt
mModule.generate("How do you do! I'm testing llama2 on mobile device", PerfTest.this);
assertFalse(tokensPerSecond.isEmpty());

final Float tps = tokensPerSecond.get(tokensPerSecond.size() - 1);
report("TPS", tps);
});
}

@Override
public void onResult(String result) {
results.add(result);
}

@Override
public void onStats(float tps) {
tokensPerSecond.add(tps);
}

private void report(final String metric, final Float value) {
Bundle bundle = new Bundle();
bundle.putFloat(metric, value);
InstrumentationRegistry.getInstrumentation().sendStatus(0, bundle);
}

private void report(final String key, final String value) {
Bundle bundle = new Bundle();
bundle.putString(key, value);
InstrumentationRegistry.getInstrumentation().sendStatus(0, bundle);
}
}
52 changes: 39 additions & 13 deletions torchchat/edge/android/torchchat/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,35 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) Meta Platforms, Inc. and affiliates.
All rights reserved.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
package="org.pytorch.torchchat">

<uses-sdk
android:maxSdkVersion="40"
android:minSdkVersion="28"
android:targetSdkVersion="34" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="android.hardware.camera" />

<application
android:name=".ETLogging"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:extractNativeLibs="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:icon="@drawable/logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.torchchat"
tools:targetApi="31">
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
tools:targetApi="34">
<activity
android:name=".LogsActivity"
android:exported="false" />
<activity
android:name=".SettingsActivity"
android:exported="false" />

<uses-native-library
android:name="libcdsprpc.so"
android:required="false" />

<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.torchchat">
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".LlmBenchmarkRunner"
android:exported="true">
<intent-filter>
<action android:name="org.pytorch.torchchat.BENCHMARK" />
</intent-filter>
</activity>

</application>

</manifest>
Loading

0 comments on commit c867660

Please sign in to comment.