Repository: deepjavalibrary/djl
Pull request #1769 (2022-07-05 18:39:57)

[aws-ai] change the sagemaker model to s3
## Description ##

Support S3 model on SageMaker


codecov-commenter: # [Codecov](https://codecov.io/gh/deepjavalibrary/djl/pull/1769?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) Report
> Merging [#1769](https://codecov.io/gh/deepjavalibrary/djl/pull/1769?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) (e16cf2d) into [master](https://codecov.io/gh/deepjavalibrary/djl/commit/bb5073f7ffc33f1883621fc1783dbb01e70b418f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) (bb5073f) will **decrease** coverage by `1.41%`.
> The diff coverage is `70.76%`.

```diff
@@             Coverage Diff              @@
##             master    #1769      +/-   ##
============================================
- Coverage     72.08%   70.67%   -1.42%     
- Complexity     5126     5574     +448     
============================================
  Files           473      527      +54     
  Lines         21970    24737    +2767     
  Branches       2351     2681     +330     
============================================
+ Hits          15838    17483    +1645     
- Misses         4925     5923     +998     
- Partials       1207     1331     +124     
```


| [Impacted Files](https://codecov.io/gh/deepjavalibrary/djl/pull/1769?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) | Coverage Δ | |
|---|---|---|
| [api/src/main/java/ai/djl/modality/cv/Image.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L0ltYWdlLmphdmE=) | `69.23% <ø> (-4.11%)` | :arrow_down: |
| [...rc/main/java/ai/djl/modality/cv/MultiBoxPrior.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L011bHRpQm94UHJpb3IuamF2YQ==) | `76.00% <ø> (ø)` | |
| [...rc/main/java/ai/djl/modality/cv/output/Joints.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L291dHB1dC9Kb2ludHMuamF2YQ==) | `71.42% <ø> (ø)` | |
| [.../main/java/ai/djl/modality/cv/output/Landmark.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L291dHB1dC9MYW5kbWFyay5qYXZh) | `100.00% <ø> (ø)` | |
| [...main/java/ai/djl/modality/cv/output/Rectangle.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L291dHB1dC9SZWN0YW5nbGUuamF2YQ==) | `72.41% <0.00%> (ø)` | |
| [...i/djl/modality/cv/translator/BigGANTranslator.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3RyYW5zbGF0b3IvQmlnR0FOVHJhbnNsYXRvci5qYXZh) | `21.42% <ø> (-5.24%)` | :arrow_down: |
| [...odality/cv/translator/BigGANTranslatorFactory.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3RyYW5zbGF0b3IvQmlnR0FOVHJhbnNsYXRvckZhY3RvcnkuamF2YQ==) | `33.33% <0.00%> (+8.33%)` | :arrow_up: |
| [...nslator/InstanceSegmentationTranslatorFactory.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3RyYW5zbGF0b3IvSW5zdGFuY2VTZWdtZW50YXRpb25UcmFuc2xhdG9yRmFjdG9yeS5qYXZh) | `14.28% <0.00%> (-3.90%)` | :arrow_down: |
| [.../cv/translator/StyleTransferTranslatorFactory.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3RyYW5zbGF0b3IvU3R5bGVUcmFuc2ZlclRyYW5zbGF0b3JGYWN0b3J5LmphdmE=) | `40.00% <ø> (ø)` | |
| [.../ai/djl/modality/cv/translator/YoloTranslator.java](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3RyYW5zbGF0b3IvWW9sb1RyYW5zbGF0b3IuamF2YQ==) | `8.33% <0.00%> (-0.50%)` | :arrow_down: |
| ... and [411 more](https://codecov.io/gh/deepjavalibrary/djl/pull/1769/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/deepjavalibrary/djl/pull/1769?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/deepjavalibrary/djl/pull/1769?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary). Last update [a1c7448...e16cf2d](https://codecov.io/gh/deepjavalibrary/djl/pull/1769?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary).


Patch:
diff --git a/extensions/aws-ai/src/main/java/ai/djl/aws/sagemaker/SageMaker.java b/extensions/aws-ai/src/main/java/ai/djl/aws/sagemaker/SageMaker.java
index 4ee3f271e..a62cf16e9 100644
--- a/extensions/aws-ai/src/main/java/ai/djl/aws/sagemaker/SageMaker.java
+++ b/extensions/aws-ai/src/main/java/ai/djl/aws/sagemaker/SageMaker.java
@@ -26,6 +26,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import software.amazon.awssdk.core.SdkBytes;
+import software.amazon.awssdk.core.exception.SdkException;
 import software.amazon.awssdk.core.sync.RequestBody;
 import software.amazon.awssdk.core.waiters.WaiterResponse;
 import software.amazon.awssdk.regions.Region;
@@ -152,34 +153,64 @@ public final class SageMaker {
         logger.info("SageMaker endpoint {} created: {}", endpointName, endpointArn);
     }
 
-    /** Deletes the Amazon SageMaker endpoint. */
-    public void deleteEndpoint() {
-        logger.info("Deleting SageMaker endpoint {} ...", endpointName);
-        DeleteEndpointRequest req =
-                DeleteEndpointRequest.builder().endpointName(endpointName).build();
-        sageMaker.deleteEndpoint(req);
-        SageMakerWaiter waiter = sageMaker.waiter();
-        DescribeEndpointRequest waitReq =
-                DescribeEndpointRequest.builder().endpointName(endpointConfigName).build();
-        waiter.waitUntilEndpointDeleted(waitReq);
-        logger.info("SageMaker endpoint {} deleted.", endpointName);
+    /**
+     * Deletes the Amazon SageMaker endpoint.
+     *
+     * @param quietly true to suppress error
+     */
+    public void deleteEndpoint(boolean quietly) {
+        try {
+            logger.info("Deleting SageMaker endpoint {} ...", endpointName);
+            DeleteEndpointRequest req =
+                    DeleteEndpointRequest.builder().endpointName(endpointName).build();
+            sageMaker.deleteEndpoint(req);
+            SageMakerWaiter waiter = sageMaker.waiter();
+            DescribeEndpointRequest waitReq =
+                    DescribeEndpointRequest.builder().endpointName(endpointConfigName).build();
+            waiter.waitUntilEndpointDeleted(waitReq);
+            logger.info("SageMaker endpoint {} deleted.", endpointName);
+        } catch (SdkException e) {
+            if (!quietly) {
+                throw e;
+            }
+        }
     }
 
-    /** Deletes the endpoint configuration. */
-    public void deleteEndpointConfig() {
-        DeleteEndpointConfigRequest req =
-                DeleteEndpointConfigRequest.builder()
-                        .endpointConfigName(endpointConfigName)
-                        .build();
-        sageMaker.deleteEndpointConfig(req);
-        logger.info("SageMaker endpoint config {} deleted.", endpointConfigName);
+    /**
+     * Deletes the endpoint configuration.
+     *
+     * @param quietly true to suppress error
+     */
+    public void deleteEndpointConfig(boolean quietly) {
+        try {
+            DeleteEndpointConfigRequest req =
+                    DeleteEndpointConfigRequest.builder()
+                            .endpointConfigName(endpointConfigName)
+                            .build();
+            sageMaker.deleteEndpointConfig(req);
+            logger.info("SageMaker endpoint config {} deleted.", endpointConfigName);
+        } catch (SdkException e) {
+            if (!quietly) {
+                throw e;
+            }
+        }
     }
 
-    /** Deletes the SageMaker model configuration. */
-    public void deleteSageMakerModel() {
-        DeleteModelRequest req = DeleteModelRequest.builder().modelName(modelName).build();
-        sageMaker.deleteModel(req);
-        logger.info("SageMaker model {} deleted.", modelName);
+    /**
+     * Deletes the SageMaker model configuration.
+     *
+     * @param quietly true to suppress error
+     */
+    public void deleteSageMakerModel(boolean quietly) {
+        try {
+            DeleteModelRequest req = DeleteModelRequest.builder().modelName(modelName).build();
+            sageMaker.deleteModel(req);
+            logger.info("SageMaker model {} deleted.", modelName);
+        } catch (SdkException e) {
+            if (!quietly) {
+                throw e;
+            }
+        }
     }
 
     /**
@@ -298,7 +329,7 @@ public final class SageMaker {
                 BufferedOutputStream bos = new BufferedOutputStream(os);
                 GzipCompressorOutputStream zos = new GzipCompressorOutputStream(bos);
                 TarArchiveOutputStream tos = new TarArchiveOutputStream(zos)) {
-
+            tos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR);
             addToTar(dir, dir, tos);
             tos.finish();
         }


Test patch:
diff --git a/extensions/aws-ai/src/test/java/ai/djl/aws/sagemaker/SageMakerTest.java b/extensions/aws-ai/src/test/java/ai/djl/aws/sagemaker/SageMakerTest.java
index 8554043c9..30ada2f7a 100644
--- a/extensions/aws-ai/src/test/java/ai/djl/aws/sagemaker/SageMakerTest.java
+++ b/extensions/aws-ai/src/test/java/ai/djl/aws/sagemaker/SageMakerTest.java
@@ -28,7 +28,6 @@ import org.testng.annotations.Test;
 
 import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
 import software.amazon.awssdk.core.exception.SdkClientException;
-import software.amazon.awssdk.core.exception.SdkException;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -50,36 +49,40 @@ public class SageMakerTest {
         Criteria<NDList, NDList> criteria =
                 Criteria.builder()
                         .setTypes(NDList.class, NDList.class)
-                        .optModelUrls("https://resources.djl.ai/test-models/mlp.tar.gz")
+                        .optModelUrls(
+                                "https://resources.djl.ai/test-models/pytorch/resnet18_jit.tar.gz")
                         .build();
         try (ZooModel<NDList, NDList> model = criteria.loadModel()) {
             SageMaker sageMaker =
                     SageMaker.builder()
                             .setModel(model)
                             .optBucketName("djl-sm-test")
-                            .optModelName("resnet")
-                            .optContainerImage("125045733377.dkr.ecr.us-east-1.amazonaws.com/djl")
+                            .optModelName("resnet18-jit")
+                            .optContainerImage(
+                                    "125045733377.dkr.ecr.us-east-1.amazonaws.com/djl-serving")
                             .optExecutionRole(
                                     "arn:aws:iam::125045733377:role/service-role/DJLSageMaker-ExecutionRole-20210213T1027050")
                             .build();
 
-            sageMaker.deploy();
+            try {
+                sageMaker.deploy();
 
-            byte[] image;
-            Path imagePath = Paths.get("../../examples/src/test/resources/0.png");
-            try (InputStream is = Files.newInputStream(imagePath)) {
-                image = Utils.toByteArray(is);
+                byte[] image;
+                Path imagePath = Paths.get("../../examples/src/test/resources/kitten.jpg");
+                try (InputStream is = Files.newInputStream(imagePath)) {
+                    image = Utils.toByteArray(is);
+                }
+                String ret = new String(sageMaker.invoke(image), StandardCharsets.UTF_8);
+                Type type = new TypeToken<List<Classifications.Classification>>() {}.getType();
+                List<Classifications.Classification> list = JsonUtils.GSON.fromJson(ret, type);
+                String className = list.get(0).getClassName();
+                Assert.assertEquals(className, "n02123159 tiger cat");
+            } finally {
+                sageMaker.deleteEndpoint(true);
+                sageMaker.deleteEndpointConfig(true);
+                sageMaker.deleteSageMakerModel(true);
             }
-            String ret = new String(sageMaker.invoke(image), StandardCharsets.UTF_8);
-            Type type = new TypeToken<List<Classifications.Classification>>() {}.getType();
-            List<Classifications.Classification> list = JsonUtils.GSON.fromJson(ret, type);
-            String className = list.get(0).getClassName();
-            Assert.assertEquals(className, "0");
-
-            sageMaker.deleteEndpoint();
-            sageMaker.deleteEndpointConfig();
-            sageMaker.deleteSageMakerModel();
-        } catch (SdkException e) {
+        } catch (SdkClientException e) {
             throw new SkipException("Skip tests that requires permission.", e);
         }
     }