Deep Java Library(六)DJLServing自定义模型,自定义Translator注意事项

2023-11-01

DJLServing自定义模型中自定义Translator注意事项需要仔细读一下DJLServing源码中的ServingTranslatorFactory类,,一开始不了解以为DJLServing选择Translator像玄学,后来看了像迷宫一样ServingTranslatorFactory类大致明白了,以下是源码注释版,还有一个整理的流程图。
在这里插入图片描述

/*
 * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
 * with the License. A copy of the License is located at
 *
 * http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file 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 ai.djl.Application;
import ai.djl.Model;
import ai.djl.modality.Input;
import ai.djl.modality.Output;
import ai.djl.modality.cv.translator.ImageClassificationTranslator;
import ai.djl.modality.cv.translator.ImageServingTranslator;
import ai.djl.translate.*;
import ai.djl.util.ClassLoaderUtils;
import ai.djl.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

class ServingTranslatorFactory implements TranslatorFactory {

    //日志打印
    private static final Logger logger = LoggerFactory.getLogger(ServingTranslatorFactory.class);

    //返回只有一个固定元素的SET,约束模型的输入,输出类型
    @Override
    public Set<Pair<Type, Type>> getSupportedTypes() {
        return Collections.singleton(new Pair<>(Input.class, Output.class));
    }

    //工厂实例化方法
    @Override
    @SuppressWarnings("unchecked")
    public <I, O> Translator<I, O> newInstance(
            Class<I> input, Class<O> output, Model model, Map<String, ?> arguments)
            throws TranslateException {

        //如果输出和输出不在支持的范围内直接抛出异常
        if (!isSupported(input, output)) {
            throw new IllegalArgumentException("Unsupported input/output types.");
        }

        //获取model的路径
        Path modelDir = model.getModelPath();
        //获取serving.properties里面的translatorFactory参数
        String factoryClass = ArgumentsUtil.stringValue(arguments, "translatorFactory");
        //如果translatorFactory参数不为null且长度不为0
        if (factoryClass != null && !factoryClass.isEmpty()) {
            //直接加载工厂类
            TranslatorFactory factory = loadTranslatorFactory(factoryClass);
            //如果工厂类加载成功并且工厂类支持要去的输入输出
            if (factory != null && factory.isSupported(input, output)) {
                //打印日志
                logger.info("Using TranslatorFactory: {}", factory.getClass().getName());
                //将工厂类实例化返回
                return factory.newInstance(input, output, model, arguments);
            }
        }

        //如果上面没有匹配上
        //获取serving.properties里面的translator参数
        String className = (String) arguments.get("translator");

        //获取model目录下的libs目录
        Path libPath = modelDir.resolve("libs");
        //如果这个libs目录不存在
        if (!Files.isDirectory(libPath)) {
            //那就找lib目录
            libPath = modelDir.resolve("lib");
            //如果lib目录也没有那就走loadDefaultTranslator(arguments)这个方法,加载默认的Translator
            if (!Files.isDirectory(libPath) && className == null) {
                return (Translator<I, O>) loadDefaultTranslator(arguments);
            }
        }
        //如果model目录下的libs目录存在那就加载class
        ServingTranslator translator = findTranslator(libPath, className);
        //如果加载上了
        if (translator != null) {
            //设置translator的参数
            translator.setArguments(arguments);
            //打印日志
            logger.info("Using translator: {}", translator.getClass().getName());
            //直接返回translator
            return (Translator<I, O>) translator;
        } else if (className != null) {
            //如果加载失败抛出异常
            throw new TranslateException("Failed to load translator: " + className);
        }
        //实在是找不到就走loadDefaultTranslator(arguments)这个方法,加载默认的Translator
        return (Translator<I, O>) loadDefaultTranslator(arguments);
    }

    private ServingTranslator findTranslator(Path path, String className) {
        //找目录里面的classes目录
        Path classesDir = path.resolve("classes");
        //把java编译成classes
        ClassLoaderUtils.compileJavaClass(classesDir);
        //返回出去Translator,该类必须是ServingTranslator的实现类,因为会强制转换成ServingTranslator在子类
        return ClassLoaderUtils.findImplementation(path, ServingTranslator.class, className);
    }

    private TranslatorFactory loadTranslatorFactory(String className) {
        try {
            //通过类名加载该类
            Class<?> clazz = Class.forName(className);
            //将该类强制转换成TranslatorFactory的子类
            Class<? extends TranslatorFactory> subclass = clazz.asSubclass(TranslatorFactory.class);
            //加载该类的构造方法
            Constructor<? extends TranslatorFactory> constructor = subclass.getConstructor();
            //构造该类返回实例
            return constructor.newInstance();
        } catch (Throwable e) {
            //捕获异常
            logger.trace("Not able to load TranslatorFactory: " + className, e);
        }
        return null;
    }

    private Translator<Input, Output> loadDefaultTranslator(Map<String, ?> arguments) {
        //获取serving.properties里面的application参数
        String appName = ArgumentsUtil.stringValue(arguments, "application");
        //如果不为空
        if (appName != null) {
            Application application = Application.of(appName);
            //如果是cv/image_classification
            if (application == Application.CV.IMAGE_CLASSIFICATION) {
                //那就加载ImageClassificationTranslator这个玩意
                return getImageClassificationTranslator(arguments);
            }
        }
        //否则的化就加载NoopServingTranslatorFactory这个玩意
        NoopServingTranslatorFactory factory = new NoopServingTranslatorFactory();
        //最后返回的是NoopServingTranslator这个玩意
        return factory.newInstance(Input.class, Output.class, null, arguments);
    }

    private Translator<Input, Output> getImageClassificationTranslator(Map<String, ?> arguments) {
        //返回ImageServingTranslator的实例
        return new ImageServingTranslator(ImageClassificationTranslator.builder(arguments).build());
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Deep Java Library(六)DJLServing自定义模型,自定义Translator注意事项 的相关文章

  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • JAXb、Hibernate 和 beans

    目前我正在开发一个使用 Spring Web 服务 hibernate 和 JAXb 的项目 1 我已经使用IDE hibernate代码生成 生成了hibernate bean 2 另外 我已经使用maven编译器生成了jaxb bean
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 禁止的软件包名称:java

    我尝试从数据库名称为 jaane 用户名 Hello 和密码 hello 获取数据 错误 java lang SecurityException Prohibited package name java at java lang Class
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j
  • 使用 xpath 和 vtd-xml 以字符串形式获取元素的子节点和文本

    这是我的 XML 的一部分

随机推荐

  • Tomcat配置出错:Using CATALINA_OPTS: ““&&Tomcat启动闪退问题解决

    文章目录 前言 一 问题描述 二 定位问题 1 CMD命令启动 2 解决方法 前言 本篇问题所处环境 Tomcat 9 Java11 Win 10 一 问题描述 在安装配置Tomcat过程中 通过startup bat脚本命令启动Tomca
  • javascript 清除字符串空格

    去除字符串前后的空格 function trim str return str replace s s g 去除字符串中所有空格 function removeAllSpace str return str replace s g 用法举例
  • 服务器散列值与文件,服务器计算的散列值和客户端安全

    服务器计算的散列值和客户端安全 内容精选 换一换 执行adc命令 系统内部通过ADC与运行环境上的ADA的交互 实现文件传输 设置日志级别 心跳检测等功能 在ADC与ADA交互时 涉及使用密钥证书实现ADA 作为服务端 和ADC 作为客户端
  • Mysql 显示替换 if or

    摘要 使用Mysql的进行sql查询过程中 经常会遇到对查询结果做一些显示的替换 方式一 select if value in 0 1 2 NO YES from table name 方式二 select if value 0 or va
  • spring事务的7种传播行为——详细介绍

    目录 事务传播行为 1 PROPAGATION REQUIRED 2 PROPAGATION SUPPORTS 3 PROPAGATION MANDATORY 4 PROPAGATION MANDATORY 5 PROPAGATION NO
  • js开发技巧-实用型

    目录 1 按位或 2 按位与 3 按位取反 4 按位异或 5 6 toString 7 gt 和 lt 8 Number EPSILON
  • 【SpringBoot学习】SpringBoot的自动配置

    SpringBoot自动配置 SpringBootApplication是一个复合注解 其中主要包含以下注解 SpringBootConfiguration 基本是属于替代品 Configuration EnableAutoConfigur
  • ROS 執行launch報錯 python2.7錯誤

    mjm mjm pc Desktop ros robot pro roslaunch ros urdf PK test launch Traceback most recent call last File opt ros melodic
  • Java输出PPT文件(二) - 占位符数据替换

    Java输出PPT文件 二 占位符数据替换 文章目录 Java输出PPT文件 二 占位符数据替换 0 前言 1 依赖 2 代码 3 测试 3 1 模板准备 3 2 替换结果 4 一点分析 4 1 parseParagraph 4 2 get
  • linux下svn命令大全

    1 将文件checkout到本地目录 svn checkout path path是服务器上的目录 例如 svn checkout svn 192 168 1 1 pro domain 简写 svn co 2 往版本库中添加新的文件 svn
  • 淤地坝安全自动监测预警系统解决方案

    一 方案背景 淤地坝是在水土流失地区各级沟道中 以拦泥淤地为目的而修建的坝工建筑物 其主要作用为 滞洪 拦泥 淤地 蓄水 减轻黄河泥沙 保持水土不流失 建设农田 发展农业生产等 我国黄土高原地区现有淤地坝58776座 存在量多面广 建设标准
  • PowerShell脚本文件无法加载运行

    显示Restricted 不允许执行任何脚本 Get ExecutionPolicy RemoteSigned 可执行任何脚本 需要管理员权限 才能设置成功 Set ExecutionPolicy RemoteSigned
  • Centos 7 配置IP地址时network 和networkmanager冲突

    一 区别 1 network service的制御网络接口配置信息改动后 网络服务必须从新启动 来激活网络新配置的使得配置生效 这部分操作和从新启动系统时时一样的作用 制御 控制 是 etc init d network这个文件 可以用这个
  • 2.4.1 用NPOI操作EXCEL--画线

    之所有说NPOI强大 是因为常用的Excel操作她都可以通过编程的方式完成 这节开始 我们开始学习NPOI的画图功能 先从最简单的开始 画一条直线 对应的代码为 HSSFSheet sheet1 hssfworkbook CreateShe
  • android中完全退出当前应用程序的四种方法

    Android程序有很多Activity 比如说主窗口A 调用了子窗口B 如果在B中直接finish 接下里显示的是A 在B中如何关闭整个Android应用程序呢 本人总结了几种比较简单的实现方法 1 Dalvik VM的本地方法 andr
  • toFixed精度丢失问题

    bug说明 10 3950 3935 00 用toFixed 2 得到的是40904 32 实际应该是40904 33 解决的方法 第一种 在main js中直接复制下面代码即可 Number prototype toFixed funct
  • 【9秒原创】cocos2d-x横版rts手游《口袋仙侠》alpha1.0正式开源

    9秒原创 Firefly cocos2d x的横版rts手机网游 口袋仙侠 alpha V1 0 商用版本 完整源码下载 特别声明 1 口袋仙侠 项目基于MIT协议 9秒社团团队允许任何厂商及个人对其进行修改和商用 并将会在本板块内进行技术
  • Linux NetworkManager网络服务详解

    一 网络配置文件 Linux 为 配 置 网 络 提 供 了 许 多 工 具 其 中 有 图 形 界 面 的 如 NetworkManager 也有伪图形界面 如 system config network 的 虽然使用这些工具来配置网络会
  • iSH使用与优化全网整合教程【持续更新】【精华】

    最后一次更新 2023 4 22 请勿利用文章内的相关技术从事非法测试 由于传播 利用此文所提供的信息而造成的任何直接或者间接的后果及损失 均由使用者本人负责 作者不为此承担任何责任 iSH介绍与换源 已安装并已完成换源的用户可直接跳过 介
  • Deep Java Library(六)DJLServing自定义模型,自定义Translator注意事项

    DJLServing自定义模型中自定义Translator注意事项需要仔细读一下DJLServing源码中的ServingTranslatorFactory类 一开始不了解以为DJLServing选择Translator像玄学 后来看了像迷