Deep Java Library(四)使用DJL Serving部署JAVA模型 For Windows

news2025/1/23 13:42:47

1.下载Windows版DJL Serving

Windows版DJL Serving下载地址:
https://publish.djl.ai/djl-serving/serving-0.23.0.zip
下载下来是一个zip压缩包,大约50M左右,目前最新版本为0.23.0

2.安装DJL Serving

解压serving-0.23.0.zip后目录如下
在这里插入图片描述
(1)bin目录是DJL Serving的主目录,里面serving.bat是启动脚本
(2)conf目录是DJL Serving的配置目录,里面我们主要看一下config.properties
这是初始化的config.properties配置

# debug=false
# inference_address=http://127.0.0.1:8080
# management_address=http://127.0.0.1:8080
# management_address=unix:/tmp/management.sock
model_store=models
load_models=ALL
# model_url_pattern=.*
# number_of_netty_threads=0
# job_queue_size=1000
# cors_allowed_origin=*
# cors_allowed_methods=*
# cors_allowed_headers=*
# keystore=conf/keystore.p12
# keystore_pass=changeit
# keystore_type=PKCS12
# private_key_file=conf/key.pem
# certificate_file=conf/certs.pem
# max_request_size=2000485760
# batch_size=1
# max_batch_delay=100

debug=false : 配置debug模式是否开启
inference_address:配置服务API接口访问地址
management_address:配置服务UI界面的访问地址
model_store:配置模型加载位置
load_models:配置模型具体加载路径,具体格式为如下:

[EndpointData]=modelUrl
其中[EndpointData]格式支持四种
1,[modelName]只配置一个模型名称
2,[modelName:version]配置模型名称,模型版本
3,[modelName:version:engine]配置模型名称,模型版本,模型引擎
4,[modelName:version:engine:deviceNames]配置模型名称,模型版本,模型引擎,模型驱动GPU或者CPU
例如:
load_models=[person:v1:MXNet:*]=file:///D:/LIHAOWORK/serving-0.23.0/person.zip
多个模型之间用逗号隔开

本次demo只应用的上述几个配置,剩余的配置说明可以具体查看官网:
https://docs.djl.ai/docs/serving/serving/docs/configuration.html
(3)lib目录是DJL Serving的类包目录
(4)plugins目录是DJL Serving是插件目录
由于DJL Serving默认启动加载插件的位置为bin目录下的plugins目录里面的插件文件,我们可以直接将plugins目录以及里面的插件直接复制到bin目录下
在这里插入图片描述plugins目录里面
在这里插入图片描述

3.启动DJL Serving

Windows下打开cmd
在这里插入图片描述
切换到DJL Serving的bin目录下
在这里插入图片描述
使用serving 启动DJL Serving
在这里插入图片描述
启动日志里面会显示所有的插件已经加载,并且API和UI的地址都是
http://127.0.0.1:8080

4.访问DJL Serving

打开浏览器访问http://127.0.0.1:8080
在这里插入图片描述

5.添加模型引擎依赖jar包

点击系统—>依赖
在这里插入图片描述
点击添加依赖
在这里插入图片描述
选择类型为JAR,方式是file或者maven
在这里插入图片描述
由于本次测试的模型为OnnxRuntime引擎,需要两个依赖包
onnxruntime-1.15.0.jar
onnxruntime-engine-0.23.0.jar
maven的具体依赖为

<dependency>
    <groupId>ai.djl.onnxruntime</groupId>
    <artifactId>onnxruntime-engine</artifactId>
    <version>0.23.0</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.microsoft.onnxruntime</groupId>
    <artifactId>onnxruntime</artifactId>
    <version>1.15.1</version>
</dependency>

由于公司的网络非常的烂,并且好像这个UI插件的上传对于较大点的jar包有问题,可以直接将需要的jar包拷贝到bin目录下的deps目录,如果没有deps目录就新建一个。
在这里插入图片描述
刷新查看
在这里插入图片描述

6.添加模型包zip文件

在这里插入图片描述
synset文件是模型的ArtifactName文件具体内容如下

person

