將python腳本打包進(jìn)docker的完整步驟記錄
1. 說明
這里以將onnx模型轉(zhuǎn)換為rknn模型為例進(jìn)行說明。這個python腳本依賴的庫非常多且非常大,并且需要一些額外的系統(tǒng)庫依賴才能正常使用。
教程將以如何進(jìn)行鏡像拉取、腳本制作、編譯腳本配置、容器打包保存和容器運(yùn)行進(jìn)行說明。
注意!這必須在Linux下按照教程操作,Windows的沒有驗(yàn)證!
2. 準(zhǔn)備工作
首先,我們需要準(zhǔn)備一個conda環(huán)境,準(zhǔn)備rknn模型轉(zhuǎn)換需要的python依賴:
conda create -n rknn python=3.8 conda activate rknn pip install rknn-toolkit2
然后創(chuàng)建一個目錄,開始我們的工程準(zhǔn)備。
2.1 腳本
創(chuàng)建目錄,如onnx2rknn,然后進(jìn)入目錄中我們寫一個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 依賴
然后我們需要進(jìn)行處理,在目錄下打開終端:
conda activate rknn pip freeze > requirements.txt pip download -r requirements.txt -d ./dependencies
這樣就可以得到所有以來的whl包了。
2.3 數(shù)據(jù)
在目錄下,我們創(chuàng)建一個images文件夾,然后隨便放一些可以用來進(jìn)行模型量化驗(yàn)證的圖片。
2.4 目錄結(jié)構(gòu)
按照如上處理之后,我們的目錄結(jié)構(gòu)是這個樣子的:
./onnx2rknn/ ├── convert.py ├── dependencies ├── images └── requirements.txt
3. 鏡像
直接制作鏡像有難度,而且無法掌控大小,所以我們需要一個初始鏡像。由于我們使用到的rknn-toolkit2推薦使用python3.8,并且我們前面創(chuàng)建的conda環(huán)境也是用的python3.8,所以我們最好找一個對應(yīng)的初始鏡像。由于我們的conda環(huán)境中的python是3.8.20,所以這里我們使用:
docker pull python:3.8.20-slim
拉取了初始鏡像之后我們就可以開始自己的鏡像制作了。
3.1 腳本
要制作一個我們自己的docker鏡像,就需要寫一個Dockerfile,所以我們在目錄下新建一個文件,名為Dockerfile,目錄結(jié)構(gòu)如下:
./onnx2rknn/ ├── convert.py ├── dependencies ├── Dockerfile ├── images └── requirements.txt
Dockerfile中增加如下內(nèi)容:
# 使用官方Python基礎(chǔ)鏡像
# 推薦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/*
# 設(shè)置工作目錄
WORKDIR /app
# 復(fù)制python依賴并安裝
COPY requirements.txt ./
COPY dependencies ./dependencies/
RUN pip install --no-cache-dir --no-index --find-links=./dependencies -r requirements.txt && rm -rf ./dependencies
# 復(fù)制項目代碼
COPY convert.py .
COPY images ./images/
# 設(shè)置啟動命令
# CMD ["python", "convert.py"]
# 能夠保證鏡像啟動之后不退出,這樣才能方便進(jìn)行vscode連接
CMD ["/bin/bash", "-c", "tail -f /dev/null"]
這些就可以實(shí)現(xiàn)自動在鏡像中安裝需要的依賴,和安裝剛才準(zhǔn)備好的python依賴包,然后將我們的python腳本和images文件夾拷貝進(jìn)去。
3.2 編譯
腳本寫好了,那么就可以進(jìn)行docker打包,也就是使用Dockerfile進(jìn)行編譯。在目錄下打開終端:
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鏡像已經(jīng)顯示了。
那么這個時候我們?nèi)绻谄渌麢C(jī)器上進(jìn)行部署,則可以通過命令保存鏡像:
docker save -o onnx2rknn-1.0.0.tar.gz onnx2rknn:1.0.0
然后我們可以在目錄下得到onnx2rknn-1.0.0.tar.gz的鏡像安裝包,就可以在其他機(jī)器上進(jìn)行部署了。由于rknn-toolkit2依賴的東西非常多且大,所以這個鏡像體積也比較離譜……
在其他機(jī)器上進(jìn)行部署可以使用命令:
docker load -i onnx2rknn-1.0.0.tar.gz
4. 運(yùn)行
剛剛編譯的機(jī)器上可以直接運(yùn)行,也可以通過命令部署之后,在其他機(jī)器上運(yùn)行,運(yùn)行的命令:
docker run onnx2rknn:1.0.0
然后,會發(fā)現(xiàn),終端啥輸出也沒有,這就正常了……
4.1 vscode遠(yuǎn)程
如果你想用docker命令來進(jìn)入容器的shell環(huán)境也可以,只不過命令很麻煩,我也不想折騰,如果有興趣請自行g(shù)oogle一下。這里介紹如何使用vscode進(jìn)入到容器中進(jìn)行開發(fā)。
首先打開vscode,安裝兩個插件:

安裝這兩個插件之后,你就可以通過vscode看到運(yùn)行中的容器了,然后我們通過這里進(jìn)入容器:

直接點(diǎn)擊這個箭頭,就可以進(jìn)入容器了,然后一定要打開/app文件夾!這個目錄才是你剛才將腳本拷貝進(jìn)來的目錄!可以看到:

然后就可以看到這里的腳本了。我們拖一個best.onnx進(jìn)來:

然后打開終端,直接執(zhí)行命令:
python convert.py
然后就可以看到正常運(yùn)行了,最后目錄下得到了best.rknn,然后將其拖出來,就可以正常使用了……
總結(jié)
到此這篇關(guān)于將python腳本打包進(jìn)docker的文章就介紹到這了,更多相關(guān)python腳本打包進(jìn)docker內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python自動化之批量生成含指定數(shù)據(jù)的word文檔
在平時工作當(dāng)中,經(jīng)常需要處理文件,特別是Word,我們常常會機(jī)械的重復(fù)打開、修改、保存文檔等一系列操作。本文將主要介紹如何通過Python批量生成含指定數(shù)據(jù)的word文檔,感興趣的同學(xué)可以來看一看2021-11-11
Python語言的面相對象編程方式初步學(xué)習(xí)
這篇文章主要介紹Python語言的面相對象編程方式的初步學(xué)習(xí),包括類和對象以及繼承特性等知識,需要的朋友可以參考下2016-03-03
selenium學(xué)習(xí)教程之定位以及切換frame(iframe)
這篇文章主要給大家介紹了關(guān)于selenium學(xué)習(xí)教程之定位以及切換frame(iframe)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
python 線程的暫停, 恢復(fù), 退出詳解及實(shí)例
這篇文章主要介紹了python 線程的暫停, 恢復(fù), 退出詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2016-12-12
基于Python3.6中的OpenCV實(shí)現(xiàn)圖片色彩空間的轉(zhuǎn)換
這篇文章主要介紹了基于Python3.6的OpenCV實(shí)現(xiàn)圖片色彩空間的轉(zhuǎn)換,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02
Python中用try-except-finally處理異常問題
這篇文章主要介紹了Python中用try-except-finally處理異常問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
簡單了解Python下用于監(jiān)視文件系統(tǒng)的pyinotify包
這篇文章主要介紹了Python下用于監(jiān)視文件系統(tǒng)的pyinotify包,pyinotify基于inotify事件驅(qū)動機(jī)制,需要的朋友可以參考下2015-11-11

