deepjavalibrary / djl

An Engine-Agnostic Deep Learning Framework in Java
https://djl.ai
Apache License 2.0
4.11k stars 653 forks source link

Error occured after packaging to jar #1428

Closed UESTCkevin closed 2 years ago

UESTCkevin commented 2 years ago

I was trying to load a Onnx model by using ModelZoo.loadModel(). Here is my code:

123 ```java public static void main(String[] args) throws MalformedURLException { LoadDll loadDll = new LoadDll(); loadDll.loadOpenCV(); Translator yoloV5Translator = YoloV5Translator.builder().optSynsetArtifactName("person.names").build(); Criteria criteria = Criteria.builder() .setTypes(Image.class, DetectedObjects.class) .optDevice(Device.cpu()) .optModelPath(Paths.get("src/main/resources/yolov5s/person.onnx")) .optTranslator(yoloV5Translator) .optEngine("OnnxRuntime") .build(); try (ZooModel model = ModelZoo.loadModel(criteria)) { FFmpegFrameGrabber fFmpegFrameGrabber = FFmpegFrameGrabber.createDefault("src/main/resources/video/person.mp4"); fFmpegFrameGrabber.start(); int videoLength = fFmpegFrameGrabber.getLengthInFrames(); Frame f; int i = 0; while (i < videoLength) { f = fFmpegFrameGrabber.grabImage(); Java2DFrameConverter converter = new Java2DFrameConverter(); BufferedImage bi = converter.getBufferedImage(f); Mat oldFrame = BufImg2Mat(bi, BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3); Mat frame = new Mat(); Imgproc.resize(oldFrame, frame, new Size(640, 640)); detect(frame, model); HighGui.imshow("yolov5", frame); HighGui.waitKey(10); i++; } fFmpegFrameGrabber.stop(); } catch (RuntimeException | ModelException | TranslateException | IOException e) { e.printStackTrace(); } } ```

Code runs perfectly fine on IDE but after I packaged it to jar and try 'java -jar PersonDetect.jar', an error occured as below: Any suggestions on this issue?

UESTCkevin commented 2 years ago

Image is here. image

frankfliu commented 2 years ago

@UESTCkevin

You might hit this issue: https://github.com/deepjavalibrary/djl/issues/940

Can you share your dependencies and build script file?

And aslo share the file names in your .jar file:

jar tvf PersonDetect.jar
UESTCkevin commented 2 years ago

@frankfliu Here is my pom.xml:

pom.xml ``` 4.0.0 org.example PersonDetect 1.0-SNAPSHOT 8 8 0.11.0 org.apache.maven.plugins maven-assembly-plugin PersonDetect jar-with-dependencies org.slf4j slf4j-nop 1.7.2 ai.djl api ${djl.version} ai.djl.pytorch pytorch-model-zoo ${djl.version} ai.djl.pytorch pytorch-engine ${djl.version} runtime ai.djl.pytorch pytorch-native-auto 1.8.1 ai.djl.onnxruntime onnxruntime-engine 0.12.0 org.bytedeco javacv-platform 1.5.6 ```

I packaged my project to jar by command 'mvn assembly:assembly' and then I got two .jar file in the 'target' folder which are 'PersonDetect-1.0-SNAPSHOT.jar' and 'PersonDetect-1.0-SNAPSHOT-jar-with-dependencies.jar'.

I ran 'java -jar PersonDetect-1.0-SNAPSHOT-jar-with-dependencies.jar' and here is what I got:

Error ``` PS E:\JavaProject\PersonDetect\target> java -jar PersonDetect-1.0-SNAPSHOT-jar-with-dependencies.jar Windows 10 64 bit load success! ai.djl.repository.zoo.ModelNotFoundException: ModelZoo doesn't support specified with engine: OnnxRuntime at ai.djl.repository.zoo.ModelZoo.loadModel(ModelZoo.java:136) at PersonDetect.main(PersonDetect.java:70) ```

Thank you for any advice.

frankfliu commented 2 years ago

@UESTCkevin You run into the same issue as: #940

We use ServiceLoader to load model zoo and engines. maven assembly removes the duplicate serviceloader files in the uber jar, you should consider use maven-shade-plugin to keep all duplicate files in your jar.

Or you can consider use gradle to build project. In gradle it's pretty straight-forward, see example: https://github.com/deepjavalibrary/djl/blob/master/engines/mxnet/jnarator/build.gradle#L28

UESTCkevin commented 2 years ago

@frankfliu Thanks for replying. I switched maven-assembly-plugin to maven-shade-plugin. This is my new pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>PersonDetect</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <djl.version>0.11.0</djl.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <configuration>
                    <transformers>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>PersonDetect</mainClass>
                        </transformer>
                    </transformers>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>PamModel/*.*</exclude>  
                                        <exclude>META-INF/*.SF</exclude> 
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.2</version>
        </dependency>
        <dependency>
            <groupId>ai.djl</groupId>
            <artifactId>api</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <dependency>
            <groupId>ai.djl.pytorch</groupId>
            <artifactId>pytorch-model-zoo</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <dependency>
            <groupId>ai.djl.pytorch</groupId>
            <artifactId>pytorch-engine</artifactId>
            <version>${djl.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>ai.djl.pytorch</groupId>
            <artifactId>pytorch-native-auto</artifactId>
            <version>1.8.1</version>
        </dependency>
        <dependency>
            <groupId>ai.djl.onnxruntime</groupId>
            <artifactId>onnxruntime-engine</artifactId>
            <version>0.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.6</version>
        </dependency>
    </dependencies>
</project>

After I executed mvn clean package I got two .jar files in the 'target' folder which are 'PersonDetect-1.0-SNAPSHOT.jar' and 'original-PersonDetect-1.0-SNAPSHOT.jar'. I executed java -jar PersonDetect-1.0-SNAPSHOT.jar but I still got the same error as below:

PS E:\JavaProject\PersonDetect\target> java -jar PersonDetect-1.0-SNAPSHOT.jar 
Windows 10 64 bit load success!
ai.djl.repository.zoo.ModelNotFoundException: No matching model with specified Input/Output type found.
        at ai.djl.repository.zoo.ModelZoo.loadModel(ModelZoo.java:202)
        at PersonDetect.main(PersonDetect.java:70)

Do you have any other advice?

frankfliu commented 2 years ago

@UESTCkevin The error message is different from your last error. Can you share the complete project so I can reproduce it?

You might want to enable debug log level, so you can see the detail about model loading:

https://docs.djl.ai/master/docs/development/configure_logging.html#configure-logging-level

UESTCkevin commented 2 years ago

@frankfliu Thanks for replying. This is my project address:https://github.com/UESTCkevin/PersonDetect Opencv resources is located in 'src/main/resources/opencv' folder. Thanks again for helping.

frankfliu commented 2 years ago

@UESTCkevin

I tried your project on Windows, it's working fine in both IntelliJ and command line:

cd PersonDetect
java -jar target/PersonDetect-1.0-SNAPSHOT.jar

The error most likely is because you are running in target folder. In your code you use relative file path src/main/resources/yolov5s/person.onnx, this path doesn't exists in target folder

UESTCkevin commented 2 years ago

@frankfliu It works after I run java -jar target/PersonDetect-1.0-SNAPSHOT.jar. Thanks for your help!