person.onnx是训练好的模型文件
libs目录里面是包含classes目录最里面是自定义的translator和translatorFactory
在这里插入图片描述

PersonTranslatorFactory类代码如下

import ai.djl.modality.Input;
import ai.djl.modality.Output;
import ai.djl.translate.TranslatorFactory;
import ai.djl.Model;
import ai.djl.translate.Translator;
import ai.djl.util.Pair;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class PersonTranslatorFactory implements TranslatorFactory, Serializable {
    private static final long serialVersionUID = 1L;

    private static final Set<Pair<Type, Type>> SUPPORTED_TYPES = new HashSet<>();

    static {
        SUPPORTED_TYPES.add(new Pair<>(Input.class, Output.class));
    }


    /** {@inheritDoc} */
    @Override
    public Set<Pair<Type, Type>> getSupportedTypes() {
        return SUPPORTED_TYPES;
    }

    /** {@inheritDoc} */
    @Override
    @SuppressWarnings("unchecked")
    public <I, O> Translator<I, O> newInstance(
            Class<I> input, Class<O> output, Model model, Map<String, ?> arguments) {
        if (isSupported(input, output)) {
            System.out.println("1");
            return (Translator<I, O>) new PersonTranslator();
        }
        throw new IllegalArgumentException("Unsupported input/output types.");
    }
}

PersonTranslator类代码如下

import ai.djl.modality.Input;
import ai.djl.modality.Output;
import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.ImageFactory;
import ai.djl.modality.cv.output.BoundingBox;
import ai.djl.modality.cv.output.DetectedObjects;
import ai.djl.modality.cv.output.Rectangle;
import ai.djl.modality.cv.transform.CenterCrop;
import ai.djl.modality.cv.transform.Resize;
import ai.djl.modality.cv.transform.ToTensor;
import ai.djl.modality.cv.translator.YoloV5Translator;
import ai.djl.ndarray.NDArray;
import ai.djl.ndarray.NDList;
import ai.djl.translate.*;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class PersonTranslator implements ServingTranslator {

        private final Integer width = 640;
        private final Integer height = 640;
        private  final float threshold = 0.2f;
        //初始化转换器
        private Translator<Image, DetectedObjects> translator = YoloV5Translator
                .builder()
                .optThreshold(threshold)
                .optSynsetArtifactName("synset.txt")
                .build();

        @Override
        public NDList processInput(TranslatorContext ctx, Input input) throws Exception {
            byte[] data = input.getAsBytes(0);
            ImageFactory factory = ImageFactory.getInstance();
            Image image = factory.fromInputStream(new ByteArrayInputStream(data));

            NDArray array = image.toNDArray(ctx.getNDManager());
            Pipeline pipeline = new Pipeline();
            pipeline.add(new CenterCrop());
            pipeline.add(new Resize(width, height));
            pipeline.add(new ToTensor());
            return pipeline.transform(new NDList(array));
        }

        @Override
        public Output processOutput(TranslatorContext ctx, NDList list) throws Exception {
            DetectedObjects output = translator.processOutput(ctx, list);
            List<String> classList = new ArrayList<>();
            List<Double> probList = new ArrayList<>();
            List<BoundingBox> rectList = new ArrayList<>();
            final List<DetectedObjects.DetectedObject> items = output.items();
            items.forEach(item -> {
                classList.add(item.getClassName());
                probList.add(item.getProbability());

                Rectangle b = item.getBoundingBox().getBounds();
                Rectangle newBox = new Rectangle(b.getX() / width, b.getY() / height, b.getWidth() / width, b.getHeight() / height);
                rectList.add(newBox);
            });
            Output out = new Output(200, "OK");
            out.add(new DetectedObjects(classList, probList, rectList).toJson());
            return out;
        }



        @Override
        public void prepare(TranslatorContext ctx) throws Exception {
            translator.prepare(ctx);
        }

        @Override
        public Batchifier getBatchifier() {
            return translator.getBatchifier();
        }

        @Override
        public void setArguments(Map<String, ?> arguments) {}
}

