docker torcherve打包mar包并部署模型

使用Docker打包深度网络模型mar包到服务端

参考链接:Docker torchserve 部署模型流程——以WSL部署YOLO-FaceV2为例_class myhandler(basehandler): def initialize(self,-CSDN博客

1、docker拉取环境镜像命令

docker images

在这里插入图片描述

在这里插入图片描述

出现此提示为没有权限取执行命令,此时修改命令为

sudo docker images

出现类似如下界面即为成功
在这里插入图片描述

**注意:**如果没有所需镜像,那么则需要去网上的镜像网站取拉镜像。命令为

docker pull registry.cn-shanghai.aliyuncs.com/jhinno/torch-serve:v6.1
docker pull 镜像

2、启动docker并进行打包

2、1启动docker服务

systemctl start docker
docker run --rm -it -p 8080:8080 -p 8081:8081 -v /home/lxz-2/lyw/class_eval/model_store:/home/model-server/model-store registry.cn-shanghai.aliyuncs.com/jhinno/torch-serve:v6.1

–rm 表示使用完立刻清空内存。

–it 表示交互式容器,会有一个伪终端,可以理解为docker容器的终端,我个人认为docker容器就是一个虚拟机,能更加方便人们去运行代码。

-p端口映射, -p 8080:8080 表示将本地8080端口映射到虚拟机8080端口

-v路径映射: -v /home/lxz-2/lyw/class_eval/model_store:/home/model-server/model-store将 /home/lxz-2/lyw/class_eval/model_store映射/home/model-server/model-store

registry.cn-shanghai.aliyuncs.com/jhinno/torch-serve:v6.1 :所使用的环境

在这里插入图片描述

输入完上述命令后进入docker容器的伪终端,此时所使用的环境为 registry.cn-shanghai.aliyuncs.com/jhinno/torch-serve:v6.1

在这里插入图片描述

2、2 编写handler文件

handler文件,是加载模型 预处理 推理 后处理的过程的函数,可以理解为跑通模型从前到后的步骤,比如加载模型,加载好后需要对数据进行预处理,进行预处理然后进行推理,将得到的加过进行后处理,应用到实际中,最后返回。

load_model、initialize第一个是下载模型用的,第二个是初始化,例如是不是用GPU啊等参数设置的,preprocess,此时这个函数的传参data就是用户在调用接口传递数据,preprocess返回的data会进入到inference的data,同时inference返回的data会进入到postprocess,最后通过接口返回给用户

在这里插入图片描述

import datetime
import os
import pickle
import sys
import zipfile
import numpy as np
import logginglogger = logging.getLogger(__name__)
import base64
import torch
import io
from PIL import Image
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from ts.torch_handler.base_handler import BaseHandler
import astclass FaceDetectHandler(BaseHandler):def __init__(self):super().__init__()# Define your scalers for normalization and standardizationself.scaler = StandardScaler()  # For standardizationself.minmax_scaler = MinMaxScaler()  # For min-max scalingself.args = 14self.order = ['ATTENDANCE_RATE','HEAD_UP_RATE', 'FRONT_RATE','FRONT_SEAT_RATE','TVOTELOG','TPREAMPANSWERLOG','TDISCUSSLOG', 'TSURVEYLOG', 'TCHOOSESOMEONELOG', 'TWORKLOG','VOTELOG','PREAMPANSWERLOG','WORKLOG','CHOOSESOMEONELOG',]self.count = ['VOTELOG', 'WORKLOG', 'PREAMPANSWERLOG', 'CHOOSESOMEONELOG', 'JOBFINISH']def load_model(self, model_path):from model import MyModelprint('loading model...')model = MyModel(1,4,1)# if not os.path.exists(model_path):#     print("Checkpoint not found: " + model_path)#     return# print("Resuming from " + model_path)states = torch.load(model_path, map_location=self.device)model.load_state_dict(states, strict=False)model = model.to(device=self.device)# print("Resumed from " + model_path)self.model = model.eval()def initialize(self, context):properties = context.system_propertieslogger.info(f"Cuda available: {torch.cuda.is_available()}")logger.info(f"GPU available: {torch.cuda.device_count()}")use_cuda = torch.cuda.is_available() and torch.cuda.device_count() > 0self.map_location = 'cuda' if use_cuda else 'cpu'self.device = torch.device(self.map_location + ':' +str(properties.get('gpu_id')) if use_cuda else 'cpu')self.manifest = context.manifestmodel_dir = properties.get('model_dir')logger.info("==================model_dir==========================="" %s loaded successfully", model_dir)self.model_pt_path = Noneself.model_path = None# 读取pth和模型if "serializedFile" in self.manifest["model"]:serialized_file = self.manifest["model"]["serializedFile"]self.model_pt_path = os.path.join(model_dir, serialized_file)model_file = self.manifest['model']['modelFile']# if "modelFile" in self.manifest["model"]:#     model_file = self.manifest['model']['modelFile']#     self.model_path = os.path.join(model_dir, model_file)# logger.info("Model file %s loaded successfully", self.model_pt_path)# with zipfile.ZipFile(model_dir + '/models.zip', 'r') as zip_ref:#     zip_ref.extractall(model_dir)self.load_model(self.model_pt_path)logger.info("Model file %s loaded successfully", self.model_pt_path)def preprocess(self, data):logger.info("preprocess ing~~~~~")logger.info(data)data_dict = data[0]['body']keys = data_dict.keys()if 'ATTENDANCE_RATE' not in keys or 'HEAD_UP_RATE' not in  keys or 'FRONT_RATE' not in keys or 'FRONT_SEAT_RATE' not in keys:return "参数不足"values_array = [data_dict[feature] for feature in self.order]MASK = [1 if value!=0 else 0 for value in values_array]MASK = np.array(MASK, dtype=np.float32).reshape(1, self.args)# 使用 StandardScaler 标准化特征数据# 将 MASK 转换为 PyTorch 张量MASK_tensor = torch.tensor(MASK, dtype=torch.float32).to(self.device)values_array = np.array(values_array, dtype=np.float32).reshape(1,self.args, 1)values_tensor = torch.tensor(values_array, dtype=torch.float32).to(self.device)logger.info(values_tensor)data = {"values_tensor":values_tensor,"MASK_tensor":MASK_tensor}return datadef inference(self, data):logger.info("inference ing~~~~~")logging.info(data)if data=="参数不足":return "参数不足"model = self.modellogger.info("model  loaded")prediction = model(data['values_tensor'],data['MASK_tensor'])logging.info(prediction)return predictiondef postprocess(self, data):logger.info("postprocess ing~~~~~")logging.info(data)if data == "参数不足":return [{"output": "参数不足"}]result = data.item()# results = data_reshape.tolist()return [{"output": result}]

可以本地编写个测试文件,看看是否能跑通


# 添加到 handler 文件的末尾if __name__ == "__main__":import logginglogging.basicConfig(level=logging.INFO)# 模拟 TorchServe 的上下文class MockContext:def __init__(self):self.system_properties = {"model_dir": "./model",  # 假设模型文件存放在 ./model 目录"gpu_id": 0              # 测试时使用 CPU}self.manifest = {"model": {"serializedFile": "model.pth",  # 假设模型权重文件名"modelFile": "model.py"        # 模型定义文件}}# 初始化 Handlerhandler = FaceDetectHandler()context = MockContext()# 确保模型目录存在os.makedirs(context.system_properties["model_dir"], exist_ok=True)# 创建一个虚拟模型文件(如果实际不存在)dummy_model_path = os.path.join(context.system_properties["model_dir"], context.manifest["model"]["serializedFile"])if not os.path.exists(dummy_model_path):torch.save(handler.model.state_dict(), dummy_model_path)# 初始化 Handlerhandler.initialize(context)# 构造测试数据(包含所有必要字段)test_data = [{"body": {"ATTENDANCE_RATE": 0.85,"HEAD_UP_RATE": 0.6,"FRONT_RATE": 0.75,"FRONT_SEAT_RATE": 0.5,"TVOTELOG": 1,"TPREAMPANSWERLOG": 2,"TDISCUSSLOG": 0,"TSURVEYLOG": 1,"TCHOOSESOMEONELOG": 0,"TWORKLOG": 3,"VOTELOG": 1,"PREAMPANSWERLOG": 2,"WORKLOG": 3,"CHOOSESOMEONELOG": 0,"LISTEN_CLASS": 0.9,"WRITE_NOTE": 0.3,"PLAY_PHONE": 0.1,"LIT_TABLE": 0.2}}]# 完整处理流程try:preprocessed = handler.preprocess(test_data)print("预处理结果:", preprocessed)if preprocessed != "参数不足":inference_result = handler.inference(preprocessed)print("推理结果:", inference_result)postprocessed = handler.postprocess(inference_result)print("最终输出:", postprocessed)else:print("错误:输入参数不完整")except Exception as e:print(f"处理出错: {str(e)}")

2.3打包

torch-model-archiver --model-name ml_regression_AICourseScoring_V2.2 --version 2.2 --model-file model.py --serialized-file test_model_loss0.2894_r20.9787_20250327_184525.pth --handler Myhandler.py

需要将参数文件、模型文件’handler文件同时放到一个文件夹下。

–model-name ml_regression_AICourseScoring_V2.2 模型的名字

–version 2.2 版本

–model-file model.py 模型文件

serialized-file test_model_loss0.2894_r20.9787_20250327_184525.pth 参数文件

–handler Myhandler.py handler文件

映射后的文件夹下的文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

执行完上述后命令会在当前文件下生成mar包,

在这里插入图片描述

我本地使用的是学校中台,只需上传mar包即可,本地测试参考

参考链接:Docker torchserve 部署模型流程——以WSL部署YOLO-FaceV2为例_class myhandler(basehandler): def initialize(self,-CSDN博客

第四点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/42583.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA实现动态IP黑名单过滤

一些恶意用户(可能是黑客、爬虫、DDoS 攻击者)可能频繁请求服务器资源,导致资源占用过高。因此需要一定的手段实时阻止可疑或恶意的用户,减少攻击风险。 通过 IP 封禁,可以有效拉黑攻击者,防止资源被滥用,保障合法用户…

RocketMQ可视化工具使用 - Dashboard(保姆级教程)

1、github拉取代码,地址: https://github.com/apache/rocketmq-dashboard 2、指定Program arguments,本地启动工程 勾上这个Program arguments,会出现多一个对应的框 写入参数 --server.port1280 --rocketmq.config.namesrvAddr…

湖南(源点咨询)市场调研 商业综合体定位调研分享(上篇)

​ 该项目位于某新一线城市的城市副中心区域,系一个正在发展中的中央居住区,项目本身是一个涵盖社区综合服务中心、商业、文体活动中心、卫生服务、社区养老等多功能复合的公共配套项目,本次调研主要针对其商业(及其他可商用的&a…

硬件测试工装设计不合理的补救措施

硬件测试工装设计不合理的补救措施主要包括重新评估设计需求、优化工装结构、强化工装校准与验证。其中,优化工装结构尤其重要,通过结构优化能够有效解决因设计不合理导致的测试准确性下降和可靠性不足的问题。根据工程实践数据,经过优化结构…

PyQt6实例_批量下载pdf工具_使用pyinstaller与installForge打包成exe文件

目录 前置: 步骤: step one 准备好已开发完毕的项目代码 step two 安装pyinstaller step three 执行pyinstaller pdfdownload.py,获取初始.spec文件 step four 修改.spec文件,将data文件夹加入到打包程序中 step five 增加…

open-cv的安装

python -m pip install numpy matplotlib opencv-python 【记得科学上网,不然太慢了】

AI写一个视频转图片帧工具(python)

现在的AI写python太方便了 说的话 我想用python实现一个能够将视频的所有帧数转化为图片的软件,可以自由配置转换的帧率或者全部,需要有界面,我需要增加一点功能,就是我需要读取出视频的分辨率,然后设置输出帧的分辨…

Axure RP9.0教程: 多级联动【设置选项改变时->情形->面板状态】(给动态面板元件设置相关交互事件的情形,来控制其他面板不同的状态。)

文章目录 引言I 多级联动(省、市、区)实现思路添加三省、市、区下拉列表给省下拉框添加数据源将市、区下拉框添加不同状态,分别以省、市命名给省下拉控件设置选项改变时的交互事件省下拉控件的交互事件情形市下拉交互事件的配置II 知识扩展: 展示省 → 地级市 → 区县的多级…

浙江大学|DeepSeek系列专题公开课|第一季|PDF+视频(全)

大家好,我是吾鳴。 之前吾鳴给大家分享过由浙大出品的DeepSeek系列专题公开课的教程,不过都比较零散,而且都只有PDF,有粉丝朋友直呼看得不过瘾。今天吾鳴把视频也给大家找来了,而且把第一季的DeepSeek系列公开课也稍做…

数据可视化(matplotlib)-------图表样式美化

目录 一、图表样式概述 (一)、默认图表样式 (二)、图表样式修改 1、局部修改 2、全局修改 二、使用颜色 (一)、使用基础颜色 1、单词缩写或单词表示的颜色 2、十六进制/HTML模式表示的颜色 3、RGB…

SpringBoot3解决跨域请求问题(同源策略、JSONP、CORS策略)(Access-Control-Allow-Origin)(2025详细教程)

目录 浏览器跨域请求问题。 浏览器同源策略。 第三方API调用。 前后端分离项目。 一、JSONP。&#xff08;dataType:jsonp&#xff09; &#xff08;1&#xff09;代码示例。 <1>前端ajax04.jsp页面。(发起Ajax请求) <2>后端springboot接口。(/hello)(返回JSONPObj…

rent8_wechat-新增提醒收租功能

本次更新中&#xff0c;rent8_wechat 小程序全新推出了“提醒收租”功能&#xff0c;为房东提供更加便捷的收租体验。房东只需在小程序内点击“提醒收租”按钮&#xff0c;系统便会在需要收租当天的上午9点准时推送通知&#xff0c;贴心提醒房东及时收取租金。 以下是该功能的…

诠视科技MR眼镜如何安装apk应用

诠视科技MR眼镜如何安装apk应用 1、使用adb工具安装1.1 adb工具下载1.2 解压adb文件1.3 使用adb安装apk 2、拷贝到文件夹安装 1、使用adb工具安装 1.1 adb工具下载 点击下面的链接开始下载adb工具&#xff0c;下载结束以后解压文件。 下载链接: https://download.xvisiotech…

JAVA学习*异常

什么是异常 在 Java 里&#xff0c;异常是指程序运行期间出现的不正常状况&#xff0c;它会中断程序的正常执行流程。 异常的分类 Java 中的异常是对象&#xff0c;这些对象都继承自 Throwable类。Throwable类有两个主要的子类&#xff1a;Error 和 Exception。 Error类表示…

DataGear 5.3.0 制作支持导出表格数据的数据可视化看板

DataGear 内置表格图表底层采用的是DataTable表格组件&#xff0c;默认并未引入导出数据的JS支持库&#xff0c;如果有导出表格数据需求&#xff0c;则可以在看板中引入导出相关JS支持库&#xff0c;制作具有导出CSV、Excel、PDF功能的表格数据看板。 在新发布的5.3.0版本中&a…

【电气设计】接地/浮地设计

在工作的过程中&#xff0c;遇到了需要测量接地阻抗的情况&#xff0c;组内讨论提到了保护接地和功能接地的相关需求。此文章用来记录这个过程的学习和感悟。 人体触电的原理&#xff1a; 可以看到我们形成了电流回路&#xff0c;导致触电。因此我们需要针对设备做一些保护设计…

【计算机操作系统】线程的概念和特点

1、什么是线程&#xff0c;为什么要引入线程&#xff1f; 还没引入进程之前&#xff0c;系统中各个程序只能串行执行。 比如&#xff1a;当我们在使用QQ与好友视频时&#xff0c;我们可以给其他好友发信息&#xff0c;发送文件...&#xff0c;我们知道进程是程序的一次执行&am…

【C++数据库】SQLite3数据库连接与操作

注意:本文代码均为C++20标准下实现 一、SQLite3库安装 1.1 安装库文件 【工具】跨平台C++包管理利器vcpkg完全指南 vcpkg install sqlite3# 集成至系统目录,之前执行过此命令的无需再次执行 vcpkg integrate install1.2 验证代码 在VS2022中新建控制台项目,测试代码如下…

CLion下载安装(Windows11)

目录 CLion工具下载安装其他 CLion CLion-2024.1.4.exe 工具 系统&#xff1a;Windows 11 下载 1.通过百度网盘分享的文件&#xff1a;CLion-2024.1.4.exe 链接&#xff1a;https://pan.baidu.com/s/1-zH0rZPCZtQ60IqdHA7Cew?pwdux5a 提取码&#xff1a;ux5a 安装 打开…

‘无法定位程序输入点kernel32.dll’详细的修复方法,一键快速修复kernel32.dll

在 Windows 系统运行过程中&#xff0c;若程序提示“无法定位程序输入点 kernel32.dll”&#xff0c;往往意味着程序调用了 kernel32.dll 中不存在或已变更的函数接口。作为系统的核心动态链接库&#xff0c;kernel32.dll 承担着内存管理、进程控制、文件操作等底层功能&#x…