前言
本次测试旨在探索本地部署 ONNX 模型的推理速度,并模拟生产环境下面临高并发的系统请求处理速度。
使用的 embedding 模型为:Alibaba-NLP/gte-multilingual-base;
测试的服务端点为:基于 TEI 部署的 embedding 模型;
ONNX 模型测试记录
ONNX 模型基于 CPU 推理时,处理单次请求需要的时间如下,单位 ms。
说明:
- 为避免长尾效应导致测试结果的异常,CPU 推理测试中的总请求数量为 1w 次;
- 表格中展示的数据为:在限制使用的 CPU 核心数为 4/8/16/32 的场景下,总请求中的 99%/75%/50% 请求耗时。例如,在使用 4 个 CPU 核心时,99% 的请求每次处理的时延为 188.04ms;
| CPU | 4 | 8 | 16 | 32 |
|---|---|---|---|---|
| 99% | 188.04 | 93.17 | 38.9 | 31.8 |
| 75% | 106.71 | 84.01 | 29.85 | 25.76 |
| 50% | 104.33 | 75.29 | 26.38 | 21.3 |
从图中的数据可以得出的结论为:
- 随着模型使用的物理核心增多,推理速度在不断加快;
- 32 核与 16 核的数据差异不明显,因为测试设备只有 16 个物理核心。尽管有 32 个逻辑核心,但调度仍在 16 核上进行。在计算密集型模型推理任务中,
从 16 核增加到 32 核并未增加实际计算资源,而超线程技术在此类任务中的收益相对有限。不过,在特定情况下,尤其是有其他任务并行时,额外的逻辑核心可能会在调度上提供一些优势,从而略微提升整体性能; - ONNX 优化后的模型具备
优秀的 tokenization 速度,每次分词的耗时在200~400 µs之间; - ONNX Runtime 进行推理时,也具备
高效的调度能力,每次调度请求的耗时在400~600 µs之间;
引入并发的测试数据
| cons | 2 | 3 | 6 | 10 |
|---|---|---|---|---|
| 99% | 60 | 86 | 158 | 213 |
| 50% | 49 | 73 | 113 | 162 |
并发场景下,可明显观测到随着并发量的增加,单个请求的处理时间延迟在爆炸式增长,从测试过程中的数据推测耗时增加的原因在于:
- 并发场景下调度延迟明显提升:
total_time="95.838661ms" tokenization_time="250.414µs" queue_time="63.300541ms" inference_time="32.212502ms"; - 推理速度保持稳定在 20~40 ms 之间,表明实际的推理过程可能不是主要瓶颈,瓶颈主要在于
调度和排队; - 根据排队理论,在高负载下,随着系统利用率接近 100%,等待时间会呈指数级增长,这能解释”爆炸式增长”现象。
GPU 测试记录
基于 CPU 推理在高并发场景下导致的性能劣化问题,我们尝试测试模型在使用 GPU 推理时的效果,理由如下:
- GPU 具备更多的小型处理核心,具备更高的并行处理能力;
- GPU 可以同时处理多个推理任务,潜在地提高系统的并发处理能力:
- 现代 GPU 往往包含专门用于深度学习的优化,提升模型的推理速度。
在进行 GPU 并发性能测试时,我们决定将请求总量从初始的 1 万次增加到 100 万次。这一决定源于我们在初步测试中的一个关键发现:GPU 的并发处理能力远超 CPU,导致在较低请求量下的测试结果可能无法准确反映系统在高负载情况下的真实性能。
具体而言,我们观察到在 1 万次请求的测试中,不同百分位数的请求处理时间存在显著差异。例如,在 512 并发的情况下,99% 分位数的请求处理延迟达到 483.93ms,而 90% 分位数仅为 90.36ms。这种巨大的差异表明,少数高延迟请求可能对整体测试结果产生了不成比例的影响。
我们推测,这种现象可能是由于以下几个因素造成的:
- GPU 资源在低请求量下未被充分利用;
- 批处理策略导致的某些请求等待时间延长;
- 系统资源(如内存传输、I/O 操作)的临时瓶颈;
- 操作系统或 GPU 驱动程序级别的调度延迟
为了获得更加准确和有代表性的性能数据,我们决定将测试规模扩大到 100 万次请求。这样做不仅能更好地模拟真实的高负载场景,还能提供更多的数据点,从而增加统计结果的可靠性。同时,这也有助于我们确定之前观察到的高延迟现象是随机异常还是系统在持续高负载下的固有特性。
通过这种方法,我们期望能够更全面地评估 GPU 推理系统的高并发性能,并为后续的性能优化工作提供更加可靠的基础数据。
100 万次请求测试
| cons | 128 | 256 | 384 | 512 |
|---|---|---|---|---|
| 99% | 44 | 61 | 79 | 96 |
| 95% | 38 | 52 | 70 | 85 |
| 90% | 36 | 49 | 65 | 79 |
| 75% | 33 | 44 | 59 | 71 |
| 50% | 30 | 40 | 52 | 64 |
通过增加测试规模到 100 万次请求,我们获得了更加稳定和可靠的性能数据。结果显示,随着并发数从 128 增加到 512,各百分位数的处理时间呈现近似线性增长。值得注意的是,99% 分位数和 50% 分位数之间的差异相对较小(如在 512 并发时分别为 96ms 和 64ms),这表明系统在高负载下仍保持了良好的一致性和稳定性。
与之前 1 万次请求的测试相比,新的结果显示出更加均匀的延迟分布。例如,在 512 并发下,99% 和 90% 分位数的差异显著减小(分别为 96ms 和 79ms)。这一改善可能归因于更大规模测试下 GPU 资源的充分利用和更有效的批处理策略。
尽管处理时间随并发数增加而增长,但增长速度相对平缓,这表明系统在 512 并发时可能仍未达到饱和点。这为进一步提高并发能力提供了潜在空间。
总结
综合以上的测试,我们建议:
- 在
低并发或测试场景下使用 ONNX 模型足以满足需求,但被导出为 ONNX 格式的模型本身会带来一定的精度损失,可能会导致ONNX 模型的推理结果与原始模型之间存在误差; - 生产环境中部署模型使用 GPU 推理,以获得更高并发与可用性。