前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次排查模型推理变慢原因

记一次排查模型推理变慢原因

原创
作者头像
aaronwjzhao
发布2022-02-25 17:57:03
2.1K0
发布2022-02-25 17:57:03
举报
文章被收录于专栏:AI工程落地AI工程落地

导语:使用nvidia dali库来做图片加载和transforms得到的tensor,比pillow+torchvision得到的tensor,在模型推理时候慢三倍。对比tensor,虽然存在精度上的损失,但没发现其他任何问题,最终定位出来是显存中tensor不连续。

问题来源

传统的图片预处理一般用pillow从byte读图,再经过torchvision的transforms去做resize、normalize、crop等操作,如果模型推理在GPU上,这种做法就比较浪费GPU,并且耗时。所以我再想有没有办法把预处理也放到GPU上,看了nvidia官网,发现2018年推出的nvidia dali就是做这个事的。

dali的实现过程本文略过,最后对比两种方式的区别

代码语言:txt
复制
平均绝对误差: 0.008177888535926072
最大误差: 0.24509800970554352
dali preprocess time: 5.385756492614746ms
torch preprocess time: 324.6474266052246ms

性能上秒杀,误差对于不敏感的模型还可以。

接下来应用到推理上,却发现torch处理后的tensor推理只要100毫秒,dali处理后的tensor推理却要300毫秒。

问题定位

  1. 首先想到的是dali出来的tensor在GPU上,模型用的时候可能需要从dali申请的显存里copy过来,所以我手动把dali tensor先放到CPU,再放回GPU,然后进行模型推理。发现推理时间不变,排除这个原因
  2. dali做预处理是按NHWC这样的方式,模型需要的是NCHW,所以我做了一次permute,想到可能是这个操作导致tensor不连续了。加上contiguous,问题解决。

经过上面排查,发现锅不是nvidia dali的,人家依然很牛,是我自己用的有问题。惭愧

问题原因剖析

Tensor操作(如transpose、permute、narrow、expand与原Tensor是共享内存中的数据,不会改变底层数组的存储,但原来在语义上相邻、内存里也相邻的元素在执行这样的操作后,在语义上相邻,但在内存不相邻,即不连续了。

所以模型推理的时候GPU需要频繁的查看内存,访问内存比访问寄存器慢100倍,自然推理性能就下降了。

contiguous会重新开辟一块内存空间保证数据是在逻辑顺序和内存中是一致的,连续内存布局减少了CPU对对内存的请求次数(访问内存比访问寄存器慢100倍,相当于空间换时间。

参考文档

https://pytorch.org/docs/stable/generated/torch.Tensor.contiguous.html

https://www.cxybb.com/article/weixin_43977640/111152239

https://zhuanlan.zhihu.com/p/64551412

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题来源
  • 问题定位
  • 问题原因剖析
  • 参考文档
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档