算法部署知识点:TensorRT、Tensorflow、Flask、Docker、TFLite
- 前言
- TensorRT
- Tensorflow部署
- [Flask + Docker 简易部署](#Flask + Docker 简易部署)
-
-
- [Docker 封装 Flask 应用:](#Docker 封装 Flask 应用:)
-
- 基于tflite的Android部署
前言
- 由于本人水平有限,难免出现错漏,敬请批评改正。
- 更多精彩内容,可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏、人工智能混合编程实践专栏或我的个人主页查看
- YOLOs-CPP:一个免费开源的YOLO全系列C++推理库(以YOLO26为例)
- PaddleOCR:Win10上安装使用PPOCRLabel标注工具
- 目标检测:使用自己的数据集微调DEIMv2进行物体检测
- 图像分割:PyTorch从零开始实现SegFormer语义分割
- 图像超分:使用自己的数据集微调Real-ESRGAN-x4plus进行超分重建
- 图像生成:PyTorch从零开始实现一个简单的扩散模型
- Stable Diffusion:使用自己的数据集微调 Stable Diffusion 3.5 LoRA 文生图模型
- 图像超分:使用自己的数据集微调Real-ESRGAN-x2plus进行超分重建
- Anomalib:使用Anomalib 2.1.0训练自己的数据集进行异常检测
- Anomalib:在Linux服务器上安装使用Anomalib 2.1.0
- 人工智能混合编程实践:C++调用封装好的DLL进行异常检测推理
- 人工智能混合编程实践:C++调用封装好的DLL进行FP16图像超分重建(v3.0)
- 隔离系统Python:源码编译3.11.8到自定义目录(含PGO性能优化)
- 在线机的Python环境迁移到离线机上
- Nuitka 将 Python 脚本封装为 .pyd 或 .so 文件
- Ultralytics:使用 YOLO11 进行速度估计
- Ultralytics:使用 YOLO11 进行物体追踪
- Ultralytics:使用 YOLO11 进行物体计数
- Ultralytics:使用 YOLO11 进行目标打码
- 人工智能混合编程实践:C++调用Python ONNX进行YOLOv8推理
- 人工智能混合编程实践:C++调用封装好的DLL进行YOLOv8实例分割
- 人工智能混合编程实践:C++调用Python ONNX进行图像超分重建
- 人工智能混合编程实践:C++调用Python AgentOCR进行文本识别
- 通过计算实例简单地理解PatchCore异常检测
- Python将YOLO格式实例分割数据集转换为COCO格式实例分割数据集
- YOLOv8 Ultralytics:使用Ultralytics框架训练RT-DETR实时目标检测模型
- 基于DETR的人脸伪装检测
- YOLOv7训练自己的数据集(口罩检测)
- YOLOv8训练自己的数据集(足球检测)
- YOLOv5:TensorRT加速YOLOv5模型推理
- YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
- 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
- YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
- YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
- Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
- YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
- 使用Kaggle GPU资源免费体验Stable Diffusion开源项目
- Stable Diffusion:在服务器上部署使用Stable Diffusion WebUI进行AI绘图(v2.0)
- Stable Diffusion:使用自己的数据集微调训练LoRA模型(v2.0)
TensorRT
TensorRT定义
TensorRT是由Nvidia推出的一个高性能的深度学习推理(Inference)优化器和运行时引擎,它可以用于在生产环境中部署深度学习模型,实现高性能的推理任务。TensorRT支持多种深度学习框架,如TensorFlow、Caffe、PyTorch、MXNet等,并可以直接载入这些框架的已训练模型文件,也可以通过编程自行构建模型。
TensorRT的核心功能包括深度学习推理优化器和运行时引擎。推理优化器可以对输入的深度学习模型进行图层优化、张量融合、精度校准等操作,以生成最优化的推理引擎。而运行时引擎则负责在Nvidia的GPU或DLA上执行推理任务,以实现高性能的推理。
此外,TensorRT还支持多种神经网络层的定义,并提供了API接口,允许开发者自行实现特殊层的操作。这使得TensorRT可以更加灵活地应对各种深度学习模型。
总的来说,TensorRT是一个针对深度学习推理任务的高性能优化库,它可以帮助开发者在生产环境中更加高效地部署和运行深度学习模型。
TensorFlow: pb,ckpt
pytorch: pt,pth
keras: h5
显卡型号: tesla T4 | tesla V100
训练:V100、P40
推理:T4、P4
- T4
整数运算能力(INT8): 130 TOPS
GPU 显存: 16GB
显存带宽: 320GB/秒
定义:推理加速(基于CUDA和cudnn的进行高性能推理加速引擎);用于从ONNX或tensorflow导入现有模型解析器,是对训练好的模型进行优化。
当网络训练完后,可以将tf训练模型文件直接丢进tensorRT中,而不再需要依赖深度学习框架(Caffe,TensorFlow等)。
tensorRT通过 组合层 和优化内核选择来优化网络,从而改善延迟、吞吐量(样本量/秒)、功效和内存消耗。
理解:
tensorRT可以将TensorFlow/pytorch的网络模型解析,然后与其中对应的层进行一一映射,把其他框架的模型统一全部 转换到tensorRT中,然后在tensorRT中可以针对NVIDIA自家GPU实施优化策略,并进行部署加速。
TensorRT对于网络结构进行了重构和优化,主要体现在:
- tensorRT通过解析网络模型将网络中无用的输出层消除以减小计算。
- 对于网络结构的垂直整合,即将目前主流神经网络的conv、BN、Relu三个层融合为了一个层。
- 对于网络的水平组合,水平组合是指将输入为相同张量和执行相同操作的层融合一起。
- 对于concat层,将contact层的输入直接送入下面的操作中,不用单独进行concat后在输入计算,相当于减少了一次传输吞吐。
TensorRT原理
低精度推理
TensorRT支持FP16和INT8的计算,在训练的时候一般是使用32位或者16位数据,它在推理时可以降低模型参数的位宽来进行低精度推理,通过在减少计算量和保持精度之间达到一个理想的权衡,以达到加速推断的目的。模型在推理计算时,是调用GPU的CUDA核进行计算的。
P16主要是P100和V100这两张卡支持;INT8主要针对的是 P4和P40这两张卡,P4是专门针对线上做推断的小卡。
int8量化算法
目标:将fp32的CNN转换为int8而不会造成明显的精度损失;
原因:int8方法具有更高的吞吐量和更低的内存需求;
为什么要量化而不使用int8直接训练?
模型训练是需要反向传播和梯度下降的,训练时的超参一般都是浮点型,如学习率等,int8类型无法进行训练。
samples文件夹下有一个命令行包装工具,叫trtexec,用来评测我们的网络模型,它有以下两个功能:
- 在指定的网络模型中,对随机输入数据进行基准测试。eg:可利用trtexc工具来测试 UFF/ONNX net-model 在推理时的表现。
- 对指定网络模型产生序列化引擎:使用完全流水线异步方式从多个线程运行具有多个执行上下文的引擎,以测试并行推理性能。
bash
trtexec --deploy=/path/to/mnist.prototxt --model=/path/to/mnist.caffemodel --output=prob --batch=16 --saveEngine=mnist16.trt
定义: FP16(Full Precise Float 16): (比FP32)更省内存空间,更节约推理时间。
了解: Tesla系列工作站端显卡:p4, p6, p40, p100 --- 支持Pascal架构
do_Inference原理
host device的方式转化将数据传输到GPU,然后异步执行做推断,推断的结果从GPU拿到Host(即设备到主机),接着将流进行同步。多个input,output结点用do_inference_2方法。
执行: convert-to-uff ./models/lenet5.pb --> 可生成lenet.uff文件
tensorflow: NWHC | tensorrt:NCWH (channel first)
uff-parser 解析tensorflow模型
先build_engine,trt.UffParser() /caffe/ONNXparser;
再对图像进行处理,do_inference进行异步方式推断
测试: python3 sample.py -d /home/featurize/work/TensorRT-6.0.1.5/data (需要install pycuda)
序列化
序列化将引擎转换为一种格式,以便以后存储和使用以进行推理。要用于推理,只需反序列化引擎即可。
序列化和反序列化是可选的。由于从网络定义创建引擎可能非常耗时,因此每次应用程序重新运行时都可以通过序列化一次并在推理时对其进行反序列化来避免重建引擎。因此,在构建引擎之后,用户通常希望将其序列化以供以后使用。
可以序列化引擎,也可以直接使用引擎进行推理。在将模型用于推理之前,序列化和反序列化是一个可选步骤-如果需要,可以直接使用引擎对象进行推理。
序列化引擎不能跨平台或TensorRT版本移植。
序列化引擎步骤
将序列化引擎保存到文件中,并从文件中读回:
- 序列化引擎并写入文件:
python
with open("sample.engine", "wb") as f:
f.write(engine.serialize))
- 从文件读取引擎并反序列化:
python
with open("sample.engine","rb") as f,trt.Runtime(TRT_LOGGER) as runtime:
engine = runtime. deserialize_cuda_engine(f.read())
使用python接口导入tf模型
- 导入TensorRT :import tensorrt as trt
- 创建冻结的TensorFlow模型
- 使用UFF转换器将冻结的Tensorflow模型转换为UFF文件
$convert-to-uff frozen_inference_graph. pb - 定义路径。更改以下路径以反映Samples中包含的模型的位置
python
model_file = '/data/mnist/mnist.uff'
5.创建builder , network和parser:
python
with builder= trt. Builder(TRI_LOGGER) as builder,
builder.create_network() as network,trt UffParser O) as parser:
parser.register_input("Placeholder",(1,28,28))
parser.register_output("fc2/Relu")
parser.parse(model_file,network)
-
builder: 搜索其CUDA内核目录以获得最快的可用实现,因此必须使用相同的CPU来构建优化引擎将运行的GPU.
-
builder具有许多属性,可以设置这些属性以控制网络应运行的精度,以及目动调整参效。
-
两个重要的属性: 最大batch size和最大workspace size.
-
最大batch大小: 指定tensorRT将优化的批量大小。在运行时,可以选择较小的批量大小;
Linux下安装TensorRT
下载地址: https://developer.nvidia.com/zh-cn/tensorrt
TensorRT安装链接
在home下新建文件夹,命名为tensorrt_tar,然后将下载的压缩文件拷贝进来解压
bash
tar xzvf TensorRT-6.0.1.5.Ubuntu-16.04.4.x86_64-gnu.cuda-9.0.cudnn7.3.tar
解压得到TensorRT-6.0.1.5的文件夹,将里边的lib绝对路径添加到环境变量中
bash
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/featurize/work/TensorRT-6.0.1.5/lib
安装TensorRT
bash
cd TensorRT-6.0.1.5/python
pip3 install tensorrt-6.0.1.5-py2.py3-none-any.whl
安装UFF,支持tensorflow模型转化
bash
cd TensorRT-6.0.1.5/uff
pip3 install uff-0.5.5-py2.py3-none-any.whl
安装graphsurgeon,支持自定义结构
bash
cd TensorRT-6.0.1.5/graphsurgeon
pip install graphsurgeon-0.3.2-py2.py3-none-any.whl
libcudart.so.10.0: cannot open shared object file错误的解决方案都是查看CUDA的版本,
但是如果CUDA版本正确的时候还是报这个错误的话,可以通过输入一下指令解决。
bash
sudo ldconfig /usr/local/cuda-10.0/lib64
Tensorflow部署
简单描述:确定好输入和输出节点,把模型导出成SavedModel格式,然后用TF-Serving启动服务,调用方发http请求或者grpc请求就可以拿到预测结果了。
- 保存权重文件:
1.ModelCheckPoint
2.model.save_weights()
keras模型转化为SavedModel:
python
tf.saved_model.save(model,'/keras_save_graph')
- 查看模型文件命令:
bash
saved_model_cli show --dir ./keras_save_graph --all
- 签名信息:
bash
saved_model_cli show --dir ./keras_save_graph --tag-set serve --signature_def serving_default
- 检查保存模型是否正常工作:(输入2个样本,28x28)
bash
saved_model_cli run --dir ./keras_save_graph --tag-set serve --signature_def serving_default
--input_exprs 'flatten_input=np.ones((2,28,28))'
- 还可以用程序进行验证:
bash
loaded_saved_model = tf.saved_model.load('./keras_save_graph')
print(list(loaded_saved_model.signatures.keys())
inference = loaded_saved_model.signatures['serving_default']
使用SaveModel导出训练模型并添加签名
签名的好处
- 可以限定函数的输入类型,以防止调用函数时调错,
- 一个函数有了input_signature之后,在tensorflow里边才可以保存成savedmodel。在保存成savedmodel的过程中,需要使用get_concrete_function函数把一个tf.function标注的普通的python函数变成带有图定义的函数。
Flask + Docker 简易部署
- Saver端:模型的离线训练与导出
使用SavedModel,将训练好的模型导出为pb文件,检查保存的模型的SignatureDef、Inputs、Outputs等信息,命令(saved_model_cli) - tf.server进行模型加载与在线预测
基于Docker的方式搭建tf-server,拉取tf/serving的镜像,新建服务实例 - Client端 构建请求
Docker:容器,可以理解成一个"黑盒"。在项目变得庞大以后,往往我们会疲于管理整个项目的部署和维护。如果我们将整个项目用一个"容器"装起来,那么我们仅仅只用维护一个配置文件告诉计算机每次部署要把什么东西装进"容器",甚至借用一些工具把这个过程自动化,部署就会变得很方便。
部署环境:
Ubuntu18.04 显卡:Tesla的P40 搭建Docker
Docker 封装 Flask 应用:
- 创建一个 Dockerfile 文件,添加部署到服务器上的路径以及启动的
bash
python文件名和变量名。
FROM python:3.6
WORKDIR /Project/demo
COPY requirements.txt ./
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
CMD ["gunicorn", "start:app", "-c", "./gunicorn.conf.py"]
- 开始构建Docker镜像,登陆远程服务器终端,把镜像 pull 下来。
bash
sudo docker build -t 'testflask' sudo docker images
- 部署到服务器上
bash
sudo apt-get install docker.io
- 运行docker镜像:
bash
sudo docker run -d -p 80:80 --name test-flask-1 testflask
- 更新项目的时候,维护好配置文件,build一下,push 上去,在服务器 pull 下来,重新运行即可。
基于tflite的Android部署
tf.lite.TFLiteConverter.from_saved_model()(推荐):转换 SavedModel。
- build.gradle: 添加tf-lite-gpu
- model放在asset文件下,tf相关的文件放于tflite文件夹下
- 设置tfliteOption( nnapi、cpu、gpu ),构造函数(loadModelFile)掉用tfliteModel,初始化图像数据,分配内存;
- 做预测的构造函数recognizeImage,先把bitmap转化为byteBuffer;
- 接下来就是runInference操作(tflite.run()),得到所以的概率值。
- 由于本人水平有限,难免出现错漏,敬请批评改正。
- 更多精彩内容,可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏、人工智能混合编程实践专栏或我的个人主页查看
- YOLOs-CPP:一个免费开源的YOLO全系列C++推理库(以YOLO26为例)
- PaddleOCR:Win10上安装使用PPOCRLabel标注工具
- 目标检测:使用自己的数据集微调DEIMv2进行物体检测
- 图像分割:PyTorch从零开始实现SegFormer语义分割
- 图像超分:使用自己的数据集微调Real-ESRGAN-x4plus进行超分重建
- 图像生成:PyTorch从零开始实现一个简单的扩散模型
- Stable Diffusion:使用自己的数据集微调 Stable Diffusion 3.5 LoRA 文生图模型
- 图像超分:使用自己的数据集微调Real-ESRGAN-x2plus进行超分重建
- Anomalib:使用Anomalib 2.1.0训练自己的数据集进行异常检测
- Anomalib:在Linux服务器上安装使用Anomalib 2.1.0
- 人工智能混合编程实践:C++调用封装好的DLL进行异常检测推理
- 人工智能混合编程实践:C++调用封装好的DLL进行FP16图像超分重建(v3.0)
- 隔离系统Python:源码编译3.11.8到自定义目录(含PGO性能优化)
- 在线机的Python环境迁移到离线机上
- Nuitka 将 Python 脚本封装为 .pyd 或 .so 文件
- Ultralytics:使用 YOLO11 进行速度估计
- Ultralytics:使用 YOLO11 进行物体追踪
- Ultralytics:使用 YOLO11 进行物体计数
- Ultralytics:使用 YOLO11 进行目标打码
- 人工智能混合编程实践:C++调用Python ONNX进行YOLOv8推理
- 人工智能混合编程实践:C++调用封装好的DLL进行YOLOv8实例分割
- 人工智能混合编程实践:C++调用Python ONNX进行图像超分重建
- 人工智能混合编程实践:C++调用Python AgentOCR进行文本识别
- 通过计算实例简单地理解PatchCore异常检测
- Python将YOLO格式实例分割数据集转换为COCO格式实例分割数据集
- YOLOv8 Ultralytics:使用Ultralytics框架训练RT-DETR实时目标检测模型
- 基于DETR的人脸伪装检测
- YOLOv7训练自己的数据集(口罩检测)
- YOLOv8训练自己的数据集(足球检测)
- YOLOv5:TensorRT加速YOLOv5模型推理
- YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
- 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
- YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
- YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
- Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
- YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
- 使用Kaggle GPU资源免费体验Stable Diffusion开源项目
- Stable Diffusion:在服务器上部署使用Stable Diffusion WebUI进行AI绘图(v2.0)
- Stable Diffusion:使用自己的数据集微调训练LoRA模型(v2.0)