diff --git a/.gitignore b/.gitignore index 0f185ea..006bb1b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,13 @@ +# Ignore custom configuration files +scripts/*.custom.sh + tmp/ tmps/ temp/ temps/ resource/ + # Vuepress/Vitepress node_modules docs/.vuepress/.temp diff --git a/README.md b/README.md index dca831a..8ec4d76 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ # deep-object-detect-track -查看[文档](https://henryzhuhr.github.io/deep-object-detect-track/) \ No newline at end of file +查看[文档](https://henryzhuhr.github.io/deep-object-detect-track/) + +也可以本地启动文档: + +```bash +pnpm install +pnpm docs:dev +``` \ No newline at end of file diff --git a/dlinfer/detector/b_onnx.py b/dlinfer/detector/b_onnx.py index 268c92b..68da51b 100644 --- a/dlinfer/detector/b_onnx.py +++ b/dlinfer/detector/b_onnx.py @@ -10,22 +10,21 @@ class ONNXDetectorBackend(IDetectoBackends): NAME = "ONNX" - SUPPORTED_VERISONS = ["1.8.0"] + SUPPORTED_VERISONS = [] SUPPORTED_DEVICES = available_providers def __init__( self, - device: str = "CPUExecutionProvider", + device: List[str] = ["CPUExecutionProvider"], inputs: List[str] = ["input"], # TODO in case of multiple inputs outputs: List[str] = ["output"], # TODO in case of multiple outputs ) -> None: - if device.lower() == "cpu": - device = "CPUExecutionProvider" - assert device in self.SUPPORTED_DEVICES, ( - f"specify device {device} is not supported, " - f"please choose one of supported device: {self.SUPPORTED_DEVICES}" - ) - self.providers = [device] + for provider in device: + assert provider in self.SUPPORTED_DEVICES, ( + f"specify device {device} is not supported, " + f"please choose one of supported device: {self.SUPPORTED_DEVICES}" + ) + self.providers = device self.ort_session: ort.InferenceSession = None self.inputs = inputs self.outputs = outputs @@ -45,15 +44,15 @@ def load_model(self, model_path: str, verbose: bool = False) -> None: if verbose: # fmt: off print(self.ColorStr.info("Parsing ONNX info:")) - print(self.ColorStr.info(" - providers:"), self.ort_session.get_providers()) - print(self.ColorStr.info(" --- inputs:"), binding__input_names) - print(self.ColorStr.info(" -- names:"), binding__input_names) - print(self.ColorStr.info(" - shapes:"), binding__input_shapes) - print(self.ColorStr.info(" -- types:"), binding__input_types) - print(self.ColorStr.info(" --- outputs:"), binding_output_names) - print(self.ColorStr.info(" -- names:"), binding_output_shapes) - print(self.ColorStr.info(" - shapes:"), binding_output_shapes) - print(self.ColorStr.info(" -- types:"), binding_output_types) + print(self.ColorStr.info("- providers:"), self.ort_session.get_providers()) + print(self.ColorStr.info("-- inputs:"), binding__input_names) + print(self.ColorStr.info(" - names: "), binding__input_names) + print(self.ColorStr.info(" - shapes: "), binding__input_shapes) + print(self.ColorStr.info(" - types: "), binding__input_types) + print(self.ColorStr.info("-- outputs:"), binding_output_names) + print(self.ColorStr.info(" - names: "), binding_output_shapes) + print(self.ColorStr.info(" - shapes: "), binding_output_shapes) + print(self.ColorStr.info(" - types: "), binding_output_types) # fmt: on # fmt: off diff --git a/dlinfer/detector/b_openvino.py b/dlinfer/detector/b_openvino.py index d80cea9..569da25 100644 --- a/dlinfer/detector/b_openvino.py +++ b/dlinfer/detector/b_openvino.py @@ -76,6 +76,7 @@ def infer(self, input: np.ndarray) -> np.ndarray: preds = next(iter(results.values())) return preds - def query_device(self): + @staticmethod + def query_device(): """Query available devices for OpenVINO backend.""" - return ["AUTO"] + self.core.available_devices + return Core().available_devices diff --git a/dlinfer/detector/interface.py b/dlinfer/detector/interface.py index 410eb10..1477645 100644 --- a/dlinfer/detector/interface.py +++ b/dlinfer/detector/interface.py @@ -48,7 +48,7 @@ def _check_version(self, version: str): for sv in self.SUPPORTED_VERISONS: if version.startswith(sv): return - raise RuntimeError( + warnings.warn( f"{self.NAME} version {version} is not supported, " f"please upgrade to support version: {self.SUPPORTED_VERISONS}" ) diff --git a/docs/dataset.md b/docs/dataset.md index f2e0a13..61d16d8 100644 --- a/docs/dataset.md +++ b/docs/dataset.md @@ -11,7 +11,7 @@ outline: deep 将数据集放入如下目录 -```bash +```shell DATASET_DIR=/path/to/dataset ``` @@ -19,14 +19,15 @@ DATASET_DIR=/path/to/dataset 这里准备好了一个示例数据集,可以下载 -```bash +```shell wget -P ~/data https://github.com/HenryZhuHR/deep-object-detect-track/releases/download/v1.0.0/bottle.tar.xz tar -xvf ~/data/bottle.tar.xz -C ~/data +mv ~/data/bottle ~/data/yolodataset ``` 随后可以设置数据集目录为 -```bash -DATASET_DIR=~/data/bottle +```shell +DATASET_DIR=~/data/yolodataset ``` 参考该目录构建自己的数据集,并且完成标注 @@ -34,7 +35,7 @@ DATASET_DIR=~/data/bottle 考虑到单张图像中可能出现不同类别的目标,因此数据集不一定需要按照类别进行划分,可以自定义划分,按照项目的需求任意归档数据集,但是请确保,每一张图像同级目录下有同名的**标签文件** 按照类别划分的目录结构参考 -```bash +```shell · └── /path/to/dataset ├── class_A @@ -48,7 +49,7 @@ DATASET_DIR=~/data/bottle ``` 不进行类别划分的目录结构参考 -```bash +```shell · └── /path/to/dataset ├─ file_1.jpg @@ -60,7 +61,7 @@ DATASET_DIR=~/data/bottle ## 启动标注工具 使用 labelImg 标注,安装并启动 -```bash +```shell pip install labelImg labelImg ``` @@ -101,11 +102,11 @@ labelImg ## 数据处理 运行脚本,生成同名目录,但是会带 `-organized` 后缀,例如 -```bash -python dataset-process.py --datadir ~/data/bottle +```shell +python dataset-process.py --datadir ~/data/yolodataset ``` -生成 `~/data/bottle-organized` 用于数据集训练,并且该目录为 yolov5 中指定的数据集路径 +生成的目录 `~/data/yolodataset-organized` 用于数据集训练,并且该目录为 yolov5 中指定的数据集路径 如果不需要完全遍历数据集、数据集自定义路径,则在 `get_all_label_files()` 函数中传入自定义的 `custom_get_all_files` 函数,以获取全部文件路径,该自定义函数可以参考 `default_get_all_files()` @@ -114,15 +115,13 @@ def default_get_all_files(directory: str): file_paths: List[str] = [] for root, dirs, files in os.walk(directory): for file in files: - if file in [".DS_Store"]: - continue file_paths.append(os.path.join(root, file)) return file_paths ``` 并且在调用的时候传入该参数 -```bash +```python # -- get all label files, type: List[ImageLabel] label_file_list = get_all_label_files(args.datadir) # [!code --] label_file_list = get_all_label_files( # [!code ++] diff --git a/docs/deploy.md b/docs/deploy.md index dd8fdfb..d1e4901 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -9,28 +9,19 @@ outline: deep ## 导出模型 -已经编写了一个脚本,可以直接导出 +提供一个导出脚本 `scripts/train.sh`,复制一份到项目目录下进行自定义修改(推荐) ```shell -# 查看脚本,修改参数 -bash scripts/export-yolov5.sh +cp scripts/export-yolov5.sh scripts/export-yolov5.custom.sh ``` -也可以自行导出,进入 yolov5 项目目录 +查看脚本 `scripts/export-yolov5.custom.sh` ,根据项目需求修改参数后执行 ```shell -cd projects/yolov5 +bash scripts/export-yolov5.custom.sh +#zsh scripts/export-yolov5.custom.sh # zsh ``` -设定参数,执行 -```shell -python export.py \ - --weights ../weights/yolov5s.pt \ - --data data/coco128.yaml \ - --include onnx openvino -``` -- `--weights` 模型路径: 修改为自己训练好的模型路径 -- `--include` 导出类型: 可以导出多个模型,用空格分隔 -- `--data` 训练模型使用的数据集,主要利用到里面的类别数据 + ## 部署模型 @@ -38,12 +29,115 @@ python export.py \ ### ONNX 部署 +修改 `scripts/variables.custom.sh` 文件中 `ENV_NAME` 如下 + +```shell +# export ENV_NAME="" # -- Uncomment to customize the environment name # [!code --] +export ENV_NAME="deploy-onnx" # [!code ++] +export ENV_PATH=$BASE_ENV_PATH/.env/$ENV_NAME +``` + +然后执行脚本创建虚拟环境,并激活 + +::: code-group + +```shell [使用 venv] +bash scripts/create-python-env.sh -e venv -ni +#zsh scripts/create-python-env.sh -e venv -ni # zsh +``` + +```shell [使用 conda] +bash scripts/create-python-env.sh -e conda -ni +#zsh scripts/create-python-env.sh -e conda -ni # zsh +``` + +::: + +根据上述脚本运行输出激活环境 + +```shell +- [INFO] Run command below to activate the environment: +... # 复制这里出现的激活命令并执行 +``` + +手动安装依赖 + +```shell +pip install -r requirements/requirements.txt +pip install onnxruntime # CPU 版本 +# pip install onnxruntime-gpu # GPU 版本 +``` + +修改 `infer.py` 文件,指定模型路径 +```python +## ------ ONNX ------ +onnx_backend = backends.ONNXBackend +print("-- Available devices:", providers := onnx_backend.SUPPORTED_DEVICES) +detector = onnx_backend( + device=providers, inputs=["images"], outputs=["output0"] +) +``` + +然后执行推理脚本 + +```shell +python infer.py --model .cache/yolov5/yolov5s.onnx +``` + + ### OpenVINO 部署 +修改 `scripts/variables.custom.sh` 文件中 `ENV_NAME` 如下 + ```shell -python infer.py +# export ENV_NAME="" # -- Uncomment to customize the environment name # [!code --] +export ENV_NAME="deploy-ov" # [!code ++] +export ENV_PATH=$BASE_ENV_PATH/.env/$ENV_NAME +``` + +然后执行脚本创建虚拟环境,并激活 + +::: code-group + +```shell [使用 venv] +bash scripts/create-python-env.sh -e venv -ni +#zsh scripts/create-python-env.sh -e venv -ni # zsh +``` + +```shell [使用 conda] +bash scripts/create-python-env.sh -e conda -ni +#zsh scripts/create-python-env.sh -e conda -ni # zsh ``` +::: + +根据上述脚本运行输出激活环境 + +```shell +- [INFO] Run command below to activate the environment: +... # 复制这里出现的激活命令并执行 +``` + +手动安装依赖 + +```shell +pip install -r requirements/requirements.txt +pip install openvino +``` + +修改 `infer.py` 文件,指定模型路径 +```python +## ------ ONNX ------ +ov_backend = backends.OpenVINOBackend +print("-- Available devices:", ov_backend.query_device()) +detector = ov_backend(device="AUTO") +``` + +然后执行推理脚本 + +```shell +python infer.py --model .cache/yolov5/yolov5s_openvino_model/yolov5s.xml +``` ### TensorRT 部署 diff --git a/docs/index.md b/docs/index.md index 440de2c..78d8e2a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -9,7 +9,7 @@ hero: actions: - theme: brand text: 项目源码 - link: https://henryzhuhr.github.io/deep-object-detect-track/ + link: https://github.com/HenryZhuHR/deep-object-detect-track - theme: alt text: 项目文档 link: /install diff --git a/docs/install.md b/docs/install.md index a6225ea..a471f04 100644 --- a/docs/install.md +++ b/docs/install.md @@ -8,20 +8,20 @@ outline: deep # 安装环境 -以 yolov5 为基础,实现目标检测和跟踪算法的训练和部署,部署 TensorRT 和 OpenVINO 两种方案。 +## 获取代码 -## 环境配置 +::: code-group -### 获取代码 +```shell [SSH(Recommend)] +# 需要配置 github 上的 SSH key +git clone --recursive git@github.com:HenryZhuHR/deep-object-detect-track.git +``` -::: code-group ```shell [HTTP] git clone --recursive https://github.com/HenryZhuHR/deep-object-detect-track.git ``` -```shell [SSH] -git clone --recursive git@github.com:HenryZhuHR/deep-object-detect-track.git -``` -::: + +::: 进入项目目录 @@ -29,7 +29,7 @@ git clone --recursive git@github.com:HenryZhuHR/deep-object-detect-track.git cd deep-object-detect-track ``` -> 后续的脚本基于 deep-object-detect-track 目录下执行 +> 后续的脚本基于 `deep-object-detect-track` 目录下执行 如果未能获取子模块,可以手动获取 ```shell @@ -38,55 +38,127 @@ git submodule init git submodule update ``` -### 创建环境并安装依赖 +## 系统要求 + +### 操作系统 + + +项目在 Linux(Ubuntu) 和 MacOS 系统并经过测试 ✅ ,经过测试的系统: +- Ubuntu 22.04 jammy (CPU & GPU) +- MacOS (CPU) + +Windows 系统暂未测试也无适配计划,如果需要在 Windows 系统上运行,可以使用 WSL2 或者根据提供的脚本手动执行,不接受 Windows 系统的问题反馈 -确保安装了 conda ,如果没有安装,请从 [Miniconda](https://docs.anaconda.com/free/miniconda/index.html) 下载,或者快速安装 +### GPU + +如果需要使用 GPU 训练模型,需要安装 CUDA Toolkit,可以参考 [CUDA Toolkit Archive](https://developer.nvidia.com/cuda-toolkit-archive) 下载对应版本的 CUDA Toolkit,具体下载的版本需要参考 [*INSTALL PYTORCH*](https://pytorch.org/get-started/locally/) + +例如 Pytorch 2.3.0 支持 CUDA 11.8/12.1,因此安装 CUDA 11.8/12.1 即可,而不需要过高的 CUDA 版本,安装后需要配置环境变量 ```shell -# linux x64 +# ~/.bashrc +export CUDA_VERSION=12.1 +export CUDA_HOME="/usr/local/cuda-${CUDA_VERSION}" +export PATH="$CUDA_HOME/bin:$PATH" +export LD_LIBRARY_PATH="$CUDA_HOME/lib64:$LD_LIBRARY_PATH" +``` + +MacOS 系统不支持 CUDA Toolkit,可以使用 CPU 训练模型 (Yolov5 项目暂不支持 MPS 训练),但是推理过程可以使用 Metal ,参考 [*Introducing Accelerated PyTorch Training on Mac*](https://pytorch.org/blog/introducing-accelerated-pytorch-training-on-mac/#getting-started) 和 [*MPS backend*](https://pytorch.org/docs/stable/notes/mps.html#mps-backend) + + +## 安装环境 + +提供两种方式安装, venv 或 conda + +- **venv** : 如果没有安装,请安装 + +::: code-group + +```shell [Linux] +sudo apt install -y python3-venv python3-pip +``` + +```shell [MacOS] +# Mac 貌似自带了 python3-venv +# brew install python3-venv python3-pip +``` + +::: + +- **conda** : 如果没有安装,请从 [Miniconda](https://docs.anaconda.com/free/miniconda/index.html) 下载,或者快速安装 + +::: code-group + +```shell [linux x64] wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh ``` +```shell [MacOS arm64] +wget https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh +zsh Miniconda3-latest-MacOSX-arm64.sh +``` + +::: + + +### 方法一:使用提供的脚本 + -#### 方法一:使用提供的脚本 +提供的安装脚本依赖于基本环境变量 `scripts/variables.sh` ,可以复制一份到项目目录下进行自定义修改(推荐),如果不需要修改,可以直接执行 +```shell +cp scripts/variables.sh scripts/variables.custom.sh +``` + +- 修改 `export PIP_QUIET=true` 为 `false` 可以查看安装过程的详细信息\ +- 安装过程会自动检测 `CUDA_VERSION` 以安装对应的 PyTorch 版本,否则默认安装 CPU 版本的 PyTorch;如果电脑有 NVIDIA GPU 但是不想安装 CUDA Toolkit 到全局系统(需要 sudo)可以取消注释 `export CUDA_VERSION=12.1` 以安装对应的 PyTorch 版本 + +运行会自动检测是否存在用户自定义的环境变量 `scripts/variables.custom.sh` ,如果存在则使用自定义的环境变量,否则使用默认的环境变量 `scripts/variables.sh` -查看 `scripts/base.sh` ,根据需要修改配置,执行命令自动创建并且激活虚拟环境 +执行命令自动创建并且激活虚拟环境 (**可以重复执行该脚本获取激活环境的提示信息或者安装依赖**) ::: code-group ```shell [使用 venv 创建虚拟环境] -bash scripts/python-activate.venv.sh +bash scripts/create-python-env.sh -e venv +#zsh scripts/create-python-env.sh -e venv # zsh ``` ```shell [使用 conda 创建虚拟环境] -bash scripts/python-activate.conda.sh +bash scripts/create-python-env.sh -e conda +#zsh scripts/create-python-env.sh -e conda # zsh ``` ::: -- **可以重复执行该脚本获取激活环境的提示信息或者安装依赖** -- 修改 `export PIP_QUIET=true` 为 `false` 可以查看安装过程 -- 该脚本会复制 `yolov5/requirements.txt` 到 `.cache/yolov5/requirements.txt`,可以自行修改 `.cache/yolov5/requirements.txt` 文件安装相关依赖,例如取消 `onnx` 的注释以支持 ONNX 格式的模型导出 +- 该脚本会复制 `yolov5/requirements.txt` 到 `.cache/yolov5/requirements.txt`,可以自行修改 `.cache/yolov5/requirements.txt` 文件安装相关依赖,例如取消 `onnx` 的注释以支持 ONNX 格式的模型导出;可以修改后再次执行脚本以重新安装依赖 -#### 方法二:手动安装 +### 方法二:手动安装 创建虚拟环境 -```shell + +::: code-group + +```shell [在项目内安装环境(推荐)] export ENV_NAME=deep-object-detect-track -# 在项目内安装环境(推荐) conda create -p .env/$ENV_NAME python=3.10 -y conda activate ./.env/$ENV_NAME -# 全局安装环境 +``` + +```shell [全局安装环境] +export ENV_NAME=deep-object-detect-track conda create -n $ENV_NAME python=3.10 -y conda activate $ENV_NAME ``` + +::: + > Python 版本选择 3.10 是因为 Ubuntu 22.04 默认安装的 Python 版本是 3.10 1. 安装 PyTorch -参考官网 [INSTALL PYTORCH](https://pytorch.org/get-started/locally/) 选择配置安装 PyTorch +参考官网 [*INSTALL PYTORCH*](https://pytorch.org/get-started/locally/) 选择配置安装 PyTorch ```shell pip install torch torchvision \ diff --git a/docs/train.md b/docs/train.md index 6a9213b..fb77f86 100644 --- a/docs/train.md +++ b/docs/train.md @@ -12,20 +12,39 @@ outline: deep 下载预训练模型 -```bash -bash scripts/download-yolov5.sh +::: code-group + +```shell [bash] bash scripts/download-yolov5.sh yolov5s # 仅下载单个模型 +# bash scripts/download-yolov5.sh # 下载所有模型 +``` +```shell [zsh] +zsh scripts/download-yolov5.sh yolov5s # 仅下载单个模型 +# zsh scripts/download-yolov5.sh # 下载所有模型 ``` -运行脚本开始训练 +::: + +提供一个训练脚本 `scripts/train.sh`,复制一份到项目目录下进行自定义修改(推荐) -```bash -bash scripts/train.sh +```shell +cp scripts/train.sh scripts/train.custom.sh ``` -在 `Set Training Variables` 项目中设置各个变量 -- `TRAIN_DATA_DIR`: 训练数据路径,例如 `$HOME/data/bottle-organized` -- `MODEL_NAME`: 训练模型,用以加载 `--cfg` 参数 + + +修改训练脚本 `train.custom.sh` 中的参数,在 `Set Training Variables` 中设置 +- `TRAIN_DATA_DIR`: (✅重要) 训练数据路径,例如 `$HOME/data/bottle-organized` +- `TRAIN_DEVICE`: (✅重要) 这里默认设置为 `cpu`;如果有 GPU 可以设置为 `0` 或者 `1`;多个 GPU 用逗号分隔,如果单 GPU 能够满足需求,建议使用单 GPU +- `MODEL_NAME`: 训练模型,用以加载 `--cfg` 参数,默认为 `yolov5s` - `PRETRAINED_MODEL`: 上面下载好的预训练模型 - `EPOCHS`: epoch -- `BATCH_SIZE`: batch size \ No newline at end of file +- `BATCH_SIZE`: batch size + + +修改完成后,运行脚本开始训练 +```shell +bash scripts/train.custom.sh +#zsh scripts/train.custom.sh # zsh +``` + diff --git a/infer.py b/infer.py index e4e9faa..7d80087 100644 --- a/infer.py +++ b/infer.py @@ -2,7 +2,6 @@ import os from typing import Dict import cv2 -import numpy as np import yaml from dlinfer.detector import DetectorInferBackends @@ -15,14 +14,6 @@ def parse_args() -> argparse.Namespace: args = parser.add_argument_group("Options") args.add_argument("--model", type=str, default=".cache/yolov5/yolov5s.onnx") args.add_argument("-i", "--input", type=str, default="images/bus.jpg") - args.add_argument( - "--device", - type=str, - default="cpu", - help="Optional. Specify the target device to infer on; CPU, GPU, GNA or HETERO: " - "is acceptable. The sample will look for a suitable plugin for device specified. " - "Default value is CPU.", - ) return parser.parse_args() @@ -30,19 +21,30 @@ def main() -> int: args = parse_args() backends = DetectorInferBackends() - ## -- ONNX - # detector = backends.ONNXBackend(device=args.device, inputs=["images"], outputs=["output0"]) - ## -- OpenVINO - # detector = backends.OpenVINOBackend(device="AUTO") - # print("-- Available devices:", detector.query_device()) - ## -- TensorRT - # args.model = ".cache/yolov5/yolov5s.engine" - detector = backends.TensorRTBackend() + # =============== Choose backend to Infer =============== + # ------ Choose one and comment out the others ------ + ## ------ ONNX ------ + onnx_backend = backends.ONNXBackend + print("-- Available devices:", providers := onnx_backend.SUPPORTED_DEVICES) + detector = onnx_backend( + device=providers, inputs=["images"], outputs=["output0"] + ) + + ## ------ OpenVINO ------ + # ov_backend = backends.OpenVINOBackend + # print("-- Available devices:", ov_backend.query_device()) + # detector = ov_backend(device="AUTO") + + ## ------ TensorRT ------ + # detector = backends.TensorRTBackend() + # ======================================================= detector.load_model(args.model, verbose=True) with open(".cache/yolov5/yolov5s_openvino_model/yolov5s.yaml", "r") as f: - label_map: Dict[int, str] = yaml.load(f, Loader=yaml.FullLoader)["names"] + label_map: Dict[int, str] = yaml.load(f, Loader=yaml.FullLoader)[ + "names" + ] label_list = list(label_map.values()) # print(label_list) @@ -73,7 +75,8 @@ def main() -> int: ) # -- mark Process.mark(img, preds, label_list, scale_h, scale_w) - cv2.imwrite("tmp/out.jpg", img) + cv2.imwrite(save_path := "tmp/out.jpg", img) + print(f"-- output saved to '{save_path}'") if __name__ == "__main__": diff --git a/out.jpg b/out.jpg deleted file mode 100644 index 8f95b70..0000000 Binary files a/out.jpg and /dev/null differ diff --git a/run-trt8_6.sh b/run-trt8_6.sh deleted file mode 100644 index 2f66e7a..0000000 --- a/run-trt8_6.sh +++ /dev/null @@ -1,17 +0,0 @@ -source ~/.bashrc - -ENV_PATH=".env/deploy-trt_10_0.venv" -if [ ! -d $ENV_PATH ];then - python3 -m venv $ENV_PATH -fi -source $ENV_PATH/bin/activate -python3 -m pip install -r requirements-trt10_0.txt - -# export TENSORRT_HOME="$HOME/program/TensorRT-8.6.1.6" -# export PATH="$TENSORRT_HOME/bin:$PATH" -# export LD_LIBRARY_PATH="$TENSORRT_HOME/lib:$LD_LIBRARY_PATH" - -# python3 -m pip install $TENSORRT_HOME/python/tensorrt-8.6.1-cp310-none-linux_x86_64.whl - - -python3 infer.py \ No newline at end of file diff --git a/scripts/base.sh b/scripts/base.sh index ac30b03..c0d4423 100644 --- a/scripts/base.sh +++ b/scripts/base.sh @@ -1,28 +1,4 @@ source ~/.$(basename $SHELL)rc -# =============== Environment Variables ================ -# install python in `user` or `project` level -# export BASE_ENV_PATH=$HOME -export BASE_ENV_PATH=. - -# export ENV_NAME=dodt # Uncomment if custom env name - -# ================== Project Variables ================== -export PROJECT_HOME=$(pwd) -export PROJECT_NAME=$(basename $PROJECT_HOME) -DEFAULT_ENV_NAME=$(echo $PROJECT_NAME | tr '[:upper:]' '[:lower:]') -export ENV_NAME=$([ -z "$ENV_NAME" ] && echo $DEFAULT_ENV_NAME || echo $ENV_NAME) -export ENV_PATH=$BASE_ENV_PATH/.env/$ENV_NAME - -# ================== Python Variables ================== -CUSTOM_PYTHON_VERSION=3.12 # Uncomment and set to the desired Python version -export PIP_QUIET=true - -# ================== Enabling OpenVINO ================== -export OPENVINO_HOME=/opt/intel/openvino_2024 -if [ -d "$OPENVINO_HOME" ]; then - source $OPENVINO_HOME/setupvars.sh -fi -unset OPENVINO_HOME # =============== Color Print =============== DEFAULT=$(echo -en '\033[0m') @@ -31,11 +7,31 @@ GREEN=$(echo -en '\033[00;32m') YELLOW=$(echo -en '\033[00;33m') CYAN=$(echo -en '\033[00;36m') -function print_base { echo -e "$1- [$2] $3${DEFAULT}"; } -function print_info { print_base "$CYAN" "INFO" "$1"; } -function print_success { print_base "$GREEN" "SUCCESS" "$1"; } -function print_warning { print_base "$YELLOW" "WARNING" "$1"; } -function print_error { print_base "$RED" "ERROR" "$1"; } - - - +function print_base { echo -e "$1- [$2] $3${DEFAULT}"; } +function print_info { print_base "$CYAN" "INFO" "$1"; } +function print_tip { print_base "$CYAN" "TIP" "$1"; } +function print_success { print_base "$GREEN" "SUCCESS" "$1"; } +function print_warning { print_base "$YELLOW" "WARNING" "$1"; } +function print_error { print_base "$RED" "ERROR" "$1"; } + + +function run_script { + if [ ! -f "$1" ]; then + echo "$1 not found" + exit 1 + fi + source $1 +} + + + +if [ -f "scripts/variables.custom.sh" ]; then + run_script "scripts/variables.custom.sh" + print_success "Loaded custom variables: 'scripts/variables.custom.sh'" +elif [ -f "scripts/variables.sh" ]; then + run_script scripts/variables.sh + print_success "Loaded default variables: 'scripts/variables.sh'" +else + echo "'scripts/variables.custom.sh' or 'scripts/variables.sh' not found" + exit 1 +fi diff --git a/scripts/build.sh b/scripts/build.sh index 9567fe1..3c9a509 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,9 +1,6 @@ export OpenVINO_HOME="$HOME/program/openvino-2023_release" source $OpenVINO_HOME/setupvars.sh - - - BUILD_DIR="build" if [ ! -d "$BUILD_DIR" ]; then diff --git a/scripts/build_engine-8.6.1.6.py b/scripts/build_engine-8.6.1.6.py deleted file mode 100644 index 2391aca..0000000 --- a/scripts/build_engine-8.6.1.6.py +++ /dev/null @@ -1,279 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os -import sys -import logging -import argparse - -import numpy as np -import tensorrt as trt -from cuda import cudart - -sys.path.insert(1, os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) -import common - -from image_batcher import ImageBatcher - -logging.basicConfig(level=logging.INFO) -logging.getLogger("EngineBuilder").setLevel(logging.INFO) -log = logging.getLogger("EngineBuilder") - - -class EngineCalibrator(trt.IInt8EntropyCalibrator2): - """ - Implements the INT8 Entropy Calibrator 2. - """ - - def __init__(self, cache_file): - """ - :param cache_file: The location of the cache file. - """ - super().__init__() - self.cache_file = cache_file - self.image_batcher = None - self.batch_allocation = None - self.batch_generator = None - - def set_image_batcher(self, image_batcher: ImageBatcher): - """ - Define the image batcher to use, if any. If using only the cache file, an image batcher doesn't need - to be defined. - :param image_batcher: The ImageBatcher object - """ - self.image_batcher = image_batcher - size = int(np.dtype(self.image_batcher.dtype).itemsize * np.prod(self.image_batcher.shape)) - self.batch_allocation = common.cuda_call(cudart.cudaMalloc(size)) - self.batch_generator = self.image_batcher.get_batch() - - def get_batch_size(self): - """ - Overrides from trt.IInt8EntropyCalibrator2. - Get the batch size to use for calibration. - :return: Batch size. - """ - if self.image_batcher: - return self.image_batcher.batch_size - return 1 - - def get_batch(self, names): - """ - Overrides from trt.IInt8EntropyCalibrator2. - Get the next batch to use for calibration, as a list of device memory pointers. - :param names: The names of the inputs, if useful to define the order of inputs. - :return: A list of int-casted memory pointers. - """ - if not self.image_batcher: - return None - try: - batch, _ = next(self.batch_generator) - log.info("Calibrating image {} / {}".format(self.image_batcher.image_index, self.image_batcher.num_images)) - common.memcpy_host_to_device(self.batch_allocation, np.ascontiguousarray(batch)) - return [int(self.batch_allocation)] - except StopIteration: - log.info("Finished calibration batches") - return None - - def read_calibration_cache(self): - """ - Overrides from trt.IInt8EntropyCalibrator2. - Read the calibration cache file stored on disk, if it exists. - :return: The contents of the cache file, if any. - """ - if os.path.exists(self.cache_file): - with open(self.cache_file, "rb") as f: - log.info("Using calibration cache file: {}".format(self.cache_file)) - return f.read() - - def write_calibration_cache(self, cache): - """ - Overrides from trt.IInt8EntropyCalibrator2. - Store the calibration cache to a file on disk. - :param cache: The contents of the calibration cache to store. - """ - with open(self.cache_file, "wb") as f: - log.info("Writing calibration cache data to: {}".format(self.cache_file)) - f.write(cache) - - -class EngineBuilder: - """ - Parses an ONNX graph and builds a TensorRT engine from it. - """ - - def __init__(self, verbose=False): - """ - :param verbose: If enabled, a higher verbosity level will be set on the TensorRT logger. - """ - self.trt_logger = trt.Logger(trt.Logger.INFO) - if verbose: - self.trt_logger.min_severity = trt.Logger.Severity.VERBOSE - - trt.init_libnvinfer_plugins(self.trt_logger, namespace="") - - self.builder = trt.Builder(self.trt_logger) - self.config = self.builder.create_builder_config() - self.config.max_workspace_size = 8 * (2 ** 30) # 8 GB - - self.batch_size = None - self.network = None - self.parser = None - - def create_network(self, onnx_path): - """ - Parse the ONNX graph and create the corresponding TensorRT network definition. - :param onnx_path: The path to the ONNX graph to load. - """ - network_flags = 1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) - - self.network = self.builder.create_network(network_flags) - self.parser = trt.OnnxParser(self.network, self.trt_logger) - - onnx_path = os.path.realpath(onnx_path) - with open(onnx_path, "rb") as f: - if not self.parser.parse(f.read()): - log.error("Failed to load ONNX file: {}".format(onnx_path)) - for error in range(self.parser.num_errors): - log.error(self.parser.get_error(error)) - sys.exit(1) - - inputs = [self.network.get_input(i) for i in range(self.network.num_inputs)] - outputs = [self.network.get_output(i) for i in range(self.network.num_outputs)] - - log.info("Network Description") - for input in inputs: - self.batch_size = input.shape[0] - log.info("Input '{}' with shape {} and dtype {}".format(input.name, input.shape, input.dtype)) - for output in outputs: - log.info("Output '{}' with shape {} and dtype {}".format(output.name, output.shape, output.dtype)) - assert self.batch_size > 0 - self.builder.max_batch_size = self.batch_size - - def create_engine( - self, - engine_path, - precision, - calib_input=None, - calib_cache=None, - calib_num_images=25000, - calib_batch_size=8, - calib_preprocessor=None, - ): - """ - Build the TensorRT engine and serialize it to disk. - :param engine_path: The path where to serialize the engine to. - :param precision: The datatype to use for the engine, either 'fp32', 'fp16' or 'int8'. - :param calib_input: The path to a directory holding the calibration images. - :param calib_cache: The path where to write the calibration cache to, or if it already exists, load it from. - :param calib_num_images: The maximum number of images to use for calibration. - :param calib_batch_size: The batch size to use for the calibration process. - :param calib_preprocessor: The ImageBatcher preprocessor algorithm to use. - """ - engine_path = os.path.realpath(engine_path) - engine_dir = os.path.dirname(engine_path) - os.makedirs(engine_dir, exist_ok=True) - log.info("Building {} Engine in {}".format(precision, engine_path)) - - inputs = [self.network.get_input(i) for i in range(self.network.num_inputs)] - - if precision == "fp16": - if not self.builder.platform_has_fast_fp16: - log.warning("FP16 is not supported natively on this platform/device") - else: - self.config.set_flag(trt.BuilderFlag.FP16) - elif precision == "int8": - if not self.builder.platform_has_fast_int8: - log.warning("INT8 is not supported natively on this platform/device") - else: - self.config.set_flag(trt.BuilderFlag.INT8) - self.config.int8_calibrator = EngineCalibrator(calib_cache) - if not os.path.exists(calib_cache): - calib_shape = [calib_batch_size] + list(inputs[0].shape[1:]) - calib_dtype = trt.nptype(inputs[0].dtype) - self.config.int8_calibrator.set_image_batcher( - ImageBatcher( - calib_input, - calib_shape, - calib_dtype, - max_num_images=calib_num_images, - exact_batches=True, - preprocessor=calib_preprocessor, - ) - ) - - with self.builder.build_engine(self.network, self.config) as engine, open(engine_path, "wb") as f: - log.info("Serializing engine to file: {:}".format(engine_path)) - f.write(engine.serialize()) - - -def main(args): - builder = EngineBuilder(args.verbose) - builder.create_network(args.onnx) - builder.create_engine( - args.engine, - args.precision, - args.calib_input, - args.calib_cache, - args.calib_num_images, - args.calib_batch_size, - args.calib_preprocessor, - ) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("-o", "--onnx", help="The input ONNX model file to load") - parser.add_argument("-e", "--engine", help="The output path for the TRT engine") - parser.add_argument( - "-p", - "--precision", - default="fp16", - choices=["fp32", "fp16", "int8"], - help="The precision mode to build in, either 'fp32', 'fp16' or 'int8', default: 'fp16'", - ) - parser.add_argument("-v", "--verbose", action="store_true", help="Enable more verbose log output") - parser.add_argument("--calib_input", help="The directory holding images to use for calibration") - parser.add_argument( - "--calib_cache", - default="./calibration.cache", - help="The file path for INT8 calibration cache to use, default: ./calibration.cache", - ) - parser.add_argument( - "--calib_num_images", - default=25000, - type=int, - help="The maximum number of images to use for calibration, default: 25000", - ) - parser.add_argument( - "--calib_batch_size", default=8, type=int, help="The batch size for the calibration process, default: 1" - ) - parser.add_argument( - "--calib_preprocessor", - default="V2", - choices=["V1", "V1MS", "V2"], - help="Set the calibration image preprocessor to use, either 'V2', 'V1' or 'V1MS', default: V2", - ) - args = parser.parse_args() - if not all([args.onnx, args.engine]): - parser.print_help() - log.error("These arguments are required: --onnx and --engine") - sys.exit(1) - if args.precision == "int8" and not any([args.calib_input, args.calib_cache]): - parser.print_help() - log.error("When building in int8 precision, either --calib_input or --calib_cache are required") - sys.exit(1) - main(args) diff --git a/scripts/create-python-env.conda.sh b/scripts/create-python-env.conda.sh deleted file mode 100644 index 5cd7d29..0000000 --- a/scripts/create-python-env.conda.sh +++ /dev/null @@ -1,13 +0,0 @@ -function run_script { - if [ ! -f "$1" ]; then - echo "$1 not found" - exit 1 - fi - source $1 -} - -run_script "scripts/base.sh" -run_script "scripts/python-activate.conda.sh" -run_script "scripts/python-install-requirements.sh" - -print_activate_env_message \ No newline at end of file diff --git a/scripts/create-python-env.sh b/scripts/create-python-env.sh new file mode 100644 index 0000000..64f7cdf --- /dev/null +++ b/scripts/create-python-env.sh @@ -0,0 +1,61 @@ +if [ ! -f "scripts/base.sh" ]; then + echo "scripts/base.sh not found" + exit 1 +fi +source scripts/base.sh + +# Set default values +env_provider="venv" +install=true + + +while [ $# -gt 0 ] +do +key="$1" +case $key in + -e|--env-provider) + env_provider="$2" + shift # shift past argument + shift # shift past value + ;; + -ni|--no-install) + install=false + shift # shift past argument + ;; + -h|--help) + echo "Usage: create-python-env.sh [OPTIONS]" + echo "Options:" + echo " -e, --env-provider Set the environment provider (venv or conda)" + echo " -ni, --no-install Skip Python requirements installation" + echo " -h, --help Show this help message and exit" + exit 0 + ;; + *) + # unknown option + echo "Unknown option: $key" + exit 1 + ;; +esac +done + +print_info "Environment Provider set to: $env_provider" + +if [ "$env_provider" = "venv" ]; then + run_script "scripts/utils/python-activate.venv.sh" +elif [ "$env_provider" = "conda" ]; then + run_script "scripts/utils/python-activate.conda.sh" +else + print_error "Invalid environment provider: $env_provider , exiting..." + print_tip "Valid options are: 'venv' or 'conda'" + exit 1 +fi + +if [ "$install" = true ]; then + print_info "Installing Python requirements..." + run_script "scripts/utils/python-install-requirements.sh" +else + print_warning "Skipping Python requirements installation..." +fi + +print_activate_env_message + diff --git a/scripts/create-python-env.venv.sh b/scripts/create-python-env.venv.sh deleted file mode 100644 index b1fde6f..0000000 --- a/scripts/create-python-env.venv.sh +++ /dev/null @@ -1,14 +0,0 @@ -function run_script { - if [ ! -f "$1" ]; then - echo "$1 not found" - exit 1 - fi - source $1 -} - -run_script "scripts/base.sh" -run_script "scripts/python-activate.venv.sh" -run_script "scripts/python-install-requirements.sh" - -print_activate_env_message - diff --git a/scripts/download-yolov5.sh b/scripts/download-yolov5.sh index 214c593..4e3f4c4 100644 --- a/scripts/download-yolov5.sh +++ b/scripts/download-yolov5.sh @@ -1,3 +1,9 @@ +if [ ! -f "scripts/base.sh" ]; then + echo "scripts/base.sh not found" + exit 1 +fi +source scripts/base.sh + tag_name=v7.0 all_model_list=( yolov5n @@ -8,7 +14,7 @@ all_model_list=( yolov5n ) -weights_dir=./.cache/yolov5 +weights_dir=$CACHE_DIR/yolov5 mkdir -p ${weights_dir} model_list=($1) @@ -17,8 +23,13 @@ if [ ${#model_list[@]} -eq 0 ]; then model_list=(${all_model_list[@]}) fi +print_info "Downloading YOLOv5 (${model_list}) weights..." +echo "" + for model_name in ${model_list[@]}; do url=https://github.com/ultralytics/yolov5/releases/download/${tag_name}/${model_name}.pt - echo "Downloading ${model_name}.pt from ${url}" - wget -c ${url} -P ${weights_dir} + print_info "Downloading ${url} ..." + wget -c ${url} -P ${weights_dir} #--no-verbose + print_success "Downloaded successfully: ${weights_dir}/${model_name}.pt" + echo done diff --git a/scripts/export-yolov5.sh b/scripts/export-yolov5.sh index a1b4280..2890e9a 100644 --- a/scripts/export-yolov5.sh +++ b/scripts/export-yolov5.sh @@ -1,32 +1,48 @@ -PROJECT_HOME=$(pwd) +if [ ! -f "scripts/base.sh" ]; then + echo "scripts/base.sh not found" + exit 1 +fi +source scripts/base.sh + + +# =============== Set Training Variables ================ + +# -- Yolov5 project path / 项目路径 yolov5_path=$PROJECT_HOME/projects/yolov5 -YOLO_PRETRAINED_MODE_DIRL=$PROJECT_HOME/.cache/yolov5 -EXPORT_MODEL=yolov5s.pt +DATASET_CONFIG=$yolov5_path/data/coco128.yaml -MODEL_PATH=$YOLO_PRETRAINED_MODE_DIRL/$EXPORT_MODEL -# MODEL_PATH=.. # 取消注释,自定义模型路径 +# -- Path to exported model / 需要导出模型的路径 +EXPORTED_MODEL_PATH=$PROJECT_HOME/.cache/yolov5/yolov5s.pt -cd $yolov5_path +# -- 导出 TensorRT 的参数 +# 如果是单卡 设置为 0 +# CUDA:0 (NVIDIA GeForce RTX 3080, 12117MiB) +# 如果是双卡 设置为 0,1 +# CUDA:0 (NVIDIA GeForce RTX 4090, 24217MiB) +# CUDA:1 (NVIDIA GeForce RTX 4090, 24217MiB) +# 电脑有多少显卡就得给多少 +TRT_EXPORTED_DEVICE="0,1" # Multiple GPUs +TRT_EXPORTED_DEVICE="0" # Single GPU -# export the model to the onnx format +# ======================================================= + +cd $yolov5_path python3 export.py \ - --weights $MODEL_PATH \ - --data data/coco128.yaml \ + --weights $EXPORTED_MODEL_PATH \ + --data $DATASET_CONFIG \ --simplify --include onnx + python3 export.py \ - --weights $MODEL_PATH \ - --data data/coco128.yaml \ + --weights $EXPORTED_MODEL_PATH \ + --data $DATASET_CONFIG \ --simplify --include openvino -python3 export.py \ - --weights $MODEL_PATH \ - --data data/coco128.yaml \ - --simplify --device 0,1 --include engine -# 0,1 单 GPU 貌似报错,电脑有多少就得给多少 -# CUDA:0 (NVIDIA GeForce RTX 4090, 24217MiB) -# CUDA:1 (NVIDIA GeForce RTX 4090, 24217MiB) \ No newline at end of file +python3 export.py \ + --weights $EXPORTED_MODEL_PATH \ + --data $DATASET_CONFIG \ + --simplify --include engine --device $TRT_EXPORTED_DEVICE diff --git a/scripts/train.sh b/scripts/train.sh index 8641b96..688c902 100644 --- a/scripts/train.sh +++ b/scripts/train.sh @@ -1,8 +1,13 @@ +if [ ! -f "scripts/base.sh" ]; then + echo "scripts/base.sh not found" + exit 1 +fi source scripts/base.sh + # =============== Set Training Variables ================ -DATASET_DIR=$HOME/data/bottle +DATASET_DIR=~/data/yolodataset TRAIN_DATA_DIR=$DATASET_DIR-organized # if GPU memory is enough, recommended training with Single but not Multiple GPU @@ -11,7 +16,7 @@ TRAIN_DEVICE="0" # Single GPU TRAIN_DEVICE="cpu" # default, MacOS or without GPU MODEL_NAME=yolov5s -PRETRAINED_MODEL=$PROJECT_HOME/.cache/yolov5/yolov5s.pt +PRETRAINED_MODEL=$CACHE_DIR/yolov5/yolov5s.pt BATCH_SIZE=4 EPOCHS=4 @@ -25,7 +30,7 @@ YOLOV5_PROJECT_HOME=$PROJECT_HOME/projects/yolov5 print_info "Checking YOLOv5 project ..." if [ ! -d "$YOLOV5_PROJECT_HOME" ]; then print_error "YOLOv5 project not found at $YOLOV5_PROJECT_HOME" - print_info "Please run 'git submodule update --init --recursive'" + print_tip "Please run 'git submodule update --init --recursive'" exit 1 else print_success "YOLOv5 project found in '$YOLOV5_PROJECT_HOME'" diff --git a/scripts/python-activate.conda.sh b/scripts/utils/python-activate.conda.sh similarity index 100% rename from scripts/python-activate.conda.sh rename to scripts/utils/python-activate.conda.sh diff --git a/scripts/python-activate.venv.sh b/scripts/utils/python-activate.venv.sh similarity index 100% rename from scripts/python-activate.venv.sh rename to scripts/utils/python-activate.venv.sh diff --git a/scripts/python-install-requirements.sh b/scripts/utils/python-install-requirements.sh similarity index 81% rename from scripts/python-install-requirements.sh rename to scripts/utils/python-install-requirements.sh index 958fb90..7acac6e 100644 --- a/scripts/python-install-requirements.sh +++ b/scripts/utils/python-install-requirements.sh @@ -26,11 +26,11 @@ fi print_info "Installing other requirements..." -mkdir -p .cache/yolov5 -if [ ! -f ".cache/yolov5/requirements.txt" ]; then - cp projects/yolov5/requirements.txt .cache/yolov5/requirements.txt +mkdir -p $CACHE_DIR/yolov5 +if [ ! -f "$CACHE_DIR/yolov5/requirements.txt" ]; then + cp projects/yolov5/requirements.txt $CACHE_DIR/yolov5/requirements.txt fi -python3 -m pip install $PIP_QUIET_FLAG -r .cache/yolov5/requirements.txt +python3 -m pip install $PIP_QUIET_FLAG -r $CACHE_DIR/yolov5/requirements.txt python3 -m pip install $PIP_QUIET_FLAG -r requirements/requirements.train.txt if [ ! -z "${CUDA_VERSION}" ]; then @@ -45,8 +45,8 @@ if [ -d "$INTEL_OPENVINO_DIR" ]; then python3 -m pip install $PIP_QUIET_FLAG -r $INTEL_OPENVINO_DIR/python/requirements.txt else print_warning "OpenVINO not found, skipping OpenVINO Python requirements installation" - # print_info "Installing OpenVINO Python requirements from pip" - # python3 -m pip install $PIP_QUIET_FLAG openvino-dev + print_info "Installing OpenVINO Python requirements from pip" + python3 -m pip install $PIP_QUIET_FLAG openvino-dev fi # freeze the requirements diff --git a/scripts/variables.sh b/scripts/variables.sh new file mode 100644 index 0000000..a723883 --- /dev/null +++ b/scripts/variables.sh @@ -0,0 +1,38 @@ + +# =============== Environment Variables ================ +# -- install python in `user` or `project` level +# export BASE_ENV_PATH=$HOME # -- user level +export BASE_ENV_PATH=. # -- project level + +# ================== Project Variables ================== +export PROJECT_HOME=$(pwd) +export PROJECT_NAME=$(basename $PROJECT_HOME) +DEFAULT_ENV_NAME=$(echo $PROJECT_NAME | tr '[:upper:]' '[:lower:]') + +export ENV_NAME=$([ -z "$ENV_NAME" ] && echo $DEFAULT_ENV_NAME || echo $ENV_NAME) +# export ENV_NAME="" # -- Uncomment to customize the environment name + +export ENV_PATH=$BASE_ENV_PATH/.env/$ENV_NAME + +# ================== Project Variables ================== +export CACHE_DIR=$PROJECT_HOME/.cache + + +# ================== Python Variables ================== +# CUSTOM_PYTHON_VERSION=3.12 # -- Uncomment and set to the desired Python version (only for conda) +export PIP_QUIET=true # -- pip install with quiet/verbose + +# ================== Enabling CUDA ================== +# -- Variables related to CUDA should be written to ~/.bashrc instead of here +# -- Uncomment to Overwrite the CUDA version if needed +# export CUDA_VERSION=12.1 +# export CUDA_HOME="/usr/local/cuda-${CUDA_VERSION}" +# export PATH="$CUDA_HOME/bin:$PATH" + +# ================== Enabling OpenVINO ================== +export OPENVINO_HOME=/opt/intel/openvino_2024 +if [ -d "$OPENVINO_HOME" ]; then + source $OPENVINO_HOME/setupvars.sh +fi +unset OPENVINO_HOME +