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

SageMaker Batch Transform多图像mini-batch>1推理异常排查

问题根源

你的配置和代码存在两个核心错配,直接导致拿到的字节是混乱的:

  • split_type='Line' 仅适用于按换行分隔的文本类输入(如CSV、JSON Lines),JPEG是二进制格式,不存在按行拆分的逻辑,SageMaker会粗暴按字节中的换行符切割二进制内容,直接把图片切碎。
  • 开启strategy='MultiRecord'后,SageMaker不会直接裸拼多张图片的字节发给容器——二进制格式没有天然分隔符,无法直接拆分单张边界,SageMaker会用带长度标记的RecordIO格式封装批量记录,你当前直接把整个请求体当单张JPEG读取,自然会读到混合了格式头、多图内容的异常字节。
修正方案

第一步:调整批量转换配置

首先要保证输入路径下每张图片单独存储为一个独立S3对象,不要把多张图片打包成单个大文件上传,二进制图片无法被自动切分。
配置修改如下:

transformer = sagemaker.transformer.Transformer(
    model_name=model_name, 
    instance_count=instance_count, 
    instance_type=instance_type,
    max_concurrent_transforms=16,
    max_payload=5, # 单批次请求最大体积,单位MB,根据单张图大小调整即可控制单批次包含的图片数量
    output_path=inference_output_data,
    strategy='MultiRecord',
    assemble_with='RecordIO' # 指定用RecordIO格式封装批量记录
)
transformer.transform(
    data=batch_input,
    content_type='image/jpeg',
    job_name=job_name,
    split_type=None, # 关闭行切分,每个S3独立对象即为单个样本
    wait=False,
    logs=False
)

第二步:修改容器端推理逻辑,解析批量请求

你需要在接口中解析RecordIO格式的请求体,按长度标记拆分出每张图片的原始字节,再做批量预处理,示例代码如下:

import struct
import io
from PIL import Image
import flask

@app.route('/invocations', methods=['POST'])
def transformation():
    request_bytes = flask.request.data
    preprocessed_imgs = []
    offset = 0
    total_len = len(request_bytes)

    while offset < total_len:
        # 校验RecordIO魔数
        magic_num, = struct.unpack('<I', request_bytes[offset:offset+4])
        if magic_num != 0xced7230a:
            flask.abort(400, description="Invalid request format")
        offset += 4
        # 读取当前记录长度
        img_len, = struct.unpack('<I', request_bytes[offset:offset+4])
        offset +=4
        # 读取单张图片字节并做预处理
        single_img_bytes = request_bytes[offset:offset+img_len]
        offset += img_len
        img = Image.open(io.BytesIO(single_img_bytes))
        preprocessed_imgs.append(preprocess_image(img))
    
    # 按下游Triton服务要求的格式封装批量预处理结果并返回
    return build_response_for_triton(preprocessed_imgs)

备选方案(无需解析RecordIO)

如果不需要mini-batch带来的吞吐提升,可以直接把strategy设为SingleRecord,保持split_type=None,此时每个POST请求仅携带单张图片,你之前batch size=1的代码可以直接运行,不需要修改解析逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:24:26