GPU压力测试篇- TensorFlow

简介

该文档介绍使用Tensorflow框架,测试 NVIDIA 驱动的常见python 代码。

环境信息

|----|------------|-----------|----|
| 编号 | 软件 | 软件版本 | 备注 |
| 01 | 驱动 | 470.57.02 | |
| 02 | cuda 版本 | 11.2 | |
| 03 | cudnn 版本 | 8.1.1.33 | |
| 04 | tensorflow | 2.6 | |

功能测试代码:

import tensorflow as tf
with tf.device('/CPU:1'):
  a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])

c = tf.matmul(a, b)
print(c)

GPU 压力测试代码:

# On Titan X (Pascal)
# 8192 x 8192 matmul took: 0.10 sec, 11304.59 G ops/sec
# http://stackoverflow.com/questions/41804380/testing-gpu-with-tensorflow-matrix-multiplication

import os
import sys
import tensorflow as tf
import time
import timeit
import datetime

n=1000000000 #10亿次
dtype = tf.float32
with tf.device("/gpu:0"):
    matrix1 = tf.Variable(tf.ones((1, n), dtype=dtype))
    matrix2 = tf.Variable(tf.ones((n, 1), dtype=dtype))


def gpu_run():
    with tf.device("/gpu:0"):
        product = tf.matmul(matrix1, matrix2)
    return product

print("开始计算:", time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))
gpu_time = timeit.timeit(gpu_run, number=1000)
print("计算结束:", time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))

CPU/GPU 压测比较代码:

# 屏蔽tensorflow输出的log信息
# 注意:代码在import tensorflow之前
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"

import sys
print("python的版本信息:",sys.version)
#python的版本信息: 3.7.9 (default, Aug 31 2020, 17:10:11) [MSC v.1916 64 bit (AMD64)]

import tensorflow as tf

'''
验证GPU相对于CPU,在并行计算优势明显
'''
n=100000000 #1亿次

# 创建在 CPU 环境上运算的 2 个矩阵
with tf.device('/cpu:0'):
    cpu_a = tf.random.normal([1, n])
    cpu_b = tf.random.normal([n, 1])
    print(cpu_a.device, cpu_b.device)

# 创建使用 GPU 环境运算的 2 个矩阵
with tf.device('/gpu:0'):
    gpu_a = tf.random.normal([1, n])
    gpu_b = tf.random.normal([n, 1])
    print(gpu_a.device, gpu_b.device)

import timeit

def cpu_run(): # CPU 运算函数
    with tf.device('/cpu:0'):
        c = tf.matmul(cpu_a, cpu_b)
    return c

def gpu_run():# GPU 运算函数
    with tf.device('/gpu:0'):
        c = tf.matmul(gpu_a, gpu_b)
    return c

# 第一次计算需要热身,避免将初始化时间结算在内
cpu_time = timeit.timeit(cpu_run, number=100)
gpu_time = timeit.timeit(gpu_run, number=100)
print('首先计算10次(含热身环境)的平均时间,CPU计算消耗时间:%.3fms,GPU计算消耗时间:%.3fms!'%(cpu_time*1000, gpu_time*1000) )

#正式计算10次,取平均时间
cpu1_time = timeit.timeit(cpu_run, number=10)
gpu1_time = timeit.timeit(gpu_run, number=10)

print('正式计算10次的平均时间,CPU计算消耗时间:%.3fms,GPU计算消耗时间:%.3fms!'%(cpu1_time*1000, gpu1_time*1000))

压测

|----|----------|------|------|---------|------|-------|--------|
| 编号 | 先卡类型 | 显卡架构 | 计算时间 | cuda 版本 | TF版本 | 算力使用率 | 备注 |
| 01 | P40-22G | 帕斯卡 | 17秒 | 10.1 | 2.3 | 100% | x86_64 |
| 02 | T4-16G | 图灵 | 15秒 | 11.2 | 2.6 | 100% | x86_64 |
| 03 | V100-32G | 沃尔塔 | 7秒 | 10.1 | 2.3 | 100% | x86_64 |
| 04 | A10-24G | 安培 | 10秒 | 11.2 | 2.6 | 100% | x86_64 |
| 05 | A100-40G | 安培 | 6秒 | 11.2 | 2.6 | 100% | x86_64 |

