Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEPLOYMENT] Jenkins remote deployment #564

Draft
wants to merge 37 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e7bee83
raw auto scripts
ismukhin Nov 17, 2024
9f12cdf
add auto tvm
ismukhin Dec 1, 2024
fcd4e04
fix conda paths
ismukhin Dec 2, 2024
f0d9e16
fix paths
ismukhin Dec 4, 2024
3b88a97
add requirements
ismukhin Dec 4, 2024
48e0ac7
remote start add python specific interpreter
ismukhin Dec 4, 2024
27d4789
fix frameworks env build
ismukhin Dec 4, 2024
542e909
nproc all
ismukhin Dec 4, 2024
03c71e1
fix
ismukhin Dec 4, 2024
6561722
fix
ismukhin Dec 4, 2024
d9b5e7a
fix python remote start
ismukhin Dec 5, 2024
8755b78
print
ismukhin Dec 5, 2024
d17e07d
print2
ismukhin Dec 5, 2024
d8d0c3f
python specific interpreter in benchmark
ismukhin Dec 5, 2024
3bf8369
fix
ismukhin Dec 6, 2024
be5ad11
fix
ismukhin Dec 6, 2024
a942d80
fix
ismukhin Dec 8, 2024
5b54797
fix
ismukhin Dec 8, 2024
5d9e75a
fix
ismukhin Dec 8, 2024
cd7634b
fix
ismukhin Dec 8, 2024
b7749a6
fix
ismukhin Dec 8, 2024
8350700
compile fix
ismukhin Dec 10, 2024
9a619fe
compile fix
ismukhin Dec 10, 2024
9628b72
compile fix
ismukhin Dec 10, 2024
37239b9
fix compile
ismukhin Dec 10, 2024
ad0b6e1
fix compile
ismukhin Dec 10, 2024
b1d8ffc
make dirs
ismukhin Dec 10, 2024
175c641
prints
ismukhin Dec 10, 2024
0a6705c
fix
ismukhin Dec 10, 2024
2dc7195
fix1
ismukhin Dec 10, 2024
b20c099
fix1
ismukhin Dec 10, 2024
657efa2
finally fix
ismukhin Dec 10, 2024
f4bc0e5
vm add
ismukhin Dec 12, 2024
4d0bc44
pytorch
ismukhin Dec 12, 2024
ed4bb4d
pytorch
ismukhin Dec 12, 2024
a56d536
fixes for name of main python env
ismukhin Jan 5, 2025
c015fd2
fixes
ismukhin Jan 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/benchmark/frameworks/tvm/tvm_process.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path

import platform
from ..processes import ProcessHandler


Expand Down Expand Up @@ -37,6 +37,17 @@ def create_process(test, executor, log):
def get_performance_metrics(self):
return self.get_performance_metrics_from_json_report()

@staticmethod
def get_cmd_python_version():
cmd_python_version = ''
os_type = platform.system()
if os_type == 'Linux':
cmd_python_version = '/home/itmm/miniconda3/envs/tvm_main/bin/python3'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Полный путь до интерпретатора, насколько я помню, планируется вынести в параметры бенчмарка. Так ведь?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, планирую вынести в параметры бенчмарка, также надо будет вшить проверку, что там действительно интерпретатор, а не какой-нибудь rm. Просто такая вещь явно не является безопасной, хотя можно оставить это на совесть пользователей :)

else:
cmd_python_version = 'python'

return cmd_python_version

def _fill_command_line(self):
dataset = self._test.dataset.path
input_shape = self._test.dep_parameters.input_shape
Expand Down Expand Up @@ -219,7 +230,7 @@ def _fill_command_line(self):
else:
raise ValueError('Wrong arguments.')
common_params += '-f tvm '
python = ProcessHandler.get_cmd_python_version()
python = TVMProcess.get_cmd_python_version()
time_limit = self._test.indep_parameters.test_time_limit
common_params += super()._fill_command_line()
common_params += f' --time {time_limit}'
Expand Down
27 changes: 27 additions & 0 deletions src/deployment/jenkins/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import logging as log
import sys


DEFAULT_FORMATTER = log.Formatter('[ %(levelname)s ] %(message)s')


def configure_logger(name='', level=log.INFO, use_default_formatter=False):

logger = log.getLogger()
logger.setLevel(level)

if logger.hasHandlers():
logger.handlers.clear()

stream_handler = log.StreamHandler(stream=sys.stdout)
stream_handler.setLevel(level)
stream_handler.setFormatter(DEFAULT_FORMATTER)
logger.addHandler(stream_handler)

