You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Amazon SageMaker批量转换GPU利用率为零问题求助

问题:SageMaker批量转换GPU利用率为0但显存占满,推理速度慢

我把本地GPU训练的Keras(TensorFlow后端)图像分类模型部署到AWS SageMaker,用Batch Transform做批量预测时,任务能成功运行,但CloudWatch显示GPU利用率始终为0,可GPU显存利用率却到了97%,处理500张图片花了7分钟,比本地GPU慢太多了。更奇怪的是,同一模型部署到实时端点时,GPU是能正常使用的。


模型准备步骤

我按照AWS指南把Keras模型转成了SageMaker兼容的格式,代码如下:

import tensorflow as tf
from tensorflow.python.saved_model import builder
from tensorflow.python.saved_model.signature_def_utils import predict_signature_def
from tensorflow.python.saved_model import tag_constants
import tarfile
import sagemaker

# 禁用即时执行模式
if tf.executing_eagerly():
    tf.compat.v1.disable_eager_execution()

builder = builder.SavedModelBuilder(export_dir)
# 创建供TensorFlow Serving Predict API使用的预测签名
signature = predict_signature_def(
    inputs={"image_bytes": model.input},
    outputs={"score_bytes": model.output})

with tf.compat.v1.keras.backend.get_session() as sess:
    # 保存元图和变量
    builder.add_meta_graph_and_variables(
        sess=sess,
        tags=[tag_constants.SERVING],
        signature_def_map={"serving_default": signature})
    builder.save()

with tarfile.open(tar_model_file, mode='w:gz') as archive:
    archive.add('export', recursive=True)

sagemaker_session = sagemaker.Session()
s3_uri = sagemaker_session.upload_data(path=tar_model_file, bucket=bucket, key_prefix=sagemaker_model_dir)

批量转换配置

我用的是GPU推理镜像:763104351884.dkr.ecr.eu-central-1.amazonaws.com/tensorflow-inference:2.0.0-gpu,相关配置代码:

framework = 'tensorflow'
instance_type='ml.p3.2xlarge'
image_scope = 'inference'
tf_version = '2.0.0'
py_version = '3.6'

sagemaker_model = TensorFlowModel(model_data=MODEL_TAR_ON_S3, role=role, image_uri=tensorflow_image)
transformer = sagemaker_model.transformer(
    instance_count = 1,
    instance_type = instance_type,
    strategy='MultiRecord',
    max_concurrent_transforms=8,
    max_payload=10, # 单位MB
    output_path = output_data_path,
)
transformer.transform(data = input_data_path, job_name = job_name, content_type = 'application/json', logs=False, wait=True )

日志片段

模型加载耗时很长,期间出现这些错误和警告:

2020-11-08T15:14:12.433+01:00 2020/11/08 14:14:12 [error] 14#14: *3066 no live upstreams while connecting to upstream, client: 169.254.255.130, server: , request: "GET /ping HTTP/1.1", subrequest: "/v1/models/my_model:predict", upstream: "http://tfs_upstream/v1/models/my_model:predict", host: "169.254.255.131:8080"
2020-11-08T15:14:12.433+01:00 169.254.255.130 - - [08/Nov/2020:14:14:12 +0000] "GET /ping HTTP/1.1" 502 157 "-" "Go-http-client/1.1"
...(其他502错误日志)

还有:

successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
No warmup data file found at /opt/ml/model/export/my_model/1/assets.extra/tf_serving_warmup_requests
[warn] getaddrinfo: address family for nodename not supported


问题分析与解决方案

结合你的配置和日志,我来拆解一下这个问题:核心是模型已经加载到GPU(所以显存占满),但推理计算完全落到了CPU上,导致GPU利用率为0。下面是针对性的解决思路:

1. 优先升级TensorFlow版本(TF 2.0的批量推理GPU坑)

你用的TF 2.0.0是比较早期的版本,SageMaker的TF 2.0推理容器在Batch Transform模式下,存在TensorFlow Serving没有正确绑定GPU的已知问题——哪怕GPU存在,批量请求也会默认 fallback到CPU计算。

解决办法:

  • 直接升级到TF 2.3+的GPU镜像,比如763104351884.dkr.ecr.eu-central-1.amazonaws.com/tensorflow-inference:2.3.0-gpu,新版本容器修复了大量批量推理的GPU调度bug。
  • 如果必须保留TF 2.0,就在创建TensorFlowModel时添加环境变量,强制Serving使用GPU:
    sagemaker_model = TensorFlowModel(
        model_data=MODEL_TAR_ON_S3, 
        role=role, 
        image_uri=tensorflow_image,
        env={
            'TF_FORCE_GPU_ALLOW_GROWTH': 'true',
            'CUDA_VISIBLE_DEVICES': '0'
        }
    )
    

2. 检查输入格式与模型签名的匹配度

你的模型签名定义的输入是image_bytes(原始图片字节),但批量转换用的content_type='application/json'——如果你的输入是JSON格式的像素数组,而非原始图片字节,TensorFlow Serving会在CPU上做格式转换和预处理,进而导致整个推理流程落到CPU,GPU只用来存储模型权重。

调整建议:

  • 如果输入是原始图片文件,把content_type改成application/x-image;
  • 如果输入是JSON格式的像素数据,修改模型导出时的签名,把输入名改成和JSON字段匹配的名称(比如inputs={"input": model.input}),确保数据能直接传到GPU张量中。

3. 优化批量转换的并发配置

你设置的max_concurrent_transforms=8可能超出了ml.p3.2xlarge的GPU处理能力,导致请求排队,反而让GPU看起来“没干活”。另外MultiRecord策略需要模型支持批量输入才能发挥作用。

调整建议:

  • 先把max_concurrent_transforms降到2-4,观察GPU利用率变化,找到合适的并发数;
  • 确认模型输入形状是(None, height, width, channels)(支持批量输入),这样MultiRecord才能把多个图片打包成一个批量请求,让GPU并行处理。

4. 补充模型预热文件(辅助优化)

日志里的No warmup data file found虽然不是直接原因,但模型加载后没有预热请求,第一次推理会初始化GPU上下文,导致启动阶段慢,也可能让Serving没有正确绑定GPU。你可以生成预热请求文件放到模型的assets.extra目录下:

  • 用TensorFlow的SavedModel Warmup API生成tf_serving_warmup_requests文件,放到export/1/assets.extra/目录后再打包模型上传到S3,让Serving启动时就初始化GPU环境。

关于其他日志警告

  • NUMA node警告是容器和实例的NUMA配置不匹配,属于环境兼容问题,不影响GPU使用,无需处理;
  • 502 Bad Gateway是模型加载过慢导致的健康检查临时失败,等模型加载完成后会自动恢复,和GPU利用率无关。

内容的提问来源于stack exchange,提问作者phi_abs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:57:38