1. 背景目的

对现有gpu的性能没有相关的测试,需要进行摸底测试

预期测试目的:

  • 完成gpu对训练及预测服务的性能测试

  • 对现场部署及使用提供支持

2. 测试环境

OS:Centos7

Linux kernel:Linux 3.10.0-1160.90.1.el7.x86_64

Docker Version:1.13.1

Docker Image:nvcr.io/nvidia/tensorflow:23.03-tf1-py3 (V1.15版本)

Docker OS:Ubuntu 20.04.5 LTS

Nvidia GPU Version:NVIDIA-SMI 470.161.03

CUDA Version: 12.1

TensorFlow Version:1.15.1

python Version:3.8.10

3. 测试方案

3.1、训练性能测试方案

  • 训练文件来源:GitHub - tensorflow/benchmarks: A benchmark framework for Tensorflow

  • 训练模型:resnet50

  • 训练数据集:全量imagenet数据,总大小约150G,图片张数超过1400w

  • 测试步骤:

    • 将全量的已转换为tfrecord格式的imagenet数据上传至存储卷下

    • 创建3个notebook任务,资源配置如下:

|-----|-----|--------|
| CPU | GPU | memory |
| 6 | 0.5 | 20G |
| 6 | 1 | 20G |
| 12 | 2 | 40G |

  • 上传tf_cnn_benchmark代码
  • 运行测试指令:python tf_cnn_benchmarks.py --model=resnet50 --num_gpus={NUM_GPUS} --batch_size=32 --variable_update=parameter_server --data_dir={DATA_DIR} --num_epochs=2

${DATA_DIR}为训练数据集文件train目录的路径

${NUM_GPUS}为当前notebook任务申请的GPU数量

2. 预测性能测试方案:

  • 预测服务模型:TensorFlow-Resnet50 v1,SavedModel格式

  • 模型来源:https://tfhub.dev/tensorflow/resnet_50/classification/1

  • 发压工具:

    • 下载

    • 说明:封装locust的性能测试工具,支持模型预测的性能测试。

  • 测试步骤:

    • 模型中心导入TensorFlow-Resnet50

    • 创建模型对应服务,资源配置如下:

|-----|-----|--------|
| CPU | GPU | MEMORY |
| 4 | 0.5 | 8G |
| 4 | 1 | 8G |
| 8 | 2 | 16G |

  • 创建相关应用
    • 利用发压工具对服务接口持续发压,观察压力测试结果及压测期间gpu显存使用情况及gpu使用率

一、GPU性能测试数据报告如下

1 需求背景

使用性能评估对服务终端进行压力测试,评估服务端性能,有助于定位性能瓶颈。

由于全量版本过多,高优测试一轮每个框架的最新版本,模型性能。

2. 测试方案

2.1 模型预测配置

  1. 每个副本 默认资源配置

    1. 副本数:1

    2. CPU:4

    3. 内存:8GB / 8192MB

    4. GPU:

      1. 仅用CPU的模型预测:0

      2. 依赖GPU(或必须使用GPU才能发挥性能的模型预测 :TensorFlow、Pytorch、Paddle):1

    5. GPU类型:Tesla-T4

注意

当测试时,发现服务的资源配置成为性能瓶颈时,应适当改大资源,否则无法测试出最大的性能数据。

2.2 模型选择

