mirror of
https://github.com/PaddlePaddle/FastDeploy.git
synced 2025-10-05 16:48:03 +08:00
[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:
3
java/android/fastdeploy/libs/.gitignore
vendored
3
java/android/fastdeploy/libs/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
fastdeploy-*
|
||||
fastdeploy-*
|
||||
arm*
|
@@ -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
|
||||
|
@@ -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
|
@@ -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
|
@@ -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
|
||||
|
@@ -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
|
@@ -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
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
package com.baidu.paddle.fastdeploy.text.uie;
|
||||
|
||||
public enum SchemaLanguage {
|
||||
ZH, // Chinese
|
||||
EN // English
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user