From cb5aea46d06b5f35f2fbf36a5229fdad767fd132 Mon Sep 17 00:00:00 2001 From: Dingjiahui Date: Sun, 16 Mar 2025 23:38:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Edebug=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E5=85=81=E8=AE=B8=E8=B7=B3=E8=BF=87=E7=89=B9=E5=AE=9A?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E4=BB=BB=E5=8A=A1=E3=80=82=E9=87=8D=E6=9E=84?= =?UTF-8?q?deepseek-r1=E9=83=A8=E7=BD=B2=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E5=B0=86=E5=AE=89=E8=A3=85=E6=B5=81=E7=A8=8B=E6=8B=86=E5=88=86?= =?UTF-8?q?=E4=B8=BA=E7=8E=AF=E5=A2=83=E5=87=86=E5=A4=87=E3=80=81=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E3=80=81=E9=85=8D=E7=BD=AE=E3=80=81=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E5=9B=9B=E4=B8=AA=E7=8B=AC=E7=AB=8B=E6=AD=A5=E9=AA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oedp/src/commands/run/run_action.py | 27 +++--- oedp/src/commands/run/run_cmd.py | 39 +++++--- oedp/src/parsers/oedp_parser.py | 8 +- plugins/deepseek-r1/main.yaml | 16 +++- .../deepseek-r1/workspace/0-env_prepare.yaml | 14 +++ .../{install.yaml => 1-install_ollama.yaml} | 88 +------------------ .../workspace/2-modify_modelfile.yaml | 79 +++++++++++++++++ .../workspace/3-start_deepseek.yaml | 11 +++ 8 files changed, 168 insertions(+), 114 deletions(-) create mode 100644 plugins/deepseek-r1/workspace/0-env_prepare.yaml rename plugins/deepseek-r1/workspace/{install.yaml => 1-install_ollama.yaml} (50%) create mode 100644 plugins/deepseek-r1/workspace/2-modify_modelfile.yaml create mode 100644 plugins/deepseek-r1/workspace/3-start_deepseek.yaml diff --git a/oedp/src/commands/run/run_action.py b/oedp/src/commands/run/run_action.py index fddf720..356aa5d 100644 --- a/oedp/src/commands/run/run_action.py +++ b/oedp/src/commands/run/run_action.py @@ -18,17 +18,19 @@ from src.utils.log.logger_generator import LoggerGenerator class RunAction: - def __init__(self, project: str, action: str, tasks: list): + def __init__(self, action: str, tasks: list, project: str, debug: bool): """ 执行指定项目的指定方法。 :param project: 项目目录路径 :param action: 方法名称 :param tasks: 方法代码路径 + :param debug: 是否启用调试模式 """ - self.project = project self.action = action self.tasks = tasks + self.project = project + self.debug = debug self.log = LoggerGenerator().get_logger('run_action') def run(self) -> bool: @@ -55,14 +57,14 @@ class RunAction: return True def _run_playbook(self, task: dict, project: str) -> bool: - if 'disabled' in task and task['disabled'] == True: - self.log.info(f'Skipping task {task.get("name", "")}') + if self.debug and task.get('disabled_in_debug', False): + self.log.info(f'Skipping task "{task.get("name", "unamed task")}"') return True self.log.info(f'Running task {task.get("name", "")}') workspace = os.path.join(project, 'workspace') playbook = os.path.join(workspace, task['playbook']) if not os.path.exists(playbook): - self.log.error(f'Playbook {playbook} does not exist') + self.log.error(f'Playbook does not exist: {os.path.abspath(playbook)}') return False inventory = os.path.join(project, 'config.yaml') cmd = ['ansible-playbook', playbook, '-i', inventory] @@ -75,12 +77,13 @@ class RunAction: if 'scope' in task and task['scope'] != 'all': cmd.extend(['--limit', task['scope']]) self.log.debug(f'Executing cmd: {cmd}') - out, err, ret = CommandExecutor.run_single_cmd(cmd, print_on_console=True) - if ret: - if err: - self.log.error(f'Execute cmd failed: {err}') - else: - self.log.error(f'Execute cmd failed') + try: + out, err, ret = CommandExecutor.run_single_cmd(cmd, print_on_console=True) + if ret != 0: + self.log.error(f'Execute cmd failed [code:{ret}]:\nSTDOUT: {out}\nSTDERR: {err}') + return False + except Exception as e: + self.log.error(f'Exception occurred: {str(e)}') return False - self.log.info(f'Execute succeeded') + self.log.info(f'Execute succeeded: {task.get("name", "unamed task")}') return True diff --git a/oedp/src/commands/run/run_cmd.py b/oedp/src/commands/run/run_cmd.py index be38854..46b6640 100644 --- a/oedp/src/commands/run/run_cmd.py +++ b/oedp/src/commands/run/run_cmd.py @@ -11,22 +11,27 @@ # Create: 2024-12-23 # ====================================================================================================================== +import time + from src.commands.run.run_action import RunAction from src.exceptions.config_exception import ConfigException from src.utils.log.logger_generator import LoggerGenerator from src.utils.main_reader import MainReader +from decimal import Decimal class RunCmd: - def __init__(self, action: str, project: str): + def __init__(self, action: str, project: str, debug: bool): """ 执行一个项目中的方法。 :param action: 方法名称 :param project: 项目目录路径 + :param debug: 是否启用调试模式 """ self.action = action self.project = project + self.debug = debug self.log = LoggerGenerator().get_logger('run_cmd') def run(self): @@ -35,15 +40,25 @@ class RunCmd: :return: 是否执行成功 """ - self.log.debug(f'Running cmd run: action={self.action}, project={self.project}') + start_time = time.time() + self.log.info(f'Start time: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(start_time))}') try: - main = MainReader(self.project) - action = main.get_action_detail(self.action) - except ConfigException as e: - self.log.error(f'Failed to get project main info: {e}') - return False - if 'tasks' not in action: - self.log.error(f'Failed to get tasks info: {action}') - return False - tasks = action['tasks'] - return RunAction(self.project, self.action, tasks).run() + self.log.debug(f'Running cmd run: action={self.action}, project={self.project}') + try: + main = MainReader(self.project) + action = main.get_action_detail(self.action) + except ConfigException as e: + self.log.error(f'Failed to get project main info: {e}') + return False + if 'tasks' not in action: + self.log.error(f'Failed to get tasks info: {action}') + return False + tasks = action['tasks'] + return RunAction(self.action, tasks, self.project, self.debug).run() + finally: + end_time = time.time() + seconds = Decimal(f"{format(end_time - start_time, '.1f')}") + formatted_time = time.strftime("%H:%M:%S", time.gmtime(float(seconds))) + elapsed_time = f"{formatted_time}.{int((seconds % 1) * 10)}" + self.log.info(f'End time: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(end_time))}') + self.log.info(f'Elapsed time: {elapsed_time}') diff --git a/oedp/src/parsers/oedp_parser.py b/oedp/src/parsers/oedp_parser.py index dd0396e..3e40a7c 100644 --- a/oedp/src/parsers/oedp_parser.py +++ b/oedp/src/parsers/oedp_parser.py @@ -169,6 +169,11 @@ class OeDeployParser: default=os.getcwd(), help='Specify the project path' ) + deploy_command.add_argument( + '-d', '--debug', + action='store_true', + help='Enable debug mode' + ) deploy_command.set_defaults(func=self._run_run_command) def _add_check_command(self): @@ -219,7 +224,8 @@ class OeDeployParser: def _run_run_command(args): action = args.action project = args.project - return RunCmd(action, project).run() + debug = args.debug + return RunCmd(action, project, debug).run() @staticmethod def _run_check_command(args): diff --git a/plugins/deepseek-r1/main.yaml b/plugins/deepseek-r1/main.yaml index cbc65e0..1df3c13 100644 --- a/plugins/deepseek-r1/main.yaml +++ b/plugins/deepseek-r1/main.yaml @@ -5,7 +5,19 @@ action: install: description: install DeepSeek-R1 tasks: - - name: install DeepSeek-R1 - playbook: install.yaml + - name: env prepare + playbook: 0-env_prepare.yaml + scope: all + disabled_in_debug: true + - name: install ollama + playbook: 1-install_ollama.yaml + scope: all + disabled_in_debug: true + - name: modify modelfile + playbook: 2-modify_modelfile.yaml + scope: all + disabled_in_debug: false + - name: start DeepSeek-R1 + playbook: 3-start_deepseek.yaml scope: all \ No newline at end of file diff --git a/plugins/deepseek-r1/workspace/0-env_prepare.yaml b/plugins/deepseek-r1/workspace/0-env_prepare.yaml new file mode 100644 index 0000000..c3c4145 --- /dev/null +++ b/plugins/deepseek-r1/workspace/0-env_prepare.yaml @@ -0,0 +1,14 @@ +--- +- name: Install Ollama and run Deepseek + hosts: all + + tasks: + - name: Ensure SELinux Python bindings are installed + yum: + name: python3-libselinux + state: present + + - name: Ensure tar is installed + yum: + name: tar + state: present diff --git a/plugins/deepseek-r1/workspace/install.yaml b/plugins/deepseek-r1/workspace/1-install_ollama.yaml similarity index 50% rename from plugins/deepseek-r1/workspace/install.yaml rename to plugins/deepseek-r1/workspace/1-install_ollama.yaml index 52e322a..506bd91 100644 --- a/plugins/deepseek-r1/workspace/install.yaml +++ b/plugins/deepseek-r1/workspace/1-install_ollama.yaml @@ -3,10 +3,8 @@ hosts: all vars: ollama_file: "{{ ollama_download | basename }}" - modelfile_file: "{{ modelfile_download | basename }}" tasks: - # ================ start ollama ===================== - name: Ensure SELinux Python bindings are installed yum: @@ -79,7 +77,7 @@ changed_when: false ignore_errors: no - - name: Create ollama system user and group + - name: Create ollama system user and group block: - name: Ensure ollama group exists group: @@ -121,87 +119,3 @@ systemd: name: ollama state: started - - # ================ modify modelfile ===================== - - - name: Download modelfile - block: - - name: Ensure modelfile download path exists - file: - path: "{{ modelfile_download_path }}" - state: directory - mode: '0755' - - - name: Copy download.sh to remote - copy: - src: download.sh - dest: "{{ modelfile_download_path }}/download.sh" - owner: root - group: root - mode: '0644' - - - name: Execute download.sh - shell: > - bash {{ modelfile_download_path }}/download.sh - {{ modelfile_download }} - {{ modelfile_download_path }} - {{ 1 if download_checksum else 0 }} - {{ download_timeout }} - {{ download_retry }} - >> {{ modelfile_download_path }}/download.log - ignore_errors: no - async: 0 - register: download_result - failed_when: download_result.rc != 0 - - rescue: - - name: Print error message of downloading modelfile - debug: - msg: "Unable to download modelfile, parameter tuning will not take effect." - - - name: Print manual execution message - debug: - msg: "Please manually execute: ollama run deepseek-r1:{{ deepseek_version }}" - - - name: Mark playbook as successful - meta: end_play - - - name: Copy Modelfile to destination - copy: - src: Modelfile - dest: "{{ modelfile_download_path }}/Modelfile" - owner: root - group: root - mode: '0644' - - - name: Modify Modelfile parameters - lineinfile: - path: "{{ modelfile_download_path }}/Modelfile" - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - backrefs: yes - loop: - - { regexp: '^FROM .*$', line: 'FROM {{ modelfile_download_path }}/{{ modelfile_file }}' } - - { regexp: '^PARAMETER temperature .*$', line: 'PARAMETER temperature {{ parameter.temperature }}' } - - { regexp: '^PARAMETER top_p .*$', line: 'PARAMETER top_p {{ parameter.top_p }}' } - - { regexp: '^PARAMETER top_k .*$', line: 'PARAMETER top_k {{ parameter.top_k }}' } - - { regexp: '^PARAMETER num_ctx .*$', line: 'PARAMETER num_ctx {{ parameter.num_ctx }}' } - - { regexp: '^PARAMETER num_thread .*$', line: 'PARAMETER num_thread {{ parameter.num_thread }}' } - - { regexp: '^PARAMETER num_gpu .*$', line: 'PARAMETER num_gpu {{ parameter.num_gpu }}' } - - - name: Verify Modelfile content - shell: cat "{{ modelfile_download_path }}/Modelfile" - register: modelfile_content - - - name: Display modified Modelfile content - debug: - msg: "{{ modelfile_content.stdout }}" - - # ================ start deepseek ===================== - - - name: Create Deepseek - command: ollama create -f {{ modelfile_download_path }}/Modelfile deepseek-r1:{{ deepseek_version }} - - - name: Print manual execution message after success - debug: - msg: "Please manually execute: ollama run deepseek-r1:{{ deepseek_version }}" diff --git a/plugins/deepseek-r1/workspace/2-modify_modelfile.yaml b/plugins/deepseek-r1/workspace/2-modify_modelfile.yaml new file mode 100644 index 0000000..1c8e8bc --- /dev/null +++ b/plugins/deepseek-r1/workspace/2-modify_modelfile.yaml @@ -0,0 +1,79 @@ +--- +- name: Install Ollama and run Deepseek + hosts: all + vars: + modelfile_file: "{{ modelfile_download | basename }}" + + tasks: + - name: Download modelfile + block: + - name: Ensure modelfile download path exists + file: + path: "{{ modelfile_download_path }}" + state: directory + mode: '0755' + + - name: Copy download.sh to remote + copy: + src: download.sh + dest: "{{ modelfile_download_path }}/download.sh" + owner: root + group: root + mode: '0644' + + - name: Execute download.sh + shell: > + bash {{ modelfile_download_path }}/download.sh + {{ modelfile_download }} + {{ modelfile_download_path }} + {{ 1 if download_checksum else 0 }} + {{ download_timeout }} + {{ download_retry }} + >> {{ modelfile_download_path }}/download.log + ignore_errors: no + async: 0 + register: download_result + failed_when: download_result.rc != 0 + + rescue: + - name: Print error message of downloading modelfile + debug: + msg: "Unable to download modelfile, parameter tuning will not take effect." + + - name: Print manual execution message + debug: + msg: "Please manually execute: ollama run deepseek-r1:{{ deepseek_version }}" + + - name: Mark playbook as successful + meta: end_play + + - name: Copy Modelfile to destination + copy: + src: Modelfile + dest: "{{ modelfile_download_path }}/Modelfile" + owner: root + group: root + mode: '0644' + + - name: Modify Modelfile parameters + lineinfile: + path: "{{ modelfile_download_path }}/Modelfile" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + backrefs: yes + loop: + - { regexp: '^FROM .*$', line: 'FROM {{ modelfile_download_path }}/{{ modelfile_file }}' } + - { regexp: '^PARAMETER temperature .*$', line: 'PARAMETER temperature {{ parameter.temperature }}' } + - { regexp: '^PARAMETER top_p .*$', line: 'PARAMETER top_p {{ parameter.top_p }}' } + - { regexp: '^PARAMETER top_k .*$', line: 'PARAMETER top_k {{ parameter.top_k }}' } + - { regexp: '^PARAMETER num_ctx .*$', line: 'PARAMETER num_ctx {{ parameter.num_ctx }}' } + - { regexp: '^PARAMETER num_thread .*$', line: 'PARAMETER num_thread {{ parameter.num_thread }}' } + - { regexp: '^PARAMETER num_gpu .*$', line: 'PARAMETER num_gpu {{ parameter.num_gpu }}' } + + - name: Verify Modelfile content + shell: cat "{{ modelfile_download_path }}/Modelfile" + register: modelfile_content + + - name: Display modified Modelfile content + debug: + msg: "{{ modelfile_content.stdout }}" diff --git a/plugins/deepseek-r1/workspace/3-start_deepseek.yaml b/plugins/deepseek-r1/workspace/3-start_deepseek.yaml new file mode 100644 index 0000000..014c381 --- /dev/null +++ b/plugins/deepseek-r1/workspace/3-start_deepseek.yaml @@ -0,0 +1,11 @@ +--- +- name: Install Ollama and run Deepseek + hosts: all + + tasks: + - name: Create Deepseek + command: ollama create -f {{ modelfile_download_path }}/Modelfile deepseek-r1:{{ deepseek_version }} + + - name: Print manual execution message after success + debug: + msg: "Please manually execute: ollama run deepseek-r1:{{ deepseek_version }}" -- Gitee