|-----------------------|----------------------------------------|--------------|---------|-------------|-------------------------------------------------------------|
| 模型类型 | 镜像名称:镜像tag | | 是否使用GPU | 模型类型 | 其他说明 |
| Sklearn-v0.20 | infsms-sklearn0.20.2 | e0828eb1d118 | 否 | modelserver | - |
| GBDT-v1.2.0 | infsms-xgboost1.2.0 | d09b82ae7baa | 否 | modelserver | 服务需要设置环境变量: OMP_NUM_THREADS:1 (NUM_WORKERS建议设置,本次测试没有设置此参数) |
| H2O-v3.26.0.5 | infsms-h2o3.26.0.5 | 929fa6a953d1 | 否 | modelserver | - |
| R-3.5.2 | infsms-r3.5.2 | 64ff114623cb | 否 | modelserver | 多并发请求成功率全部低于30 |
| PMML | infsms-pmml0.9.11 | d0276f6c47d9 | 否 | modelserver | 多并发请求成功率全部低于50 |
| TensorFlow-v2.6.0 | infsms-tensorflow2.6.0-cuda11.2-cudnn8 | e88ef44c5251 | 是 | modelserver | - |
| paddle-2.1 | infsms-paddle2.1.0-cuda10.1-cudnn7 | 683ef1373304 | 是 | modelserver | - |
| PyTorch-v1.10.1 | infsms-pytorch1.10.0-cuda10.2-cudnn7 | 8812b855b620 | 是 | modelserver | - |
| OONX-1.8 | infsms-onnx1.3.0-cuda10.1-cudnn7 | 9840c6d7a900 | 是 | modelserver | 模型起预测onnx框架image信息匹配的不对 |

2.3 性能指标说明

  1. 最大并发:长时间压测下,预测服务能承受的稳定无异常的最大并发数。

  2. 最大TPS:长时间压测下,预测服务能达到的最大TPS

  3. 资源使用率:

    1. 包括CPU使用率、GPU算力平均使用率、GPU显存平均使用率、内存使用率

    2. 来自前端页面 用户可见的副本监控数据(获取自性能评估报告、 Prometheus监控数据)

    3. 仅列出压测过程中 采样到的最大占用率

3 模型预测性能

3.1 GBDT-v1.2.0模型预测

|------------------|---------|---------|---------|---------|-----------|-----------|---------|
| 性能指标 | pod性能数据 | | | | | | |
| 性能指标 | 1个并发 | 中间数据 | 最大并发 | 中间数据 | 中间数据 | 中间数据 | 中间数据 |
| 单副本资源数 | 4/0/8G | 4/0/8G | 4/0/8G | 4/0/8G | 4/0/8G | 4/0/8G | 4/0/8G |
| Users(并发数) | 1 | 30 | 50 | 100 | 300 | 500 | 1000 |
| 递增速率(VU/s) | 1 | 2 | 5 | 10 | 20 | 35 | 66 |
| 发压时间 | 30min | 30min | 30min | 30min | 30min | 30min | 30min |
| 发送请求数 | 537930 | 1406038 | 1408861 | 1405880 | 814857 | 822581 | 873953 |
| req/s(QPS) | 299.02 | 782.87 | 784.44 | 782.78 | 452.95 | 457.24 | 485.8 |
| failures(整体失败率) | 0 | 0 | 0 | 0 | 0.68% | 1.64% | 3.61% |
| failures/s | 0 | 0 | 0 | 0 | 3.08 | 7.49 | 17.5 |
| 响应时间(最大) | 75 | 77 | 119 | 1311 | 91852 | 91792 | 92606 |
| 响应时间(最小) | 2 | 2 | 2 | 6 | 5 | 8 | 18 |
| 响应时间(中位数) | 3 | 38 | 63 | 130 | 140 | 140 | 140 |
| 响应时间(平均值) | 2.97 | 37.62 | 64.03 | 126.88 | 664.91 | 1184.59 | 2365.61 |
| 响应时间 latency 95% | 3 | 40 | 67 | 130 | 270 | 290 | 3400 |
| 响应时间 latency 99% | 4 | 42 | 69 | 140 | 7200 | 59000 | 61000 |
| CPU使用率 | 20% | 53% | 53.06% | 53.12% | 46%->32% | 40%->34% | 35% |
| 内存使用率 | 2.34% | 2.34% | 2.35% | 2.37% | 2.46% | 2.65% | 3.19% |

分析说明:

  1. 最大并发为100

  2. 30min发压时间的平均QPS 最大是784.44左右

  3. 并发达到50后,QPS基本稳定,超过100并发时,开始出现报错:报错基本集中在发压后几分钟内,几分钟后请求成功率逐步上升,趋势图如下

