【问题标题】:Unexpected error when loading the model: problem in predictor - ModuleNotFoundError: No module named 'torchvision'加载模型时出现意外错误:预测器中的问题 - ModuleNotFoundError: No module named 'torchvision'
【发布时间】:2020-09-08 01:06:31
【问题描述】:

我一直在尝试通过我的 vm 实例上的控制台将我的模型部署到 AI 平台进行预测,但我收到了错误“(gcloud.beta.ai-platform.versions.create) 创建版本失败. 检测到错误模型并出现错误:“加载模型失败:加载模型时出现意外错误:预测器中的问题 - ModuleNotFoundError: No module named 'torchvision' (Error code: 0)”

我需要同时包含torchtorchvision。我按照这个问题Cannot deploy trained model to Google Cloud Ai-Platform with custom prediction routine: Model requires more memory than allowed 中的步骤操作,但我无法获取用户gogasca 指向的文件。我尝试从 Pytorch 网站下载 this .whl 文件并将其上传到我的云存储,但得到了相同的错误,即没有模块 torchvision,即使这个版本应该包括 torch 和 torchvision。还尝试使用 Cloud AI 兼容包 here,但它们不包括 torchvision

我尝试在 --package-uris 参数中为 torchtorchvision 指向两个单独的 .whl 文件,这些文件指向我的云存储中的文件,但后来我收到超出内存容量的错误。这很奇怪,因为它们的总大小约为 130Mb。导致torchvision 缺失的命令示例如下所示:

gcloud beta ai-platform versions create version_1 \
  --model online_pred_1 \
  --runtime-version 1.15 \
  --python-version 3.7 \
  --origin gs://BUCKET/model-dir \
  --package-uris gs://BUCKET/staging-dir/my_package-0.1.tar.gz,gs://BUCKET/torchvision-dir/torch-1.4.0+cpu-cp37-cp37m-linux_x86_64.whl \
  --prediction-class predictor.MyPredictor

我尝试指向从不同来源获得的 .whl 文件的不同组合,但得到了无模块错误或内存不足。我不明白在这种情况下模块如何交互以及为什么编译器认为没有这样的模块。我该如何解决这个问题?或者,我如何自己编译一个包含torchtorchvision 的包。能否请您给出详细的答案,因为我对包管理和 bash 脚本不是很熟悉。

这是我使用的代码,torch_model.py

from torch import nn


class EthnicityClassifier44(nn.Module):
    def __init__(self, num_classes=2):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=7, stride=1, padding=3)
        self.maxpool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv22 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1)
        self.maxpool2 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv3 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        self.maxpool3 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv4 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
        self.maxpool4 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.relu = nn.ReLU(inplace=False)
        self.fc1 = nn.Linear(8*8*128, 128)
        self.fc2 = nn.Linear(128, 128)
        self.fc4 = nn.Linear(128, num_classes)


    def forward(self, x):
        x = self.relu(self.conv1(x))
        x = self.maxpool1(x)
        x = self.relu(self.conv22(x))
        x = self.maxpool2(x)
        x = self.maxpool3(self.relu(self.conv3(x)))
        x = self.maxpool4(self.relu(self.conv4(x)))
        x = self.relu(self.fc1(x.view(x.shape[0], -1)))
        x = self.relu(self.fc2(x))
        x = self.fc4(x)
        return x

这是predictor_py

from facenet_pytorch import MTCNN, InceptionResnetV1, extract_face
import torch
import torchvision
from torchvision import transforms
from torch.nn import functional as F
from PIL import Image
from sklearn.externals import joblib
import numpy as np
import os
import torch_model


