|
选自exafunction
机器之心编译
编纂:赵阳
关于并行运算,GPU 的运用效力是最高的。
在云办事中使用 GPU 是获取低提早深度学习推理办事最经济的形式。使用 GPU 的次要瓶颈之一是经过 PCIe 总线在 CPU 和 GPU 内存之间复制数据的速度。关于许多打算用于高分辨率图象和视频处置的深度学习模型来讲,简略地复制输出会大大减少零碎的总体提早,特别是当非推理工作,如解紧缩和预处置也能够在 GPU 上履行时。
在这篇博文中,钻研者们将展现如安在 TensorFlow 中间接经过 GPU 内存传递模型输出和输入以进行模型推理,彻底绕过 PCIe 总线和 CPU 内存。
因为大少数 GPU 代码是用 CUDA 编写的,本文将使用 TensorFlow 的 C++ 接口来演示这类技术。这样无利于对接其余库的接口,如用于 GPU 减速的图象预处置的 OpenCV 和用于硬件减速的视频解码的 NVIDIA NVDEC。
初始设置
在 TensorFlow 的 C++ 接口中,tensorflow::LoadSavedModel 被用来加载模型包:
而后能够使用 tensorflow::Session 来运转模型包。默许状况下,这将使用 CPU。
使用 GPU
使用 GPU 就对比费事了。首先,用户必需从会话中创立一个 tensorflow::CallableOptions 的实例,以指定哪些张量被传入和传出 GPU 内存而不是 CPU 内存。另外,有须要指定内存将从哪一个 GPU 中输出和获得。在这个例子中,为了简略起见,本文将把一切的输出和输入的张量(Tensor)放在第一个 GPU 上。
使用上面的函数能够获取 GPU 装备的称号:
当初,用户能够创立一个 tensorflow::Session::CallableHandle 的实例,这个类封装了如安在 GPU 上运转带有输出和输入的 TensorFlow 图的办法。创立和烧毁可调用对象的代价对比大,所以最佳只在模型初始化时创立和烧毁可调用对象。此外,可调用的对象应该在会话自身被烧毁以前被烧毁。
接上去就能创立一些输出张量了。在这个例子中,本文将只使用 TensorFlow 内置的 GPU 调配器,但其实也是能够经过 tensorflow::TensorBuffer 接口将内部张量传入内部 GPU 缓冲区。
最初就能运转模型了。当初,TensorFlow 既能够间接使用来自 GPU 的输出,也能够将输入放在同一个 GPU 上
使用 CUDA stream
只管 TensorFlow 外部使用 CUDA stream,但上述样例中一切的 CUDA 操作依然是同步的。运转 cudaDeviceSynchronize 必需要在调配内存以前,以确保不会破坏先前调配好的 TensorFlow 内存。还必需在写入输出落后行同步操作,以确保 TensorFlow 能获得到无效的输出。TensorFlow 自身也会在模型履行完结时与 GPU 进行同步,以确保输入的张量是无效的。
显然,人们但愿 GPU 能尽量长期地异步运转以增加 CPU 酿成的梗阻。侥幸的是,用户能够拜候外部的 TensorFlow CUDA stream。TensorFlow CUDA stream 的输出必需与 TensorFlow 的流同步,而输入的使用对象必需在拜候内存以前与 TensorFlow 的流同步。使用 TensorFlow CUDA stream,咱们能够彻底勾销与 CPU 的同步。
详细来讲,首先,在 CallableOptions 上设置一个额定的选项,以便在模型履行完结时禁用 TensorFlow 的外部同步。
能够使用上面的辅佐函数拜候外部流,需求留意的是参数包罗装备称号。
创立模型的输出,并如上面的代码所示运转。留意这里没有调用 cudaDeviceSynchronize!
请留意,假如 TensorFlow 外部需求将内存从 GPU 复制到 CPU,那末在运转模型时依然可能产生 CPU 与 GPU 同步。但是,在向模型传递输出和输入时再也不固有的需求任何与 CPU 的同步。
论断
作者旨在经过这篇文章演示如何只经过 GPU 将输出和输入传递给 TensorFlow,这样一来能够绕过 PCIe 总线,增加开消和无限的 CPU 内存带宽。在 Exafunction,钻研者们将在他们的模型办事解决计划——ExaDeploy——中使用这样的技术,以最大限制地进步 GPU 的利用率,即便是那些拥有十分大的输出和输入的模型。
参考内容:
http://exafunction.com/blog/tensorflow-gpu-inputs-outputs
|
|