PaddleSpeech的TTSAndroid编译armv7版本
2023-12-13 10:55:02
    		1.下载docker镜像
docker pull paddlepaddle/paddle-lite:2.0.0_beta
2.克隆代码
git clone https://github.com/PaddlePaddle/Paddle-Lite.git
3.运行容器
docker run -it --name paddlelite_docker  -v $PWD/Paddle-Lite:/Paddle-Lite  --net=host paddlepaddle/paddle-lite /bin/bash
4.编译opt工具
cd Paddle-Lite
./lite/tools/build.sh build_optimize_tool --with_extra=ON
5.下载模型
https://paddlespeech.bj.bcebos.com/Parakeet/released_models/fastspeech2/fastspeech2_cnndecoder_csmsc_static_1.0.0.zip
https://paddlespeech.bj.bcebos.com/Parakeet/released_models/mb_melgan/mb_melgan_csmsc_static_0.1.1.zip
mb_melgan_csmsc_static_0.1.1.zip
fastspeech2_cnndecoder_csmsc_static_1.0.0.zip
6.模型转换
cd /Paddle-Lite/build.opt/lite/api
./opt --model_file=/Paddle-Lite/models/fastspeech2_cnndecoder_csmsc_static_1.0.0/fastspeech2_csmsc.pdmodel --param_file=/Paddle-Lite/models/fastspeech2_cnndecoder_csmsc_static_1.0.0/fastspeech2_csmsc.pdiparams --valid_targets=arm --optimize_out_type=naive_buffer --optimize_out=/Paddle-Lite/models/fastspeech2_csmsc_arm --quant_model=true --quant_type=QUANT_INT8 
./opt --model_file=/Paddle-Lite/models/mb_melgan_csmsc_static_0.1.1/mb_melgan_csmsc.pdmodel --param_file=/Paddle-Lite/models/mb_melgan_csmsc_static_0.1.1/mb_melgan_csmsc.pdiparams --valid_targets=arm --optimize_out_type=naive_buffer --optimize_out=/Paddle-Lite/models/mb_melgan_csmsc_arm --quant_model=true --quant_type=QUANT_INT8
7.编译预测动态库
a.修改代码Paddle-Lite/lite/kernels/arm/slice_compute.cc
inline std::vector<int64_t> get_new_data_from_tensorlist(
    const std::vector<lite::Tensor*>& list_new_data_tensor) {
  // get tensor
  std::vector<int64_t> vec_new_data;
  for (size_t i = 0; i < list_new_data_tensor.size(); ++i) {
    auto tensor = list_new_data_tensor[i];
    LOG(WARNING) <<" tensor dims is :"<<tensor->dims();
    // CHECK_EQ(tensor->dims(), DDim({1})) << "shape of dim tensor should be [1]";
    if (tensor->precision() == PrecisionType::kInt32) {
      vec_new_data.push_back(static_cast<int64_t>(*tensor->data<int32_t>()));
    } else if (tensor->precision() == PrecisionType::kInt64) {
      vec_new_data.push_back(static_cast<int64_t>(*tensor->data<int64_t>()));
    } else {
      vec_new_data.push_back(static_cast<int64_t>(*tensor->data<int32_t>()));
      LOG(WARNING) << "slice StartsTensor or EndsTensor :The dtype of Tensor "
                      "must be int32 "
                      "or int64";
    }
  }
  return vec_new_data;
}
b.修改Paddle-Lite/lite/api/android/jni/native/tensor_jni.h,新增声明
/*
 * Class:     com_baidu_paddle_lite_Tensor
 * Method:    nativeSetData
 * Signature: ([J)Z
 */
JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_lite_Tensor_nativeSetData___3J(
    JNIEnv *, jobject, jlongArray);
c.修改Paddle-Lite/lite/api/android/jni/native/tensor_jni.cc,新增实现
JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_lite_Tensor_nativeSetData___3J(
    JNIEnv *env, jobject jtensor, jlongArray buf) {
  std::unique_ptr<Tensor> *tensor = get_writable_tensor_pointer(env, jtensor);
  if (tensor == nullptr || (*tensor == nullptr)) {
    return JNI_FALSE;
  }
  int64_t buf_size = (int64_t)env->GetArrayLength(buf);
  if (buf_size != product((*tensor)->shape())) {
    return JNI_FALSE;
  }
  int64_t *input = (*tensor)->mutable_data<int64_t>();
  env->GetLongArrayRegion(buf, 0, buf_size, input);
  return JNI_TRUE;
}
d.编译脚本
./lite/tools/build_android.sh --arch=armv7 --toolchain=gcc --android_stl=c++_static --with_java=ON --with_extra=ON
e.编译产物
8.调整Android工程代码
a.修改D:\02Code\code\PaddleSpeech-r1.4.1\demos\TTSAndroid\app\build.gradle
import java.security.MessageDigest
apply plugin: 'com.android.application'
android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.baidu.paddle.lite.demo.tts"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters 'armeabi-v7a'//, 'arm64-v8a'
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation files('libs/PaddlePredictor.jar')
}
b.修改com/baidu/paddle/lite/demo/tts/Predictor.java及对应的调用地方,主要是数据类型由float改为long
public boolean runModel(long[] phones) {
	if (!isLoaded()) {
		return false;
	}
	Date start = new Date();
	Tensor am_output_handle = getAMOutput(phones, AMPredictor);
	wav = getVOCOutput(am_output_handle, VOCPredictor);
	Date end = new Date();
	inferenceTime = (end.getTime() - start.getTime());
	Log.d(TAG, "runModel: "+inferenceTime+"ms");
	return true;
}
public Tensor getAMOutput(long[] phones, PaddlePredictor am_predictor) {
        Tensor phones_handle = am_predictor.getInput(0);
        long[] dims = {phones.length};
        phones_handle.resize(dims);
        phones_handle.setData(phones);
        am_predictor.run();
        Tensor am_output_handle = am_predictor.getOutput(0);
        // [?, 80]
        // long outputShape[] = am_output_handle.shape();
        float[] am_output_data = am_output_handle.getFloatData();
        return am_output_handle;
    }
c.工程结构
 
 
ndk需要于docker镜像一致,采用17.2
 
d.编译产出
    			文章来源:https://blog.csdn.net/q317379184/article/details/134950807
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!