在PersonTranslator中主要是实现ServingTranslator接口,里面我们重写了
processInput和processOutput,其中processInput我们将image处理为NDList,processOutput中我们将结果转为DetectedObjects。
后面我们会专门总结写一下自定义模型上传的形式和种类以及注意事项。
最后将person文件打包成zip包

7.指定自定义模型启动

具体命令如下:
serving -m “person::OnnxRuntime=file:///D:/LIHAOWORK/serving-0.23.0/person.zip”
在这里插入图片描述
在这里插入图片描述
其中标红的地方显示使用我们自定义的工厂。

8.模型测试

点击model
在这里插入图片描述
我们自定义的模型已经READY就绪,点击READY下面三角图标测试,
Data type选择raw,点击上传图片,点击推理
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

测试图片如下:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络技术七:命令行基础

命令行操作基础 命令类型 常见设备管理命令 H3C路由交换产品连接方法 使用console线本地连接 协议Serial&#xff0c;接口com口&#xff0c;波特率9600 适用于设备的初次调试 使用Telnet远程访问 适用于设备上架配置好后的维护管理 使用SSH远程访问 数据传输过程加密&…

设计模式系列-外观模式

一、上篇回顾 上篇我们主要讲述了创建型模式中的最后一个模式-原型模式&#xff0c;我们主要讲述了原型模式的几类实现方案&#xff0c;和原型模式的应用的场景和特点&#xff0c;原型模式 适合在哪些场景下使用呢&#xff1f;我们先来回顾一下我们上篇讲述的3个常用的场景。 1…

聚观早报|全球AI领域投资总额暴降;哈啰租车开启假期早鸟预定

【聚观365】9月7日消息 全球AI领域投资总额暴降 哈啰租车开启假期早鸟预定 微信上线“腾讯混元助手”小程序 腾讯“QQ群恢复”功能下线 一嗨租车1.1万个直营网点接入滴滴APP 全球AI领域投资总额暴降 媒体报道称&#xff0c;科技巨头Meta&#xff08;原Facebook&#xff…

TCP/IP基础

前言&#xff1a; TCP/IP协议是计算机网络领域中最基本的协议之一&#xff0c;它被广泛应用于互联网和局域网中&#xff0c;实现了不同类型、不同厂家、运行不同操作系统的计算机之间的相互通信。本文将介绍TCP/IP协议栈的层次结构、各层功能以及数据封装过程&#xff0c;帮助您…

js-14---什么是事件代理?应用场景是什么?

1、事件代理是什么&#xff1f; 事件代理&#xff0c;通俗来讲就是把一个元素响应事件&#xff08;click&#xff0c;keydown…&#xff09;的函数委托到另一个元素。 事件流都会经过三个阶段&#xff1a;捕获阶段–>目标阶段----->冒泡阶段 事件委托就是在冒泡阶段完成&…

Fiddler安装与使用教程(2) —— 软测大玩家

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

AI新时代,新华三存储新思考

在数字经济蓬勃发展下&#xff0c;数据正在重塑社会运行模式&#xff0c;推动百行百业的创新发展&#xff0c;成为经济发展的关键驱动力。如今数据成为企业的重要资产&#xff0c;企业希望通过数据了解市场和客户的需求来快速决策&#xff0c;这不仅需要数据高效流转&#xff0…

Python爬取电影信息:Ajax介绍、爬取案例实战 + MongoDB存储

Ajax介绍 Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一种用于在Web应用程序中实现异步通信的技术。它允许在不刷新整个网页的情况下&#xff0c;通过在后台与服务器进行数据交换&#xff0c;实时更新网页的一部分。Ajax的主要特点包括&#xff1a; 异步通…

【解决】mysqladmin flush-hosts

问题 mysql出现 mysqladmin flush-hosts&#xff0c;是因为其他客户机连接错误次数过多时&#xff0c;mysql会禁止客户机连接。 解决方法 1、进入服务器数据库&#xff0c;打开数据库命令行界面输入 flush hosts; 此时便可连接 2、可以.修改mysql配置文件&#xff0c;在[…

SpringBoot项目--电脑商城【上传头像】

