├── .gitattributes ├── AUTHORS ├── Android ├── README.md └── testlac │ ├── .project │ ├── app │ ├── .gitignore │ ├── .project │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── testlac │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ │ └── lac_model │ │ │ │ ├── model.nb │ │ │ │ ├── q2b.dic │ │ │ │ ├── tag.dic │ │ │ │ └── word.dic │ │ ├── cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── lac.cpp │ │ │ ├── lac.h │ │ │ ├── lac_util.cpp │ │ │ ├── lac_util.h │ │ │ ├── native_lib.cpp │ │ │ └── paddle │ │ │ │ └── include │ │ │ │ ├── paddle_api.h │ │ │ │ ├── paddle_image_preprocess.h │ │ │ │ ├── paddle_lite_factory_helper.h │ │ │ │ ├── paddle_place.h │ │ │ │ ├── paddle_use_kernels.h │ │ │ │ ├── paddle_use_ops.h │ │ │ │ └── paddle_use_passes.h │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── testlac │ │ │ │ └── MainActivity.java │ │ ├── jniLibs │ │ │ ├── arm64-v8a │ │ │ │ └── libpaddle_lite_jni.so │ │ │ └── armeabi-v7a │ │ │ │ └── libpaddle_light_api_shared.so │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ └── ic_launcher_background.xml │ │ │ ├── layout │ │ │ └── activity_main.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── testlac │ │ └── ExampleUnitTest.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ ├── local.properties │ ├── settings.gradle │ └── testlac.iml ├── CMakeLists.txt ├── Changelog ├── LICENSE ├── README.md ├── c++ ├── README.md ├── include │ ├── ahocorasick.h │ ├── lac.h │ ├── lac_custom.h │ └── lac_util.h ├── lac_demo.cpp ├── lac_multi.cpp └── src │ ├── ahocorasick.cpp │ ├── lac.cpp │ ├── lac_custom.cpp │ └── lac_util.cpp ├── compile4windows.md ├── image ├── cmake_install.png ├── modify_cmakelists.png ├── open_lac.png ├── run_cmake.png └── run_lacjava.png ├── java ├── LacDemo.java ├── LacMulti.java ├── README.md ├── com │ └── baidu │ │ └── nlp │ │ └── LAC.java └── cpp │ ├── lac_jni.cpp │ └── lac_jni.h ├── python ├── LAC │ ├── __init__.py │ ├── _compat.py │ ├── ahocorasick.py │ ├── cmdline.py │ ├── custom.py │ ├── lac.py │ ├── models.py │ ├── nets.py │ ├── prefix_tree.py │ ├── reader.py │ ├── segment.py │ ├── tests │ │ ├── __init__.py │ │ └── lac_test.py │ └── utils.py ├── README.md ├── setup.cfg └── setup.py └── technical-report └── report.pdf /.gitattributes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/lac/3e10dbed9bfd87bea927c84a6627a167c17b5617/.gitattributes -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Contributors should be added to this file in the following format: 2 | # Name or Organization 3 | 4 | Baidu.com, Inc. 5 | 6 | # Initial version authors: 7 | Sun Shuqi 8 | Sun Huifeng 9 | Jiao Zhenyu 10 | Yang Yu 11 | 12 | # Partial list of contributors: 13 | Huang Dingbang 14 | -------------------------------------------------------------------------------- /Android/README.md: -------------------------------------------------------------------------------- 1 | ## LAC的Android调用 2 | 3 | Android的调用中,我们采用[NDK](https://developer.android.google.cn/ndk/)调用[C++的接口](../c++/README.md)的代码。NDK的使用可以参照[NDK官网](https://developer.android.google.cn/ndk/)或其他博客的教程,这里我们主要展示如何将我们的LAC模型集成到Android应用中 4 | 5 | ### 示例运行 6 | 7 | #### 1. 直接安装运行 8 | 9 | - 我们编译了一个**APK安装包**`lac_demo.apk`,可在[release界面](https://github.com/baidu/lac/releases/)下载文件、安装到Android手机中进行测试,目前该demo仅集成了armeabi-v7a或arm64-v8a的库。 10 | 11 | #### 2. 编译APK文件 12 | 13 | - 下载代码后,可直接使用Android Studio打开[testlac](./testlac)这个文件夹的项目,编译运行该项目即可直接生成一个Android手机的apk文件(支持armeabi-v7a或arm64-v8a)。 14 | - 项目依赖于[NDK](https://developer.android.google.cn/ndk/)和[CMake](https://developer.android.google.cn/ndk/guides/cmake)进行编译,如果编译过程中提示NDK配置有误,可参照此处进行安装配置: 15 | - **安装**:依次打开Tools>SDK Manager>SDK Tools,勾选LLDB、CMake和NDK进行下载 16 | - **配置**:打开File > Project Structure > SDK Location,选择默认NDK的路径 17 | 18 | ### 模型集成过程 19 | 20 | LAC模型是使用Paddle训练所得的模型,若要在移动端的调用自己训练的Paddle模型,需要进行以下两项工作 21 | 22 | - 集成依赖库[PaddleLite](https://paddle-lite.readthedocs.io/zh/latest/index.html),该库Paddle为移动端调用模型所定制的轻量库,并集成模型压缩和优化等相关功能 23 | - 为了适配移动端设备,还需要使用PaddleLite的工具对模型进行优化 24 | 25 | #### 1. 依赖库准备 26 | 27 | `testlac`项目仅支持armeabi-v7a和arm64-v8a是因为在该项目中仅集成了armeabi-v7a和arm64-v8a的PaddleLite依赖库,即testlac项目中jniLibs中的文件。如需更多平台依赖库的支持,需要集成对应的libs文件: 28 | 29 | - 直接下载:https://paddle-lite.readthedocs.io/zh/latest/user_guides/release_lib.html 30 | - 自行编译:https://paddle-lite.readthedocs.io/zh/latest/user_guides/source_compile.html 31 | 32 | 下载或编译完成后,参照示例将其放于testlac项目的jniLibs文件夹,同时修改build.gradle中ndk的abiFilters选项,即可完成其他框架的支持。 33 | 34 | > 注:PaddleLite预测库的Libs链接需要在CMakeLists.txt文件中声明,如需在自己项目中进行集成,可参考testlac项目中CMakeLists.txt文件的写法。 35 | 36 | 37 | #### 2. 模型优化 38 | 39 | 为了适配于移动端设备,我们需要通过PaddleLite的工具对模型进行优化。具体模型优化可以参考PaddleLite官网的介绍:[模型优化工具 opt](https://paddle-lite.readthedocs.io/zh/latest/user_guides/model_optimize_tool.html),在此我们给出一个简单的使用示例: 40 | 41 | - 到[官网](https://paddle-lite.readthedocs.io/zh/latest/user_guides/model_optimize_tool.html)中下载优化工具opt 42 | - 执行下列命令生成优化后的模型 43 | 44 | ```sh 45 | # valid_targets可选(arm|opencl|x86|npu|xpu) 46 | ./opt --model_dir=./lac_model/model \ 47 | --valid_targets=arm \ 48 | --optimize_out_type=naive_buffer \ 49 | --optimize_out=lac_model_opt 50 | ``` 51 | 52 | > 经过转换后的模型,对应于testlac项目assets目录下的lac_model/model.nb文件。 53 | 54 | - 我们在[release界面](https://github.com/baidu/lac/releases/)提供了经过优化转换的LAC模型`models_android.zip`,以供大家下载使用,解压后其中包含三个不同的模型: 55 | - `seg_model`:仅实现分词的模型,体积小 56 | - `lac_model`:实现分词、词性标注、实体识别于一体的词法分析模型 57 | - `laclite_model`:`lac_model`的轻量化版本,效果会稍差于`lac_model` 58 | 59 | #### 3. 其他 60 | 61 | - 目前PaddleLite已支持直接使用Java接口调用模型,而不用通过jni的形式调用c++接口,具体可参照官网提供的[Android Demo](https://paddle-lite.readthedocs.io/zh/latest/demo_guides/android_app_demo.html)进行修改 62 | - PaddleLite官网也提供了[iOS Demo](https://paddle-lite.readthedocs.io/zh/latest/demo_guides/ios_app_demo.html),有需要的同学可参照[iOS Demo](https://paddle-lite.readthedocs.io/zh/latest/demo_guides/ios_app_demo.html)实现在iOS上的应用 -------------------------------------------------------------------------------- /Android/testlac/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | testlac 4 | Project testlac created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Android/testlac/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Android/testlac/app/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | app 4 | Project app created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | -------------------------------------------------------------------------------- /Android/testlac/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.example.testlac" 9 | minSdkVersion 23 10 | targetSdkVersion 29 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | 16 | externalNativeBuild { 17 | cmake { 18 | cppFlags "" 19 | arguments "-DANDROID_STL=c++_shared" 20 | } 21 | } 22 | ndk { 23 | abiFilters "armeabi-v7a", "arm64-v8a" 24 | } 25 | } 26 | 27 | buildTypes { 28 | release { 29 | minifyEnabled false 30 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 31 | } 32 | } 33 | 34 | externalNativeBuild { 35 | cmake { 36 | path "src/main/cpp/CMakeLists.txt" 37 | version "3.10.2" 38 | } 39 | } 40 | } 41 | 42 | dependencies { 43 | implementation fileTree(dir: 'libs', include: ['*.jar']) 44 | 45 | implementation 'androidx.appcompat:appcompat:1.0.2' 46 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 47 | testImplementation 'junit:junit:4.12' 48 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 49 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 50 | } 51 | -------------------------------------------------------------------------------- /Android/testlac/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /Android/testlac/app/src/androidTest/java/com/example/testlac/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.testlac; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.example.testlac", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/assets/lac_model/model.nb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/lac/3e10dbed9bfd87bea927c84a6627a167c17b5617/Android/testlac/app/src/main/assets/lac_model/model.nb -------------------------------------------------------------------------------- /Android/testlac/app/src/main/assets/lac_model/tag.dic: -------------------------------------------------------------------------------- 1 | 0 a-B 2 | 1 a-I 3 | 2 ad-B 4 | 3 ad-I 5 | 4 an-B 6 | 5 an-I 7 | 6 c-B 8 | 7 c-I 9 | 8 d-B 10 | 9 d-I 11 | 10 f-B 12 | 11 f-I 13 | 12 m-B 14 | 13 m-I 15 | 14 n-B 16 | 15 n-I 17 | 16 nr-B 18 | 17 nr-I 19 | 18 ns-B 20 | 19 ns-I 21 | 20 nt-B 22 | 21 nt-I 23 | 22 nw-B 24 | 23 nw-I 25 | 24 nz-B 26 | 25 nz-I 27 | 26 p-B 28 | 27 p-I 29 | 28 q-B 30 | 29 q-I 31 | 30 r-B 32 | 31 r-I 33 | 32 s-B 34 | 33 s-I 35 | 34 t-B 36 | 35 t-I 37 | 36 u-B 38 | 37 u-I 39 | 38 v-B 40 | 39 v-I 41 | 40 vd-B 42 | 41 vd-I 43 | 42 vn-B 44 | 43 vn-I 45 | 44 w-B 46 | 45 w-I 47 | 46 xc-B 48 | 47 xc-I 49 | 16 PER-B 50 | 17 PER-I 51 | 18 LOC-B 52 | 19 LOC-I 53 | 20 ORG-B 54 | 21 ORG-I 55 | 34 TIME-B 56 | 35 TIME-I 57 | 48 O 58 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.4.1) 7 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/paddle/include) 8 | 9 | # Creates and names a library, sets it as either STATIC 10 | # or SHARED, and provides the relative paths to its source code. 11 | # You can define multiple libraries, and CMake builds them for you. 12 | # Gradle automatically packages shared libraries with your APK. 13 | set(CMAKE_CXX_FLAGS 14 | "${CMAKE_CXX_FLAGS} -ffast-math -Ofast -Os -DNDEBUG -fno-exceptions -fomit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables" 15 | ) 16 | set(CMAKE_CXX_FLAGS 17 | "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden -fdata-sections -ffunction-sections" 18 | ) 19 | set(CMAKE_SHARED_LINKER_FLAGS 20 | "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections -Wl,-z,nocopyreloc") 21 | 22 | add_library( # Sets the name of the library. 23 | native_lib 24 | # Sets the library as a shared library. 25 | SHARED 26 | # Provides a relative path to your source file(s). 27 | native_lib.cpp 28 | lac.h 29 | lac.cpp 30 | lac_util.h 31 | lac_util.cpp 32 | ) 33 | 34 | find_library( # Sets the name of the path variable. 35 | log-lib 36 | # Specifies the name of the NDK library that 37 | # you want CMake to locate. 38 | log) 39 | 40 | # add paddle library 41 | add_library( 42 | paddle_lite_jni 43 | SHARED 44 | IMPORTED 45 | ) 46 | 47 | if(${ANDROID_ABI} STREQUAL "armeabi-v7a") 48 | set_target_properties( 49 | paddle_lite_jni 50 | PROPERTIES IMPORTED_LOCATION 51 | ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libpaddle_light_api_shared.so) 52 | else() 53 | set_target_properties( 54 | paddle_lite_jni 55 | PROPERTIES IMPORTED_LOCATION 56 | ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libpaddle_lite_jni.so) 57 | 58 | endif() 59 | 60 | target_link_libraries( # Specifies the target library. 61 | native_lib 62 | paddle_lite_jni 63 | # Links the target library to the log library 64 | # included in the NDK. 65 | ${log-lib}) -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/lac.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include "lac.h" 19 | #include "lac_util.h" 20 | #include "paddle_api.h" 21 | 22 | /* LAC构造函数:初始化、装载模型和词典 */ 23 | LAC::LAC(std::string model_dict_path, int threads, CODE_TYPE type) 24 | : _codetype(type), 25 | _lod(std::vector >(1)), 26 | _word2id_dict(new std::unordered_map), 27 | _q2b_dict(new std::unordered_map), 28 | _id2label_dict(new std::unordered_map) 29 | { 30 | /* 装载词典 */ 31 | std::string word_dict_path = model_dict_path + "/word.dic"; 32 | load_word2id_dict(word_dict_path, *_word2id_dict); 33 | std::string q2b_dict_path = model_dict_path + "/q2b.dic"; 34 | load_q2b_dict(q2b_dict_path, *_q2b_dict); 35 | std::string label_dict_path = model_dict_path + "/tag.dic"; 36 | load_id2label_dict(label_dict_path, *_id2label_dict); 37 | std::cout << "read word dict succeed" << std::endl; 38 | 39 | paddle::lite_api::MobileConfig config; 40 | config.set_threads(threads); // 自行设置多线程 41 | 42 | /* 装载模型 */ 43 | config.set_model_from_file(model_dict_path + "/model.nb"); 44 | this->_predictor = paddle::lite_api::CreatePaddlePredictor(config); 45 | 46 | std::cout << "load model succeed" << std::endl; 47 | 48 | /* 初始化输入输出变量 */ 49 | this->_input_tensor = this->_predictor->GetInput(0); 50 | this->_output_tensor = this->_predictor->GetOutput(0); 51 | this->_oov_id = this->_word2id_dict->size() - 1; 52 | auto word_iter = this->_word2id_dict->find("OOV"); 53 | if (word_iter != this->_word2id_dict->end()) 54 | { 55 | this->_oov_id = word_iter->second; 56 | } 57 | 58 | std::cout << "init succeed" << std::endl; 59 | } 60 | 61 | 62 | int LAC::feed_data(const std::vector &querys) 63 | { 64 | this->_seq_words_batch.clear(); 65 | this->_lod[0].clear(); 66 | 67 | this->_lod[0].push_back(0); 68 | long shape = 0; 69 | for (size_t i = 0; i < querys.size(); ++i) 70 | { 71 | split_words(querys[i], this->_codetype, this->_seq_words); 72 | this->_seq_words_batch.push_back(this->_seq_words); 73 | shape += this->_seq_words.size(); 74 | this->_lod[0].push_back(shape); 75 | } 76 | this->_input_tensor->Resize({shape, 1}); 77 | this->_input_tensor->SetLoD(this->_lod); 78 | 79 | int64_t *input_d = this->_input_tensor->mutable_data(); 80 | int index = 0; 81 | for (size_t i = 0; i < this->_seq_words_batch.size(); ++i) 82 | { 83 | for (size_t j = 0; j < this->_seq_words_batch[i].size(); ++j) 84 | { 85 | /* normalization */ 86 | std::string word = this->_seq_words_batch[i][j]; 87 | auto q2b_iter = this->_q2b_dict->find(word); 88 | if (q2b_iter != this->_q2b_dict->end()) 89 | { 90 | word = q2b_iter->second; 91 | } 92 | 93 | /* get word_id */ 94 | int64_t word_id = this->_oov_id; // OOV word 95 | auto word_iter = this->_word2id_dict->find(word); 96 | if (word_iter != this->_word2id_dict->end()) 97 | { 98 | word_id = word_iter->second; 99 | } 100 | input_d[index++] = word_id; 101 | } 102 | } 103 | return 0; 104 | } 105 | 106 | /* 对输出的标签进行解码转换为模型输出格式 */ 107 | int LAC::parse_targets( 108 | const std::vector &tags, 109 | const std::vector &words, 110 | std::vector &result) 111 | { 112 | result.clear(); 113 | for (size_t i = 0; i < tags.size(); ++i) 114 | { 115 | /* 若新词,则push_back一个新词,否则append到上一个词中 */ 116 | if (result.empty() || tags[i].rfind("B") == tags[i].length() - 1 || tags[i].rfind("S") == tags[i].length() - 1) 117 | { 118 | OutputItem output_item; 119 | output_item.word = words[i]; 120 | output_item.tag = tags[i].substr(0, tags[i].length() - 2); 121 | result.push_back(output_item); 122 | } 123 | else 124 | { 125 | result[result.size() - 1].word += words[i]; 126 | } 127 | } 128 | return 0; 129 | } 130 | 131 | std::vector LAC::lexer(const std::string &query) 132 | { 133 | 134 | std::vector query_vector = std::vector({query}); 135 | 136 | auto result = lexer(query_vector); 137 | return result[0]; 138 | } 139 | 140 | std::vector> LAC::lexer(const std::vector &querys) 141 | { 142 | 143 | this->feed_data(querys); 144 | this->_predictor->Run(); 145 | 146 | /* 对模型输出进行解码 */ 147 | int output_size = 0; 148 | const int64_t *output_d = this->_output_tensor->data(); 149 | this->_labels.clear(); 150 | this->_results_batch.clear(); 151 | for (size_t i = 0; i < this->_lod[0].size() - 1; ++i) 152 | { 153 | for (size_t j = 0; j < _lod[0][i + 1] - _lod[0][i]; ++j) 154 | { 155 | 156 | int64_t cur_label_id = output_d[_lod[0][i] + j]; 157 | auto it = this->_id2label_dict->find(cur_label_id); 158 | this->_labels.push_back(it->second); 159 | } 160 | parse_targets(this->_labels, this->_seq_words_batch[i], this->_results); 161 | this->_labels.clear(); 162 | 163 | _results_batch.push_back(this->_results); 164 | } 165 | 166 | return this->_results_batch; 167 | } 168 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/lac.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. */ 14 | 15 | #ifndef BAIDU_LAC_LAC_H 16 | #define BAIDU_LAC_LAC_H 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "paddle_api.h" 22 | 23 | /* 编码设置 */ 24 | enum CODE_TYPE 25 | { 26 | CODE_GB18030 = 0, 27 | CODE_UTF8 = 1, 28 | }; 29 | 30 | /* 模型输出的结构 */ 31 | struct OutputItem 32 | { 33 | std::string word; // 分词结果 34 | std::string tag; // 单词类型 35 | }; 36 | 37 | #endif 38 | 39 | #ifndef LAC_CLASS 40 | #define LAC_CLASS 41 | class LAC 42 | { 43 | private: 44 | CODE_TYPE _codetype; 45 | 46 | /* 中间变量 */ 47 | std::vector _seq_words; 48 | std::vector> _seq_words_batch; 49 | std::vector> _lod; 50 | std::vector _labels; 51 | std::vector _results; 52 | std::vector> _results_batch; 53 | 54 | /* 数据转换词典 */ 55 | std::shared_ptr> _id2label_dict; 56 | std::shared_ptr> _q2b_dict; 57 | std::shared_ptr> _word2id_dict; 58 | int64_t _oov_id; 59 | 60 | /* paddle数据结构*/ 61 | std::shared_ptr _predictor; // 62 | std::unique_ptr _input_tensor; // 63 | std::unique_ptr _output_tensor; // 64 | 65 | private: 66 | /* 将字符串输入转为Tensor */ 67 | int feed_data(const std::vector &querys); 68 | 69 | /* 将模型标签结果转换为模型输出格式 */ 70 | int parse_targets( 71 | const std::vector &tag_ids, 72 | const std::vector &words, 73 | std::vector &result); 74 | 75 | public: 76 | /* 初始化:装载模型和词典 */ 77 | explicit LAC(std::string model_dict_path, int threads = 1, CODE_TYPE type = CODE_UTF8); 78 | /* 更新为单个字典文件, 去除protobuf依赖删除 */ 79 | // explicit LAC(std::string model_dict_path, int threads = 1, CODE_TYPE type = CODE_UTF8); 80 | 81 | 82 | /* 调用程序 */ 83 | std::vector lexer(const std::string &query); // 单个query 84 | std::vector> lexer(const std::vector &query); // batch 85 | }; 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/lac_util.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. */ 14 | 15 | #include "lac_util.h" 16 | 17 | // 以pattern作为切割符,对line进行切分并放入tokens中 18 | RVAL split_tokens(const std::string &line, const std::string &pattern, 19 | std::vector &tokens) 20 | { 21 | if ("" == line || "" == pattern) 22 | { 23 | return _FAILD; 24 | } 25 | 26 | tokens.clear(); 27 | int pos = 0; 28 | int size = line.size(); 29 | 30 | for (int i = 0; i < size; i++) 31 | { 32 | pos = line.find(pattern, i); 33 | 34 | if (-1 != pos) 35 | { 36 | tokens.push_back(line.substr(i, pos - i)); 37 | i = pos + pattern.size() - 1; 38 | } 39 | else 40 | { 41 | tokens.push_back(line.substr(i)); 42 | break; 43 | } 44 | } // end of for 45 | return _SUCCESS; 46 | } 47 | 48 | // 装载字符转为数字index的词典 49 | RVAL load_word2id_dict(const std::string &filepath, 50 | std::unordered_map &kv_dict) 51 | { 52 | kv_dict.clear(); 53 | std::ifstream infile(filepath); 54 | if (infile.fail()) 55 | { 56 | return _FAILD; 57 | } 58 | 59 | std::string line = ""; 60 | std::vector tokens; 61 | while (std::getline(infile, line) && infile.good()) 62 | { 63 | split_tokens(line, "\t", tokens); 64 | if ("" == line || 2 != tokens.size()) 65 | { 66 | continue; 67 | } 68 | int64_t val = std::stoll(tokens[0]); 69 | std::string key = tokens[1]; 70 | kv_dict[key] = val; 71 | } 72 | infile.close(); 73 | return _SUCCESS; 74 | } 75 | 76 | // 装载字符正则化的词典 77 | RVAL load_q2b_dict(const std::string &filepath, 78 | std::unordered_map &kv_dict) 79 | { 80 | kv_dict.clear(); 81 | std::ifstream infile(filepath); 82 | if (infile.fail()) 83 | { 84 | return _FAILD; 85 | } 86 | 87 | std::string line = ""; 88 | std::vector tokens; 89 | while (std::getline(infile, line) && infile.good()) 90 | { 91 | split_tokens(line, "\t", tokens); 92 | if ("" == line || 2 != tokens.size()) 93 | { 94 | continue; 95 | } 96 | kv_dict[tokens[0]] = tokens[1]; 97 | } 98 | infile.close(); 99 | return _SUCCESS; 100 | } 101 | 102 | // 装载label解码用的词典 103 | RVAL load_id2label_dict(const std::string &filepath, 104 | std::unordered_map &kv_dict) 105 | { 106 | kv_dict.clear(); 107 | std::ifstream infile(filepath); 108 | if (infile.fail()) 109 | { 110 | return _FAILD; 111 | } 112 | 113 | std::string line = ""; 114 | std::vector tokens; 115 | while (std::getline(infile, line) && infile.good()) 116 | { 117 | split_tokens(line, "\t", tokens); 118 | if ("" == line || 2 != tokens.size()) 119 | { 120 | continue; 121 | } 122 | int64_t key = std::stoll(tokens[0]); 123 | std::string val = tokens[1]; 124 | kv_dict[key] = val; 125 | } 126 | infile.close(); 127 | return _SUCCESS; 128 | } 129 | 130 | // 获取下一个gb18030字符的长度 131 | int get_next_gb18030(const char *str) 132 | { 133 | unsigned char *str_in = (unsigned char *)str; 134 | if (str_in[0] < 0x80) 135 | { 136 | return 1; 137 | } 138 | if (str_in[0] >= 0x81 && str_in[0] <= 0xfe && 139 | str_in[1] >= 0x40 && str_in[1] <= 0xFE && str_in[1] != 0x7F) 140 | { 141 | return 2; 142 | } 143 | if (str_in[0] >= 0x81 && str_in[0] <= 0xfe && 144 | str_in[1] >= 0x30 && str_in[1] <= 0x39 && 145 | str_in[2] >= 0x81 && str_in[2] <= 0xfe && 146 | str_in[3] >= 0x30 && str_in[3] <= 0x39) 147 | { 148 | return 4; 149 | } 150 | return 0; 151 | } 152 | 153 | // 获取下一个UTF8字符的长度 154 | int get_next_utf8(const char *str) 155 | { 156 | unsigned char *str_in = (unsigned char *)str; 157 | if (str_in[0] < 0x80) 158 | { 159 | return 1; 160 | } 161 | if (str_in[0] >= 0xC2 && str_in[0] < 0xE0 && 162 | str_in[1] >> 6 == 2) 163 | { 164 | return 2; 165 | } 166 | if (str_in[0] >> 4 == 14 && str_in[1] >> 6 == 2 && 167 | str_in[2] >> 6 == 2 && (str_in[0] > 0xE0 || str_in[1] >= 0xA0)) 168 | { 169 | return 3; 170 | } 171 | if (str_in[0] >> 3 == 30 && str_in[1] >> 6 == 2 && str_in[2] >> 6 == 2 && 172 | str_in[3] >> 6 == 2 && str_in[0] <= 0xF4 && (str_in[0] > 0xF0 || str_in[1] >= 0x90)) 173 | { 174 | return 4; 175 | } 176 | return 0; 177 | } 178 | 179 | // 获取下一个codetype字符的长度 180 | int get_next_word(const char *str, CODE_TYPE codetype) 181 | { 182 | int len = 0; 183 | switch (codetype) 184 | { 185 | case CODE_GB18030: 186 | len = get_next_gb18030(str); 187 | break; 188 | case CODE_UTF8: 189 | len = get_next_utf8(str); 190 | break; 191 | default: 192 | len = 0; 193 | break; 194 | } 195 | len = len == 0 ? 1 : len; 196 | return len; 197 | } 198 | 199 | // 将字符串按照单字切分 200 | RVAL split_words(const char *input, int len, CODE_TYPE codetype, std::vector &words) 201 | { 202 | words.clear(); 203 | char *p = (char *)input; 204 | int temp_len = 0; 205 | std::string key; 206 | for (int i = 0; i < len; i += temp_len) 207 | { 208 | temp_len = get_next_word(p, codetype); 209 | key.assign(p, temp_len); 210 | words.push_back(key); 211 | p += temp_len; 212 | } 213 | return _SUCCESS; 214 | } 215 | 216 | // 将字符串按照单字切分 217 | RVAL split_words(const std::string &input, CODE_TYPE codetype, std::vector &words) 218 | { 219 | const char *p = input.c_str(); 220 | int len = input.length(); 221 | return split_words(p, len, codetype, words); 222 | } 223 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/lac_util.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Baidu, Inc. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. */ 14 | 15 | #ifndef BAIDU_LAC_LAC_UTIL_H 16 | #define BAIDU_LAC_LAC_UTIL_H 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "lac.h" 24 | /* 函数返回值 */ 25 | enum RVAL 26 | { 27 | _SUCCESS = 0, 28 | _FAILD = -1, 29 | }; 30 | 31 | // 以pattern作为切割符,对line进行切分并放入tokens中 32 | RVAL split_tokens(const std::string &line, const std::string &pattern, 33 | std::vector &tokens); 34 | 35 | // 装载字符串输入转为数字的词典 36 | RVAL load_word2id_dict(const std::string &filepath, 37 | std::unordered_map &kv_dict); 38 | 39 | // 装载字符正则化的词典 40 | RVAL load_q2b_dict(const std::string &filepath, 41 | std::unordered_map &kv_dict); 42 | 43 | // 装载label解码用的词典 44 | RVAL load_id2label_dict(const std::string &filepath, 45 | std::unordered_map &kv_dict); 46 | 47 | // 获取下一个字的长度 48 | int get_next_gb18030(const char *str); 49 | int get_next_utf8(const char *str); 50 | int get_next_word(const char *str, CODE_TYPE codetype); 51 | 52 | // 将字符串按照单字切分 53 | RVAL split_words(const char *input, int len, CODE_TYPE codetype, std::vector &words); 54 | RVAL split_words(const std::string &input, CODE_TYPE codetype, std::vector &words); 55 | 56 | #endif 57 | 58 | 59 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/native_lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "lac.h" 9 | #define LOGI(...) \ 10 | ((void)__android_log_print(ANDROID_LOG_INFO, "lac_demo::", __VA_ARGS__)) 11 | 12 | std::unique_ptr uPtr_Lac; 13 | 14 | extern "C" 15 | JNIEXPORT void JNICALL 16 | Java_com_example_testlac_MainActivity_initLac(JNIEnv *env, jobject thiz, jstring model_path) { 17 | std::unique_ptr lac(new LAC(env->GetStringUTFChars(model_path, 0), 1)); 18 | uPtr_Lac = std::move(lac); 19 | } 20 | 21 | 22 | /* 23 | Java_com_example_testlac_MainActivity_initLac(JNIEnv *env, jobject thiz, jbyteArray buffer, jint length) { 24 | 25 | jbyte * lac_dict = new jbyte[length]; 26 | env->GetByteArrayRegion(buffer, 0, length, lac_dict); 27 | std::unique_ptr lac(new LAC((void*) lac_dict, length, 1)); 28 | uPtr_Lac = std::move(lac); 29 | } */ 30 | 31 | extern "C" 32 | JNIEXPORT void JNICALL 33 | Java_com_example_testlac_MainActivity_releaseLac(JNIEnv *env, jobject thiz) { 34 | uPtr_Lac.release(); 35 | } 36 | 37 | extern "C" JNIEXPORT jstring JNICALL 38 | Java_com_example_testlac_MainActivity_stringFromJNI( 39 | JNIEnv *env, 40 | jobject /* this */) { 41 | std::string hello = "测试分词from LAC"; 42 | return env->NewStringUTF(hello.c_str()); 43 | } 44 | extern "C" 45 | JNIEXPORT jstring JNICALL 46 | Java_com_example_testlac_MainActivity_stringCutFromJNI(JNIEnv *env, jobject thiz, 47 | jstring source_text) { 48 | const char *utf8 = env->GetStringUTFChars(source_text, NULL); 49 | std::string str_source_text = std::string(utf8); 50 | env->ReleaseStringUTFChars(source_text, utf8); 51 | 52 | 53 | auto result = uPtr_Lac->lexer(str_source_text); 54 | std::string output_str = ""; 55 | for (int i=0; iNewStringUTF(output_str.c_str()); 66 | } 67 | 68 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/paddle/include/paddle_image_preprocess.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include "lite/api/paddle_api.h" 21 | #include "lite/api/paddle_place.h" 22 | 23 | namespace paddle { 24 | namespace lite { 25 | namespace utils { 26 | namespace cv { 27 | typedef paddle::lite_api::Tensor Tensor; 28 | typedef paddle::lite_api::DataLayoutType LayoutType; 29 | // color enum 30 | enum ImageFormat { 31 | RGBA = 0, 32 | BGRA, 33 | RGB, 34 | BGR, 35 | GRAY, 36 | NV21 = 11, 37 | NV12, 38 | }; 39 | // flip enum 40 | enum FlipParam { 41 | XY = -1, // flip along the XY axis 42 | X = 0, // flip along the X axis 43 | Y // flip along the Y axis 44 | }; 45 | // transform param 46 | typedef struct { 47 | int ih; // input height 48 | int iw; // input width 49 | int oh; // outpu theight 50 | int ow; // output width 51 | FlipParam flip_param; // flip, support x, y, xy 52 | float rotate_param; // rotate, support 90, 180, 270 53 | } TransParam; 54 | 55 | class ImagePreprocess { 56 | public: 57 | /* 58 | * init 59 | * param srcFormat: input image color 60 | * param dstFormat: output image color 61 | * param param: input image parameter, egs: input size 62 | */ 63 | ImagePreprocess(ImageFormat srcFormat, 64 | ImageFormat dstFormat, 65 | TransParam param); 66 | 67 | /* 68 | * image color convert 69 | * support NV12/NV21_to_BGR(RGB), NV12/NV21_to_BGRA(RGBA), 70 | * BGR(RGB)and BGRA(RGBA) transform, 71 | * BGR(RGB)and RGB(BGR) transform, 72 | * BGR(RGB)and RGBA(BGRA) transform, 73 | * BGR(RGB) and GRAY transform, 74 | * BGRA(RGBA) and GRAY transform, 75 | * param src: input image data 76 | * param dst: output image data 77 | */ 78 | void imageConvert(const uint8_t* src, uint8_t* dst); 79 | /* 80 | * image color convert 81 | * support NV12/NV21_to_BGR(RGB), NV12/NV21_to_BGRA(RGBA), 82 | * BGR(RGB)and BGRA(RGBA) transform, 83 | * BGR(RGB)and RGB(BGR) transform, 84 | * BGR(RGB)and RGBA(BGRA) transform, 85 | * BGR(RGB)and GRAY transform, 86 | * BGRA(RGBA) and GRAY transform, 87 | * param src: input image data 88 | * param dst: output image data 89 | * param srcFormat: input image image format support: GRAY, NV12(NV21), 90 | * BGR(RGB) and BGRA(RGBA) 91 | * param dstFormat: output image image format, support GRAY, BGR(RGB) and 92 | * BGRA(RGBA) 93 | */ 94 | void imageConvert(const uint8_t* src, 95 | uint8_t* dst, 96 | ImageFormat srcFormat, 97 | ImageFormat dstFormat); 98 | /* 99 | * image resize, use bilinear method 100 | * support image format: 1-channel image (egs: GRAY, 2-channel image (egs: 101 | * NV12, NV21), 3-channel(egs: BGR), 4-channel(egs: BGRA) 102 | * param src: input image data 103 | * param dst: output image data 104 | */ 105 | void imageResize(const uint8_t* src, uint8_t* dst); 106 | /* 107 | image resize, use bilinear method 108 | * support image format: 1-channel image (egs: GRAY, 2-channel image (egs: 109 | NV12, NV21), 3-channel image(egs: BGR), 4-channel image(egs: BGRA) 110 | * param src: input image data 111 | * param dst: output image data 112 | * param srcw: input image width 113 | * param srch: input image height 114 | * param dstw: output image width 115 | * param dsth: output image height 116 | */ 117 | void imageResize(const uint8_t* src, 118 | uint8_t* dst, 119 | ImageFormat srcFormat, 120 | int srcw, 121 | int srch, 122 | int dstw, 123 | int dsth); 124 | 125 | /* 126 | * image Rotate 127 | * support 90, 180 and 270 Rotate process 128 | * color format support 1-channel image, 3-channel image and 4-channel image 129 | * param src: input image data 130 | * param dst: output image data 131 | */ 132 | void imageRotate(const uint8_t* src, uint8_t* dst); 133 | /* 134 | * image Rotate 135 | * support 90, 180 and 270 Rotate process 136 | * color format support 1-channel image, 3-channel image and 4-channel image 137 | * param src: input image data 138 | * param dst: output image data 139 | * param srcFormat: input image format, support GRAY, BGR(RGB) and BGRA(RGBA) 140 | * param srcw: input image width 141 | * param srch: input image height 142 | * param degree: Rotate degree, support 90, 180 and 270 143 | */ 144 | void imageRotate(const uint8_t* src, 145 | uint8_t* dst, 146 | ImageFormat srcFormat, 147 | int srcw, 148 | int srch, 149 | float degree); 150 | /* 151 | * image Flip 152 | * support X, Y and XY flip process 153 | * color format support 1-channel image, 3-channel image and 4-channel image 154 | * param src: input image data 155 | * param dst: output image data 156 | */ 157 | void imageFlip(const uint8_t* src, uint8_t* dst); 158 | /* 159 | * image Flip 160 | * support X, Y and XY flip process 161 | * color format support 1-channel image, 3-channel image and 4-channel image 162 | * param src: input image data 163 | * param dst: output image data 164 | * param srcFormat: input image format, support GRAY, BGR(RGB) and BGRA(RGBA) 165 | * param srcw: input image width 166 | * param srch: input image height 167 | * param flip_param: flip parameter, support X, Y and XY 168 | */ 169 | void imageFlip(const uint8_t* src, 170 | uint8_t* dst, 171 | ImageFormat srcFormat, 172 | int srcw, 173 | int srch, 174 | FlipParam flip_param); 175 | /* 176 | * change image data to tensor data 177 | * support image format is GRAY, BGR(RGB) and BGRA(RGBA), Data layout is NHWC 178 | * and 179 | * NCHW 180 | * param src: input image data 181 | * param dstTensor: output tensor data 182 | * param layout: output tensor layout,support NHWC and NCHW 183 | * param means: means of image 184 | * param scales: scales of image 185 | */ 186 | void image2Tensor(const uint8_t* src, 187 | Tensor* dstTensor, 188 | LayoutType layout, 189 | float* means, 190 | float* scales); 191 | /* 192 | * change image data to tensor data 193 | * support image format is GRAY, BGR(RGB) and BGRA(RGBA), Data layout is NHWC 194 | * and 195 | * NCHW 196 | * param src: input image data 197 | * param dstTensor: output tensor data 198 | * param srcFormat: input image format, support BGR(RGB) and BGRA(RGBA) 199 | * param srcw: input image width 200 | * param srch: input image height 201 | * param layout: output tensor layout,support NHWC and NCHW 202 | * param means: means of image 203 | * param scales: scales of image 204 | */ 205 | void image2Tensor(const uint8_t* src, 206 | Tensor* dstTensor, 207 | ImageFormat srcFormat, 208 | int srcw, 209 | int srch, 210 | LayoutType layout, 211 | float* means, 212 | float* scales); 213 | 214 | private: 215 | ImageFormat srcFormat_; 216 | ImageFormat dstFormat_; 217 | TransParam transParam_; 218 | }; 219 | } // namespace cv 220 | } // namespace utils 221 | } // namespace lite 222 | } // namespace paddle 223 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/paddle/include/paddle_lite_factory_helper.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /* 16 | * This file defines some MACROS that explicitly determine the op, kernel, mir 17 | * passes used in the inference lib. 18 | */ 19 | #pragma once 20 | 21 | // some platform-independent defintion 22 | #include "lite/utils/macros.h" 23 | 24 | #define USE_LITE_OP(op_type__) \ 25 | extern int touch_op_##op_type__(); \ 26 | int LITE_OP_REGISTER_FAKE(op_type__) UNUSED = touch_op_##op_type__(); 27 | 28 | #define USE_LITE_KERNEL(op_type__, target__, precision__, layout__, alias__) \ 29 | extern int touch_##op_type__##target__##precision__##layout__##alias__(); \ 30 | int op_type__##target__##precision__##layout__##alias__##__use_lite_kernel \ 31 | UNUSED = touch_##op_type__##target__##precision__##layout__##alias__(); 32 | 33 | #define USE_MIR_PASS(name__) \ 34 | extern bool mir_pass_registry##name__##_fake(); \ 35 | static bool mir_pass_usage##name__ UNUSED = \ 36 | mir_pass_registry##name__##_fake(); 37 | 38 | #define LITE_OP_REGISTER_FAKE(op_type__) op_type__##__registry__ 39 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/paddle/include/paddle_place.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include 17 | #include 18 | 19 | // Generic helper definitions for shared library support 20 | #if defined _WIN32 || defined __CYGWIN__ 21 | #define PADDLE_LITE_HELPER_DLL_IMPORT __declspec(dllimport) 22 | #define PADDLE_LITE_HELPER_DLL_EXPORT __declspec(dllexport) 23 | #define PADDLE_LITE_HELPER_DLL_LOCAL 24 | #else 25 | #if __GNUC__ >= 4 26 | #define PADDLE_LITE_HELPER_DLL_IMPORT __attribute__((visibility("default"))) 27 | #define PADDLE_LITE_HELPER_DLL_EXPORT __attribute__((visibility("default"))) 28 | #else 29 | #define PADDLE_LITE_HELPER_DLL_IMPORT 30 | #define PADDLE_LITE_HELPER_DLL_EXPORT 31 | #endif 32 | #endif 33 | 34 | #ifdef LITE_ON_TINY_PUBLISH 35 | #define LITE_API PADDLE_LITE_HELPER_DLL_EXPORT 36 | #define LITE_API_IMPORT PADDLE_LITE_HELPER_DLL_IMPORT 37 | #else 38 | #define LITE_API 39 | #define LITE_API_IMPORT 40 | #endif 41 | 42 | namespace paddle { 43 | namespace lite_api { 44 | 45 | enum class TargetType : int { 46 | kUnk = 0, 47 | kHost = 1, 48 | kX86 = 2, 49 | kCUDA = 3, 50 | kARM = 4, 51 | kOpenCL = 5, 52 | kAny = 6, // any target 53 | kFPGA = 7, 54 | kNPU = 8, 55 | kXPU = 9, 56 | kBM = 10, 57 | kMLU = 11, 58 | kRKNPU = 12, 59 | kAPU = 13, 60 | NUM = 14, // number of fields. 61 | }; 62 | enum class PrecisionType : int { 63 | kUnk = 0, 64 | kFloat = 1, 65 | kInt8 = 2, 66 | kInt32 = 3, 67 | kAny = 4, // any precision 68 | kFP16 = 5, 69 | kBool = 6, 70 | kInt64 = 7, 71 | kInt16 = 8, 72 | NUM = 9, // number of fields. 73 | }; 74 | enum class DataLayoutType : int { 75 | kUnk = 0, 76 | kNCHW = 1, 77 | kNHWC = 3, 78 | kImageDefault = 4, // for opencl image2d 79 | kImageFolder = 5, // for opencl image2d 80 | kImageNW = 6, // for opencl image2d 81 | kAny = 2, // any data layout 82 | NUM = 7, // number of fields. 83 | }; 84 | 85 | typedef enum { 86 | LITE_POWER_HIGH = 0, 87 | LITE_POWER_LOW = 1, 88 | LITE_POWER_FULL = 2, 89 | LITE_POWER_NO_BIND = 3, 90 | LITE_POWER_RAND_HIGH = 4, 91 | LITE_POWER_RAND_LOW = 5 92 | } PowerMode; 93 | 94 | typedef enum { MLU_220 = 0, MLU_270 = 1 } MLUCoreVersion; 95 | 96 | enum class ActivationType : int { 97 | kIndentity = 0, 98 | kRelu = 1, 99 | kRelu6 = 2, 100 | kPRelu = 3, 101 | kLeakyRelu = 4, 102 | kSigmoid = 5, 103 | kTanh = 6, 104 | kSwish = 7, 105 | kExp = 8, 106 | kAbs = 9, 107 | kHardSwish = 10, 108 | kReciprocal = 11, 109 | NUM = 12, 110 | }; 111 | 112 | static size_t PrecisionTypeLength(PrecisionType type) { 113 | switch (type) { 114 | case PrecisionType::kFloat: 115 | return 4; 116 | case PrecisionType::kInt8: 117 | return 1; 118 | case PrecisionType::kInt32: 119 | return 4; 120 | case PrecisionType::kInt64: 121 | return 8; 122 | case PrecisionType::kFP16: 123 | return 2; 124 | default: 125 | return 4; 126 | } 127 | } 128 | 129 | template 130 | struct PrecisionTypeTrait { 131 | constexpr static PrecisionType Type() { return PrecisionType::kUnk; } 132 | }; 133 | 134 | #define _ForEachPrecisionTypeHelper(callback, cpp_type, precision_type) \ 135 | callback(cpp_type, ::paddle::lite_api::PrecisionType::precision_type); 136 | 137 | #define _ForEachPrecisionType(callback) \ 138 | _ForEachPrecisionTypeHelper(callback, bool, kBool); \ 139 | _ForEachPrecisionTypeHelper(callback, float, kFloat); \ 140 | _ForEachPrecisionTypeHelper(callback, int8_t, kInt8); \ 141 | _ForEachPrecisionTypeHelper(callback, int16_t, kInt16); \ 142 | _ForEachPrecisionTypeHelper(callback, int, kInt32); \ 143 | _ForEachPrecisionTypeHelper(callback, int64_t, kInt64); 144 | 145 | #define DefinePrecisionTypeTrait(cpp_type, precision_type) \ 146 | template <> \ 147 | struct PrecisionTypeTrait { \ 148 | constexpr static PrecisionType Type() { return precision_type; } \ 149 | } 150 | 151 | _ForEachPrecisionType(DefinePrecisionTypeTrait); 152 | 153 | #undef _ForEachPrecisionTypeHelper 154 | #undef _ForEachPrecisionType 155 | #undef DefinePrecisionTypeTrait 156 | 157 | #define TARGET(item__) paddle::lite_api::TargetType::item__ 158 | #define PRECISION(item__) paddle::lite_api::PrecisionType::item__ 159 | #define DATALAYOUT(item__) paddle::lite_api::DataLayoutType::item__ 160 | 161 | const std::string& ActivationTypeToStr(ActivationType act); 162 | 163 | const std::string& TargetToStr(TargetType target); 164 | 165 | const std::string& PrecisionToStr(PrecisionType precision); 166 | 167 | const std::string& DataLayoutToStr(DataLayoutType layout); 168 | 169 | const std::string& TargetRepr(TargetType target); 170 | 171 | const std::string& PrecisionRepr(PrecisionType precision); 172 | 173 | const std::string& DataLayoutRepr(DataLayoutType layout); 174 | 175 | // Get a set of all the elements represented by the target. 176 | std::set ExpandValidTargets(TargetType target = TARGET(kAny)); 177 | 178 | // Get a set of all the elements represented by the precision. 179 | std::set ExpandValidPrecisions( 180 | PrecisionType precision = PRECISION(kAny)); 181 | 182 | // Get a set of all the elements represented by the layout. 183 | std::set ExpandValidLayouts( 184 | DataLayoutType layout = DATALAYOUT(kAny)); 185 | 186 | /* 187 | * Place specifies the execution context of a Kernel or input/output for a 188 | * kernel. It is used to make the analysis of the MIR more clear and accurate. 189 | */ 190 | struct LITE_API Place { 191 | TargetType target{TARGET(kUnk)}; 192 | PrecisionType precision{PRECISION(kUnk)}; 193 | DataLayoutType layout{DATALAYOUT(kUnk)}; 194 | int16_t device{0}; // device ID 195 | 196 | Place() = default; 197 | Place(TargetType target, 198 | PrecisionType precision = PRECISION(kFloat), 199 | DataLayoutType layout = DATALAYOUT(kNCHW), 200 | int16_t device = 0) 201 | : target(target), precision(precision), layout(layout), device(device) {} 202 | 203 | bool is_valid() const { 204 | return target != TARGET(kUnk) && precision != PRECISION(kUnk) && 205 | layout != DATALAYOUT(kUnk); 206 | } 207 | 208 | size_t hash() const; 209 | 210 | bool operator==(const Place& other) const { 211 | return target == other.target && precision == other.precision && 212 | layout == other.layout && device == other.device; 213 | } 214 | 215 | bool operator!=(const Place& other) const { return !(*this == other); } 216 | 217 | friend bool operator<(const Place& a, const Place& b); 218 | 219 | std::string DebugString() const; 220 | }; 221 | 222 | } // namespace lite_api 223 | } // namespace paddle 224 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/paddle/include/paddle_use_ops.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "paddle_lite_factory_helper.h" 3 | 4 | USE_LITE_OP(unsqueeze); 5 | USE_LITE_OP(unsqueeze2); 6 | USE_LITE_OP(softmax); 7 | USE_LITE_OP(search_group_padding); 8 | USE_LITE_OP(collect_fpn_proposals); 9 | USE_LITE_OP(beam_search); 10 | USE_LITE_OP(search_seq_softmax); 11 | USE_LITE_OP(mean); 12 | USE_LITE_OP(attention_padding_mask); 13 | USE_LITE_OP(search_attention_padding_mask); 14 | USE_LITE_OP(increment); 15 | USE_LITE_OP(search_seq_fc); 16 | USE_LITE_OP(scale); 17 | USE_LITE_OP(lookup_table_dequant); 18 | USE_LITE_OP(reduce_mean); 19 | USE_LITE_OP(write_to_array); 20 | USE_LITE_OP(match_matrix_tensor); 21 | USE_LITE_OP(sequence_reshape); 22 | USE_LITE_OP(im2sequence); 23 | USE_LITE_OP(sequence_arithmetic); 24 | USE_LITE_OP(search_seq_arithmetic); 25 | USE_LITE_OP(dropout); 26 | USE_LITE_OP(lrn); 27 | USE_LITE_OP(calib); 28 | USE_LITE_OP(search_grnn); 29 | USE_LITE_OP(cast); 30 | USE_LITE_OP(io_copy); 31 | USE_LITE_OP(reduce_prod); 32 | USE_LITE_OP(fc); 33 | USE_LITE_OP(power); 34 | USE_LITE_OP(sequence_softmax); 35 | USE_LITE_OP(assign); 36 | USE_LITE_OP(ctc_align); 37 | USE_LITE_OP(while); 38 | USE_LITE_OP(affine_channel); 39 | USE_LITE_OP(gru); 40 | USE_LITE_OP(__xpu__multi_encoder); 41 | USE_LITE_OP(uniform_random); 42 | USE_LITE_OP(yolo_box); 43 | USE_LITE_OP(stack); 44 | USE_LITE_OP(shape); 45 | USE_LITE_OP(anchor_generator); 46 | USE_LITE_OP(sequence_reverse); 47 | USE_LITE_OP(square); 48 | USE_LITE_OP(relu_clipped); 49 | USE_LITE_OP(swish); 50 | USE_LITE_OP(log); 51 | USE_LITE_OP(exp); 52 | USE_LITE_OP(abs); 53 | USE_LITE_OP(floor); 54 | USE_LITE_OP(hard_sigmoid); 55 | USE_LITE_OP(sqrt); 56 | USE_LITE_OP(rsqrt); 57 | USE_LITE_OP(softsign); 58 | USE_LITE_OP(gelu); 59 | USE_LITE_OP(hard_swish); 60 | USE_LITE_OP(reciprocal); 61 | USE_LITE_OP(var_conv_2d); 62 | USE_LITE_OP(generate_proposals); 63 | USE_LITE_OP(feed); 64 | USE_LITE_OP(mul); 65 | USE_LITE_OP(decode_bboxes); 66 | USE_LITE_OP(sequence_topk_avg_pooling); 67 | USE_LITE_OP(pad2d); 68 | USE_LITE_OP(layer_norm); 69 | USE_LITE_OP(sequence_pool_concat); 70 | USE_LITE_OP(multiclass_nms); 71 | USE_LITE_OP(multiclass_nms2); 72 | USE_LITE_OP(top_k); 73 | USE_LITE_OP(elementwise_sub); 74 | USE_LITE_OP(elementwise_add); 75 | USE_LITE_OP(elementwise_mul); 76 | USE_LITE_OP(elementwise_max); 77 | USE_LITE_OP(elementwise_div); 78 | USE_LITE_OP(batch_norm); 79 | USE_LITE_OP(flatten); 80 | USE_LITE_OP(flatten2); 81 | USE_LITE_OP(is_empty); 82 | USE_LITE_OP(nearest_interp); 83 | USE_LITE_OP(bilinear_interp); 84 | USE_LITE_OP(fetch); 85 | USE_LITE_OP(fake_quantize_moving_average_abs_max); 86 | USE_LITE_OP(sequence_expand_as); 87 | USE_LITE_OP(reshape); 88 | USE_LITE_OP(reshape2); 89 | USE_LITE_OP(matmul); 90 | USE_LITE_OP(fake_quantize_dequantize_moving_average_abs_max); 91 | USE_LITE_OP(assign_value); 92 | USE_LITE_OP(merge_lod_tensor); 93 | USE_LITE_OP(sequence_expand); 94 | USE_LITE_OP(density_prior_box); 95 | USE_LITE_OP(crop); 96 | USE_LITE_OP(grid_sampler); 97 | USE_LITE_OP(subgraph); 98 | USE_LITE_OP(fill_constant_batch_size_like); 99 | USE_LITE_OP(fake_dequantize_max_abs); 100 | USE_LITE_OP(sequence_concat); 101 | USE_LITE_OP(transpose); 102 | USE_LITE_OP(transpose2); 103 | USE_LITE_OP(search_fc); 104 | USE_LITE_OP(lookup_table_v2); 105 | USE_LITE_OP(box_coder); 106 | USE_LITE_OP(sequence_conv); 107 | USE_LITE_OP(equal); 108 | USE_LITE_OP(not_equal); 109 | USE_LITE_OP(less_than); 110 | USE_LITE_OP(less_equal); 111 | USE_LITE_OP(greater_than); 112 | USE_LITE_OP(greater_equal); 113 | USE_LITE_OP(fake_channel_wise_dequantize_max_abs); 114 | USE_LITE_OP(beam_search_decode); 115 | USE_LITE_OP(__xpu__resnet50); 116 | USE_LITE_OP(io_copy_once); 117 | USE_LITE_OP(layout); 118 | USE_LITE_OP(instance_norm); 119 | USE_LITE_OP(negative); 120 | USE_LITE_OP(lod_reset); 121 | USE_LITE_OP(norm); 122 | USE_LITE_OP(lstm); 123 | USE_LITE_OP(fake_quantize_range_abs_max); 124 | USE_LITE_OP(fake_quantize_abs_max); 125 | USE_LITE_OP(sigmoid); 126 | USE_LITE_OP(tanh); 127 | USE_LITE_OP(relu); 128 | USE_LITE_OP(leaky_relu); 129 | USE_LITE_OP(relu6); 130 | USE_LITE_OP(prelu); 131 | USE_LITE_OP(reduce_max); 132 | USE_LITE_OP(logical_xor); 133 | USE_LITE_OP(logical_and); 134 | USE_LITE_OP(logical_or); 135 | USE_LITE_OP(logical_not); 136 | USE_LITE_OP(distribute_fpn_proposals); 137 | USE_LITE_OP(split_lod_tensor); 138 | USE_LITE_OP(reduce_sum); 139 | USE_LITE_OP(sequence_unpad); 140 | USE_LITE_OP(shuffle_channel); 141 | USE_LITE_OP(read_from_array); 142 | USE_LITE_OP(search_aligned_mat_mul); 143 | USE_LITE_OP(arg_max); 144 | USE_LITE_OP(conv2d); 145 | USE_LITE_OP(depthwise_conv2d); 146 | USE_LITE_OP(gather); 147 | USE_LITE_OP(gru_unit); 148 | USE_LITE_OP(expand); 149 | USE_LITE_OP(fusion_elementwise_sub_activation); 150 | USE_LITE_OP(fusion_elementwise_add_activation); 151 | USE_LITE_OP(fusion_elementwise_mul_activation); 152 | USE_LITE_OP(fusion_elementwise_max_activation); 153 | USE_LITE_OP(fusion_elementwise_div_activation); 154 | USE_LITE_OP(prior_box); 155 | USE_LITE_OP(split); 156 | USE_LITE_OP(lookup_table); 157 | USE_LITE_OP(conv2d_transpose); 158 | USE_LITE_OP(depthwise_conv2d_transpose); 159 | USE_LITE_OP(crf_decoding); 160 | USE_LITE_OP(roi_align); 161 | USE_LITE_OP(box_clip); 162 | USE_LITE_OP(calib_once); 163 | USE_LITE_OP(concat); 164 | USE_LITE_OP(pool2d); 165 | USE_LITE_OP(conditional_block); 166 | USE_LITE_OP(search_seq_depadding); 167 | USE_LITE_OP(range); 168 | USE_LITE_OP(squeeze); 169 | USE_LITE_OP(squeeze2); 170 | USE_LITE_OP(fill_constant); 171 | USE_LITE_OP(sequence_pool); 172 | USE_LITE_OP(axpy); 173 | USE_LITE_OP(slice); 174 | USE_LITE_OP(layout_once); -------------------------------------------------------------------------------- /Android/testlac/app/src/main/cpp/paddle/include/paddle_use_passes.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include "paddle_lite_factory_helper.h" // NOLINT 17 | 18 | USE_MIR_PASS(demo); 19 | USE_MIR_PASS(static_kernel_pick_pass); 20 | USE_MIR_PASS(variable_place_inference_pass); 21 | USE_MIR_PASS(type_target_cast_pass); 22 | USE_MIR_PASS(generate_program_pass); 23 | 24 | USE_MIR_PASS(io_copy_kernel_pick_pass); 25 | USE_MIR_PASS(argument_type_display_pass); 26 | USE_MIR_PASS(runtime_context_assign_pass); 27 | USE_MIR_PASS(graph_visualize_pass); 28 | 29 | USE_MIR_PASS(lite_conv_bn_fuse_pass); 30 | USE_MIR_PASS(lite_fc_fuse_pass); 31 | USE_MIR_PASS(lite_shuffle_channel_fuse_pass); 32 | USE_MIR_PASS(lite_transpose_softmax_transpose_fuse_pass); 33 | USE_MIR_PASS(lite_interpolate_fuse_pass); 34 | USE_MIR_PASS(lite_sequence_pool_concat_fuse_pass); 35 | USE_MIR_PASS(identity_scale_eliminate_pass); 36 | USE_MIR_PASS(lite_conv_elementwise_fuse_pass); 37 | USE_MIR_PASS(lite_conv_activation_fuse_pass); 38 | USE_MIR_PASS(lite_var_conv_2d_activation_fuse_pass); 39 | USE_MIR_PASS(lite_elementwise_add_activation_fuse_pass); 40 | USE_MIR_PASS(lite_quant_dequant_fuse_pass); 41 | USE_MIR_PASS(type_precision_cast_pass); 42 | USE_MIR_PASS(type_layout_cast_pass); 43 | USE_MIR_PASS(type_layout_cast_preprocess_pass); 44 | USE_MIR_PASS(memory_optimize_pass); 45 | USE_MIR_PASS(multi_stream_analysis_pass); 46 | USE_MIR_PASS(elementwise_mul_constant_eliminate_pass) 47 | USE_MIR_PASS(npu_subgraph_pass); 48 | USE_MIR_PASS(xpu_subgraph_pass); 49 | USE_MIR_PASS(mlu_subgraph_pass); 50 | USE_MIR_PASS(mlu_postprocess_pass); 51 | USE_MIR_PASS(weight_quantization_preprocess_pass); 52 | USE_MIR_PASS(apu_subgraph_pass); 53 | USE_MIR_PASS(quantized_op_attributes_inference_pass); 54 | USE_MIR_PASS(__xpu__resnet_fuse_pass); 55 | USE_MIR_PASS(__xpu__multi_encoder_fuse_pass); 56 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/java/com/example/testlac/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.testlac; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | import androidx.core.app.ActivityCompat; 6 | import androidx.core.content.ContextCompat; 7 | 8 | import android.Manifest; 9 | import android.app.AlertDialog; 10 | import android.content.Context; 11 | import android.content.DialogInterface; 12 | import android.content.pm.PackageManager; 13 | import android.content.res.Resources; 14 | import android.os.Bundle; 15 | import android.text.TextUtils; 16 | import android.view.View; 17 | import android.widget.Button; 18 | import android.widget.EditText; 19 | import android.widget.TextView; 20 | 21 | import java.io.BufferedOutputStream; 22 | import java.io.File; 23 | import java.io.FileOutputStream; 24 | import java.io.IOException; 25 | import java.io.InputStream; 26 | import java.io.OutputStream; 27 | 28 | public class MainActivity extends AppCompatActivity { 29 | private TextView mCutResult; 30 | private EditText mInputText; 31 | private Button mButton; 32 | 33 | // Used to load the 'native-lib' library on application startup. 34 | static { 35 | System.loadLibrary("native_lib"); 36 | } 37 | 38 | @Override 39 | protected void onCreate(Bundle savedInstanceState) { 40 | super.onCreate(savedInstanceState); 41 | setContentView(R.layout.activity_main); 42 | mInputText = (EditText) findViewById(R.id.input_text); 43 | mCutResult = (TextView) findViewById(R.id.cut_result); 44 | mButton = (Button) findViewById((R.id.cut_button)); 45 | // Example of a call to a native method 46 | TextView tv = findViewById(R.id.sample_text); 47 | if (!checkAllPermissions()) { 48 | requestAllPermissions(); 49 | } 50 | tv.setText(stringFromJNI()); 51 | mButton.setOnClickListener(new View.OnClickListener() { 52 | @Override 53 | public void onClick(View v) { 54 | String inputText = mInputText.getText().toString(); 55 | if (!TextUtils.isEmpty(inputText)) { 56 | mCutResult.setText(stringCutFromJNI(inputText)); 57 | } else { 58 | mCutResult.setText(stringCutFromJNI("输入太短")); 59 | } 60 | } 61 | }); 62 | 63 | String model_path = copyFromAssetsToCache("lac_model", this); 64 | initLac(model_path); 65 | 66 | /* load model for protobuf file, need protobuf lib, abandon 67 | Resources res = getResources(); 68 | try { 69 | //获取文件的字节数 70 | InputStream lac_dict = res.openRawResource(R.raw.lac_dict_model); 71 | int length = lac_dict.available(); 72 | //创建byte数组 73 | byte[] buffer = new byte[length]; 74 | //将文件中的数据读到byte数组中 75 | lac_dict.read(buffer); 76 | // 初始化模型 77 | initLac(buffer, length); 78 | } catch (IOException e) { 79 | e.printStackTrace(); 80 | } 81 | */ 82 | 83 | } 84 | 85 | @Override 86 | protected void onDestroy() { 87 | releaseLac(); 88 | super.onDestroy(); 89 | } 90 | 91 | @Override 92 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 93 | @NonNull int[] grantResults) { 94 | super.onRequestPermissionsResult(requestCode, permissions, grantResults); 95 | if (grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) { 96 | new AlertDialog.Builder(MainActivity.this) 97 | .setTitle("Permission denied") 98 | .setMessage("Click to force quit the app, then open Settings->Apps & notifications->Target " + 99 | "App->Permissions to grant all of the permissions.") 100 | .setCancelable(false) 101 | .setPositiveButton("Exit", new DialogInterface.OnClickListener() { 102 | @Override 103 | public void onClick(DialogInterface dialog, int which) { 104 | MainActivity.this.finish(); 105 | } 106 | }).show(); 107 | } 108 | } 109 | 110 | public static String copyFromAssetsToCache(String modelPath, Context context) { 111 | String newPath = context.getCacheDir() + "/" + modelPath; 112 | // String newPath = "/sdcard/" + modelPath; 113 | File desDir = new File(newPath); 114 | 115 | try { 116 | if (!desDir.exists()) { 117 | desDir.mkdir(); 118 | } 119 | for (String fileName : context.getAssets().list(modelPath)) { 120 | InputStream stream = context.getAssets().open(modelPath + "/" + fileName); 121 | OutputStream output = new BufferedOutputStream(new FileOutputStream(newPath + "/" + fileName)); 122 | 123 | byte data[] = new byte[1024]; 124 | int count; 125 | 126 | while ((count = stream.read(data)) != -1) { 127 | output.write(data, 0, count); 128 | } 129 | 130 | output.flush(); 131 | output.close(); 132 | stream.close(); 133 | } 134 | 135 | } catch (Exception e) { 136 | throw new RuntimeException(e); 137 | } 138 | 139 | return desDir.getPath(); 140 | } 141 | 142 | private void requestAllPermissions() { 143 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, 144 | Manifest.permission.READ_EXTERNAL_STORAGE}, 0); 145 | } 146 | 147 | private boolean checkAllPermissions() { 148 | return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED 149 | && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; 150 | } 151 | 152 | /** 153 | * A native method that is implemented by the 'native-lib' native library, 154 | * which is packaged with this application. 155 | * 156 | */ 157 | // public native void initLac(byte[] lac_dict, int length); 158 | 159 | public native void initLac(String model_path); 160 | 161 | public native void releaseLac(); 162 | 163 | public native String stringFromJNI(); 164 | 165 | public native String stringCutFromJNI(String source_text); 166 | } 167 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/jniLibs/arm64-v8a/libpaddle_lite_jni.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/lac/3e10dbed9bfd87bea927c84a6627a167c17b5617/Android/testlac/app/src/main/jniLibs/arm64-v8a/libpaddle_lite_jni.so -------------------------------------------------------------------------------- /Android/testlac/app/src/main/jniLibs/armeabi-v7a/libpaddle_light_api_shared.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/lac/3e10dbed9bfd87bea927c84a6627a167c17b5617/Android/testlac/app/src/main/jniLibs/armeabi-v7a/libpaddle_light_api_shared.so -------------------------------------------------------------------------------- /Android/testlac/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /Android/testlac/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 18 | 19 | 27 | 28 | 35 |