[普通]深入了解Python的wheel文件格式

作者(passion) 阅读(506次) 评论(0) 分类( 软件)

背景

在进行image-service中的U-2-Net时,遇到一个问题:按照官方说明是要 PyTorch 0.4.0,考虑到仅作为演示的目的以及运行在Docker中、需要能在无GPU的环境运行等因素安装CPU版本的PyTorch,但是直接按照官方的安装命令无法安装。

搜索了一下,最终在历史版本下载的页面,下载了torch-0.4.0-cp36-cp36m-linux_x86_64.whl

在进行Docker镜像的构建时,Dockerfile中

COPY torch-0.4.0-cp36-cp36m-linux_x86_64.whl /
RUN pip3 install  torch-0.4.0-cp36-cp36m-linux_x86_64.whl && rm -f  torch-0.4.0-cp36-cp36m-linux_x86_64.whl

但是这样做有两个问题:

  1. torch-0.4.0-cp36-cp36m-linux_x86_64.whl 需要在代码库中;虽说可以通过 Git LFS相关技术 上传,但总归不是好的实践

  2. 会增大生成的镜像文件的体积

后来,又根据推断试验一番

RUN pip3 install torch==0.4.0 -f https://download.pytorch.org/whl/torch_stable.html

可以看到在这一步要下载pytorch 484M,离缩减镜像体积的目标更远了……

自建一pypi包

受之前 创建dlib-binary包的影响,想到:是否可以自建一个whl包,上传到 pypi上,然后就可以直接pip安装了?

步骤

于是,又根据官网文档

创建 LICENSEREADME.md 等

创建 setup.py

import setuptools

with open("README.md", "r") as fh:
   long_description = fh.read()

setuptools.setup(
   name="torch-u2net",
   version="0.4.0",
   author="linxiaohui",
   author_email="llinxiaohui@126.com",
   description="U-2-Net安装所需要的pytorch"
   long_description=long_description,
   long_description_content_type="text/markdown",
   url="https://github.com/linxiaohui/image-service",
   packages=setuptools.find_packages(),
   classifiers=[
       "Programming Language :: Python :: 3",
       "License :: OSI Approved :: MIT License",
       "Operating System :: POSIX :: Linux",
       "Programming Language :: Python :: 3.6"
   ],
   python_requires='>=3.6',
)

将下载的 torch-0.4.0-cp36-cp36m-linux_x86_64.whl文件名修改为torch_u2net-0.4.0-cp36-cp36m-manylinux1_x86_64.whl, 放在dist目录下

执行twine upload dist/*

问题

经过一段时间的等待(文件上传上去,70M+):

报错,无权限上传torch……

分析

于是推测,包的名称不是仅仅根据文件名的,whl文件内部也有什么地方标记了包的名字

上网搜索whl格式发现,有人提到它就是一个压缩包;在Linux中,使用归档管理器解压缩 whl文件,产生两个目录torchtorch-0.4.0.dist-info, 前者里分析是使用时实际调用的代码和包,推测后者是包名相关的内容

考虑修改其名称进行试验。考虑到文件格式的问题,决定使用归档管理器打开, 在压缩包中修改。修改了文件夹的名字后发现,里面有文件METADATAtop_level.txt, 其中也有涉及到包名称的字段,修改之;

进而发现其中RECORD文件,其中有包中各个文件的名字以及其SHA256值和文件大小;但其SHA256值内容与openssl sha256计算出来并不一样; 于是继续搜索,在 Wheel文件格式找到了答案:是文件SHA256的值的BASE64编码去掉尾部的=

可以用以下Python代码计算

import sys
import base64
import hashlib

def calc_sha(f_path):
   """Calculates the base64-encoded SHA hash of a file."""
   sha = hashlib.sha256()
   with open(f_path, "rb") as fp:
       sha.update(fp.read())
   r = sha.digest()
   r = base64.urlsafe_b64encode(r)
   return r

print(calc_sha(sys.argv[1]))

或者SHELL命令
openssl dgst -binary -sha256 METADATA| openssl base64

至此,修改whl包的步骤完成了

上传

twine upload dist/* 成功执行,pypi网站上可以查到包 torch-u2net

Dockerfile

RUN pip3 install --no-cache-dir torch-u2net==0.4.0

效果

u-2-net                     3.0                 fde2b078aaa2        About an hour ago   861MB
u-2-net                     2.0                 52dfed27f635        6 hours ago         2.11GB
u-2-net                     1.0                 36173b6469fc        7 hours ago         940MB

其中 1.0 是COPY后install的; 2.0 是直接安装的(-f参数); 3.0 是安装了这里新建的 torch-u2net的

可以看出效果比较显著(镜像体积缩小了torch安装包的大小);并且代码库比较”整洁”


« 上一篇:tensorflow 下载地址分享
« 下一篇:关于ChatGPT八个技术问题的猜想
在这里写下您精彩的评论
  • 微信

  • QQ

  • 支付宝

返回首页
返回首页 img
返回顶部~
返回顶部 img