离线部署python项目全流程详解
python项目虚拟环境
关于虚拟环境基础知识,可参考python虚拟环境详解博文。由于个人工作需要,本文采用conda工具进行python虚拟环境配置及移植。
配置虚拟环境前,首先要对python解释器、python运行库(以下称“python依赖”或“依赖”)及其功能有初步的了解。
python解释器版本主要分python2和python3两个大版本,大版本之间有重大差异,大版本中的小版本之间也会有一定的不同。愿意深入了解的可以参考博文python版本差异总结学习。本文主要以常用的python3进行示例说明。
python依赖拥有强大的功能,能够对系统内各种工具、文件等进行操作,基本可以完成你能想到的任何任务。但是python依赖除对python解释器有版本匹配的要求外,其内部还包含大量依赖关系,并不是每个依赖的新版本都能兼容旧版本的python代码,并且某些特殊的python依赖还需要非python的第三方运行库进行支持。因此,每个python虚拟环境的依赖版本控制都是比较严格的,需要用到版本管理工具(本文使用conda)进行辅助。
这里以神经网络框架pytorch为例,pytorch除对python计算库numpy、scipy、matplotlib等有依赖要求外,还对显卡的第三方专用计算库Nvidia驱动、CUDA、CUDNN等有依赖要求。(pytorch相对方便的一点就是把cuda集成到了python依赖中,就可以不用另外安装CUDA,非常方便)
因此,如果需要配置一个包含pytorch计算库的python虚拟计算环境,并使其能够调用显卡作为算力,就需要安装显卡驱动、CUDA、CUDNN、python解释器及python依赖。
外网准备
对python及其依赖有基本了解后,就可以在具备联网条件的外网设备展开工作了
版本控制工具conda安装
Anaconda下载地址
安装过程除以下两点外,其他默认即可:
A)为降低在离线环境的工作量,请安装路径和离线环境的anaconda保持一致,本人工作需要,将anaconda安装在D盘根目录,如下所示:
B)勾选“配置环境变量”的选项
python调试工具pycharm安装
按装这个主要是为了用于运行开源python项目确认环境配置无误,对虚拟环境本身没有影响。
pycharm下载地址
**下载社区版!!!**多数python项目不需要专业版pycharm。绝大多数情况下,专业版pycharm除了增加破解难度以外没有其他作用。
安装时同样需要勾选配置环境变量的选项
python项目下载
github下载需要的项目源代码即可
python项目中一般会有一个名为readme(大小写可能有区别)的markdown文件(.md/.MD),一般都内含该项目环境要求,包括python解释器版本、python依赖库及版本、其他第三方依赖库等
初学者建议按照项目中对依赖库的最低版本要求配置虚拟环境,有一定的版本控制经验后再使用较高版本依赖库进行兼容替代
这里以经典目标检测算法YOLOv5作为部署案例进行实战讲解。进入项目github发布页后,下载源码到本地并解压即可。
配置python虚拟环境
(可选,建议新手执行)用pycharm打开项目
打开后,会发现pycharm试图自动帮助我们配置虚拟环境,这里我们先取消,因为使用venv部署虚拟环境,管理起来相对麻烦一点。
打开后,找到readme文件(YOLOv5功能完善,还有专门的中文版readme),点开后在里面会找到一段以install为标题的内容,里面包含python版本(这里是>=3.8),依赖版本以及安装指令==(在其他项目中,这段内容所在的位置及形式各不相同,最常见的是readme,具体情况需要详细阅读项目的说明文档后自行寻找)==
这里详细解释一下这几条指令的含义
git clone https://github.com/ultralytics/yolov5 # clone
该指令是使用git工具下载项目源码,我们是直接在github上下载下来了,就跳过这一步。感兴趣的可以参考git使用方法学习使用该指令。
cd yolov5
该指令是在命令行中用于“打开文件夹”的指令,可以理解为在“我的电脑”里面点开了一个文件夹,然后“我的电脑”就会显示该文件夹的内容,我们也可以跳过。具体使用效果如下(其中ls指令是在命令行查看目录内文件的指令):
需要注意的是,命令行就可以当成一种纯指令交互的“我的电脑”。执行指令时,会优先从当前目录中寻找相关文件。windows命令行学习请参考深入了解命令提示符(CMD)。
pip install -r requirements.txt # install
该指令是用于下载python依赖的指令。pip是每个python虚拟环境都自带的python依赖下载工具,详细用法参考pip详细用法。该指令的含义是指从requirments.txt中寻找项目对python依赖的要求并批量化安装,我们可以找到该文件,发现内部格式如下:
可以发现,有的依赖库设置了版本要求(==表示python依赖只能采用该版本号,>=表示python依赖需新于该版本号,<=表示python依赖需旧于该版本号),而有的没有。pip工具就会根据这些要求,自动选择requirments.txt限制下能够安装的最新版本的依赖进行安装。
anaconda创建虚拟环境
有两种方式(界面/命令行,推荐学习命令行方式,因为命令行安装依赖库相对方便)
anaconda界面创建虚拟环境
打开anaconda navigator,依次点击environment→create,配置虚拟环境名称及python版本(根据项目要求决定)后点击create,然后等待安装进程跑完即可。
anaconda命令行创建虚拟环境
打开anaconda powershell Prompt,使用指令创建环境,格式为:
conda create -n yolov5 python==3.8
其中,-n后面的参数代表虚拟环境名称,python==后面跟python版本号,指令运行完毕并无报错,则虚拟环境创建完成.,安装完毕后,还会提示在命令行激活该虚拟环境的指令,如下图所示:
激活python虚拟环境
激活python虚拟环境是指在命令行将通过conda配置的虚拟环境设置为默认python解释器的过程,激活python后,在命令行就会使用虚拟环境中的python解释器运行程序。如下图所示,激活前后的默认python解释器发生了改变。
激活python虚拟环境有两种方式(anaconda命令行/pycharm命令行),建议在初学阶段使用pycharm命令行。
anaconda命令行激活虚拟环境
使用以下指令激活虚拟环境,左边括号会从base变为环境名称yolov5,conda相关指令请参考conda指令大全。
conda activate yolov5
pycharm命令行激活python虚拟环境
使用pycharm打开python项目,依次按下图点击对应位置(英文版请自行对应成英文)。
点击确定后,该项目的python解释器被配置为anaconda创建的虚拟环境
此时,点击“终端”进入已激活该虚拟环境的命令行,若已有已开启的终端,先关闭即可,正常情况下,会显示如下终端信息:
部分电脑会遇到报错:无法加载文件 xx.ps1,因为在此系统上禁止运行脚本,解决方法详见链接。
配置python依赖
命令行进行python依赖配置
需要在任意一个激活了指定python虚拟环境的终端中展开该工作,这里以pycharm为例。
之前已经讲过,yolov5官方readme中,使用如下指令进行python依赖配置。
pip install -r requirements.txt # install
但由于pip工具默认从国外python依赖源作为下载源,经常会出现下载速度慢,甚至无法下载的问题,所以这里使用如下指令将下载源替换为国内源。(对于其他项目来说,有的python依赖只能从指定下载源下载,届时根据项目中的要求进行下载源替换即可)
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
在pycharm激活了yolov5的虚拟环境中使用该指令,会自动开始按照requirements.txt中的python依赖版本需求进行安装。
指令执行完毕不报错时,表示安装成功,如下图所示:
这时,使用如下指令,可以看到当前python虚拟环境中依赖的版本信息。如下所示,可以发现,实际安装的python依赖比requirements.txt中的依赖需求要多,因为安装python依赖时,会先根据requirements.txt中的依赖库要求,安装更底层的依赖库,导致实际安装的依赖会更多。
pip list
(yolov5) PS F:\work\pythonBlog\yolov5-master> pip list
Package Version
------------------- --------------------
certifi 2024.7.4
charset-normalizer 3.3.2
colorama 0.4.6
contourpy 1.1.1
cycler 0.12.1
filelock 3.15.4
fonttools 4.53.1
fsspec 2024.6.1
gitdb 4.0.11
GitPython 3.1.43
idna 3.7
importlib_resources 6.4.3
Jinja2 3.1.4
kiwisolver 1.4.5
MarkupSafe 2.1.5
matplotlib 3.7.5
mpmath 1.3.0
networkx 3.1
numpy 1.24.4
opencv-python 4.10.0.84
packaging 24.1
pandas 2.0.3
pillow 10.4.0
pip 24.2
psutil 6.0.0
py-cpuinfo 9.0.0
pyparsing 3.1.2
python-dateutil 2.9.0.post0
pytz 2024.1
PyYAML 6.0.2
requests 2.32.3
scipy 1.10.1
seaborn 0.13.2
setuptools 72.1.0
six 1.16.0
smmap 5.0.1
sympy 1.13.2
thop 0.1.1.post2209072238
torch 2.4.0
torchvision 0.19.0
tqdm 4.66.5
typing_extensions 4.12.2
tzdata 2024.1
ultralytics 8.2.79
ultralytics-thop 2.0.5
urllib3 2.2.2
wheel 0.43.0
zipp 3.20.0
也可以在pycharm中查看已安装的python依赖及其版本
(可选)使用pytorch的CUDA版本依赖替换普通版本
如前文所说,由于pytorch需要使用显卡进行神经网络加速,所以需要安装合适版本的显卡驱动和CUDA。显卡驱动的安装无法跳过,但是可以通过使用pytorch的CUDA版本,来跳过安装CUDA的过程(仅pytorch等少数依赖库具备该功能,并不是每个python依赖都具备该功能)。
根据上述方法,我们已经安装了如下版本的torch和torchvision,这两个库需要CUDA支持,也有官方CUDA版本。
torch 2.4.0
torchvision 0.19.0
在torch官方下载源和torchvision官方下载源中,可以找到这两个库的CUDA版本。
可以通过下载后手动安装的方式进行替换,也可以用指令安装进行替换
手动安装
手动安装需要选择完全合适的版本进行安装,包括
1.torch/torchvision版本
2.cuda版本
3.python解释器版本
4.操作系统版本
5.CPU架构版本
具体版本号为和下图中从左到右所示:
安装前,首先确保以安装显卡驱动(这里以N卡为例),在终端使用指令,得到如下输出:
nvidia-smi
其中,右上角的CUDA Version表示该驱动最高支持的CUDA版本,笔者电脑为12.2,不能安装高于12.2的CUDA。
汇总得到具体版本如下表所示:
版本号 | |
---|---|
torch | 2.4.0 |
torchvision | 0.19.0 |
CUDA版本 | <=12.2 |
python解释器版本 | 3.8 |
操作系统版本 | windows |
CPU架构 | AMD |
因此,需下载以下两个whl文件:
下载后,将其放入yolov5项目目录中,在pycharm中输入如下指令进行安装
pip install torch-2.4.0+cu121-cp38-cp38-win_amd64.whl
pip install torchvision-0.19.0+cu121-cp38-cp38-win_amd64.whl
(yolov5) PS F:\work\pythonBlog\yolov5-master> pip install .\torch-2.4.0+cu121-cp38-cp38-win_amd64.whl
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Processing f:\work\pythonblog\yolov5-master\torch-2.4.0+cu121-cp38-cp38-win_amd64.whl
Requirement already satisfied: filelock in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121) (3.15.4)
Requirement already satisfied: typing-extensions>=4.8.0 in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121) (4.12.2)
Requirement already satisfied: sympy in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121) (1.13.2)
Requirement already satisfied: networkx in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121) (3.1)
Requirement already satisfied: jinja2 in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121) (3.1.4)
Requirement already satisfied: fsspec in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121) (2024.6.1)
Requirement already satisfied: MarkupSafe>=2.0 in d:\anaconda\envs\yolov5\lib\site-packages (from jinja2->torch==2.4.0+cu121) (2.1.5)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in d:\anaconda\envs\yolov5\lib\site-packages (from sympy->torch==2.4.0+cu121) (1.3.0)
Installing collected packages: torch
Attempting uninstall: torch
Found existing installation: torch 2.4.0
Uninstalling torch-2.4.0:
Successfully uninstalled torch-2.4.0
WARNING: Failed to remove contents in a temporary directory 'D:\Anaconda\envs\yolov5\Lib\site-packages\~unctorch'.
You can safely remove it manually.
Successfully installed torch-2.4.0+cu121
(yolov5) PS F:\work\pythonBlog\yolov5-master> pip install .\torchvision-0.19.0+cu121-cp38-cp38-win_amd64.whl
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Processing f:\work\pythonblog\yolov5-master\torchvision-0.19.0+cu121-cp38-cp38-win_amd64.whl
Requirement already satisfied: numpy in d:\anaconda\envs\yolov5\lib\site-packages (from torchvision==0.19.0+cu121) (1.24.4)
Requirement already satisfied: torch==2.4.0+cu121 in d:\anaconda\envs\yolov5\lib\site-packages (from torchvision==0.19.0+cu121) (2.4.0+cu121)
Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in d:\anaconda\envs\yolov5\lib\site-packages (from torchvision==0.19.0+cu121) (10.4.0)
Requirement already satisfied: filelock in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121->torchvision==0.19.0+cu121) (3.15.4)
Requirement already satisfied: typing-extensions>=4.8.0 in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121->torchvision==0.19.0+cu121) (4.12.2)
Requirement already satisfied: sympy in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121->torchvision==0.19.0+cu121) (1.13.2)
Requirement already satisfied: networkx in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121->torchvision==0.19.0+cu121) (3.1)
Requirement already satisfied: jinja2 in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121->torchvision==0.19.0+cu121) (3.1.4)
Requirement already satisfied: fsspec in d:\anaconda\envs\yolov5\lib\site-packages (from torch==2.4.0+cu121->torchvision==0.19.0+cu121) (2024.6.1)
Requirement already satisfied: MarkupSafe>=2.0 in d:\anaconda\envs\yolov5\lib\site-packages (from jinja2->torch==2.4.0+cu121->torchvision==0.19.0+cu121) (2.1.5)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in d:\anaconda\envs\yolov5\lib\site-packages (from sympy->torch==2.4.0+cu121->torchvision==0.19.0+cu121) (1.3.0)
Installing collected packages: torchvision
Attempting uninstall: torchvision
Found existing installation: torchvision 0.19.0
Uninstalling torchvision-0.19.0:
Successfully uninstalled torchvision-0.19.0
Successfully installed torchvision-0.19.0+cu121
指令不报错,表示安装完毕,再次使用指令查看python依赖版本,发现已经替换成功:
pip list
(yolov5) PS F:\work\pythonBlog\yolov5-master> pip list
Package Version
------------------- --------------------
certifi 2024.7.4
charset-normalizer 3.3.2
colorama 0.4.6
contourpy 1.1.1
cycler 0.12.1
filelock 3.15.4
fonttools 4.53.1
fsspec 2024.6.1
gitdb 4.0.11
GitPython 3.1.43
idna 3.7
importlib_resources 6.4.3
Jinja2 3.1.4
kiwisolver 1.4.5
MarkupSafe 2.1.5
matplotlib 3.7.5
mpmath 1.3.0
networkx 3.1
numpy 1.24.4
opencv-python 4.10.0.84
packaging 24.1
pandas 2.0.3
pillow 10.4.0
pip 24.2
psutil 6.0.0
py-cpuinfo 9.0.0
pyparsing 3.1.2
python-dateutil 2.9.0.post0
pytz 2024.1
PyYAML 6.0.2
requests 2.32.3
scipy 1.10.1
seaborn 0.13.2
setuptools 72.1.0
six 1.16.0
smmap 5.0.1
sympy 1.13.2
thop 0.1.1.post2209072238
torch 2.4.0+cu121
torchvision 0.19.0+cu121
tqdm 4.66.5
typing_extensions 4.12.2
tzdata 2024.1
ultralytics 8.2.79
ultralytics-thop 2.0.5
urllib3 2.2.2
wheel 0.43.0
zipp 3.20.0
指令安装
指令安装相对简单很多,在官网查看到下图后,得知需安装cu121的python依赖,所以在虚拟环境输入下述指令,系统会自动安装对应版本的python依赖:
pip install torch==2.4.0+cu121 -f https://download.pytorch.org/whl/torch
pip install torchvision==0.19.0+cu121 -f https://download.pytorch.org/whl/torchvision
等待指令运行完毕,即为安装成功。
环境测试
此时,yolov5项目的python虚拟环境已经在外网设备完成部署,注释掉100行的check_git_info(),并执行train.py
LOCAL_RANK = int(os.getenv("LOCAL_RANK", -1)) # https://pytorch.org/docs/stable/elastic/run.html
RANK = int(os.getenv("RANK", -1))
WORLD_SIZE = int(os.getenv("WORLD_SIZE", 1))
# GIT_INFO = check_git_info() # 注释这句
程序会进入自动下载coco数据集的阶段,这表示yolov5的依赖check已经完全完成,环境部署成功。
D:\Anaconda\envs\yolov5\python.exe F:\work\pythonBlog\yolov5-master\train.py
github: skipping check (not a git repository), for updates see https://github.com/ultralytics/yolov5
train: weights=yolov5s.pt, cfg=, data=data\coco128.yaml, hyp=data\hyps\hyp.scratch-low.yaml, epochs=100, batch_size=16, imgsz=640, rect=False, resume=False, nosave=False, noval=False, noautoanchor=False, noplots=False, evolve=None, evolve_population=data\hyps, resume_evolve=None, bucket=, cache=None, image_weights=False, device=, multi_scale=False, single_cls=False, optimizer=SGD, sync_bn=False, workers=8, project=runs\train, name=exp, exist_ok=False, quad=False, cos_lr=False, label_smoothing=0.0, patience=100, freeze=[0], save_period=-1, seed=0, local_rank=-1, entity=None, upload_dataset=False, bbox_interval=-1, artifact_alias=latest, ndjson_console=False, ndjson_file=False
YOLOv5 2024-8-20 Python-3.8.0 torch-2.4.0+cu121 CUDA:0 (NVIDIA GeForce RTX 4070 Ti, 12282MiB)
hyperparameters: lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.5, cls_pw=1.0, obj=1.0, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, fl_gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0
Comet: run 'pip install comet_ml' to automatically track and visualize YOLOv5 runs in Comet
TensorBoard: Start with 'tensorboard --logdir runs\train', view at http://localhost:6006/
Dataset not found , missing paths ['F:\\work\\pythonBlog\\datasets\\coco128\\images\\train2017']
Downloading https://github.com/ultralytics/assets/releases/download/v0.0.0/coco128.zip to coco128.zip...
离线环境部署
首先,要确保离线设备的CPU架构、操作系统和外网设备的一致。
资源准备
1.anaconda安装包
2.pycharm安装包
3.python项目源码
4.已配置好依赖的python解释器压缩包(python解释器地址如下,压缩即可)
D:\Anaconda\envs\yolov5
具体配置
1.安装anaconda,流程和外网安装一致,也最好保证路径一致
2.将python解释器压缩包解压缩到以下目录中,确保解压后的python程序在该目录的下一级子目录中,即和外网压缩前完全一致
D:\Anaconda\envs
3.安装pycharm,使用pycharm打开pycharm项目,并根据外网流程配置解释器为第二步解压缩的python解释器
做完这三步后,就完成了在离线环境下部署python项目的流程。
(可选)外网设备和离线设备conda路径不一致时的情况
如果两者不一致,则在解压缩python解释器后,需要用pycharm打开python解释器所在目录,按ctrl+shift+R,或者按下图所示,进入“从文件中替换”模式。
搜索框中输入外网的虚拟环境路径,这里以E盘路径为例:
E:\Anaconda\envs\yolov5
全部替换为离线设备的虚拟环境路径,这里以D盘路径为例:
D:\Anaconda\envs\yolov5
替换完成后,虚拟环境就可以正常使用了。