高通AI应用快速上手:基于Transformers的智能问答

文章介绍

       智能问答是自然语言处理(NLP) 中很重要的一个领域,此应用的功能是在段落或文章中找到所需的答案。本文主要介绍一个基于高通Snapdragon Neural Processing Engine SDK和ICLR 2020 Electra Transformer模型的智能问答Android应用程序该应用的所有源代码都可以在https://github.com/quic/qidk/tree/master/Solutions/NLPSolution1-QuestionAnswering 上获得。

       使用模型为Electra-small:https://huggingface.co/mrm8488/electra-small-finetuned-squadv2,是一款小型、高效、方便的Transformer模型,在SQUAD v2.0数据集上进行了微调,用于智能问答。我们将展示如何在Snapdragon 8 Gen 2的手机上高效转换、部署和加速Electra-small模型,来执行设备上的智能问答应用。

前置条件

  • 高通Snapdragon 安卓手机,推荐Snapdragon 8 Gen 2系列手机
  • PC上下载并设置好Qualcomm Neural Processing SDK

相关步骤参考https://developer.qualcomm.com/sites/default/files/docs/snpe/setup.html

  • Android Studio导入示例项目
  • Android NDK “r19c”或“r21e”在Android Studio中构建本地代码
  • 一台Linux机器
  • Python 3.6、PyTorch 1.10.1、Tensorflow 2.6.2、Transformers 4.18.0、Datasets  2.4.0,用于准备和验证模型

(上面提到的Python软件包版本和Android Studio版本只是一个建议,不是硬性要求。请在Python 3.6虚拟环境中安装SDK依赖项,在本教程的开发过程中,AI SDK推荐Python 3.6版本,可能会随着未来SDK版本的变化而变化。请参阅SDK发行说明。)

操作步骤

1. 生成模型
1.1) 生成Electra-small作为Tensorflow Frozen Graph

python scripts/qa_model_gen.py

1.2) 设置Qualcomm® Neural Processing SDK环境

source /bin/envsetup.sh -t $TENSORFLOW_DIR

1.3) 将生成的frozen graph转换为DLCDeep Learning Container

snpe-tensorflow-to-dlc -i frozen_models/electra_small_squad2.pb -d input_ids 1,384 -d attention_mask 1,384 -d token_type_ids 1,384 --out_node Identity --out_node Identity_1 -o frozen_models/electra_small_squad2.dlc  

其中“input_ids,attention\ymask,token_type_ids”是模型的输入,“Identity,Identity_1”是其输出。

该命令将Tensorflow frozen graph转换为DLC格式,DSP、GPU和CPU的加速器可以理解该格式以推理运行。DLC将保存在“frozen_models”目录中,名称为electra_small_squad2.DLC。

(如果您使用不同的Tensorflow版本来生成PB文件,则可能是输出层名称发生了更改。请使用Netron查看器或任何其他可视化工具通过可视化图形进行一次检查)

1.4) DLC的本地资源缓存(用于优化DSP加速器上的模型加载时间)

snpe-dlc-graph-prepare --input_dlc frozen_models/electra_small_squad2.dlc --use_float_io --htp_archs v73 --set_output_tensors Identity:0,Identity_1:0

生成的DLC将保存在frozen_models目录中,名称为electra_small_squad2_cached.DLC。

如果您想跳过以下可选的第2节和第3节的性能评测,那么,可以跳到第4节。直接使用Android Studio构建并运行

2. 模型和DLC验证
2.1) 创建validation_set目录并执行以下脚本

mkdir -p validation_set

cd validation_set/

python ../scripts/generate_representative_dataset_squadv2.py mrm8488/electra-small-finetuned-squadv2 50 384

该脚本使用Golden Answers从SQUAD-v2验证数据集中保存50个样本,其中每个输入的序列长度为384。

如果您在终端上遇到 “UnicodeEncodeError”提示

import sys, io

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

然后在python脚本中添加/取消注释上面的代码段。

python ../scripts/gen_raw_list.py 50

该脚本生成两个文本文件tf_raw_list.txt和snpe_raw_list.txt,其中包含输入文件的位置,这将有助于运行推理。

2.2) 验证生成的Electra-small TF Frozen graph

python ../scripts/batch_tf_inf.py ../frozen_models/electra_small_squad2.pb tf_raw_list.txt input_ids:0,attention_mask:0,token_type_ids:0 Identity:0,Identity_1:0

此脚本在“electra_small_squad2.pb”上运行推理,并将结果存储在tf_out目录中。请仅从validation_set目录运行此推理脚本,因为tf_raw_list.txt包含相对路径。

python ../scripts/logits_to_F1_score.py --model_name mrm8488/electra-small-finetuned-squadv2 --sequence_len 384 --logits_dir tf_out --golden_answers_dir golden_answers --top_k 1

此脚本评估模型输出并生成F1和EM(Exact Match score)。输出如下:

Metrics report

===============================================================

exact = 68.0

f1 = 71.33333333333334

total = 50

HasAns_exact = 71.42857142857143

HasAns_f1 = 77.38095238095238

