【问题标题】:what causes an unpickling stack underflow when trying to serialize a succesfully generated SageMaker model尝试序列化成功生成的 SageMaker 模型时导致 unpickling 堆栈下溢的原因
【发布时间】:2021-09-08 08:32:46
【问题描述】:

我目前正致力于在 Amazon Sagemaker 中设置管道。为此,我设置了一个 xgboost-estimator 并在我的数据集上对其进行了训练。训练作业按预期运行,新训练的模型将保存到指定的输出存储桶中。稍后我想重新导入模型,这是通过从输出存储桶中获取 mode.tar.gz,提取模型并通过 pickle 序列化二进制文件来完成的。

# download the model artifact from AWS S3
!aws s3 cp s3://my-bucket/output/sagemaker-xgboost-2021-09-06-12-19-41-306/output/model.tar.gz .

# opens the downloaded model artifcat and loads it as 'model' variable
model_path = "model.tar.gz"
with tarfile.open(model_path) as tar:
    tar.extractall(path=".")

model = pkl.load(open("xgboost-model", "rb"))

每当我尝试调整这个时,我都会收到一个 unpickling 堆栈下溢:

---------------------------------------------------------------------------
UnpicklingError                           Traceback (most recent call last)
<ipython-input-9-b88a7424f790> in <module>
     10     tar.extractall(path=".")
     11 
---> 12 model = pkl.load(open("xgboost-model", "rb"))
     13 

UnpicklingError: unpickling stack underflow

到目前为止,我重新训练了模型以查看错误是否发生在不同的模型文件中,并且确实如此。我还下载了 model.tar.gz 并通过 gunzip 对其进行了验证。当提取二进制文件 xgboost-model 正确提取时,我就是无法腌制它。我在 stackoverflow 上发现的每次错误都指向损坏的文件,但这个错误是由 SageMaker 直接生成的,我确实注意到对其执行任何转换,但从 model.tar.gz 中提取它。参考文档和不同的教程,重新加载这样的模型似乎是一个很常见的用例。 在本地,我收到与下载的文件相同的错误。我试图直接进入pickle进行调试,但无法理解它。完整的错误堆栈如下所示:

Exception has occurred: UnpicklingError       (note: full exception trace is shown but execution is paused at: _run_module_as_main)
unpickling stack underflow
  File "/sagemaker_model.py", line 10, in <module>
    model = pkl.load(open('xgboost-model', 'rb'))
  File "/usr/local/Cellar/python@3.9/3.9.1_5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/local/Cellar/python@3.9/3.9.1_5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/local/Cellar/python@3.9/3.9.1_5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 268, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "/usr/local/Cellar/python@3.9/3.9.1_5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/local/Cellar/python@3.9/3.9.1_5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 197, in _run_module_as_main (Current frame)
    return _run_code(code, main_globals, None,

什么可能导致此问题,我可以在此过程中的哪个步骤应用更改来修复或解决问题。

【问题讨论】:

  • 试试这个with tarfile.open(fname, "r:gz") as tar。因为错误 unpickling stack underflow 可能会在 pickle 意外结束时发生,这可能表明文件已损坏或未正确提取。
  • model_path = "model.tar.gz" with tarfile.open(model_path, "r:gz") as tar: tar.extractall(path=".") model = pkl.load(open("xgboost-model", "rb")) 产生相同的解酸错误,提取本身至少会生成正确命名的二进制文件
  • 您能否在提取的泡菜上运行命令文件以确认文件类型。 man7.org/linux/man-pages/man1/file.1.html?
  • 文件只是说“数据”。感谢您的努力。

标签: python-3.x pickle amazon-sagemaker


【解决方案1】:

最新的 XGBoost 版本似乎改变了这个过程。这适用于1.3.x

import xgboost as xgb

model = xgb.Booster()
model.load_model('xgboost-model')

【讨论】:

    【解决方案2】:

    问题源于用于 xgboost 框架的模型版本。从 1.3.0 开始,默认输出从 pickle 更改为 json,并且 sagemaker 文档似乎没有相应更新。所以如果你想通过

    阅读模型
        tar.extractall(path=".")
    
    model = pkl.load(open("xgboost-model", "rb"))
    

    如 sagemaker 文档中所述,您需要使用旧版本导入 XGBOOST 框架,例如1.2.1.

    【讨论】:

    • 我也有同样的问题。你能解释一下你是如何一步一步解决这个问题的吗?
    • 当您像构建估计器一样导入框架时,像 estimator = XGBoost(...)。框架必须设置为 1.2.1 而不是 ^1.3.0,因为从这个版本开始,modeloutput 不再使用 pickle 序列化。
    【解决方案3】:

    阅读@Imoe41 的答案后,我也想为这个问题做出贡献。问题是,如果您单击错误中的链接,您会看到 (https://xgboost.readthedocs.io/en/latest/tutorials/saving_model.html),从 xgboost 的 1.0 版开始,模型被保存在 json 中,而在 1.0 版之前,模型被保存在 pickle 中。 我在 2020 年用 sagemaker 训练了 xgboost 模型,使用的是 0.90 的 xgboost 版本。但是,在我的笔记本中,xgboost 软件包的版本是 1.5.1。

    解决方案:

    1. 检查已安装 xgboost 的版本

    将 xgboost 导入为 xgb print(xgb.version)

    1. 如果版本高于 1.0,则需要降级。要降级 xgboost,您还需要降级其他软件包。
    pip install scipy==1.4.1
    pip install shap==0.37.0
    pip install xgboost==0.90.0
    
    1. 将模型加载为泡菜
    import pickle as pkl
    import tarfile
    t = tarfile.open('model.tar.gz', 'r:gz')
    t.extractall()
    model = pkl.load(open("xgboost-model", 'rb'))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-20
      • 1970-01-01
      • 2012-08-31
      • 2011-07-26
      • 2023-04-03
      • 2018-07-30
      • 2015-05-21
      • 2014-02-14
      相关资源
      最近更新 更多