[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

@@ -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/keypointdetection/pptinypose_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

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();
}
}