3.2 Sklearn-v0.20 模型预测

|------------------|--------|---------|---------|-----------|
| 性能指标 | pod性能数据 ||||
| 性能指标 | 1个并发 | 中间数据 | 最大并发 | 中间数据 |
| 单副本资源数 | 4/0/8G | 4/0/8G | 4/0/8G | 4/0/8G |
| Users(并发数) | 1 | 50 | 100 | 300 |
| 递增速率(VU/s) | 1 | 5 | 10 | 20 |
| 发压时间 | 30min | 30min | 30min | 30min |
| 发送请求数 | 450442 | 1255059 | 1260003 | 690064 |
| req/s(TPS) | 250.38 | 697.64 | 700.39 | 383.58 |
| failures(整体失败率) | 0 | 0 | 0 | 0.86% |
| failures/s | 0 | 0 | 0 | 3.29 |
| 响应时间(最大) | 1046 | 1078 | 1343 | 91855 |
| 响应时间(最小) | 2 | 3 | 5 | 15 |
| 响应时间(中位数) | 3 | 70 | 140 | 150 |
| 响应时间(平均值) | 3.07 | 70.3 | 141.36 | 772.63 |
| 响应时间 latency 95% | 3 | 77 | 160 | 1100 |
| 响应时间 latency 99% | 5 | 83 | 160 | 12000 |
| CPU使用率 | 19% | 54.27% | 54.33% | 54%->34% |
| 内存使用率 | 1.95% | 2% | 2.02% | 2.15% |

分析说明

  1. 最大并发为200

  2. 30min发压时间的平均TPS 最大是700.39左右

  3. 并发达到100后,TPS 基本稳定,超过100并发时,开始出现报错。

3.3 H2O-V3.26.5模型预测

|------------------|--------|--------|--------|--------|---------|----------|
| 性能指标 | pod性能数据 ||||||
| 性能指标 | 1个并发 | 最大并发 | 中间数据 | 中间数据 | 中间数据 | 中间数据 |
| 单副本资源数 | 4/0/8G | 4/0/8G | 4/0/8G | 4/0/8G | 4/0/8G | 4/0/8G |
| Users(并发数) | 1 | 50 | 100 | 300 | 500 | 1000 |
| 递增速率(VU/s) | 1 | 5 | 10 | 20 | 35 | 66 |
| 发压时间 | 30min | 30min | 30min | 30min | 30min | 30min |
| 发送请求数 | 29799 | 28356 | 10579 | 11883 | 18374 | 36941 |
| req/s(TPS) | 16.59 | 15.79 | 5.9 | 6.62 | 10.24 | 20.59 |
| failures(整体失败率) | 0 | 0 | 0.59 | 66.66 | 75.15 | 99.91 |
| 响应时间(最大) | 1671 | 6552 | 61043 | 92294 | 92502 | 61352.15 |
| 响应时间(最小) | 33 | 102 | 1963 | 21743 | 21946 | 26621 |
| 响应时间(中位数) | 57 | 3100 | 8300 | 60000 | 60000 | 61000 |
| 响应时间(平均值) | 59.57 | 3166 | 17643 | 55670 | 61223.9 | 61352.15 |
| 响应时间 latency 95% | 80 | 3900 | 38000 | 67000 | 78000 | 85000 |
| 响应时间 latency 99% | 94 | 4800 | 58000 | 92000 | 92000 | 92000 |
| CPU使用率 | 50% | 76.43% | 91.5% | 92.5% | 94.14% | 94.56% |
| 内存使用率 | 20% | 33.34% | 35.09% | 35.62% | 36.14% | 37.18% |

分析说明

  1. 最大并发为50

  2. 30min发压时间的平均TPS 最大是16.59左右

  3. 并发超过50时,开始出现报错。

3.4 Paddle-v2.1模型预测

