将python脚本打包进docker的完整步骤记录
作者:凌佚
1. 说明
这里以将onnx
模型转换为rknn
模型为例进行说明。这个python脚本依赖的库非常多且非常大,并且需要一些额外的系统库依赖才能正常使用。
教程将以如何进行镜像拉取、脚本制作、编译脚本配置、容器打包保存和容器运行进行说明。
注意!这必须在Linux下按照教程操作,Windows的没有验证!
2. 准备工作
首先,我们需要准备一个conda
环境,准备rknn
模型转换需要的python依赖:
conda create -n rknn python=3.8 conda activate rknn pip install rknn-toolkit2
然后创建一个目录,开始我们的工程准备。
2.1 脚本
创建目录,如onnx2rknn
,然后进入目录中我们写一个python脚本,命名为convert.py
:
import argparse from pathlib import Path from rknn.api import RKNN def parse_opt(): parser = argparse.ArgumentParser( description='Convert ONNX model to RKNN format') parser.add_argument('--src', type=str, default='best.onnx', help='Path to the ONNX model file (default: best.onnx') parser.add_argument('--plat', type=str, choices=[ 'rk3562', 'rk3566', 'rk3568', 'rk3588', 'rk3576', 'rk1808', 'rv1109', 'rv1126' ], default='rk3588', help='Target platform for the RKNN model') parser.add_argument('--type', type=str, choices=['i8', 'u8', 'fp'], default='i8', help='Data type for the model (default: fp)') parser.add_argument('--dst', type=str, default='best.rknn', help='Output path for the RKNN model (default: best.rknn)') return parser.parse_args() def get_dataset_path(): img_dir = Path('./images') if not img_dir.exists(): raise FileNotFoundError(f"Image directory '{img_dir}' does not exist.") dataset_file = './datasets.txt' img_extensions = ['.jpg', '.jpeg', '.png'] img_paths = [] for img_path in img_dir.glob('*'): if img_path.suffix.lower() in img_extensions: img_name = img_path.name img_paths.append(f"./images/{img_name}") if not img_paths: raise ValueError(f"No valid images found in '{img_dir}'.") with open(dataset_file, 'w') as f: for img in img_paths: f.write(f"{img}\n") print(f"Dataset file created at: {dataset_file}") return dataset_file if __name__ == '__main__': print('---------- parse arguments ----------') opt = parse_opt() print('---------- prepare datasets ----------') try: dataset_path = get_dataset_path() except Exception as e: print(f"Error preparing dataset: {e}") exit(1) print('---------- rknn ----------') rknn = RKNN() rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform=opt.plat) ret = rknn.load_onnx(model=opt.src) if ret != 0: print('Load model failed!') exit(ret) if opt.type == 'i8': do_quant = True elif opt.type == 'u8': do_quant = True rknn.config(quantization_method='dynamic') else: do_quant = False ret = rknn.build(do_quantization=do_quant, dataset=dataset_path) if ret != 0: print('Build model failed!') exit(ret) ret = rknn.export_rknn(opt.dst) if ret != 0: print('Export rknn model failed!') exit(ret) # Release rknn.release() print(f'RKNN model exported to: {opt.dst}') print('---------- done ----------')
2.2 依赖
然后我们需要进行处理,在目录下打开终端:
conda activate rknn pip freeze > requirements.txt pip download -r requirements.txt -d ./dependencies
这样就可以得到所有以来的whl
包了。
2.3 数据
在目录下,我们创建一个images
文件夹,然后随便放一些可以用来进行模型量化验证的图片。
2.4 目录结构
按照如上处理之后,我们的目录结构是这个样子的:
./onnx2rknn/ ├── convert.py ├── dependencies ├── images └── requirements.txt
3. 镜像
直接制作镜像有难度,而且无法掌控大小,所以我们需要一个初始镜像。由于我们使用到的rknn-toolkit2
推荐使用python3.8
,并且我们前面创建的conda
环境也是用的python3.8
,所以我们最好找一个对应的初始镜像。由于我们的conda
环境中的python
是3.8.20
,所以这里我们使用:
docker pull python:3.8.20-slim
拉取了初始镜像之后我们就可以开始自己的镜像制作了。
3.1 脚本
要制作一个我们自己的docker镜像,就需要写一个Dockerfile
,所以我们在目录下新建一个文件,名为Dockerfile
,目录结构如下:
./onnx2rknn/ ├── convert.py ├── dependencies ├── Dockerfile ├── images └── requirements.txt
Dockerfile
中增加如下内容:
# 使用官方Python基础镜像 # 推荐slim镜像减小体积 FROM python:3.8.20-slim # ARG HTTP_PROXY # ARG HTTPS_PROXY # 安装依赖 RUN apt-get update &&\ apt-get install -y --no-install-recommends libgl1 libglib2.0-0 && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # 设置工作目录 WORKDIR /app # 复制python依赖并安装 COPY requirements.txt ./ COPY dependencies ./dependencies/ RUN pip install --no-cache-dir --no-index --find-links=./dependencies -r requirements.txt && rm -rf ./dependencies # 复制项目代码 COPY convert.py . COPY images ./images/ # 设置启动命令 # CMD ["python", "convert.py"] # 能够保证镜像启动之后不退出,这样才能方便进行vscode连接 CMD ["/bin/bash", "-c", "tail -f /dev/null"]
这些就可以实现自动在镜像中安装需要的依赖,和安装刚才准备好的python依赖包,然后将我们的python脚本和images
文件夹拷贝进去。
3.2 编译
脚本写好了,那么就可以进行docker打包,也就是使用Dockerfile
进行编译。在目录下打开终端:
docker build -t onnx2rknn:1.0.0 . # docker build --build-arg HTTP_PROXY="http://10.1.41.43:7890" --build-arg HTTPS_PROXY="http://10.1.41.43:7890" -t onnx2rknn:1.0.0 .
3.3 镜像
编译完成之后,我们可以使用命令查看我们的镜像了:
captain@ubuntu2404:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE onnx2rknn 1.0.0 0d5d2f9c2a23 47 minutes ago 6.51GB ubuntu 24.04 bf16bdcff9c9 2 weeks ago 78.1MB hello-world latest 74cc54e27dc4 4 months ago 10.1kB python 3.8.20-slim b5f62925bd0f 9 months ago 125MB
然后注意到这里的onnx2rknn
镜像已经显示了。
那么这个时候我们如果要在其他机器上进行部署,则可以通过命令保存镜像:
docker save -o onnx2rknn-1.0.0.tar.gz onnx2rknn:1.0.0
然后我们可以在目录下得到onnx2rknn-1.0.0.tar.gz
的镜像安装包,就可以在其他机器上进行部署了。由于rknn-toolkit2
依赖的东西非常多且大,所以这个镜像体积也比较离谱……
在其他机器上进行部署可以使用命令:
docker load -i onnx2rknn-1.0.0.tar.gz
4. 运行
刚刚编译的机器上可以直接运行,也可以通过命令部署之后,在其他机器上运行,运行的命令:
docker run onnx2rknn:1.0.0
然后,会发现,终端啥输出也没有,这就正常了……
4.1 vscode远程
如果你想用docker命令来进入容器的shell环境也可以,只不过命令很麻烦,我也不想折腾,如果有兴趣请自行google一下。这里介绍如何使用vscode进入到容器中进行开发。
首先打开vscode,安装两个插件:
安装这两个插件之后,你就可以通过vscode看到运行中的容器了,然后我们通过这里进入容器:
直接点击这个箭头,就可以进入容器了,然后一定要打开/app
文件夹!这个目录才是你刚才将脚本拷贝进来的目录!可以看到:
然后就可以看到这里的脚本了。我们拖一个best.onnx
进来:
然后打开终端,直接执行命令:
python convert.py
然后就可以看到正常运行了,最后目录下得到了best.rknn
,然后将其拖出来,就可以正常使用了……
总结
到此这篇关于将python脚本打包进docker的文章就介绍到这了,更多相关python脚本打包进docker内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!