第二章 压测环境搭建:硬件选型与软件栈配置
环境搭建这件事,说白了就是给你的压测找个靠谱的「跑道」。跑道不行,你测出来的数据全是噪音。我见过太多团队,花大价钱买了卡,结果环境没配好,跑出来的吞吐量还不如隔壁用旧卡的同学。嗯,这里面的坑,我一个个给你说清楚。
2.1 硬件选型:GPU vs CPU,到底选谁?
先问个问题:你的算子是计算密集型,还是访存密集型?
我个人习惯,先看算子的计算密度(Compute Intensity)。如果每个元素的计算量很大,比如卷积、矩阵乘法,那GPU是首选。如果算子主要是数据搬运、条件分支多,比如某些稀疏操作,CPU反而更稳。
GPU选型建议:
- NVIDIA A100 / H100:适合大模型、高吞吐场景。我去年压测一个Transformer算子,A100的FP16算力达到312 TFLOPS,比V100翻了3倍多。
- NVIDIA V100 / A10:性价比之选。如果你的算子不是特别吃显存,V100的32GB显存够用,而且价格只有A100的1/3。
- RTX 4090:个人开发机首选。24GB显存,FP16算力82 TFLOPS,关键是便宜。但注意,它没有NVLink,多卡通信会慢。
CPU选型建议:
- AMD EPYC 7763:64核128线程,适合并行度高的CPU算子。我测过一个稀疏矩阵乘法,EPYC比Intel Xeon快40%。
- Intel Xeon Platinum 8380:40核80线程,AVX-512指令集对某些算子有奇效。但功耗高,散热要跟上。
核心原则:压测环境要和生产环境保持一致。你想想看,如果生产用A100,你拿4090测,那数据能信吗?
2.2 软件栈配置:CUDA、PyTorch/TensorFlow
硬件选好了,接下来就是软件栈。这里我踩过不少坑,一个个说。
2.2.1 CUDA版本选择
CUDA版本不是越新越好。我建议:
- CUDA 11.8:最稳的版本。PyTorch 2.0、TensorFlow 2.12都原生支持。我压测时90%的场景用这个。
- CUDA 12.x:如果你用H100或者需要FP8支持,可以上。但注意,有些旧算子可能不兼容。
我曾经因为CUDA版本没对齐,导致一个自定义算子跑出来的结果比预期慢3倍。查了两天才发现是CUDA runtime和driver版本不匹配。嗯,这种低级错误,犯一次就够了。
2.2.2 PyTorch vs TensorFlow
说实话,两个框架我都用。但压测时,我倾向PyTorch:
- PyTorch 2.0+:torch.compile能自动融合算子,对压测很友好。我测过一个LayerNorm,开启编译后吞吐提升30%。
- TensorFlow 2.x:如果你用TF Serving做推理,那压测环境必须用TF。但注意,TF的算子执行顺序有时候会变,影响结果复现。
小技巧:压测前,用 torch.backends.cudnn.benchmark = True 让cuDNN自动选择最优算法。我测卷积算子时,这个开关能带来15%-20%的性能提升。
2.2.3 其他依赖库
除了框架本身,还有几个库必须配齐:
- cuDNN 8.9+:卷积、池化算子的加速库。版本要和CUDA对齐。
- NCCL 2.18+:多卡通信库。如果你做多卡压测,这个必须装。我遇到过NCCL版本太低导致通信带宽只有理论值一半的情况。
- TensorRT 8.6+:推理优化库。如果你压测的是推理场景,用TensorRT能再压榨20%-50%的性能。
2.3 Docker环境准备:一次配置,到处运行
环境配置最怕什么?怕换台机器就崩。Docker就是来解决这个问题的。我个人的习惯是:所有压测环境都容器化,绝不直接在宿主机上跑。
2.3.1 基础镜像选择
别从零开始搭。直接用NVIDIA官方提供的镜像:
# 拉取PyTorch镜像
docker pull nvcr.io/nvidia/pytorch:23.12-py3
# 拉取TensorFlow镜像
docker pull nvcr.io/nvidia/tensorflow:23.12-tf2-py3
这些镜像已经装好了CUDA、cuDNN、NCCL,你只需要装自己的算子库就行。
2.3.2 Dockerfile示例
我一般这样写Dockerfile:
FROM nvcr.io/nvidia/pytorch:23.12-py3
# 安装额外依赖
RUN pip install --no-cache-dir \
pytest \
psutil \
nvidia-ml-py3
# 复制算子代码
COPY ./operators /workspace/operators
# 设置工作目录
WORKDIR /workspace/operators
# 默认命令
CMD ["python", "benchmark.py"]
注意:Docker容器默认不共享宿主机内存。如果你压测大模型,记得加 --shm-size=32g 参数。我曾经因为这个,一个Batch Size为32的模型直接OOM,排查了半天才发现是共享内存不够。
2.3.3 启动容器
启动命令我一般这样写:
docker run --gpus all \
--shm-size=32g \
-v /data:/data \
-v /home/user/operators:/workspace/operators \
-it nvcr.io/nvidia/pytorch:23.12-py3 \
python benchmark.py --op conv --batch_size 64
这里有几个关键点:
--gpus all:让容器访问所有GPU。如果你只想用某张卡,可以指定--gpus '"device=0,1"'。-v:挂载数据卷。我习惯把数据集和代码挂载进去,这样镜像可以保持轻量。--shm-size:前面说过了,大模型必加。
2.4 环境验证:跑个简单的算子试试
环境搭好了,别急着压测。先跑个简单的算子验证一下:
import torch
import time
# 验证CUDA是否可用
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"GPU count: {torch.cuda.device_count()}")
print(f"GPU name: {torch.cuda.get_device_name(0)}")
# 跑一个简单的矩阵乘法
a = torch.randn(4096, 4096, device='cuda')
b = torch.randn(4096, 4096, device='cuda')
# 预热
for _ in range(10):
c = torch.matmul(a, b)
# 正式测试
start = time.time()
for _ in range(100):
c = torch.matmul(a, b)
torch.cuda.synchronize()
end = time.time()
print(f"Average time: {(end - start) / 100 * 1000:.2f} ms")
print(f"TFLOPS: {2 * 4096**3 / ((end - start) / 100) / 1e12:.2f}")
如果这个代码能跑通,而且TFLOPS接近理论值,那你的环境就基本没问题了。
避坑指南:我曾经在Docker里跑这个测试,发现TFLOPS只有理论值的60%。查了半天,发现是容器没开 --gpus all,导致只用了1张卡。嗯,这种低级错误,犯一次就够了。
2.5 本章知识体系
下面这张图,帮你理清压测环境搭建的核心逻辑:
这张图把整个流程串起来了。从硬件选型开始,到软件栈配置,再到Docker容器化,最后用矩阵乘法验证。每一步都踩过坑,希望你别再踩一遍。
环境搭好了,下一步就是设计压测用例了。不过那是下一章的事,咱们先把眼前的环境搞定。
最后提醒一句:压测环境一定要和生产环境保持一致。你想想看,如果生产用A100,你拿4090测,那数据能信吗?我见过太多团队,因为环境不一致,压测数据漂亮,上线就崩。嗯,这种坑,咱们不踩。
想要更多资料,联系可可