class MyPredictor(object):

    import torch
    import torchvision

    def __init__(self, model, preprocessor, device):
        """Stores artifacts for prediction. Only initialized via `from_path`.
        """
        self._resnet = model
        self._mtcnn_mult = preprocessor
        self._device = device
        self.get_std_tensor = transforms.Compose([
            np.float32,
            np.uint8,
            transforms.ToTensor(),
        ])
        self.tensor2pil = transforms.ToPILImage(mode='RGB')
        self.trans_resnet = transforms.Compose([
            transforms.Resize((100, 100)),
            np.float32,
            transforms.ToTensor()
        ])

    def predict(self, instances, **kwargs):

        pil_transform = transforms.Resize((512, 512))

        imarr = np.asarray(instances)
        pil_im = Image.fromarray(imarr)
        image = pil_im.convert('RGB')
        pil_im_512 = pil_transform(image)

        boxes, _ = self._mtcnn_mult(pil_im_512)
        box = boxes[0]

        face_tensor = extract_face(pil_im_512, box, margin=40)
        std_tensor = self.get_std_tensor(face_tensor.permute(1, 2, 0))
        cropped_pil_im = self.tensor2pil(std_tensor)

        face_tensor = self.trans_resnet(cropped_pil_im)
        face_tensor4d = face_tensor.unsqueeze(0)
        face_tensor4d = face_tensor4d.to(self._device)

        prediction = self._resnet(face_tensor4d)
        preds = F.softmax(prediction, dim=1).detach().numpy().reshape(-1)
        print('probability of (class1, class2) = ({:.4f}, {:.4f})'.format(preds[0], preds[1]))

        return preds.tolist()

    @classmethod
    def from_path(cls, model_dir):
        import torch
        import torchvision
        import torch_model

        model_path = os.path.join(model_dir, 'class44_M40RefinedExtra_bin_no_norm_7860.joblib')
        classifier = joblib.load(model_path)

        mtcnn_path = os.path.join(model_dir, 'mtcnn_mult.joblib')
        mtcnn_mult = joblib.load(mtcnn_path)

        device_path = os.path.join(model_dir, 'device_cpu.joblib')
        device = joblib.load(device_path)

        return cls(classifier, mtcnn_mult, device)

还有setup.py:

from setuptools import setup

REQUIRED_PACKAGES = ['opencv-python-headless', 'facenet-pytorch']

setup(
 name="my_package",
 version="0.1",
 include_package_data=True,
 scripts=["predictor.py", "torch_model.py"],
 install_requires=REQUIRED_PACKAGES
)

【问题讨论】:

  • “这个版本应该包括 torch 和 torchvision” - 不,这只是 torch 本身。 torchvision 比较小(即使是 GPU 版本也只有 20MB 左右),所以 PyPI 版本应该没问题。但我真的不知道torchvision 会安装在哪里。它不在您的REQUIRED_PACKAGES 中,也不在requirements of facenet-pytorch 中。您可以尝试将'torchvision==0.5.0' 添加到REQUIRED_PACKAGES 吗? 0.5.0 因为那是 PyTorch 1.4.0 的版本。
  • @MichaelJungo,感谢您的回复!我之前尝试过,但出现错误,指出空间不足(gcloud.beta.ai-platform.versions.create) Create Version failed. Bad model detected with error: Model requires more memory than allowed. Please try to decrease the model size an d re-deploy.。我又试了一次,同样的错误,这没有意义,因为tochvision确实很小。
  • @MichaelJungo 此外,我发现 facenet-pytorch 在设置文件中没有 torchvision 很奇怪,因为它用于 detect_face 模块 here
  • torchvision 依赖于torch,所以它也会自动尝试安装它。然后您需要确保它获取torch 的CPU 版本,您可以尝试同时指定torch==1.4.0+cpu 作为要求,这样torchvision 就不会尝试获取常规torch,这将是GPU 版本。
  • @MichaelJungo 我将torch 和torchvision 作为单独的条目传递给REQUIRED_PACKAGES。我还在--package-uris 参数中省略了指向我的云存储中包含torch 的.whl 包的链接。得到以下错误,这是新的:Bad model detected with error: "Failed to load model: User-provided package my_package-0.1.tar.gz failed to ins tall: Command '['python-default', '-m', 'pip', 'install', '--target=/tmp/custom_lib', '--no-cache-dir', '-b', '/tmp/pip_builds', '/tmp/custom_code/my_package-0.1.tar.gz']' returned non -zero exit status 1. (Error code: 0)

标签: python google-cloud-platform pytorch google-cloud-ml gcp-ai-platform-training


【解决方案1】:

解决方案是将以下包放入自定义预测代码的 thsetup.py 文件中:

REQUIRED_PACKAGES = ['torchvision==0.5.0', 'torch @ https://download.pytorch.org/whl/cpu/torch-1.4.0%2Bcpu-cp37-cp37m-linux_x86_64.whl', 'opencv-python', 'facenet-pytorch']

然后我在自定义类实例化方面遇到了不同的问题,但this 文章很好地解释了它。因此,我能够成功地将我的模型部署到 AI 平台进行预测。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 2021-03-13
    • 2020-12-29
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 2022-10-13
    相关资源
    最近更新 更多