共计 2033 个字符,预计需要花费 6 分钟才能阅读完成。
痛点分析:为什么你的 GPU 跑不满?
在实际生产环境中,我们经常遇到这些典型症状:
- GPU 利用率长期低于 30%,但推理延迟却居高不下
- 批量请求处理时,显存占用暴涨但计算单元闲置
- 服务吞吐量遇到明显天花板,增加节点数效果有限
这些现象的本质是传统静态批处理模式下,硬件资源调度存在三大缺陷:
- 请求队列空闲时 GPU 计算单元停工等待
- 固定 batch size 导致小请求也占用全量资源
- 单卡加载完整大模型造成显存浪费
技术选型:优化工具链对比
TensorRT 的独特优势
- 内核融合 (Kernel Fusion) 减少内存搬运开销
- INT8 量化实现 4 倍理论算力提升
- 层优化器自动选择最优计算路径
ONNX Runtime 的适用场景
- 跨平台部署更灵活(支持 CPU/ARM)
- 动态形状 (Dynamic Shape) 支持更好
- 与 PyTorch 生态无缝对接
# TensorRT 与 ONNX Runtime 的典型性能对比(ResNet50, T4 GPU)
| 框架 | 吞吐量(qps) | P99 延迟(ms) |
|--------------|------------|------------|
| 原始 PyTorch | 120 | 45 |
| ONNX Runtime | 210 | 28 |
| TensorRT | 350 | 16 |
核心优化方案
动态批处理实现
通过装饰器实现请求的智能堆积:
class DynamicBatcher:
def __init__(self, max_batch_size=32, timeout_ms=50):
self.buffer = []
self.max_size = max_batch_size
self.timeout = timeout_ms / 1000
def __call__(self, func):
async def wrapper(input_data):
self.buffer.append(input_data)
# 触发条件:缓冲区满或超时
if (len(self.buffer) >= self.max_size or
(len(self.buffer) > 0 and time.time() - self.last_flush > self.timeout)):
try:
batch = torch.stack(self.buffer)
result = await func(batch)
self.buffer.clear()
self.last_flush = time.time()
return result
except CUDAOutOfMemoryError:
# 自动降级处理
half_batch = len(self.buffer) // 2
return await wrapper(self.buffer[:half_batch]) + \
await wrapper(self.buffer[half_batch:])
return wrapper
模型分片架构

- 垂直分片:按模型层拆分到不同设备
- 水平分片:同一层参数分布式计算
- 流水线并行:微批次 (Micro-batch) 重叠计算
性能实测数据
在 AWS g4dn.xlarge 实例 (T4 GPU) 的测试结果:
| 优化手段 | 吞吐量提升 | 显存占用下降 |
|---|---|---|
| 动态批处理 | 2.8x | 15% |
| TensorRT 优化 | 3.1x | 40% |
| 模型分片(2 卡) | 1.9x | 55% |
| 综合优化 | 5.7x | 65% |
避坑指南
内存碎片预防
- 使用
torch.cuda.empty_cache()前先同步设备 - 为不同生命周期张量分配独立 CUDA Stream
- 启用
PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128
CUDA 流最佳实践
# 创建专用计算流
compute_stream = torch.cuda.Stream()
# 典型使用模式
with torch.cuda.stream(compute_stream):
output = model(input)
torch.cuda.current_stream().wait_stream(compute_stream)
延伸思考
精度与性能的平衡
- 量化校准:使用 500-1000 个代表性样本进行校正
- 混合精度:对敏感层保持 FP16,其他层使用 INT8
- 动态精度:根据请求 QoS 自动切换精度模式
Kubernetes 弹性调度建议
- 基于 Prometheus 指标实现 HPA 自动扩缩
- 使用 Node Affinity 绑定特定 GPU 机型
- 通过 Batch Job 处理离线推理任务
# Triton 典型配置示例(config.pbtxt)
platform: "pytorch_libtorch"
max_batch_size: 64
dynamic_batching {preferred_batch_size: [16, 32]
max_queue_delay_microseconds: 5000
}
instance_group [
{
count: 2
kind: KIND_GPU
}
]
经过这些优化,我们成功将线上服务的单卡 QPS 从 80 提升到 450,同时将推理成本降低 67%。关键是要根据实际业务特点选择合适的优化组合——没有放之四海而皆准的银弹方案。
正文完
