无法加载 XGBoost 库 (libxgboost.so)

kel*_*lin 5 python docker aws-lambda xgboost serverless-framework

问题

在无服务器项目中,我想将 XGBoost 导入到用 Python 编写的 lambda 中。但是当我尝试调用 lambda 时,我在 CloudWatch 上看到了这个错误:

[错误] XGBoostError:无法加载 XGBoost 库 (libxgboost.so)。
可能的原因:
* 未安装 OpenMP 运行时(Windows 为 vcomp140.dll 或 libgomp-1.dll,类 UNIX 操作系统为 libgomp.so)
* 您在 64 位操作系统上运行 32 位 Python
错误消息: ['libgomp.so.1: 无法打开共享对象文件:没有那个文件或目录']

我尝试了什么?

  1. sls deploy在 macOS 上运行,所以我已经添加dockerizePip: true到我的 serverless.yml

  2. 我尝试通过使用自定义 Dockerfile 修复丢失的依赖项:

    FROM lambci/lambda:build-python3.6
    
    RUN apt-get update && apt-get install libaio1
    
    Run Code Online (Sandbox Code Playgroud)

    我还必须指定库路径,dockerExtraFiles但我不知道 libgomp.so 在 Linux 上的位置。所以,我坚持这一点。

我的代码

无服务器.yml:

app: improve
org: kvadrug
service: testservice

provider:
  name: aws
  runtime: python3.8
  versionFunctions: false
  stage: dev
  region: us-west-2
  timeout: 30

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    dockerFile: Dockerfile
    zip: true
    dockerizePip: true

functions:
  hello:
    handler: hello.hello
    events:
      - http:
          path: hello
          method: post
          private: true
Run Code Online (Sandbox Code Playgroud)

包.json:

{
    "name": "testservice",
    "version": "1.0.0",
    "description": "Test service",
    "dependencies": {},
    "devDependencies": {
        "serverless-python-requirements": "^5.1.0"
    }
}
Run Code Online (Sandbox Code Playgroud)

要求.txt:

xgboost==1.0.2
Run Code Online (Sandbox Code Playgroud)

Ale*_*ade 5

工作配置 - Python 3.7

在 Mojave 10.14.6 (18G4032) 和 Docker v2.1.0.2 (37877) 上测试。

脚步:

sls requirements clean
rm -Rf ~/Library/Caches/serverless-python-requirements/
sls deploy
Run Code Online (Sandbox Code Playgroud)

要求.txt:

xgboost==1.0.2
Run Code Online (Sandbox Code Playgroud)

无服务器.yml:

service: xgboost
provider:
  name: aws
  timeout:60
  runtime: python3.7

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    zip: true
    dockerizePip: non-linux
    dockerExtraFiles:
      - /usr/lib64/libgomp.so.1

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: post
          private: true
Run Code Online (Sandbox Code Playgroud)

处理程序.py:

    try:
        import unzip_requirements
    except ImportError:
        pass

    import sys
    import glob
    import os

    def hello(event, context):
        pkgdir = '/tmp/sls-py-req/'

        print("-------- Sys Path --------")
        for p in sys.path:
            print(p)

        if os.path.exists(pkgdir):
            print("-------- Pkg Dir ----------")
            os.chdir(pkgdir)
            for file in glob.glob("*"):
                print(file)

        print("-------- Var Task ----------")
        os.chdir("/var/task")
        for file in glob.glob("*"):
            print(file)

        try:
            import xgboost as xgb
            print(xgb)
        except Exception as ex:
            template = "An exception of type {0} occurred. Arguments:\n{1!r}"
            message = template.format(type(ex).__name__, ex.args)
            print(message)

        return True
Run Code Online (Sandbox Code Playgroud)

Python 3.8

由于某种原因,运行 Python 3.8 的 Lambda 会忽略'sys.path'上的'/tmp/sls-py-req'条目。因此,您需要手动将库文件“libgomp.so.1”添加到应用程序的根目录。

要尝试一下,请将serverless.yml 上的“runtime: python3.7”更新为“runtime: python3.8”,并按照以下步骤操作:

sls requirements clean
rm -Rf ~/Library/Caches/serverless-python-requirements/
sls package
cp .serverless/requirements/libgomp.so.1 ./
sls deploy
Run Code Online (Sandbox Code Playgroud)

仅供参考 - 如何在 Lambda docker 映像中查找库位置

跑步:

docker run --rm -ti --entrypoint /bin/sh -u 0 lambci/lambda\:build-python3.8
Run Code Online (Sandbox Code Playgroud)

然后:

find / -name libgomp.so.1
Run Code Online (Sandbox Code Playgroud)