|------------------|--------|------------|-------------------|----------|----------|----------|
| 性能指标 | pod性能数据 ||||||
| 性能指标 | 1个并发 | 最大并发 | 中间数据 | 中间数据 | 中间数据 | 中间数据 |
| 单副本资源数 | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G |
| Users(并发数) | 1 | 50 | 100 | 300 | 500 | 1000 |
| 递增速率(VU/s) | 1 | 5 | 10 | 20 | 35 | 66 |
| 发压时间 | 30min | 30min | 30min | 30min | 30min | 30min |
| 发送请求数 | 20305 | 50549 | 50534 | 46758 | 57051 | 81977 |
| req/s(TPS) | 11.29 | 28.1 | 28.14 | 26.03 | 31.77 | 45.64 |
| failures(整体失败率) | 0 | 0 | 0.37 | 16.19 | 31.11 | 51.93 |
| 响应时间(最大) | 1366 | 3977 | 62301 | 92458 | 91758 | 109176 |
| 响应时间(最小) | 33 | 147 | 531 | 101 | 59 | 1 |
| 响应时间(中位数) | 83 | 1800 | 3500 | 3600 | 4700 | 7500 |
| 响应时间(平均值) | 79.65 | 1768.93 | 3592.37 | 12314.43 | 17432.58 | 26336.36 |
| 响应时间 latency 95% | 87 | 1800 | 3600 | 60000 | 60000 | 61000 |
| 响应时间 latency 99% | 90 | 1800 | 3600 | 67000 | 68000 | 68000 |
| CPU使用率 | 11.73 | 26.80 | 26.42 | 26.42 | 26.34 | 23.13 |
| 内存使用率 | 21.39 | 21.42 | 21.46 | 21.60 | 22.11 | 22.79 |
| AI加速卡算力平均使用率 | 21.30 | 16.64 后期是0 | 17.22 中途有使用率为0的一段 | 72.27 | 59.12 | 58.96 |
| AI加速卡显存平均使用率 | 5.94 | 5.94 | 5.94 | 5.94 | 5.94 | 5.94 |

分析说明

  1. 最大并发为50

  2. 30min发压时间的平均TPS 最大是28.1左右

  3. 并发超过50时,开始出现报错。 加速卡算力平均使用率存在0的情况。

3.5 Tensorflow-v2.6模型预测

|------------------|--------|---------|---------|---------|----------|----------|
| 性能指标 | pod性能数据 ||||||
| 性能指标 | 1个并发 | 中间数据 | 最大并发 | 中间数据 | 中间数据 | 中间数据 |
| 单副本资源数 | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G |
| Users(并发数) | 1 | 50 | 100 | 300 | 500 | 1000 |
| 递增速率(VU/s) | 1 | 5 | 10 | 20 | 35 | 66 |
| 发压时间 | 30min | 30min | 30min | 30min | 30min | 30min |
| 发送请求数 | 20992 | 78283 | 76802 | 65464 | 78072 | 103178 |
| req/s(TPS) | 11.67 | 43.51 | 42.76 | 36.45 | 43.4 | 57.35 |
| failures(整体失败率) | 0 | 0 | 0 | 11.94 | 21.95 | 41.15 |
| 响应时间(最大) | 1892 | 2224 | 63084 | 92619 | 92785 | 91528 |
| 响应时间(最小) | 36 | 78 | 153 | 872 | 1004 | 1 |
| 响应时间(中位数) | 86 | 1100 | 2300 | 2900 | 2900 | 3700 |
| 响应时间(平均值) | 76.74 | 1139.09 | 2344.31 | 8678.17 | 13413.85 | 20421.58 |
| 响应时间 latency 95% | 90 | 1300 | 2500 | 60000 | 60000 | 60000 |
| 响应时间 latency 99% | 92 | 1300 | 2600 | 61000 | 61000 | 61000 |
| CPU使用率 | 14.16 | 53.05 | 53.08 | 53.04 | 42.71 | 42.73 |
| 内存使用率 | 29.98 | 30.34 | 30.49 | 30.83 | 31.32 | 32.01 |
| AI加速卡显存平均使用率 | 96.44 | 96.44 | 96.44 | 96.44 | 96.44 | 96.44 |
| AI加速卡算力平均使用率 | 32.58 | 120.36 | 120.47 | 136.48 | 119.38 | 134.65 |

