aboutsummaryrefslogtreecommitdiffstats
path: root/model-evaluation
diff options
context:
space:
mode:
authorLester Solbakken <lesters@oath.com>2021-09-27 13:45:10 +0200
committerLester Solbakken <lesters@oath.com>2021-09-27 13:45:10 +0200
commite02be90cd8ea302cb23444a7dd321c9ef774913a (patch)
tree609821fc539839867fb652c55709b424fa1127a5 /model-evaluation
parent9377da84086392e118d69b467006e73fe9ae3f70 (diff)
Stateless REST API: short forms for sparse and mixed tensors
Diffstat (limited to 'model-evaluation')
-rw-r--r--model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java8
-rw-r--r--model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java34
-rw-r--r--model-evaluation/src/test/resources/config/models/rank-profiles.cfg9
3 files changed, 47 insertions, 4 deletions
diff --git a/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java b/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java
index bbd9962be77..e7e453d8fe3 100644
--- a/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java
+++ b/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
@@ -90,8 +91,11 @@ public class ModelsEvaluationHandler extends ThreadedHttpRequestHandler {
Tensor result = evaluator.evaluate();
Optional<String> format = property(request, "format");
- if (format.isPresent() && format.get().equalsIgnoreCase("short") && result instanceof IndexedTensor) {
- return new Response(200, JsonFormat.encodeShortForm((IndexedTensor) result));
+ if (format.isPresent() && format.get().equalsIgnoreCase("short")) {
+ return new Response(200, JsonFormat.encodeShortForm(result));
+ }
+ else if (format.isPresent() && format.get().equalsIgnoreCase("literal")) {
+ return new Response(200, result.toString().getBytes(StandardCharsets.UTF_8));
}
return new Response(200, JsonFormat.encode(result));
}
diff --git a/model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java b/model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java
index 8034be6bb22..3a900b0e815 100644
--- a/model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java
+++ b/model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java
@@ -48,7 +48,7 @@ public class ModelsEvaluationHandlerTest {
public void testListModels() {
String url = "http://localhost/model-evaluation/v1";
String expected =
- "{\"mnist_softmax\":\"http://localhost/model-evaluation/v1/mnist_softmax\",\"mnist_saved\":\"http://localhost/model-evaluation/v1/mnist_saved\",\"mnist_softmax_saved\":\"http://localhost/model-evaluation/v1/mnist_softmax_saved\",\"xgboost_2_2\":\"http://localhost/model-evaluation/v1/xgboost_2_2\",\"lightgbm_regression\":\"http://localhost/model-evaluation/v1/lightgbm_regression\"}";
+ "{\"mnist_softmax\":\"http://localhost/model-evaluation/v1/mnist_softmax\",\"mnist_saved\":\"http://localhost/model-evaluation/v1/mnist_saved\",\"mnist_softmax_saved\":\"http://localhost/model-evaluation/v1/mnist_softmax_saved\",\"vespa_model\":\"http://localhost/model-evaluation/v1/vespa_model\",\"xgboost_2_2\":\"http://localhost/model-evaluation/v1/xgboost_2_2\",\"lightgbm_regression\":\"http://localhost/model-evaluation/v1/lightgbm_regression\"}";
handler.assertResponse(url, 200, expected);
}
@@ -56,7 +56,7 @@ public class ModelsEvaluationHandlerTest {
public void testListModelsWithDifferentHost() {
String url = "http://localhost/model-evaluation/v1";
String expected =
- "{\"mnist_softmax\":\"http://localhost:8088/model-evaluation/v1/mnist_softmax\",\"mnist_saved\":\"http://localhost:8088/model-evaluation/v1/mnist_saved\",\"mnist_softmax_saved\":\"http://localhost:8088/model-evaluation/v1/mnist_softmax_saved\",\"xgboost_2_2\":\"http://localhost:8088/model-evaluation/v1/xgboost_2_2\",\"lightgbm_regression\":\"http://localhost:8088/model-evaluation/v1/lightgbm_regression\"}";
+ "{\"mnist_softmax\":\"http://localhost:8088/model-evaluation/v1/mnist_softmax\",\"mnist_saved\":\"http://localhost:8088/model-evaluation/v1/mnist_saved\",\"mnist_softmax_saved\":\"http://localhost:8088/model-evaluation/v1/mnist_softmax_saved\",\"vespa_model\":\"http://localhost:8088/model-evaluation/v1/vespa_model\",\"xgboost_2_2\":\"http://localhost:8088/model-evaluation/v1/xgboost_2_2\",\"lightgbm_regression\":\"http://localhost:8088/model-evaluation/v1/lightgbm_regression\"}";
handler.assertResponse(url, 200, expected, Map.of("Host", "localhost:8088"));
}
@@ -214,6 +214,36 @@ public class ModelsEvaluationHandlerTest {
}
@Test
+ public void testVespaModelShortOutput() {
+ Map<String, String> properties = new HashMap<>();
+ properties.put("format", "short");
+ String url = "http://localhost/model-evaluation/v1/vespa_model/";
+ handler.assertResponse(url + "test_mapped/eval", properties, 200,
+ "{\"type\":\"tensor(d0{})\",\"value\":{\"a\":1.0,\"b\":2.0}}");
+ handler.assertResponse(url + "test_indexed/eval", properties, 200,
+ "{\"type\":\"tensor(d0[2],d1[3])\",\"value\":[[1.0,2.0,3.0],[4.0,5.0,6.0]]}");
+ handler.assertResponse(url + "test_mixed/eval", properties, 200,
+ "{\"type\":\"tensor(x{},y[3])\",\"value\":{\"a\":[1.0,2.0,3.0],\"b\":[4.0,5.0,6.0]}}");
+ handler.assertResponse(url + "test_mixed_2/eval", properties, 200,
+ "{\"type\":\"tensor(a[2],b[2],c{},d[2])\",\"value\":{\"a\":[[[1.0,2.0],[3.0,4.0]],[[5.0,6.0],[7.0,8.0]]],\"b\":[[[1.0,2.0],[3.0,4.0]],[[5.0,6.0],[7.0,8.0]]]}}");
+ }
+
+ @Test
+ public void testVespaModelLiteralOutput() {
+ Map<String, String> properties = new HashMap<>();
+ properties.put("format", "literal");
+ String url = "http://localhost/model-evaluation/v1/vespa_model/";
+ handler.assertResponse(url + "test_mapped/eval", properties, 200,
+ "tensor(d0{}):{a:1.0,b:2.0}");
+ handler.assertResponse(url + "test_indexed/eval", properties, 200,
+ "tensor(d0[2],d1[3]):[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]");
+ handler.assertResponse(url + "test_mixed/eval", properties, 200,
+ "tensor(x{},y[3]):{a:[1.0, 2.0, 3.0],b:[4.0, 5.0, 6.0]}");
+ handler.assertResponse(url + "test_mixed_2/eval", properties, 200,
+ "tensor(a[2],b[2],c{},d[2]):{a:[[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]],b:[[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]}");
+ }
+
+ @Test
public void testMnistSavedEvaluateSpecificFunction() {
Map<String, String> properties = new HashMap<>();
properties.put("input", inputTensor());
diff --git a/model-evaluation/src/test/resources/config/models/rank-profiles.cfg b/model-evaluation/src/test/resources/config/models/rank-profiles.cfg
index 385115b7cd4..4877a24f171 100644
--- a/model-evaluation/src/test/resources/config/models/rank-profiles.cfg
+++ b/model-evaluation/src/test/resources/config/models/rank-profiles.cfg
@@ -29,3 +29,12 @@ rankprofile[3].fef.property[4].value "tensor(d1[10])"
rankprofile[4].name "lightgbm_regression"
rankprofile[4].fef.property[0].name "rankingExpression(lightgbm_regression).rankingScript"
rankprofile[4].fef.property[0].value "if (!(numerical_2 >= 0.46643291586559305), 2.1594397038037663, if (categorical_2 in ["k", "l", "m"], 2.235297305276056, 2.1792953471546546)) + if (categorical_1 in ["d", "e"], 0.03070842919354316, if (!(numerical_1 >= 0.5102250691730842), -0.04439151147520909, 0.005117411709368601)) + if (!(numerical_2 >= 0.668665477622446), if (!(numerical_2 >= 0.008118820676863816), -0.15361238490967524, -0.01192330846157292), 0.03499044894987518) + if (!(numerical_1 >= 0.5201391072644542), -0.02141000620783247, if (categorical_1 in ["a", "b"], -0.004121485787596721, 0.04534090904886873)) + if (categorical_2 in ["k", "l", "m"], if (!(numerical_2 >= 0.27283279016959255), -0.01924803254356527, 0.03643772842347651), -0.02701711918923075)"
+rankprofile[5].name "vespa_model"
+rankprofile[5].fef.property[0].name "rankingExpression(test_mapped).rankingScript"
+rankprofile[5].fef.property[0].value "tensor(d0{}):{a:1, b:2}"
+rankprofile[5].fef.property[1].name "rankingExpression(test_indexed).rankingScript"
+rankprofile[5].fef.property[1].value "tensor(d0[2],d1[3]):[[1,2,3],[4,5,6]]"
+rankprofile[5].fef.property[2].name "rankingExpression(test_mixed).rankingScript"
+rankprofile[5].fef.property[2].value "tensor(x{},y[3]):{a:[1,2,3], b:[4,5,6]}"
+rankprofile[5].fef.property[3].name "rankingExpression(test_mixed_2).rankingScript"
+rankprofile[5].fef.property[3].value "tensor(a[2],b[2],c{},d[2]):{a:[[[1,2], [3,4]], [[5,6], [7,8]]], b:[[[1,2], [3,4]], [[5,6], [7,8]]] }"