python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > python脚本打包进docker

将python脚本打包进docker的完整步骤记录

作者:凌佚

Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,这篇文章主要介绍了将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环境中的python3.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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文