分析说明

  1. 最大并发为100

  2. 30min发压时间的平均QPS 最大是42.76左右

  3. 并发超过100时,开始出现报错。

  4. 并发超过100时,加速卡算力平均使用率存在一直为96.44的情况。.

  5. 并发超过50时,AI加速卡算力平均使用率超过100%。

3.6 Pytorch-v1.10模型预测

|------------------|------------|-----------|-----------|---------|----------|----------|
| 性能指标 | pod性能数据 ||||||
| 性能指标 | 1个并发 | 最大并发 | 中间数据 | 中间数据 | 中间数据 | 中间数据 |
| 单副本资源数 | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G | 4/1/8G |
| Users(并发数) | 1 | 50 | 100 | 300 | 500 | 1000 |
| 递增速率(VU/s) | 1 | 5 | 10 | 20 | 35 | 66 |
| 发压时间 | 30min | 30min | 30min | 30min | 30min | 30min |
| 发送请求数 | 19985 | 50643 | 49420 | 47723 | 55325 | 83476 |
| req/s(TPS) | 11.11 | 28.15 | 27.52 | 26.57 | 30.8 | 46.48 |
| failures(整体失败率) | 0 | 0 | 0.16 | 15.29 | 30.06 | 51.07 |
| 响应时间(最大) | 123 | 3926 | 54769 | 92485 | 92408 | 91646 |
| 响应时间(最小) | 34 | 165 | 599 | 228 | 1006 | 2 |
| 响应时间(中位数) | 83 | 1800 | 3600 | 3700 | 6200 | 7300 |
| 响应时间(平均值) | 81.1 | 1766.19 | 3656.31 | 12284.4 | 18043.53 | 24809.95 |
| 响应时间 latency 95% | 87 | 1800 | 3600 | 60000 | 60000 | 60000 |
| 响应时间 latency 99% | 89 | 1800 | 3700 | 67000 | 66000 | 61000 |
| CPU使用率 | 11.92 | 26.84 | 26.73 | 23.50 | 24.78 | 22.76 |
| AI加速卡显存平均使用率 | 8.87 | 8.87 | 8.87 | 8.87 | 8.87 | 8.87 |
| AI加速卡算力平均使用率 | 6.4 出现为0情况 | 11 出现为0情况 | 30 出现为0情况 | 70 | 60 | 64.9 |
| 内存使用率 | 32.72 | 35.72 | 32.80 | 33.15 | 33.56 | 34.38 |

分析说明

  1. 最大并发为50

  2. 30min发压时间的平均TPS 最大是28.15左右

  3. 并发超过50时,开始出现报错

  4. 加速卡算力平均使用率存在一直为8.87的情况

  5. 并发小于300时,AI加速卡算力平均使用率出现为0时间段

相关推荐
豆本-豆豆奶27 分钟前
最全面的Python重点知识汇总,建议收藏!
开发语言·数据库·python·oracle
Bosenya1231 分钟前
【信号处理】绘制IQ信号时域图、星座图、功率谱
开发语言·python·信号处理
再不会python就不礼貌了34 分钟前
Ollama 0.4 发布!支持 Llama 3.2 Vision,实现多模态 RAG
人工智能·学习·机器学习·ai·开源·产品经理·llama
大大大反派37 分钟前
ONLYOFFICE 8.2深度测评:集成PDF编辑、数据可视化与AI功能的强大办公套件
人工智能·信息可视化·pdf
AI原吾1 小时前
探索PyAV:Python中的多媒体处理利器
开发语言·python·ai·pyav
DK221511 小时前
机器学习系列-----主成分分析(PCA)
人工智能·算法·机器学习
oliveira-time1 小时前
爬虫学习8
开发语言·javascript·爬虫·python·算法
正义的彬彬侠1 小时前
XGBoost算法Python代码实现
python·决策树·机器学习·numpy·集成学习·boosting·xgboost
昨天今天明天好多天1 小时前
【Python】解析 XML
xml·python
侯喵喵2 小时前
从零开始 blender插件开发
python·blender