一、易错点 1.错误写法&#xff1a; 把文件存到数据库中,需要图片时访问数据库,数据库将文件解析为字节流返回,最后写到本地的某一个文件.这种方法太耗费资源和时间了 2.正确写法&#xff1a; 将对应的文件保存在操作系统上,然后再把这个文件路径记录下来,因为在记录路径的…

重生奇迹通关恶魔广场攻略篇

初次进入重生奇迹MU的血色城堡&#xff0c;你可能会对里面不断刷新出来的怪物产生一种密集恐惧症&#xff0c;但是请相信一点&#xff0c;那就是恶魔广场里面的怪物更多&#xff0c;而且品种还不重复&#xff0c;由低至高&#xff0c;轮番刷新&#xff0c;一波又一波……在我看…

Linux部署kettle并设置定时任务

一.安装Kettle linux中使用kettle时首先需要jdk环境&#xff0c;这里就不概述linux中jdk的安装与配置了。 1.首先将kettle压缩包放入linux并解压 unzip data-integration.zip kettle安装路径为:/root/Kettle9.3/data-integration 设置权限 chmod -R 755 /root/Kettle9.3/d…

Allegro画原理图时不能用的非法字符,你知道吗?

Cadence Allegro是一款电子设计自动化工具&#xff0c;常用于原理图绘制和电路设计&#xff0c;在使用Allegro画原理图时&#xff0c;电子工程师可能为了确保文件的准确性和稳定性&#xff0c;能够顺利进行后续的PCB设计和制造&#xff0c;需要注意这些非法字符&#xff0c;那么…

提高 Web 开发效率的10个VS Code扩展插件,你知道吗?

前言 一个出色的开发工具可以显著提高开发人员的开发效率&#xff0c;而优秀的扩展插件则能更进一步地提升工具的效率。在前端开发领域&#xff0c;VSCode毫无疑问是目前最受欢迎的开发工具。为了帮助前端开发人员提高工作效率&#xff0c;今天小编将向大家推荐10个强大的VSCo…

TSINGSEE青犀视频AI智能算法平台电动车入梯检测解决方案

一、方案背景 随着大众的出行要求逐渐提升&#xff0c;交通拥堵现象也随处可见&#xff0c;电动车出行&#xff0c;就成了大家的首选。随着电动车数量的激增&#xff0c;众多用户为了个人方便&#xff0c;大多在室内停放或充电&#xff0c;有的甚至停放在走道、楼梯间等公共区…

无涯教程-JavaScript - BITOR函数

描述 BITOR函数返回两个数字的按位"或"。 语法 BITOR (number1, number2)争论 Argument描述Required/OptionalNumber1Must be in decimal form and greater than or equal to 0.RequiredNumber2Must be in decimal form and greater than or equal to 0.Required…

基于Java+SpringBoot+Vue前后端分离青年公寓服务平台设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

vue基础知识七:SPA首屏加载速度慢的怎么解决?

一、什么是首屏加载 首屏时间&#xff08;First Contentful Paint&#xff09;&#xff0c;指的是浏览器从响应用户输入网址地址&#xff0c;到首屏内容渲染完成的时间&#xff0c;此时整个网页不一定要全部渲染完成&#xff0c;但需要展示当前视窗需要的内容 首屏加载可以说…

指针跃动(济南)客户运营服务中心上线了!

指针跃动&#xff08;济南&#xff09;客户运营服务中心上线了&#xff01; ——打通客户运营服务全链路—— 随着全国代驾业务需求的不断增长&#xff0c;“指针跃动”宣布&#xff1a;指针跃动&#xff08;济南&#xff09;客户运营服务中心上线了&#xff01; 以新的思维方式…

CMT:卷积与Transformers的高效结合

论文提出了一种基于卷积和VIT的混合网络&#xff0c;利用Transformers捕获远程依赖关系&#xff0c;利用cnn提取局部信息。构建了一系列模型cmt&#xff0c;它在准确性和效率方面有更好的权衡。 CMT:体系结构 CMT块由一个局部感知单元(LPU)、一个轻量级多头自注意模块(LMHSA)和…