【问题标题】:Loading the pre-trained model of torch and sentence_transformers when running in a docker container failing在 docker 容器中运行时加载预训练的 torch 和 sentence_transformers 模型失败
【发布时间】:2021-01-08 17:47:30
【问题描述】:

在尝试在 docker 容器中运行时,我在加载预先训练的 torch 模型和 sentence_transformers("distilbert-base-nli-stsb-mean-tokens") 时遇到错误。

Error: Invalid value for '-A' / '--app': 
 Unable to load celery application.
 While trying to load the module app.celery the following error occurred:
 Traceback (most recent call last):
   File "/usr/local/lib/python3.8/site-packages/celery/bin/celery.py", line 53, in convert
     return find_app(value)
   File "/usr/local/lib/python3.8/site-packages/celery/app/utils.py", line 384, in find_app
     sym = symbol_by_name(app, imp=imp)
   File "/usr/local/lib/python3.8/site-packages/kombu/utils/imports.py", line 56, in symbol_by_name
     module = imp(module_name, package=package, **kwargs)
   File "/usr/local/lib/python3.8/site-packages/celery/utils/imports.py", line 100, in import_from_cwd
     return imp(module, package=package)
   File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
     return _bootstrap._gcd_import(name[level:], package, level)
   File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
   File "<frozen importlib._bootstrap>", line 991, in _find_and_load
   File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
   File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
   File "<frozen importlib._bootstrap_external>", line 783, in exec_module
   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
   File "/code/app.py", line 997, in <module>
     load_model()
   File "/code/app.py", line 255, in load_model
     embedder = SentenceTransformer('distilbert-base-nli-stsb-mean-tokens')
   File "/usr/local/lib/python3.8/site-packages/sentence_transformers/SentenceTransformer.py", line 48, in __init__
     os.makedirs(model_path, exist_ok=True)
   File "/usr/local/lib/python3.8/os.py", line 213, in makedirs
     makedirs(head, exist_ok=exist_ok)
   File "/usr/local/lib/python3.8/os.py", line 213, in makedirs
     makedirs(head, exist_ok=exist_ok)
   File "/usr/local/lib/python3.8/os.py", line 213, in makedirs
     makedirs(head, exist_ok=exist_ok)
   [Previous line repeated 1 more time]
   File "/usr/local/lib/python3.8/os.py", line 223, in makedirs
     mkdir(name, mode)
 PermissionError: [Errno 13] Permission denied: '/nonexistent'

这里是说创建文件夹时权限被拒绝错误。但我尝试在Dockerfile 中提供USER root。纠结这个问题很久了。请任何人在这里帮助我。

更新: 我的 Dockerfile:

FROM python:3.8.5-slim

WORKDIR /code

ENV ENVIRONMENT='LOCAL'
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN apt-get update && apt-get install -y sudo netcat apt-utils
RUN apt-get install -y python3-dev  build-essential python3-pip

COPY ./requirements_local.txt /code/requirements_local.txt
RUN pip install -r /code/requirements_local.txt

EXPOSE 8000
COPY . /code/

CMD [ "gunicorn", "app:app", "-b", "0.0.0.0:8000","--timeout","7200"]

Docker-compose

services:
  web:
    build: 
      context: .
      dockerfile: ./Dockerfile.prod
    hostname: flaskapp
    env_file:
      - ./.env.prod
    links:
      - redis
      - celery
    depends_on:
      - redis
    volumes:
      - data:/code
      - type: bind
        source: /home/ubuntu/models
        target: /mnt/models

【问题讨论】:

  • 可以添加 Dockerfile 吗?你如何启动容器? (请提供命令参数或撰写文件)
  • 嗨@anemyte,我刚刚添加了Dockerfile。我在 AWS EC2 上使用 docker-compose 启动。
  • 似乎是 gunicorn 工作人员在运行您的脚本(创建目录)。出于安全原因,它们不能在 root 下运行,但为了测试,您可以同时以 root 运行容器和 gunicorn worker 来检查理论。
  • 如何在 Dockerfile 中以 root 身份运行 gunicorn。我尝试使用 CMD [“sudo”、“gunicorn”、“app:app”、“-b”、“0.0.0.0:8000”、“--timeout”、“7200”]。但没有成功。
  • 我自己搞定了。实际上,我也在使用 celery 和 redis。这里芹菜实际上是造成问题的原因。它还尝试加载所有模型,但未能在 docker 中为 user:nobody 创建正确的 sentence_transformers 目录。我通过删除 celery 和 celery-beat 来测试该应用程序。现在它工作得很好。但我无法使用它们使其工作。如果您知道任何解决方案,也请告诉我。顺便说一句,我也会尝试你的方法并让你知道。谢谢。

标签: python-3.x docker docker-compose pytorch sentence-transformers


【解决方案1】:

sentence-transformers 下载模型并将其存储在 ~/.cache 目录中(或任何 cache_folder 评估的目录 - https://github.com/UKPLab/sentence-transformers/blob/a13a4ec98b8fdda83855aca7992ea793444a207f/sentence_transformers/SentenceTransformer.py#L63)。对你来说,这看起来像 /nonexistant 目录。权限被拒绝错误表明您无权访问该目录(创建缓存文件夹)。

您可以修改 Dockerfile 以创建此目录并使其可供任何需要访问此目录的用户访问:-

RUN mkdir ~/.cache
RUN chmod -R 777 ~/.cache # don't do this in production - modify command to give permission to users who require it.

或者您可以尝试在 Dockerfile 中下载模型 -

RUN python -c 'from sentence-transformers import SentenceTransformer; embedder = SentenceTransformer("distilbert-base-nli-stsb-mean-tokens")'

【讨论】:

    【解决方案2】:

    它对我有用,我正在使用 bert-base-NER

    RUN python3 -c 'from transformers import AutoTokenizer, AutoModelForTokenClassification; tokenizer = AutoTokenizer.from_pretrained("dslim/bert-base-NER"); model = AutoModelForTokenClassification.from_pretrained("dslim/bert-base-NER")'

    【讨论】:

      猜你喜欢
      • 2021-02-19
      • 2021-01-02
      • 2020-02-07
      • 2019-07-17
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      • 2019-08-28
      • 2021-03-22
      相关资源
      最近更新 更多