关键词: 流水线 、 并行 、 异步
前言
由于神经网络模型通常较大且计算密集,因此需要大量的计算资源和时间来训练和推理。加速程序可以显著减少训练和推理时间,提高效率,同时降低成本。此外,通过优化神经网络模型的训练和推理过程,可以减少不必要的计算量,进一步加速程序。在项目需要落地进行推理时往往会因为设备算力不够 或因为利用率不高导致运行效率低下,今天便从优化推理架构角度进行分析。
流水线
流水线技术是一种将一个任务分解为若干顺序执行子任务的方法,不同的子任务由不同的执行机构负责执行,而这些机构可以同时并行工作,任一任务只占用其中一个执行机构,这样就可以实现多个任务的重叠执行,以提高工作效率。
如果以传统的方式,完成k个任务所需的时间是kNt,而使用流水线技术执行,花费的时间是Nt + (k - 1)t。也就是说,除了第一个任务需要完整的时间外,其他任务都通过并行执行以节省大量时间。所以流水线的执行时间可以通俗地表达为: 【流水线执行时间 = 第1条指令的执行时间 + (n - 1)* 流水线周期】 。
这里我们可以化抽象为具体进行分析,如下这三个模块耗时所示:
- 生产数据(耗时1秒)
- 处理数据(耗时3秒)
- 推送数据(耗时可忽略不计)
当我们执行一次上述模块耗时为4秒,生产数据占25%运行时间,有75%的时间属于空闲状态,这明显是可以进行优化的。
在处理模块这里耗时为3秒,我们可以增加处理数据模块的数量为3个进行优化,我们采用流水线操作可得耗时数据流明细:
时间 | 生产(1个) | 处理(3个) | 推送(1个) |
---|---|---|---|
1 | 1 | 空 | 空 |
2 | 2 | 1.1 | 空 |
3 | 3 | 1.2-2.1 | 空 |
4 | 4 | 1.3;2.2;3.1 | 1 |
5 | 5 | 2.3;3.2;4.1 | 2 |
6 | 6 | 3.3;4.2;5.1 | 3 |
7 | 7 | 4.3;5.2;6.1 | 4 |
8 | 8 | 5.3;6.2;7.1 | 5 |
9 | 9 | 6.3;7.2;8.1 | 6 |
python代码
由于模型推理代码较为繁杂,在这里我将推理模块抽象为上述模块进行模拟实验进行验证:
python
import time
from concurrent.futures import ThreadPoolExecutor
# 处理一个数据用时3秒
def myFunc(n):
time.sleep(3)
return n
# 生产一个数据时间用时1秒
def num(n):
time.sleep(1)
return n
max_works = 3
count = 1
# 使用ThreadPoolExecutor来并行处理数据
with ThreadPoolExecutor(max_workers=max_works) as executor:
while True:
n = num(count)
future = executor.submit(myFunc, n)
future.add_done_callback(lambda future: print("此时输出的数据为", future.result()))
print("此时运行的时间t为:", count)
count += 1
在上述代码中我们分别使用sleep模拟了处理耗时,运行上述代码可以得到只有前三秒时间无法获取数据,在第四秒开始可以陆陆续续得到处理好的数据,这样我们的生产数据环节处于一直工作状态,如果大家需要
此时运行的时间t为: 1
此时运行的时间t为: 2
此时运行的时间t为: 3
此时运行的时间t为: 4
此时输出的数据为 1
此时输出的数据为 2
此时运行的时间t为: 5
此时输出的数据为 3
此时运行的时间t为: 6
此时输出的数据为 4
此时运行的时间t为: 7
此时输出的数据为 5
此时运行的时间t为: 8
此时输出的数据为 6
此时运行的时间t为: 9
此时输出的数据为 7