[Android] add Android UIE JNI support (#885)

* [UIE] init UIE JNI codes

* [UIE] init UIE JNI codes

* [Android] Add UIE SchemaNode

* [Android] Add UIE SchemaNode

* [Android] Add AllocateUIECxxSchemaNodeFromJava func

* [Android] Add AllocateUIECxxSchemaNodeFromJava func

* Delete README_Ру́сский_язы́к.md

* Delete README_한국어.md

* [Android] add uie utils jni

* [Android] add uie-nano model download task

* [Android] add uie jni support

* [Java] remove log

* [Java] remove log
This commit is contained in:
DefTruth
2022-12-22 10:14:02 +08:00
committed by GitHub
parent 64e744dcf4
commit d4faddc0aa
20 changed files with 1566 additions and 12 deletions

View File

@@ -5,14 +5,14 @@
cache cache
build build
app/cache app/cache
app/libs/fastdeploy* app/libs/*
app/.cxx app/.cxx
app/build app/build
app/src/main/assets/models/* app/src/main/assets/models/*
app/.gradle app/.gradle
app/.idea app/.idea
fastdeploy/cache fastdeploy/cache
fastdeploy/libs/fastdeploy* fastdeploy/libs/*
fastdeploy/.cxx fastdeploy/.cxx
fastdeploy/build fastdeploy/build
fastdeploy/src/main/assets/models/* fastdeploy/src/main/assets/models/*

View File

@@ -23,13 +23,14 @@ android {
dependencies { dependencies {
implementation fileTree(include: ['*.aar'], dir: 'libs') implementation fileTree(include: ['*.aar'], dir: 'libs')
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:appcompat-v7:28.0.0'
//noinspection GradleDependency //noinspection GradleDependency
implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0' implementation 'com.android.support:design:28.0.0'
implementation 'org.jetbrains:annotations:15.0' implementation 'org.jetbrains:annotations:15.0'
implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'
// implementation project(path: ':fastdeploy') // implementation project(path: ':fastdeploy')
implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'
implementation project(path: ':ui') implementation project(path: ':ui')
//noinspection GradleDependency //noinspection GradleDependency
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
@@ -73,6 +74,10 @@ def FD_MODEL = [
[ [
'src' : 'https://bj.bcebos.com/paddlehub/fastdeploy/PP_TinyPose_128x96_infer.tgz', 'src' : 'https://bj.bcebos.com/paddlehub/fastdeploy/PP_TinyPose_128x96_infer.tgz',
'dest': 'src/main/assets/models' 'dest': 'src/main/assets/models'
],
[
'src': 'https://bj.bcebos.com/paddlehub/fastdeploy/uie-nano.tgz',
'dest': 'src/main/assets/models'
] ]
] ]

View File

@@ -0,0 +1,242 @@
package com.baidu.paddle.fastdeploy.app.examples.text.uie;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import com.baidu.paddle.fastdeploy.RuntimeOption;
import com.baidu.paddle.fastdeploy.app.examples.R;
import com.baidu.paddle.fastdeploy.text.UIEResult;
import com.baidu.paddle.fastdeploy.text.uie.UIEModel;
import com.baidu.paddle.fastdeploy.text.uie.SchemaLanguage;
import com.baidu.paddle.fastdeploy.ui.Utils;
import java.util.HashMap;
public class UIEMainActivity extends Activity implements View.OnClickListener {
private static final String TAG = UIEMainActivity.class.getSimpleName() + "[FastDeploy][Java]";
private ImageView back;
private ImageButton btnSettings;
private EditText etUIEInput;
private EditText etUIESchema;
private EditText etUIEOutput;
private Button btnUIEAnalysis;
private String[] inputTexts;
private String[] schemaTexts;
// Call 'init' and 'release' manually later
UIEModel predictor = new UIEModel();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Fullscreen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.uie_activity_main);
// Clear all setting items to avoid app crashing due to the incorrect settings
initSettings();
// Check and request CAMERA and WRITE_EXTERNAL_STORAGE permissions
if (!checkAllPermissions()) {
requestAllPermissions();
}
// Init the camera preview and UI components
initView();
}
@Override
protected void onResume() {
super.onResume();
// Reload settings and re-initialize the predictor
checkAndUpdateSettings();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
if (predictor != null) {
predictor.release();
}
super.onDestroy();
}
private void initView() {
// Back from setting page to main page
back = findViewById(R.id.iv_back);
back.setOnClickListener(this);
// Apply UIE predict
btnUIEAnalysis = findViewById(R.id.btn_uie_analysis);
btnUIEAnalysis.setOnClickListener(this);
// UIE input, schema and output texts
etUIEInput = findViewById(R.id.et_uie_input);
etUIESchema = findViewById(R.id.et_uie_schema);
etUIEOutput = findViewById(R.id.et_uie_output);
// Setting page
btnSettings = findViewById(R.id.btn_settings);
btnSettings.setOnClickListener(this);
}
@SuppressLint("NonConstantResourceId")
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_settings:
startActivity(new Intent(UIEMainActivity.this, UIESettingsActivity.class));
break;
case R.id.iv_back:
finish();
break;
case R.id.btn_uie_analysis:
extractTextsInformation();
break;
default:
break;
}
}
public void extractTextsInformation() {
if (updateInputTexts() && updateSchemaTexts()) {
// Set schema before predict
if (predictor.setSchema(schemaTexts)) {
// Apply Information Extraction
HashMap<String, UIEResult[]>[] results = predictor.predict(inputTexts);
updateOutputTexts(results);
}
}
}
public void updateOutputTexts(HashMap<String, UIEResult[]>[] results) {
if (results == null) {
etUIEOutput.setText("抽取结果为空");
return;
}
// Merge UIEResult strings -> combinedOutputText
String combinedOutputText = UIEResult.printResult(results);
// Update output text view (EditText)
etUIEOutput.setText(combinedOutputText);
}
public boolean updateInputTexts() {
String combinedInputText = etUIEInput.getText().toString();
if (combinedInputText == null || combinedInputText.length() == 0) {
// Use default text if no custom text
combinedInputText = getString(R.string.UIE_INPUT_TEXTS_DEFAULT);
}
String[] texts = combinedInputText.split("[。!!:;]");
if (texts.length <= 0) {
return false;
}
for (int i = 0; i < texts.length; ++i) {
texts[i] = texts[i].trim();
}
// Update input texts
inputTexts = texts;
return true;
}
public boolean updateSchemaTexts() {
String combinedSchemaText = etUIESchema.getText().toString();
if (combinedSchemaText == null || combinedSchemaText.length() == 0) {
// Use default schema if no custom schema
combinedSchemaText = getString(R.string.UIE_SCHEMA_DEFAULT);
}
String[] schemas = combinedSchemaText.split("[,|、:;]");
if (schemas.length <= 0) {
return false;
}
for (int i = 0; i < schemas.length; ++i) {
schemas[i] = schemas[i].trim();
}
// Update schema texts
schemaTexts = schemas;
return true;
}
@SuppressLint("ApplySharedPref")
public void initSettings() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear();
editor.commit();
UIESettingsActivity.resetSettings();
}
public void checkAndUpdateSettings() {
if (UIESettingsActivity.checkAndUpdateSettings(this)) {
String realModelDir = getCacheDir() + "/" + UIESettingsActivity.modelDir;
Utils.copyDirectoryFromAssets(this, UIESettingsActivity.modelDir, realModelDir);
String modelFile = realModelDir + "/" + "inference.pdmodel";
String paramsFile = realModelDir + "/" + "inference.pdiparams";
String vocabFile = realModelDir + "/" + "vocab.txt";
RuntimeOption option = new RuntimeOption();
option.setCpuThreadNum(UIESettingsActivity.cpuThreadNum);
option.setLitePowerMode(UIESettingsActivity.cpuPowerMode);
if (Boolean.parseBoolean(UIESettingsActivity.enableLiteFp16)) {
option.enableLiteFp16();
}
predictor.init(modelFile, paramsFile, vocabFile,
0.3f, 128, schemaTexts,
option, SchemaLanguage.ZH);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) {
new AlertDialog.Builder(UIEMainActivity.this)
.setTitle("Permission denied")
.setMessage("Click to force quit the app, then open Settings->Apps & notifications->Target " +
"App->Permissions to grant all of the permissions.")
.setCancelable(false)
.setPositiveButton("Exit", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
UIEMainActivity.this.finish();
}
}).show();
}
}
private void requestAllPermissions() {
ActivityCompat.requestPermissions(
this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
0);
}
private boolean checkAllPermissions() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED;
}
}

View File

@@ -0,0 +1,164 @@
package com.baidu.paddle.fastdeploy.app.examples.text.uie;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBar;
import com.baidu.paddle.fastdeploy.app.examples.R;
import com.baidu.paddle.fastdeploy.ui.Utils;
import com.baidu.paddle.fastdeploy.ui.view.AppCompatPreferenceActivity;
import java.util.ArrayList;
import java.util.List;
public class UIESettingsActivity extends AppCompatPreferenceActivity implements
SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = UIESettingsActivity.class.getSimpleName();
static public int selectedModelIdx = -1;
static public String modelDir = "";
static public int cpuThreadNum = 2;
static public String cpuPowerMode = "";
static public String enableLiteFp16 = "true";
ListPreference lpChoosePreInstalledModel = null;
EditTextPreference etModelDir = null;
ListPreference lpCPUThreadNum = null;
ListPreference lpCPUPowerMode = null;
ListPreference lpEnableLiteFp16 = null;
List<String> preInstalledModelDirs = null;
List<String> preInstalledCPUThreadNums = null;
List<String> preInstalledCPUPowerModes = null;
List<String> preInstalledEnableLiteFp16s = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.uie_settings);
ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
supportActionBar.setDisplayHomeAsUpEnabled(true);
}
// Initialize pre-installed models
preInstalledModelDirs = new ArrayList<String>();
preInstalledCPUThreadNums = new ArrayList<String>();
preInstalledCPUPowerModes = new ArrayList<String>();
preInstalledEnableLiteFp16s = new ArrayList<String>();
preInstalledModelDirs.add(getString(R.string.UIE_MODEL_DIR_DEFAULT));
preInstalledCPUThreadNums.add(getString(R.string.CPU_THREAD_NUM_DEFAULT));
preInstalledCPUPowerModes.add(getString(R.string.CPU_POWER_MODE_DEFAULT));
preInstalledEnableLiteFp16s.add(getString(R.string.ENABLE_LITE_FP16_MODE_DEFAULT));
// Setup UI components
lpChoosePreInstalledModel =
(ListPreference) findPreference(getString(R.string.CHOOSE_PRE_INSTALLED_MODEL_KEY));
String[] preInstalledModelNames = new String[preInstalledModelDirs.size()];
for (int i = 0; i < preInstalledModelDirs.size(); i++) {
preInstalledModelNames[i] = preInstalledModelDirs.get(i).substring(preInstalledModelDirs.get(i).lastIndexOf("/") + 1);
}
lpChoosePreInstalledModel.setEntries(preInstalledModelNames);
lpChoosePreInstalledModel.setEntryValues(preInstalledModelDirs.toArray(new String[preInstalledModelDirs.size()]));
lpCPUThreadNum = (ListPreference) findPreference(getString(R.string.CPU_THREAD_NUM_KEY));
lpCPUPowerMode = (ListPreference) findPreference(getString(R.string.CPU_POWER_MODE_KEY));
etModelDir = (EditTextPreference) findPreference(getString(R.string.MODEL_DIR_KEY));
etModelDir.setTitle("Model dir (SDCard: " + Utils.getSDCardDirectory() + ")");
lpEnableLiteFp16 = (ListPreference) findPreference(getString(R.string.ENABLE_LITE_FP16_MODE_KEY));
}
@SuppressLint("ApplySharedPref")
private void reloadSettingsAndUpdateUI() {
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
String selected_model_dir = sharedPreferences.getString(getString(R.string.CHOOSE_PRE_INSTALLED_MODEL_KEY),
getString(R.string.UIE_MODEL_DIR_DEFAULT));
int selected_model_idx = lpChoosePreInstalledModel.findIndexOfValue(selected_model_dir);
if (selected_model_idx >= 0 && selected_model_idx < preInstalledModelDirs.size() && selected_model_idx != selectedModelIdx) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(getString(R.string.MODEL_DIR_KEY), preInstalledModelDirs.get(selected_model_idx));
editor.putString(getString(R.string.CPU_THREAD_NUM_KEY), preInstalledCPUThreadNums.get(selected_model_idx));
editor.putString(getString(R.string.CPU_POWER_MODE_KEY), preInstalledCPUPowerModes.get(selected_model_idx));
editor.putString(getString(R.string.ENABLE_LITE_FP16_MODE_DEFAULT), preInstalledEnableLiteFp16s.get(selected_model_idx));
editor.commit();
lpChoosePreInstalledModel.setSummary(selected_model_dir);
selectedModelIdx = selected_model_idx;
}
String model_dir = sharedPreferences.getString(getString(R.string.MODEL_DIR_KEY),
getString(R.string.UIE_MODEL_DIR_DEFAULT));
String cpu_thread_num = sharedPreferences.getString(getString(R.string.CPU_THREAD_NUM_KEY),
getString(R.string.CPU_THREAD_NUM_DEFAULT));
String cpu_power_mode = sharedPreferences.getString(getString(R.string.CPU_POWER_MODE_KEY),
getString(R.string.CPU_POWER_MODE_DEFAULT));
String enable_lite_fp16 = sharedPreferences.getString(getString(R.string.ENABLE_LITE_FP16_MODE_KEY),
getString(R.string.ENABLE_LITE_FP16_MODE_DEFAULT));
etModelDir.setSummary(model_dir);
lpCPUThreadNum.setValue(cpu_thread_num);
lpCPUThreadNum.setSummary(cpu_thread_num);
lpCPUPowerMode.setValue(cpu_power_mode);
lpCPUPowerMode.setSummary(cpu_power_mode);
lpEnableLiteFp16.setValue(enable_lite_fp16);
lpEnableLiteFp16.setSummary(enable_lite_fp16);
}
static boolean checkAndUpdateSettings(Context ctx) {
boolean settingsChanged = false;
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ctx);
String model_dir = sharedPreferences.getString(ctx.getString(R.string.MODEL_DIR_KEY),
ctx.getString(R.string.UIE_MODEL_DIR_DEFAULT));
settingsChanged |= !modelDir.equalsIgnoreCase(model_dir);
modelDir = model_dir;
String cpu_thread_num = sharedPreferences.getString(ctx.getString(R.string.CPU_THREAD_NUM_KEY),
ctx.getString(R.string.CPU_THREAD_NUM_DEFAULT));
settingsChanged |= cpuThreadNum != Integer.parseInt(cpu_thread_num);
cpuThreadNum = Integer.parseInt(cpu_thread_num);
String cpu_power_mode = sharedPreferences.getString(ctx.getString(R.string.CPU_POWER_MODE_KEY),
ctx.getString(R.string.CPU_POWER_MODE_DEFAULT));
settingsChanged |= !cpuPowerMode.equalsIgnoreCase(cpu_power_mode);
cpuPowerMode = cpu_power_mode;
String enable_lite_fp16 = sharedPreferences.getString(ctx.getString(R.string.ENABLE_LITE_FP16_MODE_KEY),
ctx.getString(R.string.ENABLE_LITE_FP16_MODE_DEFAULT));
settingsChanged |= !enableLiteFp16.equalsIgnoreCase(enable_lite_fp16);
enableLiteFp16 = enable_lite_fp16;
return settingsChanged;
}
static void resetSettings() {
selectedModelIdx = -1;
modelDir = "";
cpuThreadNum = 2;
cpuPowerMode = "";
enableLiteFp16 = "true";
}
@Override
protected void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
reloadSettingsAndUpdateUI();
}
@Override
protected void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
reloadSettingsAndUpdateUI();
}
}

View File

@@ -0,0 +1,30 @@
package com.baidu.paddle.fastdeploy.app.examples.text.uie;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import com.baidu.paddle.fastdeploy.app.examples.R;
public class UIEWelcomeActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
setContentView(R.layout.uie_welcome);
}
public void startActivity(View view) {
Intent intent = new Intent(UIEWelcomeActivity.this, UIEMainActivity.class);
startActivity(intent);
}
}

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.baidu.paddle.fastdeploy.ui.layout.ActionBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:cropToPadding="true"
android:paddingLeft="40px"
android:paddingTop="60px"
android:paddingRight="60px"
android:paddingBottom="40px"
android:src="@drawable/back_btn" />
<TextView
style="@style/action_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50px"
android:text="@string/uie_app_name"
android:textSize="15sp" />
<ImageButton
android:id="@+id/btn_settings"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:background="@null"
android:scaleType="fitXY"
android:src="@drawable/btn_settings" />
</com.baidu.paddle.fastdeploy.ui.layout.ActionBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<EditText
android:id="@+id/et_uie_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_marginRight="20dp"
android:lines="3"
android:inputType="textMultiLine"
android:hint="@string/UIE_INPUT_TEXTS_HINT"
android:textColor="@android:color/black"
android:textSize="20sp" />
<EditText
android:id="@+id/et_uie_schema"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_marginRight="20dp"
android:lines="3"
android:inputType="textMultiLine"
android:hint="@string/UIE_SCHEMA_HINT"
android:textColor="@android:color/black"
android:textSize="20sp" />
<Button
android:id="@+id/btn_uie_analysis"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:textSize="20sp"
android:text="开始抽取信息" />
<EditText
android:id="@+id/et_uie_output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_marginRight="20dp"
android:textColor="@android:color/black"
android:textSize="20sp"
android:lines="4"
android:inputType="textMultiLine"
android:hint="信息抽取结果:" />
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:background="@drawable/main_bk"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/model_text"
android:layout_width="320dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="120dp"
android:background="@color/colorStartBtn"
android:gravity="center"
android:text="UIE Nano"
android:textColor="@color/colorTextWrite"
android:textSize="30sp" />
<TextView
android:id="@+id/baidu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/model_text"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="百度FastDeploy"
android:textColor="@color/colorTextWrite"
android:textSize="22sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/baidu"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:text="Powered by EasyEdge"
android:textColor="@color/colorTextWrite"
android:textSize="18sp" />
<Button
android:id="@+id/start_ui_activity"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="70dp"
android:background="@drawable/round_corner_btn"
android:text="@string/start_ui_activity"
android:textColor="@color/colorTextWrite"
android:textSize="22sp"
android:onClick="startActivity"/>
<ImageView
android:id="@+id/logo"
android:layout_width="95dp"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:background="@drawable/paddle_logo"
android:scaleType="centerCrop" />
</RelativeLayout>
</FrameLayout>

View File

@@ -1,14 +1,15 @@
<resources> <resources>
<!-- Default App name --> <!-- Default App name -->
<string name="app_name">EasyEdge</string> <string name="app_name">FastDeploy</string>
<!-- Other App name --> <!-- Other App name -->
<string name="detection_app_name">EasyEdge</string> <string name="detection_app_name">FastDeploy Detection</string>
<string name="ocr_app_name">EasyEdge</string> <string name="ocr_app_name">FastDeploy OCR</string>
<string name="classification_app_name">EasyEdge</string> <string name="classification_app_name">FastDeploy Classification</string>
<string name="facedet_app_name">EasyEdge</string> <string name="facedet_app_name">FastDeploy Face Detection</string>
<string name="segmentation_app_name">EasyEdge</string> <string name="segmentation_app_name">FastDeploy Segmentation</string>
<string name="voice_assistant_app_name">voice assistant</string> <string name="voice_assistant_app_name">FastDeploy Voice Assistant</string>
<string name="super_resolution_app_name">Super Resolution</string> <string name="super_resolution_app_name">FastDeploy Super Resolution</string>
<string name="uie_app_name">FastDeploy UIE</string>
<string name="start_ui_activity">开始使用</string> <string name="start_ui_activity">开始使用</string>
<!-- Keys for PreferenceScreen --> <!-- Keys for PreferenceScreen -->
<string name="CHOOSE_PRE_INSTALLED_MODEL_KEY">CHOOSE_INSTALLED_MODEL_KEY</string> <string name="CHOOSE_PRE_INSTALLED_MODEL_KEY">CHOOSE_INSTALLED_MODEL_KEY</string>
@@ -44,6 +45,7 @@
<string name="KEYPOINT_DETECTION_MODEL_DIR_DEFAULT">models/PP_TinyPose_128x96_infer</string> <string name="KEYPOINT_DETECTION_MODEL_DIR_DEFAULT">models/PP_TinyPose_128x96_infer</string>
<string name="VOICE_ASSISTANT_MODEL_DIR_DEFAULT">models</string> <string name="VOICE_ASSISTANT_MODEL_DIR_DEFAULT">models</string>
<string name="SUPER_RESOLUTION_MODEL_DIR_DEFAULT">models</string> <string name="SUPER_RESOLUTION_MODEL_DIR_DEFAULT">models</string>
<string name="UIE_MODEL_DIR_DEFAULT">models/uie-nano</string>
<!-- Other resources values--> <!-- Other resources values-->
<string name="action_bar_take_photo">拍照识别</string> <string name="action_bar_take_photo">拍照识别</string>
<string name="action_bar_realtime">实时识别</string> <string name="action_bar_realtime">实时识别</string>
@@ -56,4 +58,9 @@
<string name="operation_confidence_control">阈值控制</string> <string name="operation_confidence_control">阈值控制</string>
<string name="operation_retry">重新识别</string> <string name="operation_retry">重新识别</string>
<string name="operation_save">保存结果</string> <string name="operation_save">保存结果</string>
<!-- NLP Text values -->
<string name="UIE_SCHEMA_HINT">请输入需要的信息模式,如: 时间,选手,赛事名称</string>
<string name="UIE_SCHEMA_DEFAULT">时间, 选手, 赛事名称</string>
<string name="UIE_INPUT_TEXTS_HINT">请输入需要分析的文本2月8日上午北京冬奥会自由式滑雪女子大跳台决赛中中国选手谷爱凌以188.25分获得金牌!</string>
<string name="UIE_INPUT_TEXTS_DEFAULT">2月8日上午北京冬奥会自由式滑雪女子大跳台决赛中中国选手谷爱凌以188.25分获得金牌!</string>
</resources> </resources>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:defaultValue="@string/VOICE_ASSISTANT_MODEL_DIR_DEFAULT"
android:key="@string/CHOOSE_PRE_INSTALLED_MODEL_KEY"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="Choose Pre-Installed Models" />
<EditTextPreference
android:defaultValue="@string/UIE_MODEL_DIR_DEFAULT"
android:key="@string/MODEL_DIR_KEY"
android:title="Model Dir" />
<ListPreference
android:defaultValue="@string/CPU_THREAD_NUM_DEFAULT"
android:entries="@array/cpu_thread_num_entries"
android:entryValues="@array/cpu_thread_num_values"
android:key="@string/CPU_THREAD_NUM_KEY"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="CPU Thread Num" />
<ListPreference
android:defaultValue="@string/CPU_POWER_MODE_DEFAULT"
android:entries="@array/cpu_power_mode_entries"
android:entryValues="@array/cpu_power_mode_values"
android:key="@string/CPU_POWER_MODE_KEY"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="CPU Power Mode" />
<ListPreference
android:defaultValue="@string/ENABLE_LITE_FP16_MODE_DEFAULT"
android:entries="@array/enable_lite_fp16_mode_entries"
android:entryValues="@array/enable_lite_fp16_mode_values"
android:key="@string/ENABLE_LITE_FP16_MODE_KEY"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="Enable Lite FP16" />
</PreferenceScreen>

View File

@@ -1 +1,2 @@
fastdeploy-* fastdeploy-*
arm*

View File

@@ -45,6 +45,9 @@ add_library(
fastdeploy_jni/vision/facedet/facedet_utils_jni.cc fastdeploy_jni/vision/facedet/facedet_utils_jni.cc
fastdeploy_jni/vision/keypointdetection/pptinypose_jni.cc fastdeploy_jni/vision/keypointdetection/pptinypose_jni.cc
fastdeploy_jni/vision/keypointdetection/keypointdetection_utils_jni.cc fastdeploy_jni/vision/keypointdetection/keypointdetection_utils_jni.cc
fastdeploy_jni/text/text_results_jni.cc
fastdeploy_jni/text/uie/uie_model_jni.cc
fastdeploy_jni/text/uie/uie_utils_jni.cc
) )
# Searches for a specified prebuilt library and stores the path as a # Searches for a specified prebuilt library and stores the path as a

View File

@@ -0,0 +1,195 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <jni.h> // NOLINT
#include "fastdeploy_jni/perf_jni.h" // NOLINT
#include "fastdeploy_jni/convert_jni.h" // NOLINT
#include "fastdeploy_jni/text/text_results_jni.h" // NOLINT
#ifdef ENABLE_TEXT
#include "fastdeploy/text.h" // NOLINT
#endif
namespace fastdeploy {
namespace jni {
jobject NewUIEJavaResultFromCxx(JNIEnv *env, void *cxx_result) {
// Field signatures of Java UIEResult:
// (1) mStart long: J
// (2) mEnd long: J
// (3) mProbability double: D
// (4) mText String: Ljava/lang/String;
// (5) mRelation HashMap<String, UIEResult[]>: Ljava/util/HashMap;
// (6) mInitialized boolean: Z
// Return NULL directly if Text API was not enabled. The Text API
// is not necessarily enabled. Whether or not it is enabled depends
// on the C++ SDK.
#ifndef ENABLE_TEXT
return NULL;
#else
// Allocate Java UIEResult if Text API was enabled.
if (cxx_result == nullptr) {
return NULL;
}
auto c_result_ptr = reinterpret_cast<text::UIEResult*>(cxx_result);
const int len = static_cast<int>(c_result_ptr->text_.size());
if (len == 0) {
return NULL;
}
const jclass j_uie_result_clazz = env->FindClass(
"com/baidu/paddle/fastdeploy/text/UIEResult");
const jfieldID j_uie_start_id = env->GetFieldID(
j_uie_result_clazz, "mStart", "J");
const jfieldID j_uie_end_id = env->GetFieldID(
j_uie_result_clazz, "mEnd", "J");
const jfieldID j_uie_probability_id = env->GetFieldID(
j_uie_result_clazz, "mProbability", "D");
const jfieldID j_uie_text_id = env->GetFieldID(
j_uie_result_clazz, "mText", "Ljava/lang/String;");
const jfieldID j_uie_relation_id = env->GetFieldID(
j_uie_result_clazz, "mRelation", "Ljava/util/HashMap;");
const jfieldID j_uie_initialized_id = env->GetFieldID(
j_uie_result_clazz, "mInitialized", "Z");
// Default UIEResult constructor.
const jmethodID j_uie_result_init = env->GetMethodID(
j_uie_result_clazz, "<init>", "()V");
jobject j_uie_result_obj = env->NewObject(j_uie_result_clazz, j_uie_result_init);
// Allocate for current UIEResult
// mStart long: J & mEnd long: J
env->SetLongField(j_uie_result_obj, j_uie_start_id,
static_cast<jlong>(c_result_ptr->start_));
env->SetLongField(j_uie_result_obj, j_uie_end_id,
static_cast<jlong>(c_result_ptr->end_));
// mProbability double: D
env->SetDoubleField(j_uie_result_obj, j_uie_probability_id,
static_cast<jdouble>(c_result_ptr->probability_));
// mText String: Ljava/lang/String;
env->SetObjectField(j_uie_result_obj, j_uie_text_id,
ConvertTo<jstring>(env, c_result_ptr->text_));
// mInitialized boolean: Z
env->SetBooleanField(j_uie_result_obj, j_uie_initialized_id, JNI_TRUE);
// mRelation HashMap<String, UIEResult[]>: Ljava/util/HashMap;
if (c_result_ptr->relation_.size() > 0) {
const jclass j_hashmap_clazz = env->FindClass("java/util/HashMap");
const jmethodID j_hashmap_init = env->GetMethodID(
j_hashmap_clazz, "<init>", "()V");
const jmethodID j_hashmap_put = env->GetMethodID(
j_hashmap_clazz,"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
// std::unordered_map<std::string, std::vector<UIEResult>> relation_;
jobject j_uie_relation_hashmap = env->NewObject(j_hashmap_clazz, j_hashmap_init);
for (auto&& curr_relation : c_result_ptr->relation_) {
// Processing each key-value cxx uie relation:
// Key: string, Value: std::vector<UIEResult>
const auto& curr_c_relation_key = curr_relation.first;
jstring curr_j_relation_key = ConvertTo<jstring>(env, curr_c_relation_key);
// Init current relation array (array of UIEResult)
const int curr_c_uie_result_size = curr_relation.second.size();
jobjectArray curr_j_uie_result_obj_arr = env->NewObjectArray(
curr_c_uie_result_size, j_uie_result_clazz, NULL);
for (int i = 0; i < curr_c_uie_result_size; ++i) {
text::UIEResult* child_cxx_result = (&(curr_relation.second[i]));
// Recursively generates the curr_j_uie_result_obj
jobject curr_j_uie_result_obj = NewUIEJavaResultFromCxx(
env, reinterpret_cast<void*>(child_cxx_result));
env->SetObjectArrayElement(curr_j_uie_result_obj_arr, i, curr_j_uie_result_obj);
env->DeleteLocalRef(curr_j_uie_result_obj);
}
// Put current relation array (array of UIEResult) to HashMap
env->CallObjectMethod(j_uie_relation_hashmap, j_hashmap_put, curr_j_relation_key,
curr_j_uie_result_obj_arr);
env->DeleteLocalRef(curr_j_relation_key);
env->DeleteLocalRef(curr_j_uie_result_obj_arr);
}
// Set relation HashMap from native
env->SetObjectField(j_uie_result_obj, j_uie_relation_id, j_uie_relation_hashmap);
env->DeleteLocalRef(j_hashmap_clazz);
env->DeleteLocalRef(j_uie_relation_hashmap);
}
env->DeleteLocalRef(j_uie_result_clazz);
return j_uie_result_obj;
#endif
}
bool AllocateUIECxxSchemaNodeFromJava(
JNIEnv *env, jobject j_schema_node_obj, void *cxx_schema_node) {
#ifndef ENABLE_TEXT
return false;
#else
// Allocate cxx SchemaNode from Java SchemaNode
if (cxx_schema_node == nullptr) {
return false;
}
text::SchemaNode* c_mutable_schema_node_ptr =
reinterpret_cast<text::SchemaNode*>(cxx_schema_node);
const jclass j_schema_node_clazz = env->FindClass(
"com/baidu/paddle/fastdeploy/text/uie/SchemaNode");
if (!env->IsInstanceOf(j_schema_node_obj, j_schema_node_clazz)) {
return false;
}
const jfieldID j_schema_node_name_id = env->GetFieldID(
j_schema_node_clazz, "mName", "Ljava/lang/String;");
const jfieldID j_schema_node_child_id = env->GetFieldID(
j_schema_node_clazz, "mChildren",
"Ljava/util/ArrayList;");
// Java ArrayList in JNI
const jclass j_array_list_clazz = env->FindClass(
"java/util/ArrayList");
const jmethodID j_array_list_get = env->GetMethodID(
j_array_list_clazz,"get", "(I)Ljava/lang/Object;");
const jmethodID j_array_list_size = env->GetMethodID(
j_array_list_clazz,"size", "()I");
// mName String: Ljava/lang/String;
c_mutable_schema_node_ptr->name_ = ConvertTo<std::string>(
env, reinterpret_cast<jstring>(env->GetObjectField(
j_schema_node_obj, j_schema_node_name_id)));
// mChildren ArrayList: Ljava/util/ArrayList;
jobject j_schema_node_child_array_list = env->GetObjectField(
j_schema_node_obj, j_schema_node_child_id); // ArrayList
const int j_schema_node_child_size = static_cast<int>(
env->CallIntMethod(j_schema_node_child_array_list,
j_array_list_size));
// Recursively add child if child size > 0
if (j_schema_node_child_size > 0) {
for (int i = 0; i < j_schema_node_child_size; ++i) {
text::SchemaNode curr_c_schema_node_child;
jobject curr_j_schema_node_child = env->CallObjectMethod(
j_schema_node_child_array_list, j_array_list_get, i);
if (AllocateUIECxxSchemaNodeFromJava(
env, curr_j_schema_node_child, reinterpret_cast<void*>(
&curr_c_schema_node_child))) {
c_mutable_schema_node_ptr->AddChild(curr_c_schema_node_child);
}
}
}
return true;
#endif
}
} // namespace jni
} // namespace fastdeploy

View File

@@ -0,0 +1,40 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <jni.h> // NOLINT
namespace fastdeploy {
namespace jni {
/**
* @param env A Pointer of JNIENV.
* @param cxx_result A pointer of cxx 'text::UIEResult'
* @return jobject that stands for Java UIEResult
*/
jobject NewUIEJavaResultFromCxx(JNIEnv *env, void *cxx_result);
/**
* Allocate one cxx SchemaNode from Java SchemaNode
* @param env A Pointer of JNIENV.
* @param j_schema_node_obj jobject that stands for Java SchemaNode
* @param cxx_schema_node A pointer of cxx 'text::SchemaNode'
* @return true if success, false if failed.
*/
bool AllocateUIECxxSchemaNodeFromJava(
JNIEnv *env, jobject j_schema_node_obj, void *cxx_schema_node);
} // namespace jni
} // namespace fastdeploy

