diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2018-01-16 09:47:20 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2018-01-16 09:47:20 +0100 |
commit | dd744223e7db5f14805b7e23dbe69f143b60f1a3 (patch) | |
tree | 6e4fae4ed8c166f93bb75a63ce51d6f81e512b29 /config-model | |
parent | 8d4892a8bec37fd938269417925c652da23a7ad2 (diff) |
Use either model or stored expressions only
Diffstat (limited to 'config-model')
5 files changed, 64 insertions, 58 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/ConfigModel.java b/config-model/src/main/java/com/yahoo/config/model/ConfigModel.java index 5daf5ca70a5..385cd883da4 100644 --- a/config-model/src/main/java/com/yahoo/config/model/ConfigModel.java +++ b/config-model/src/main/java/com/yahoo/config/model/ConfigModel.java @@ -8,7 +8,7 @@ package com.yahoo.config.model; * * @author gjoranv * @author bratseth - * @author lulf + * @author Ulf Lilleengen */ public abstract class ConfigModel { diff --git a/config-model/src/main/java/com/yahoo/config/model/admin/AdminModel.java b/config-model/src/main/java/com/yahoo/config/model/admin/AdminModel.java index 5eb4afcc241..5912b476783 100644 --- a/config-model/src/main/java/com/yahoo/config/model/admin/AdminModel.java +++ b/config-model/src/main/java/com/yahoo/config/model/admin/AdminModel.java @@ -21,8 +21,7 @@ import java.util.*; /** * Config model adaptor of the Admin class. * - * @author lulf - * @since 5.1 + * @author Ulf Lilleengen */ public class AdminModel extends ConfigModel { @@ -46,8 +45,9 @@ public class AdminModel extends ConfigModel { @Override public void prepare(ConfigModelRepo configModelRepo) { verifyClusterControllersOnlyDefinedForContent(configModelRepo); - if (admin == null || admin.getClusterControllers() == null) return; - admin.getClusterControllers().prepare(); + if (admin == null) return; + if (admin.getClusterControllers() != null) + admin.getClusterControllers().prepare(); } private void verifyClusterControllersOnlyDefinedForContent(ConfigModelRepo configModelRepo) { @@ -61,9 +61,9 @@ public class AdminModel extends ConfigModel { public static class BuilderV2 extends ConfigModelBuilder<AdminModel> { public static final List<ConfigModelId> configModelIds = - ImmutableList.of(ConfigModelId.fromNameAndVersion("admin", "2.0"), + ImmutableList.of(ConfigModelId.fromNameAndVersion("admin", "2.0"), ConfigModelId.fromNameAndVersion("admin", "1.0")); - + public BuilderV2() { super(AdminModel.class); } @@ -91,7 +91,7 @@ public class AdminModel extends ConfigModel { public static class BuilderV4 extends ConfigModelBuilder<AdminModel> { public static final List<ConfigModelId> configModelIds = - ImmutableList.of(ConfigModelId.fromNameAndVersion("admin", "3.0"), + ImmutableList.of(ConfigModelId.fromNameAndVersion("admin", "3.0"), ConfigModelId.fromNameAndVersion("admin", "4.0")); public BuilderV4() { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/TensorFlowFeatureConverter.java b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/TensorFlowFeatureConverter.java index 5e0df37d122..9fd4199f833 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/TensorFlowFeatureConverter.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/expressiontransforms/TensorFlowFeatureConverter.java @@ -68,37 +68,18 @@ public class TensorFlowFeatureConverter extends ExpressionTransformer<RankProfil // modelPath: The relative path to this model below the "models/" dir in the application package Path modelPath = Path.fromString(asString(feature.getArguments().expressions().get(0))); - TensorFlowModel model = importedModels.computeIfAbsent(modelPath, k -> importModel(modelPath)); - - // Find the specified expression - Signature signature = chooseSignature(model, optionalArgument(1, feature.getArguments())); - String output = chooseOutput(signature, optionalArgument(2, feature.getArguments())); - RankingExpression expression = readExpression(model, modelPath, signature.name(), output); - - // Add all constants (after finding outputs to fail faster when the output is not found) - if (constantsInConfig) - model.constants().forEach((k, v) -> context.rankProfile().addConstantTensor(k, new TensorValue(v))); - else // correct way, disabled for now - model.constants().forEach((k, v) -> transformConstant(modelPath, context.rankProfile(), k, v)); - - return expression.getRoot(); + Optional<String> signatureArg = optionalArgument(1, feature.getArguments()); + Optional<String> outputArg = optionalArgument(2, feature.getArguments()); + if (new File(ApplicationPackage.MODELS_DIR.append(modelPath).getRelative()).getCanonicalFile().exists()) + return transformFromTensorFlowModel(modelPath, signatureArg, outputArg, context.rankProfile()); + else + return transformFromStoredConvertedModel(modelPath, signatureArg, outputArg); } - catch (IllegalArgumentException e) { + catch (IllegalArgumentException | IOException e) { throw new IllegalArgumentException("Could not use tensorflow model from " + feature, e); } } - private TensorFlowModel importModel(Path modelPath) { - try { - return tensorFlowImporter.importModel(new File(ApplicationPackage.MODELS_DIR.append(modelPath) - .getRelative()) - .getCanonicalPath()); - } - catch (IOException e) { - throw new UncheckedIOException(e); - } - } - /** * Returns the specified, existing signature, or the only signature if none is specified. * Throws IllegalArgumentException in all other cases. @@ -152,38 +133,57 @@ public class TensorFlowFeatureConverter extends ExpressionTransformer<RankProfil } } - /** - * Store converted ranking expression for file distribution to be able to read them when creating the model - * on a different config server in the same cluster. - */ - private RankingExpression readExpression(TensorFlowModel model, Path modelPath, String signature, String output) { - Optional<RankingExpression> storedConvertedExpression = readConverted(signature, output, modelPath); - if (storedConvertedExpression.isPresent()) - return storedConvertedExpression.get(); + private ExpressionNode transformFromTensorFlowModel(Path modelPath, + Optional<String> signatureArg, + Optional<String> outputArg, + RankProfile rankProfile) { + TensorFlowModel model = importedModels.computeIfAbsent(modelPath, k -> importModel(modelPath)); - RankingExpression convertedExpression = model.expressions().get(output); - writeConverted(signature, output, convertedExpression, modelPath); - return convertedExpression; + // Find the specified expression + Signature signature = chooseSignature(model, signatureArg); + String output = chooseOutput(signature, outputArg); + RankingExpression expression = model.expressions().get(output); + writeConverted(modelPath, signatureArg, outputArg, expression); + + // Add all constants (after finding outputs to fail faster when the output is not found) + if (constantsInConfig) + model.constants().forEach((k, v) -> rankProfile.addConstantTensor(k, new TensorValue(v))); + else // correct way, disabled for now + model.constants().forEach((k, v) -> transformConstant(modelPath, rankProfile, k, v)); + + return expression.getRoot(); } - /** Reads a previously stored converted ranking expression, or returns empty if it does not exist */ - private Optional<RankingExpression> readConverted(String signature, String output, Path modelPath) { - File expressionFile = expressionFile(modelPath, signature, output); + private ExpressionNode transformFromStoredConvertedModel(Path modelPath, + Optional<String> signatureArg, + Optional<String> outputArg) { + File expressionFile = null; try { - if ( ! expressionFile.exists()) return Optional.empty(); - return Optional.of(new RankingExpression(IOUtils.readFile(expressionFile))); + expressionFile = expressionFile(modelPath, signatureArg, outputArg); + return new RankingExpression(IOUtils.readFile(expressionFile)).getRoot(); } catch (IOException e) { - throw new UncheckedIOException(e); + throw new UncheckedIOException("Could not read " + expressionFile, e); } catch (ParseException e) { throw new IllegalStateException("Could not parse " + expressionFile, e); } } - private void writeConverted(String signature, String output, RankingExpression expression, Path modelPath) { + private TensorFlowModel importModel(Path modelPath) { try { - IOUtils.writeFile(expressionFile(modelPath, signature, output), expression.getRoot().toString(), false); + return tensorFlowImporter.importModel(new File(ApplicationPackage.MODELS_DIR.append(modelPath) + .getRelative()) + .getCanonicalPath()); + } + catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private void writeConverted(Path modelPath, Optional<String> signatureArg, Optional<String> outputArg, RankingExpression expression) { + try { + IOUtils.writeFile(expressionFile(modelPath, signatureArg, outputArg), expression.getRoot().toString(), false); } catch (IOException e) { throw new UncheckedIOException(e); @@ -242,11 +242,18 @@ public class TensorFlowFeatureConverter extends ExpressionTransformer<RankProfil return c == '\'' || c == '"'; } - private File expressionFile(Path modelPath, String signature, String output) { + private File expressionFile(Path modelPath, Optional<String> signatureArg, Optional<String> outputArg) { try { + StringBuilder fileName = new StringBuilder(); + signatureArg.ifPresent(s -> fileName.append(s).append(".")); + outputArg.ifPresent(s -> fileName.append(s).append(".")); + if (fileName.length() == 0) // single signature and output + fileName.append("single."); + fileName.append("expression"); + return new File(ApplicationPackage.MODELS_GENERATED_DIR.append(modelPath) .append("expressions") - .append(signature + ". " + output + ".expression") + .append(fileName.toString()) .getRelative()) .getCanonicalFile(); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java index 59b7388f5bb..071b3090f99 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java @@ -73,9 +73,7 @@ public class Admin extends AbstractConfigProducer implements Serializable { this.fileDistribution = fileDistributionConfigProducer; } - public Configserver getConfigserver() { - return defaultConfigserver; - } + public Configserver getConfigserver() { return defaultConfigserver; } /** Returns the configured monitoring endpoint, or null if not configured */ public Monitoring getMonitoring() { diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java index aa47b0b3b81..efd2f51ba42 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java @@ -34,6 +34,7 @@ public class RankingExpressionWithTensorFlowTestCase { @After public void removeGeneratedConstantTensorFiles() { IOUtils.recursiveDeleteDir(new File(modelDirectory.substring(3), "constants")); + IOUtils.recursiveDeleteDir(new File(modelDirectory.substring(3), "expressions")); } @Test |