训练(training)vs 推理(inference)
训练是通过从已有的数据中学习到某种能力,而推理是简化并使用该能力,使其能快速、高效地对未知的数据进行操作,以获得预期的结果。
训练是计算密集型操作,模型一般都需要使用大量的数据来进行训练,通过反向传播来不断的优化模型的参数,以使得模型获取某种能力。在训练的过程中,我们常常是将模型在数据集上面的拟合情况放在首要位置的。而推理过程在很多场景下,除了模型的精度外,还更加关注模型的大小和速度等指标。这就需要对训练的模型进行一些压缩、剪枝或者是操作上面的计算优化。
我们做算法的最终目的都是希望自己的方法可以真正的应用起来,那么在对模型部署上面,每一个算法工程师都应该有一些基本的 sense。下面本文会简单介绍一些推理时比较关注的指标。
重要指标
Throughput 吞吐量
单位时间内所处理的数据量 一般用 推理/秒 或者 样本/秒 衡量。每台服务器的吞吐量对于数据中心能否合算的扩展至关重要。
# 包含并行情况
def calc_ips(batch_size, time):
# 全局进程个数
world_size = (
torch.distributed.get_world_size() if torch.distributed.is_initialized() else 1
)
tbs = world_size * batch_size
return tbs / time
Latency 延迟
执行一次推理所花的时间,单位一般为 ms。低延迟对于实时且快速增长地推理服务至关重要。一般在压测时,我们都是通过增加并发数,来观察 Latency 平均线、90 线、 95 线和 99 线
# time_list 为每个请求从发送到返回的时间列表
avg = np.mean(time_list)
cf_90 = max(time_list[:int(len(time_list) * 0.90)])
cf_95 = max(time_list[:int(len(time_list) * 0.95)])
cf_99 = max(time_list[:int(len(time_list) * 0.99)])
或者直接使用 numpy 提供的方法来求
# 根据不同的线来改变 q
np.quantile(time_list, q, interpolation=“nearest”)
Accuracy 准确率
训练后的模型能够提供正确结果的能力。一般推理时,我们会评估模型在模型压缩或者优化后能够和训练时达到一样或者可接受的相似效果。模型是否正确部署,结果具有幂等性。同时根据应用场景的情况,我们可以针对自己在意的指标进行衡量(和训练时相同)。例如:一般针对图像分类而言,我们会参考 top-1 or top-5 的准确率。
Memory usage 内存使用情况
在众多场景下,在推理过程中很关注内存的使用情况。尤其是在多个网络模型并且内存资源有限的系统中尤为重要。另外,有时也需要在意内存的利用率情况,这对于评估资源是否浪费以及模型外工程方面的优化方向至关重要。在 GPU 设备上,我们可以使用下面命令来监控内存的使用情况。
nvidia-smi
watch -n 1 nvidia-smi #每个 1s 更新显示
Efficiency 效率
单位功率的吞吐量, 一般单位为 performance/watt。Efficiency 是数据中心扩展合算分析的另一个关键因素。因为服务器、服务器机架和整个数据中心必须在固定的功率预算内运行。
FLOPs
是 floating point operations 的缩写(s 表复数),意指浮点运算数,理解为计算量。可以用来衡量算法/模型的复杂度。
FLOPS
是 floating point operations per second 的缩写,意指每秒浮点运算次数,理解为计算速度。是一个衡量硬件性能的指标。
硬件相关
在大数据的时代,对于各种卡的选择我们也是需要有一点点了解的,很多优化操作都是针对不同的卡进行的。我现在用到比较多的就是 V100 和 T4,两者相关信息对比:
更多详见:List of Nvidia graphics processing units
参考文献
https://en.wikipedia.org/wiki/List_of_Nvidia_graphics_processing_units
https://blogs.nvidia.com/blog/2016/08/22/difference-deep-learning-training-inference-ai/
https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#overview