file_handler = log.FileHandler(name, 'w')
file_handler.setLevel(level)
file_handler.setFormatter(DEFAULT_FORMATTER)
logger.addHandler(file_handler)

logger.propagate = False
return logger
11 changes: 11 additions & 0 deletions src/deployment/jenkins/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
traitlets==5.9.0
decorator
attrs
typing-extensions
psutil
scipy
pybind11
numpy
opencv-python
scipy
openvino-dev==2024.3.0
63 changes: 63 additions & 0 deletions src/deployment/jenkins/tvm_build_envs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import sys
import argparse
import os
import subprocess


class EnvCreator:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Предлагаю назвать этот клас TVMEnvCreator, чтобы не было никаких вопросов.

def __init__(self, frameworks, py_version, conda):
self.frameworks = frameworks.split(',')
self.py_version = py_version
self.conda_prefix = conda

def _run(self, cmd):
return subprocess.run(cmd, shell=True)

def create_envs(self):
if len(self.frameworks) != 0:
for framework in self.frameworks:
self._run(f'{self.conda_prefix}/bin/conda create -y --name tvm_{framework} --clone tvm_main')
if framework != 'mxnet':
self._run(f'{self.conda_prefix}/envs/tvm_{framework}/bin/pip3 install {framework}')
else:
self._run(f'{self.conda_prefix}/envs/tvm_{framework}/bin/pip3 install {framework}==1.9.1')
self._run(f'{self.conda_prefix}/envs/tvm_{framework}/bin/pip3 install gluoncv[full]')
self._run(f'{self.conda_prefix}/envs/tvm_{framework}/bin/pip3 uninstall -y numpy')
self._run(f'{self.conda_prefix}/envs/tvm_{framework}/bin/pip3 install numpy==1.23.1')


def cli_arguments_parse():
parser = argparse.ArgumentParser()

parser.add_argument('-b', '--branch',
help='Branch to build tvm.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tvm -> TVM

dest='branch',
required=True,
type=str)
parser.add_argument('-f', '--frameworks',
help='Frameworks to create conda envs.',
dest='frameworks',
default='',
required=False,
type=str)
parser.add_argument('-p', '--python_version',
help='Python version to create conda env.',
dest='py',
required=True,
type=str)
parser.add_argument('-cp', '--conda_prefix',
help='Path to miniconda3 directory.',
dest='conda',
required=True,
type=str)

return parser.parse_args()

def main():
args = cli_arguments_parse()
cr = EnvCreator(args.frameworks, args.py, args.conda)
cr.create_envs()


if __name__=='__main__':
sys.exit(main() or 0)
54 changes: 54 additions & 0 deletions src/deployment/jenkins/tvm_build_pipeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import sys
import argparse
import os
import subprocess


class TVMBuilder:
def __init__(self, branch, conda, py):
self.branch = branch
self.conda = conda
self.py_version = py

def _run(self, cmd):
return subprocess.run(cmd, shell=True)

def build_tvm(self):
self._run(f'{self.conda}/bin/conda create -y -n tvm_main python=={self.py_version}')
self._run(f'{self.conda}/bin/conda install -n tvm_main -c conda-forge -y gcc=12.1.0')
self._run(f'{self.conda}/bin/conda install -n tvm_main -c conda-forge -y gxx_linux-64')
self._run(f'{self.conda}/envs/tvm_main/bin/pip3 install -r requirements.txt')
self._run(f'git clone --recursive https://github.com/apache/tvm -b {self.branch}')
self._run(f'cd tvm && mkdir -p build && cd build && cmake -DUSE_LLVM=ON ../ && make -j$(nproc --all) && cd ../python && {self.conda}/envs/tvm_main/bin/python setup.py install --user')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Разбейте, пожалуйста, строку на несколько, чтобы было не более 80 символов. Что-то типа такого должно сработать:

self._run(f'cd tvm && mkdir -p build && cd build && '
        f'cmake -DUSE_LLVM=ON ../ && make -j$(nproc --all) && cd ../python && `
        f`{self.conda}/envs/tvm_main/bin/python setup.py install --user')



def cli_arguments_parse():
parser = argparse.ArgumentParser()

parser.add_argument('-b', '--branch',
help='Branch to build tvm.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tvm -> TVM

dest='branch',
required=True,
type=str)
parser.add_argument('-p', '--python_version',
help='Python version to create conda env.',
dest='py',
required=True,
type=str)
parser.add_argument('-cp', '--conda_prefix',
help='Path to miniconda3 directory.',
dest='conda',
required=True,
type=str)

return parser.parse_args()


def main():
args = cli_arguments_parse()
cr = TVMBuilder(args.branch, args.conda, args.py)
cr.build_tvm()


if __name__ == '__main__':
sys.exit(main() or 0)
132 changes: 132 additions & 0 deletions src/deployment/jenkins/tvm_compile_pipeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import argparse
import sys
import subprocess
from logger import configure_logger
import traceback
from pathlib import Path

sys.path.append(str(Path(__file__).parents[3]))


log = configure_logger('tvm_converter_log.txt')


class TXTParser:
def __init__(self, filepath):
self.filepath = filepath
self.lines = None

def parse(self):
if not self.filepath.exists():
raise FileNotFoundError('File doesn\'t exist.')
log.info(f'Parsing file: {self.filepath.as_posix()}')
with self.filepath.open() as file:
self.lines = file.read().splitlines()
for i, line in enumerate(self.lines):
self.lines[i] = line.split(';')
self.lines[i][5] = [int(batch) for batch in self.lines[i][5].split(',')]
return self.lines


class TVMCompilerProcess:
def __init__(self, models_dir, conda, output_dir, vm):
self.converter = Path(__file__).parents[2]
self.converter = self.converter.joinpath('model_converters')
self.converter = self.converter.joinpath('tvm_converter')
self.converter = str(self.converter.joinpath('tvm_compiler.py'))
self.conda = conda
self.vm = vm
self.models_dir = models_dir.absolute().as_posix()
if output_dir is not None:
self.output_dir = output_dir
else:
self.output_dir = models_dir
self._command_line = f''

def _add_argument(self, name_of_arg, value_of_arg):
if value_of_arg != '':
self._command_line += f' {name_of_arg} {value_of_arg}'

def _add_option(self, name_of_arg):
self._command_line += f' {name_of_arg}'

def create_command_line(self, model_name, target, batch, opt_level):
self._command_line = (f'{self.conda}/envs/tvm_main/bin/python3 ' + f'{self.converter}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Где-то написан python (tvm_build_pipeline.py, строка 22), а где-то python3. Понимаю, что при запуске разницы нет, но лучше везде использовать одинаковое название интерпретатора. Вообще у меня есть мысль, что идентичные константные f-строки надо вытащить в отдельный python-скрипт, а потом их везде использовать.

self._add_argument('--mod', f'{self.models_dir}/{model_name}/batch_{batch}/{model_name}.json')
self._add_argument('--params', f'{self.models_dir}/{model_name}/batch_{batch}/{model_name}.params')
self._add_argument('-t', f'"{target}"')
self._add_argument('--opt_level', f'{opt_level}')
self._add_argument('--lib_name', f'{model_name}.so')
self._add_argument('-op', f'{self.output_dir}/{model_name}/batch_{batch}/opt_level{opt_level}')
if self.vm:
self._add_option('-vm')

def execute(self):
log.info(f'Starting process: {self._command_line}\n')
proc = subprocess.run(self._command_line, shell=True)
self.exit_code = proc.returncode
self._command_line = ''



def cli_arguments_parse():
parser = argparse.ArgumentParser()

parser.add_argument('-md', '--models_dir',
help='Path to directory with models.',
dest='models_dir',
required=True,
type=Path)
parser.add_argument('-mi', '--models_info',
help='Txt file with info about models.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Имеет смысл выложить пример этого файла.

dest='models_info',
required=True,
type=Path)
parser.add_argument('-op', '--output_dir',
help='Path to save the model.',
default=None,
type=str,
dest='output_dir')
parser.add_argument('--opt_level',
help='The optimization level of the task extractions.',
type=list,
default=[0, 1, 2, 3],
dest='opt_levels')
parser.add_argument('--target',
help='Parameter for hardware-dependent optimizations.',
default='llvm',
type=str,
dest='target')
parser.add_argument('-cp', '--conda_prefix',
help='Path to miniconda3 directory.',
dest='conda',
required=True,
type=str)
parser.add_argument('-vm', '--virtual_machine',
help='Flag to use VirtualMachine API',
action='store_true',
dest='vm')

return parser.parse_args()


def main():
args = cli_arguments_parse()
parser = TXTParser(args.models_info)
models = parser.parse()
proc = TVMCompilerProcess(args.models_dir, args.conda, args.output_dir, args.vm)
for (model_name, _, _,
_, _, batches, _) in models:
for batch in batches:
for level in args.opt_levels:
proc.create_command_line(
model_name, args.target,
batch, level
)
proc.execute()




if __name__=='__main__':
sys.exit(main() or 0)
Loading
Loading