HasAns_total = 28

NoAns_exact = 63.63636363636363

NoAns_f1 = 63.63636363636363

NoAns_total = 22

best_exact = 68.0

best_exact_thresh = 0.0

best_f1 = 71.33333333333333

best_f1_thresh = 0.0

NOTE:这是使用“generate_erepresentative _dataset_squadv2.py”脚本生成的SQUAD-V2数据集的50个样本的结果

2.3) 验证在DSP运行时生成的Electra-small DLC

python $SNPE_ROOT/benchmarks/snpe_bench.py -c dsp_accuracy_test.json -t android-aarch64 -p burst -z

该命令将在连接的设备上推送DLC、SDK assets和Input artifacts,并在DSP运行时自动运行推理。

adb pull /data/local/tmp/8550snpeQA/dOut/output snpe_dsp_out

此命令将提取snpe_dsp_out目录中的所有推理输出。

tree snpe_dsp_out

The directory structure will be like :
snpe_dsp_out/Result_0/Identity:0.raw
snpe_dsp_out/Result_0/Identity_1:0.raw
snpe_dsp_out/Result_1/Identity:0.raw
snpe_dsp_out/Result_1/Identity_1:0.raw
...

python ../scripts/logits_to_F1_score.py --model_name mrm8488/electra-small-finetuned-squadv2 --sequence_len 384 --logits_dir snpe_dsp_out --golden_answers_dir golden_answers --top_k 1

此脚本评估模型输出并生成F1和EM(Exact Match)分数。输出将与上面提到的TF Frozen graph相同:

Metrics report

===============================================================

exact = 68.0

f1 = 71.33333333333334

total = 50

3. OnDevice性能评测

python $SNPE_ROOT/benchmarks/snpe_bench.py -c ondevice_perf_test.json -t android-aarch64 -p burst -z

该命令将在连接的设备上推送DLC、SDK assets和Input artifacts,并在DSP、GPU_FP16和CPU运行时自动运行推理。

完成后,基准测试结果将存储在:dOut/results/latest_results/beachmark_stats_dOut.csv请参阅csv文件中的“总推断时间”字段,该字段显示模型执行时间(以微秒(us)为单位)

性能结果(越低越好):

DSP_FP16

GPU_FP16

CPU_FP32

Inference time (ms)

99.302 ms

574.111 ms

885.543 ms

注意:性能可能会根据SDK版本和device meta build而变化。

4. 编译生成APK
4.1) 将AI SDK库和生成的DLC添加到app assetsjniLibscmakeLibs目录中

确保已设置SNPE_ROOT env变量

./scripts/fetch_snpe_assets.sh

4.2) 使用Android Studio中打开QuestionAnswering目录并build project

在打开项目时,Android Studio可能会要求您下载构建AI SDK C++Native API所需的Android NDK。成功完成项目同步和构建过程后,按播放图标在连接的设备上安装并运行应用程序。

如果构建过程因libSNPE.so而失败,则出现重复错误,请将其路径从“jniLibs”更改为“cmakeLibs”,如下所示:在QuestionAnswering/bert/src/main/cpp/CMakeList.txt中的target_link_libraries开启${CMAKE_CURRENT_SOURCE_DIR}//cmakeLibs/arm64-v8a/libSNPE.so,并注释“jniLibs”目录中的libSNPE.so。

4.3) 手动安装APK

如果Android Studio无法检测到设备,或者设备位于远程位置并将APK复制到当前目录:

cp ./QuestionAnswering/app/build/outputs/apk/debug/app-debug.apk ./qa-app.apk

adb install -r -t qa-app.apk

4.4) 调试提示

安装应用程序后,如果crash,请尝试从QIDK设备收集日志。

要收集日志,请运行以下命令。

  • adb logcat-c
  • adb logcat>log.txt
  • 运行应用程序。一旦应用程序崩溃,请按Ctrl+C来日志收集。
  • log.txt将在当前文件夹中生成。
  • 搜索关键字“crash”来分析错误。

打开应用程序时,如果未检测到未签名或已签名的DSP运行时,请使用关键字 DSP搜索logcat日志以查找FastRPC错误。由于某些Android版本中的SE Linux安全策略,可能无法检测到DSP运行时。请尝试以下命令来设置允许的SE Linux策略。

  • adb disable-verity
  • adb reboot
  • adb root
  • adb remount
  • adb shell setenforce 0
  • // launch the application

4.5) QA应用程序工作流程

以下是基本的Android智能问答应用程序操作。

  • 从应用程序主页屏幕上的文章列表中选择任何文章
  • 论文章选择实例化SDK网络
  • 从下拉菜单中选择所需的运行时(例如,DSP、GPU、CPU)
  • 提问并准备模型的输入数据(input_ids、attention\ymask、token_type_ids)
  • 执行SDK Network

演示视频和性能细节如下所示:

作者:戴忠忠 (Zhongzhong Dai),高通工程师

你可能感兴趣的:(QIDK,AI,NLP,Qualcomm,AI,QIDK,NLP,Question,Answering)