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

SageMaker推理脚本初始化S3客户端时触发递归深度超限错误

解决AWS SageMaker推理脚本中boto3 S3客户端递归深度超限错误

问题分析

从错误栈可以明确,递归循环发生在Python标准库ssl.py的SSLContext.options属性赋值环节。这是因为gevent猴子补丁改写了属性访问逻辑,与Python 3.10+版本中SSLContext的super()调用实现产生冲突,最终形成无限递归。

解决方案

方案1:全局初始化S3客户端(最优解)

每次推理请求都创建新的S3客户端不仅会触发递归问题,还会浪费资源。将客户端初始化移至模块全局作用域,仅创建一次:

# 模块顶部执行,仅初始化一次
import boto3
s3_client = boto3.client('s3')

def get_video_bytes_from_s3(bucket_name, key):
    try:
        video_object = s3_client.get_object(Bucket=bucket_name, Key=key)
        video_bytes = video_object['Body'].read()
        return video_bytes
    except Exception as e:
        print(f"Failed to fetch video from S3: {e}")

方案2:缩小gevent猴子补丁范围

若必须使用gevent,避免全量补丁,仅patch必要模块并排除ssl:

from gevent import monkey
# 只patch核心模块,跳过ssl以避免冲突
monkey.patch_all(ssl=False)

方案3:强制boto3使用原生HTTP会话

让boto3绕过gevent补丁的HTTP会话,改用原生urllib3实现:

from botocore.httpsession import URLLib3Session

def get_video_bytes_from_s3(bucket_name, key):
    # 创建带原生会话的S3客户端
    s3_client = boto3.client('s3', config=boto3.session.Config(
        http_session=URLLib3Session()
    ))
    try:
        video_object = s3_client.get_object(Bucket=bucket_name, Key=key)
        video_bytes = video_object['Body'].read()
        return video_bytes
    except Exception as e:
        print(f"Failed to fetch video from S3: {e}")

方案4:降级Python版本(临时应急)

若以上方案无法快速落地,可将SageMaker容器的Python版本降级至3.9及以下,该版本的SSLContext实现不会触发此递归问题。

验证方式

将修改后的推理脚本部署到SageMaker端点,测试S3对象读取功能,检查CloudWatch日志是否不再出现递归错误。

内容的提问来源于stack exchange,提问作者Mustapha Unubi Momoh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:27:33