View File

@@ -0,0 +1,267 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <jni.h> // NOLINT
#include "fastdeploy_jni/perf_jni.h" // NOLINT
#include "fastdeploy_jni/convert_jni.h" // NOLINT
#include "fastdeploy_jni/runtime_option_jni.h" // NOLINT
#include "fastdeploy_jni/text/text_results_jni.h" // NOLINT
#include "fastdeploy_jni/text/uie/uie_utils_jni.h" // NOLINT
#ifdef ENABLE_TEXT
#include "fastdeploy/text.h" // NOLINT
#endif
namespace fni = fastdeploy::jni;
#ifdef ENABLE_TEXT
namespace text = fastdeploy::text;
#endif
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jlong JNICALL
Java_com_baidu_paddle_fastdeploy_text_uie_UIEModel_bindNative(JNIEnv *env,
jobject thiz,
jstring model_file,
jstring params_file,
jstring vocab_file,
jfloat position_prob,
jint max_length,
jobjectArray schema,
jobject runtime_option,
jint schema_language) {
#ifndef ENABLE_TEXT
return 0;
#else
auto c_model_file = fni::ConvertTo<std::string>(env, model_file);
auto c_params_file = fni::ConvertTo<std::string>(env, params_file);
auto c_vocab_file = fni::ConvertTo<std::string>(env, vocab_file);
auto c_position_prob = static_cast<jfloat>(position_prob);
auto c_max_length = static_cast<size_t>(max_length);
auto c_schema = fni::ConvertTo<std::vector<std::string>>(env, schema);
auto c_runtime_option = fni::NewCxxRuntimeOption(env, runtime_option);
auto c_schema_language = static_cast<text::SchemaLanguage>(schema_language);
auto c_paddle_model_format = fastdeploy::ModelFormat::PADDLE;
auto c_model_ptr = new text::UIEModel(c_model_file,
c_params_file,
c_vocab_file,
c_position_prob,
c_max_length,
c_schema,
c_runtime_option,
c_paddle_model_format,
c_schema_language);
INITIALIZED_OR_RETURN(c_model_ptr)
#ifdef ENABLE_RUNTIME_PERF
c_model_ptr->EnableRecordTimeOfRuntime();
#endif
return reinterpret_cast<jlong>(c_model_ptr);
#endif
}
JNIEXPORT jobjectArray JNICALL
Java_com_baidu_paddle_fastdeploy_text_uie_UIEModel_predictNative(JNIEnv *env,
jobject thiz,
jlong cxx_context,
jobjectArray texts) {
#ifndef ENABLE_TEXT
return NULL;
#else
if (cxx_context == 0) {
return NULL;
}
auto c_model_ptr = reinterpret_cast<text::UIEModel *>(cxx_context);
auto c_texts = fni::ConvertTo<std::vector<std::string>>(env, texts);
if (c_texts.empty()) {
LOGE("c_texts is empty!");
return NULL;
}
LOGD("c_texts: %s", fni::UIETextsStr(c_texts).c_str());
std::vector<std::unordered_map<
std::string, std::vector<text::UIEResult>>> c_results;
auto t = fni::GetCurrentTime();
c_model_ptr->Predict(c_texts, &c_results);
PERF_TIME_OF_RUNTIME(c_model_ptr, t)
if (c_results.empty()) {
LOGE("c_results is empty!");
return NULL;
}
LOGD("c_results: %s", fni::UIEResultsStr(c_results).c_str());
// Push results to HashMap array
const char* j_hashmap_put_signature =
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;";
const jclass j_hashmap_clazz = env->FindClass(
"java/util/HashMap");
const jclass j_uie_result_clazz = env->FindClass(
"com/baidu/paddle/fastdeploy/text/UIEResult");
// Get HashMap method id
const jmethodID j_hashmap_init = env->GetMethodID(
j_hashmap_clazz, "<init>", "()V");
const jmethodID j_hashmap_put = env->GetMethodID(
j_hashmap_clazz,"put", j_hashmap_put_signature);
const int c_uie_result_hashmap_size = c_results.size();
jobjectArray j_hashmap_uie_result_arr = env->NewObjectArray(
c_uie_result_hashmap_size, j_hashmap_clazz, NULL);
for (int i = 0; i < c_uie_result_hashmap_size; ++i) {
auto& curr_c_uie_result_map = c_results[i];
// Convert unordered_map<string, vector<UIEResult>>
// -> HashMap<String, UIEResult[]>
jobject curr_j_uie_result_hashmap = env->NewObject(
j_hashmap_clazz, j_hashmap_init);
for (auto&& curr_c_uie_result: curr_c_uie_result_map) {
const auto& curr_inner_c_uie_key = curr_c_uie_result.first;
jstring curr_inner_j_uie_key = fni::ConvertTo<jstring>(
env, curr_inner_c_uie_key); // Key of HashMap
if (curr_c_uie_result.second.size() > 0) {
// Value of HashMap: HashMap<String, UIEResult[]>
jobjectArray curr_inner_j_uie_result_values =
env->NewObjectArray(curr_c_uie_result.second.size(),
j_uie_result_clazz,
NULL);
// Convert vector<UIEResult> -> Java UIEResult[]
for (int j = 0; j < curr_c_uie_result.second.size(); ++j) {
text::UIEResult* inner_c_uie_result = (
&(curr_c_uie_result.second[j]));
jobject curr_inner_j_uie_result_obj =
fni::NewUIEJavaResultFromCxx(
env, reinterpret_cast<void *>(inner_c_uie_result));
env->SetObjectArrayElement(curr_inner_j_uie_result_values, j,
curr_inner_j_uie_result_obj);
env->DeleteLocalRef(curr_inner_j_uie_result_obj);
}
// Set element of 'curr_j_uie_result_hashmap':
// HashMap<String, UIEResult[]>
env->CallObjectMethod(
curr_j_uie_result_hashmap, j_hashmap_put,
curr_inner_j_uie_key, curr_inner_j_uie_result_values);
env->DeleteLocalRef(curr_inner_j_uie_key);
env->DeleteLocalRef(curr_inner_j_uie_result_values);
} // end if
} // end for
// Set current HashMap<String, UIEResult[]> to HashMap[i]
env->SetObjectArrayElement(j_hashmap_uie_result_arr, i,
curr_j_uie_result_hashmap);
env->DeleteLocalRef(curr_j_uie_result_hashmap);
}
return j_hashmap_uie_result_arr;
#endif
}
JNIEXPORT jboolean JNICALL
Java_com_baidu_paddle_fastdeploy_text_uie_UIEModel_releaseNative(JNIEnv *env,
jobject thiz,
jlong cxx_context) {
#ifndef ENABLE_TEXT
return JNI_FALSE;
#else
if (cxx_context == 0) {
return JNI_FALSE;
}
auto c_model_ptr = reinterpret_cast<text::UIEModel *>(cxx_context);
PERF_TIME_OF_RUNTIME(c_model_ptr, -1)
delete c_model_ptr;
LOGD("[End] Release UIEModel in native !");
return JNI_TRUE;
#endif
}
JNIEXPORT jboolean JNICALL
Java_com_baidu_paddle_fastdeploy_text_uie_UIEModel_setSchemaStringNative(
JNIEnv *env, jobject thiz, jlong cxx_context,
jobjectArray schema) {
#ifndef ENABLE_TEXT
return JNI_FALSE;
#else
if (cxx_context == 0) {
return JNI_FALSE;
}
auto c_model_ptr = reinterpret_cast<text::UIEModel *>(cxx_context);
auto c_schema = fni::ConvertTo<std::vector<std::string>>(env, schema);
if (c_schema.empty()) {
LOGE("c_schema is empty!");
return JNI_FALSE;
}
LOGD("c_schema is: %s", fni::UIESchemasStr(c_schema).c_str());
c_model_ptr->SetSchema(c_schema);
return JNI_TRUE;
#endif
}
JNIEXPORT jboolean JNICALL
Java_com_baidu_paddle_fastdeploy_text_uie_UIEModel_setSchemaNodeNative(
JNIEnv *env, jobject thiz, jlong cxx_context,
jobjectArray schema) {
#ifndef ENABLE_TEXT
return JNI_FALSE;
#else
if (schema == NULL) {
return JNI_FALSE;
}
const int j_schema_size = env->GetArrayLength(schema);
if (j_schema_size == 0) {
return JNI_FALSE;
}
if (cxx_context == 0) {
return JNI_FALSE;
}
auto c_model_ptr = reinterpret_cast<text::UIEModel *>(cxx_context);
std::vector<text::SchemaNode> c_schema;
for (int i = 0; i < j_schema_size; ++i) {
jobject curr_j_schema_node = env->GetObjectArrayElement(schema, i);
text::SchemaNode curr_c_schema_node;
if (fni::AllocateUIECxxSchemaNodeFromJava(
env, curr_j_schema_node, reinterpret_cast<void *>(
&curr_c_schema_node))) {
c_schema.push_back(curr_c_schema_node);
}
env->DeleteLocalRef(curr_j_schema_node);
}
if (c_schema.empty()) {
LOGE("c_schema is empty!");
return JNI_FALSE;
}
c_model_ptr->SetSchema(c_schema);
return JNI_TRUE;
#endif
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastdeploy_jni/text/uie/uie_utils_jni.h" // NOLINT
namespace fastdeploy {
namespace jni {
#ifdef ENABLE_TEXT
std::string UIEResultStr(const text::UIEResult& result) {
std::ostringstream oss;
oss << result;
return oss.str();
}
std::string UIEResultsStr(
const std::vector<std::unordered_map<
std::string, std::vector<text::UIEResult>>>& results) {
std::ostringstream oss;
oss << results;
return oss.str();
}
std::string UIETextsStr(const std::vector<std::string>& texts) {
std::string str = "";
for (const auto& s: texts) {
str += (s + ";");
}
return str;
}
std::string UIESchemasStr(const std::vector<std::string>& schemas) {
std::string str = "";
for (const auto& s: schemas) {
str += (s + ";");
}
return str;
}
#endif
} // namespace jni
} // namespace fastdeploy

View File

@@ -0,0 +1,39 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <jni.h> // NOLINT
#include "fastdeploy/core/config.h" // NOLINT
#ifdef ENABLE_TEXT
#include "fastdeploy/text.h" // NOLINT
#endif
namespace fastdeploy {
namespace jni {
#ifdef ENABLE_TEXT
std::string UIEResultStr(const text::UIEResult& result);
std::string UIEResultsStr(
const std::vector<std::unordered_map<
std::string, std::vector<text::UIEResult>>>& results);
std::string UIETextsStr(const std::vector<std::string>& texts);
std::string UIESchemasStr(const std::vector<std::string>& schemas);
#endif
} // namespace jni
} // namespace fastdeploy

View File

@@ -0,0 +1,64 @@
package com.baidu.paddle.fastdeploy.text;
import android.support.annotation.NonNull;
import java.util.HashMap;
import java.util.Map;
public class UIEResult {
public long mStart;
public long mEnd;
public double mProbability;
public String mText;
public HashMap<String, UIEResult[]> mRelation;
public boolean mInitialized = false;
public UIEResult() {
mInitialized = false;
}
public static String printResult(@NonNull UIEResult result, int tabSize) {
final int TAB_OFFSET = 4;
StringBuilder os = new StringBuilder();
StringBuilder tabStr = new StringBuilder();
for (int i = 0; i < tabSize; ++i) {
tabStr.append(" ");
}
os.append(tabStr).append("text: ").append(result.mText).append("\n");
os.append(tabStr).append("probability: ").append(result.mProbability).append("\n");
if (result.mStart != 0 || result.mEnd != 0) {
os.append(tabStr).append("start: ").append(result.mStart).append("\n");
os.append(tabStr).append("end: ").append(result.mEnd).append("\n");
}
if (result.mRelation == null) {
os.append("\n");
return os.toString();
}
if (result.mRelation.size() > 0) {
os.append(tabStr).append("relation:\n");
for (Map.Entry<String, UIEResult[]> currRelation : result.mRelation.entrySet()) {
os.append(" ").append(currRelation.getKey()).append(":\n");
for (UIEResult uieResult : currRelation.getValue()) {
os.append(printResult(uieResult, tabSize + 2 * TAB_OFFSET));
}
}
}
os.append("\n");
return os.toString();
}
public static String printResult(@NonNull HashMap<String, UIEResult[]>[] results) {
StringBuilder os = new StringBuilder();
os.append("The result:\n");
for (HashMap<String, UIEResult[]> result : results) {
for (Map.Entry<String, UIEResult[]> currResult : result.entrySet()) {
os.append(currResult.getKey()).append(": \n");
for (UIEResult uie_result : currResult.getValue()) {
os.append(printResult(uie_result, 4));
}
}
os.append("\n");
}
return os.toString();
}
}

View File

@@ -0,0 +1,6 @@
package com.baidu.paddle.fastdeploy.text.uie;
public enum SchemaLanguage {
ZH, // Chinese
EN // English
}

View File

@@ -0,0 +1,55 @@
package com.baidu.paddle.fastdeploy.text.uie;
import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.Arrays;
public class SchemaNode {
// Relation Extraction in native: Pass 'SchemaNode[] schema' from Java
// SchemaNode c_node_0; // From Java schema[0] Java SchemaNode via BFS
// SchemaNode c_node_1; // From Java schema[1] Java SchemaNode via BFS
// predictor.SetSchema({c_node_0, c_node_1});
// predictor.Predict({"xxx"}, &results);
public String mName;
public ArrayList<SchemaNode> mChildren = new ArrayList<SchemaNode>();
public SchemaNode() {
}
public SchemaNode(String name) {
mName = name;
}
public SchemaNode(String name, SchemaNode[] children) {
mName = name;
mChildren.addAll(Arrays.asList(children));
}
public SchemaNode(String name, ArrayList<SchemaNode> children) {
mName = name;
mChildren.addAll(children);
}
public void addChild(String schema) {
mChildren.add(new SchemaNode(schema));
}
public void addChild(SchemaNode schema) {
mChildren.add(schema);
}
public void addChild(String schema, @NonNull String[] children) {
SchemaNode schemaNode = new SchemaNode(schema);
for (String child : children) {
schemaNode.mChildren.add(new SchemaNode(child));
}
mChildren.add(schemaNode);
}
public void addChild(String schema, ArrayList<SchemaNode> children) {
SchemaNode schemaNode = new SchemaNode(schema);
schemaNode.mChildren = children;
mChildren.add(schemaNode);
}
}

View File

@@ -0,0 +1,173 @@
package com.baidu.paddle.fastdeploy.text.uie;
import android.util.Log;
import com.baidu.paddle.fastdeploy.FastDeployInitializer;
import com.baidu.paddle.fastdeploy.RuntimeOption;
import com.baidu.paddle.fastdeploy.text.UIEResult;
import java.util.HashMap;
public class UIEModel {
protected long mCxxContext = 0; // Context from native.
protected boolean mInitialized = false;
public UIEModel() {
mInitialized = false;
}
// Constructor with default runtime option
public UIEModel(String modelFile,
String paramsFile,
String vocabFile,
String[] schema) {
init_(modelFile, paramsFile, vocabFile, 0.5f, 128,
schema, new RuntimeOption(), SchemaLanguage.ZH);
}
// Constructor with custom runtime option
public UIEModel(String modelFile,
String paramsFile,
String vocabFile,
float positionProb,
int maxLength,
String[] schema,
RuntimeOption runtimeOption,
SchemaLanguage schemaLanguage) {
init_(modelFile, paramsFile, vocabFile, positionProb, maxLength,
schema, runtimeOption, schemaLanguage);
}
// Call init manually with label file
public boolean init(String modelFile,
String paramsFile,
String vocabFile,
String[] schema) {
return init_(modelFile, paramsFile, vocabFile, 0.5f, 128,
schema, new RuntimeOption(), SchemaLanguage.ZH);
}
public boolean init(String modelFile,
String paramsFile,
String vocabFile,
float positionProb,
int maxLength,
String[] schema,
RuntimeOption runtimeOption,
SchemaLanguage schemaLanguage) {
return init_(modelFile, paramsFile, vocabFile, positionProb, maxLength,
schema, runtimeOption, schemaLanguage);
}
public boolean release() {
mInitialized = false;
if (mCxxContext == 0) {
return false;
}
return releaseNative(mCxxContext);
}
public boolean initialized() {
return mInitialized;
}
// Set schema for Named Entity Recognition
public boolean setSchema(String[] schema) {
if (schema == null || schema.length == 0
|| mCxxContext == 0) {
return false;
}
return setSchemaStringNative(mCxxContext, schema);
}
// Set schema for Cross task extraction
public boolean setSchema(SchemaNode[] schema) {
if (schema == null || schema.length == 0
|| mCxxContext == 0) {
return false;
}
return setSchemaNodeNative(mCxxContext, schema);
}
// Fetch text information (will call predict from native)
public HashMap<String, UIEResult[]>[] predict(String[] texts) {
if (mCxxContext == 0) {
return null;
}
return predictNative(mCxxContext, texts);
}
private boolean init_(String modelFile,
String paramsFile,
String vocabFile,
float positionProb,
int maxLength,
String[] schema,
RuntimeOption runtimeOption,
SchemaLanguage schemaLanguage) {
if (!mInitialized) {
mCxxContext = bindNative(
modelFile,
paramsFile,
vocabFile,
positionProb,
maxLength,
schema,
runtimeOption,
schemaLanguage.ordinal()
);
if (mCxxContext != 0) {
mInitialized = true;
}
return mInitialized;
} else {
// release current native context and bind a new one.
if (release()) {
mCxxContext = bindNative(
modelFile,
paramsFile,
vocabFile,
positionProb,
maxLength,
schema,
runtimeOption,
schemaLanguage.ordinal()
);
if (mCxxContext != 0) {
mInitialized = true;
}
return mInitialized;
}
return false;
}
}
// Bind predictor from native context.
private native long bindNative(String modelFile,
String paramsFile,
String vocabFile,
float positionProb,
int maxLength,
String[] schema,
RuntimeOption runtimeOption,
int schemaLanguage);
// Call prediction from native context.
private native HashMap<String, UIEResult[]>[] predictNative(long CxxContext,
String[] texts);
// Release buffers allocated in native context.
private native boolean releaseNative(long CxxContext);
// Set schema from native for different tasks.
private native boolean setSchemaStringNative(long CxxContext,
String[] schema);
private native boolean setSchemaNodeNative(long CxxContext,
SchemaNode[] schema);
// Initializes at the beginning.
static {
FastDeployInitializer.init();
}
}