SDK configuration
AutoML SDK configuration is a Java Spring-like set of definitions for AutoML SDK components — Annotators, Feature Extractors, Post-Processors, and so on.
AutoML SDK configuration is created declaratively using Java Annotations. There are two main annotations: @ModelConfiguration and @Named (similar to
Spring's @Configuration and @Bean annotations). Annotating a class with @ModelConfiguration indicates that the class can be used as a source of component definitions. The @Named annotation declares a component and tells that a method will return an actual component which should be registered in ComponentRegistry.
Your @ModelConfiguration class can have a declaration for more than one @Named. Once your classes are defined, you can use the configuration for model training.
Configuration
Let's start with a basic configuration:
- First, use
@ModelConfigurationto declare a class as a configuration instance. - Next, add the main configuration class
@HypermodelConfigurationto the hyper-model declaration.
@ModelConfiguration
public class ExampleConfiguration {
}
@HypermodelConfiguration(ExampleConfiguration.class)
public class ExampleHypermodel extends GenericIeHypermodel {
public ExampleHypermodel() throws Exception {
super();
}
}
Note, that the previous configuration example extends the default GenericIeHypermodel configuration. This can be changed during the project configuration by specifying the importConfigurationFromGenericModel parameter.
Components Configuration
To declare one or multiple AutoML SDK components,
use @Named annotation with a string value to attach a name identifier
to a component. Note, that @Named can return a single component or a
list of components. Components are recognized based on the response
type.
The following example declares 3 named components: basePostProcessors, featureExtractors, and a list of annotators.
import java.util.ArrayList;
import java.util.List;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Named;
import com.workfusion.vds.sdk.api.nlp.annotator.Annotator;
import com.workfusion.vds.sdk.api.nlp.fe.FeatureExtractor;
import com.workfusion.vds.sdk.api.nlp.model.Cell;
import com.workfusion.vds.sdk.api.nlp.model.Element;
import com.workfusion.vds.sdk.api.nlp.model.IeDocument;
import com.workfusion.vds.sdk.api.nlp.processing.Processor;
import com.workfusion.vds.sdk.nlp.component.annotator.EntityBoundaryAnnotator;
import com.workfusion.vds.sdk.nlp.component.annotator.tokenizer.SplitterTokenAnnotator;
import com.workfusion.vds.sdk.nlp.component.fe.ner.IsFirstNerInFocusElementFE;
import com.workfusion.vds.sdk.nlp.component.processing.grouping.RowBasedGroupingProcessor;
@ModelConfiguration
public class ExampleConfiguration {
@Named("basePostProcessors")
public Processor<IeDocument> postProcessors() {
return new RowBasedGroupingProcessor();
}
@Named("featureExtractors")
public FeatureExtractor<Element> featureExtractors() {
return new IsFirstNerInFocusElementFE(Cell.class);
}
@Named("annotators")
public List<Annotator> annotators() {
List<Annotator> annotators = new ArrayList<>();
annotators.add(new SplitterTokenAnnotator("\\s+"));
annotators.add(new EntityBoundaryAnnotator());
return annotators;
}
}
The result of this configuration will be: Post-Processor from basePostProcessors, Feature Extractor from featureExtractors and two Annotators from annotators.
Advanced components are described in the following chapters of the document.
Configuration Context
ConfigurationContext is an interface that provides a map of initial configuration parameters and a reference to the field object. Field value is used to specify settings for a concrete sub-model configuration. For example, apply specific annotators only for field with type — ADDRESS.
@Named methods can accept a ConfigurationContext object or an IeConfigurationContext object in case of information extraction models.
ConfigurationContext and IeConfigurationContext contain methods to access different properties. The most commonly used property is FieldInfo — a class for information extraction, which contains information about the current sub-model configuration. Using this property one @Named method can produce different sets of AutoML SDK components for different sub-models using a switch case or an if-else statement.
The following ConfigurationContext methods are considered the most useful. For a full list of methods, refer to ConfigurationContext documentation.
getField Method
getField gets FieldInfo associated with the current sub-model configuration. For ConfigurationContext that
isn't related to the particular field, getField returns empty FieldInfo with code — default.
FieldInfo getField()
The following example contains an IeConfigurationContext object. In this case, each AutoML SDK configuration produces a different set of Annotators depending on the code type: invoice_number or address.
import java.util.ArrayList;
import java.util.List;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Named;
import com.workfusion.vds.sdk.api.nlp.annotator.Annotator;
import com.workfusion.vds.sdk.api.nlp.configuration.IeConfigurationContext;
import com.workfusion.vds.sdk.nlp.component.annotator.EntityBoundaryAnnotator;
import com.workfusion.vds.sdk.nlp.component.annotator.ner.BaseRegexNerAnnotator;
import com.workfusion.vds.sdk.nlp.component.annotator.tokenizer.SplitterTokenAnnotator;
@ModelConfiguration
public class TrainingIeModelConfiguration {
public static final String REGEX_SPLITTER_TOKEN = "\\s+";
public static final String REGEX_ZIP = "[0-9]{5}(-[0-9]{4,5})?";
public static final String REGEX_CITY = "[A-Z][a-z]{3,18}";
public static final String REGEX_INVOICE_NUMBER = "([\\d]{10,11})";
@Named("annotators")
public List<Annotator> annotators(IeConfigurationContext context) {
List<Annotator> annotators = new ArrayList<>();
annotators.add(new SplitterTokenAnnotator(REGEX_SPLITTER_TOKEN));
annotators.add(new EntityBoundaryAnnotator());
String codeType = context.getField().getCode();
switch (codeType) {
case "invoice_number": {
annotators.add(BaseRegexNerAnnotator.getJavaPatternRegexNerAnnotator("invoice_number", REGEX_INVOICE_NUMBER));
break;
}
case "address": {
annotators.add(BaseRegexNerAnnotator.getJavaPatternRegexNerAnnotator("city", REGEX_CITY));
annotators.add(BaseRegexNerAnnotator.getJavaPatternRegexNerAnnotator("zip", REGEX_ZIP));
break;
}
}
return annotators;
}
}
For more information, refer to FieldInfo documentation.
getResource Method
Resource getResource(String path)
getResource provides a Resource instance
for a specified path:
- Classpath resource, for example classpath:test.csv.
- Model resource, for example /ref-data/test.csv, /dictionaries/test.csv, /corrections/test.csv.
Here's an example of getResource usage with a dictionary.
@Named("annotators")
public List<Annotator> annotators(IeConfigurationContext context) {
List<Annotator> annotators = new ArrayList<>();
annotators.add(new AhoCorasickDictionaryNerAnnotator("company_name",
new CsvDictionaryKeywordProvider(context.getResource("/dictionaries/CompanyNames.csv"))));
return annotators;
}
InputStream
InputStream openInputStream()
In case, the Resource instance is provided by an external WorkFusion source, for example attached to human
task, use an input stream to read data. The try-with-resources construct should be used to ensure that the opened stream is closed at the end of the statement.
getParameter Method
getParameter gets a configuration parameter (for example, parameter name) acquired externally from a WorkFusion service. This parameter can be used for further advanced model configuration.
Object getParameter(String name)
For more information, refer to getParameter() documentation.
Component Registry
ComponentRegistry is an interface to provide access to @Named components as Java Objects. An instance of such object can be obtained in a @Named method. Using this interface, you can obtain a Component instance by ID or internal return type (for example, FeatureExtactor.class ). In some cases, this can simplify the configuration code.
ComponentRegistry default implementation contains the following methods:
getComponentgetComponents
For usage information, refer to ComponentRegistry documentation.
getComponent
getComponent gets a single component based on a unique component ID.
Component getComponent(String componentName)
| Parameter | Description |
|---|---|
@componentName | @Named component annotation value. |
@return | Single component. |
getComponents
getComponents gets a collection of @Named components based on the return type.
Collection<Component> getComponents(Class<?> type)
| Parameter | Description |
|---|---|
@type | Components type. |
@return | Collection of components. |
import com.workfusion.vds.nlp.model.configuration.DefaultComponentRegistry;
import com.workfusion.vds.sdk.api.hpo.Dimensions;
import com.workfusion.vds.sdk.api.hpo.ParameterSpace;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Named;
import com.workfusion.vds.sdk.api.nlp.annotator.Annotator;
import com.workfusion.vds.sdk.api.nlp.configuration.IeConfigurationContext;
import com.workfusion.vds.sdk.nlp.component.annotator.ner.BaseRegexNerAnnotator;
@ModelConfiguration
public class Config {
public static final String REGEX_ZIP = "[0-9]{5}(-[0-9]{4,5})?";
public static final String REGEX_CITY = "[A-Z][a-z]{3,18}";
public static final String REGEX_INVOICE_NUMBER = "([\\d]{10,11})";
@Named("a1")
public Annotator a1() {
return BaseRegexNerAnnotator.getJavaPatternRegexNerAnnotator("invoice_number", REGEX_INVOICE_NUMBER);
}
@Named("a2")
public Annotator a2() {
return BaseRegexNerAnnotator.getJavaPatternRegexNerAnnotator("zip", REGEX_ZIP);
}
@Named("a3")
public Annotator a3() {
return BaseRegexNerAnnotator.getJavaPatternRegexNerAnnotator("city", REGEX_CITY);
}
@Named("featureExtractorsParameterSpace")
public ParameterSpace configureHPO(DefaultComponentRegistry registry, IeConfigurationContext configurationContext) {
return new ParameterSpace.Builder()
.add(Dimensions.selectOne(registry.getComponent("a1"), registry.getComponent("a3")))
.build();
}
}
Importing a Configuration
One or multiple configurations can be imported into another configuration to avoid writing it from scratch. In this case, the imported configuration is considered a child and the target configuration is considered a parent. The resulting configuration contains all components from child configurations and a parent configuration.
To import a configuration(-s) to another configuration, use @Import class-level annotation together with @ModelConfiguration. The latter contains a reference to the child configuration class.
import com.workfusion.vds.sdk.api.hypermodel.annotation.Import;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Named;
import com.workfusion.vds.sdk.api.nlp.processing.Processor;
@ModelConfiguration
class PostProcessorConfig {
@Named("presentationPostProcessor")
public Processor getPostProcessors() {
return new ExamplePostProcessing1();
}
@Named("basePostProcessor")
public Processor postProcessors() {
return new ExamplePostProcessing2();
}
}
@ModelConfiguration
@Import(configurations = {
@Import.Configuration(PostProcessorConfig.class)
})
class GenericPostProcessorConfig {
@Named("basePostProcessor")
public Processor postProcessors() {
return new ExamplePostProcessing3();
}
}
The result of GenericPostProcessorConfig processing will consist of all named components from the child PostProcessorConfig configuration and all components from the parent GenericPostProcessorConfig configuration.
note
Both configurations contain a Post-Processor basePostProcessor. In this case, the component declared in the parent GenericPostProcessorConfig configuration will override the component with the same name declared in the child PostProcessorConfig configuration.
The resulting configuration will contain the following Components:
presentationPostProcessorfromPostProcessorConfigbasePostProcessorfromGenericPostProcessorConfig
Hyper Parameter Optimization
Configuration described in previous sections is an example of fixed configuration with a strictly pre-defined set of components. Starting with v9.0 AutoML SDK enables configuring Hyper Parameter Optimization which significantly extends the capabilities of a configuration allowing smart selection of components. For example, a configuration can have a number of declared Annotators, but only a particular combination of these Annotators performs the best result.
To configure HPO within your model configuration, proceed with the following steps:
Declare a class as a configuration instance using the
@ModelConfigurationannotation, just like in a fixed configuration.Declare your named components. For example, a couple of Annotators and a list of Feature Extractors.
- Alternatively, import a child configuration(-s) with a ready-to-go set of components.
Declare a @Named component with some unique ID (for example,
annotatorParameterSpace), and then add a method producing ParameterSpace.Use
ParameterSpace.Builder()to define the dimensions—component selection strategy—according to the following criteria:Parameter Description Example requiredComponent is required at all times. required("annotator1")selectOneOnly one component from a subset is required. selectOne("annotator2", "annotator3")optionalOneNone or only one component from a subset is required. optionalOne("annotator2", "annotator3")optionalComponent is optional. optional("annotator3")
warning
Configuring HPO requires explicit selection strategy setup. This means that components not mentioned in HPO configuration will not be processed.
The following configuration with HPO will result in finding the best combination of Annotators.
import java.util.ArrayList;
import java.util.List;
import com.workfusion.vds.sdk.api.hpo.Dimensions;
import com.workfusion.vds.sdk.api.hpo.ParameterSpace;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Named;
import com.workfusion.vds.sdk.api.nlp.annotator.Annotator;
import com.workfusion.vds.sdk.api.nlp.fe.FeatureExtractor;
@ModelConfiguration
public class ExampleConfiguration {
@Named("annotator1")
public Annotator getAnnotator1() {
return new AnnotatorExample1();
}
@Named("annotator2")
public Annotator getAnnotator2() {
return new AnnotatorExample2();
}
@Named("annotator3")
public Annotator getAnnotator3() {
return new AnnotatorExample3();
}
@Named("fes")
public List<FeatureExtractor> getPostProcessors() {
List<FeatureExtractor> fes = new ArrayList<>();
fes.add(new FeatureExtractorExample1());
fes.add(new FeatureExtractorExample2());
return fes;
}
@Named("annotatorParameterSpace")
public ParameterSpace configureParameterSpace() {
return new ParameterSpace.Builder()
.add(Dimensions.required("annotator1"))
.add(Dimensions.selectOne("annotator2", "annotator3"))
.add(Dimensions.required("fes"))
.build();
}
}
The above-mentioned configuration can be further extended by adding ConfigurationContext to choose the best configuration for each field by adding dimensions as in the following example.
- For
invoice_amountthe configuration will always usefesandannotator1, and then choose the best fromannotator2orannotator3. - For
client_addressthe configuration will always usefesandannotator1, and then optionally chooseannotator4.
import java.util.ArrayList;
import java.util.List;
import com.workfusion.vds.sdk.api.hpo.Dimensions;
import com.workfusion.vds.sdk.api.hpo.ParameterSpace;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Named;
import com.workfusion.vds.sdk.api.nlp.annotator.Annotator;
import com.workfusion.vds.sdk.api.nlp.configuration.IeConfigurationContext;
import com.workfusion.vds.sdk.api.nlp.fe.FeatureExtractor;
@ModelConfiguration
public class ExampleConfiguration {
@Named("annotator1")
public Annotator getAnnotator1() {
return new Annotator1();
}
@Named("annotator2")
public Annotator getAnnotator2() {
return new Annotator2();
}
@Named("annotator3")
public Annotator getAnnotator3() {
return new Annotator3();
}
@Named("annotator4")
public Annotator getAnnotator4() {
return new Annotator4();
}
@Named("fes")
public List<FeatureExtractor> getPostProcessors() {
List<FeatureExtractor> fes = new ArrayList<>();
fes.add(new FeatureExtractorExample1());
fes.add(new FeatureExtractorExample2());
return fes;
}
@Named("annotatorParameterSpace")
public ParameterSpace configureParameterSpace(IeConfigurationContext context) {
ParameterSpace.Builder builder = new ParameterSpace.Builder();
builder.add(Dimensions.required("annotator1")).add(Dimensions.required("fes"));
switch (context.getField().getCode()) {
case "invoice_amount":
builder.add(Dimensions.selectOne("annotator2", "annotator3"));
break;
case "client_address":
builder.add(Dimensions.optional("annotator4"));
break;
}
return builder.build();
}
}
Fixed Serialized Configuration
By default AutoML SDK in-built GenericIeHypermodel configuration produces a set of HPO experiments. Each HPO experiment results in a list of JSON files with serialized configurations, each related to a particular field in a document. A configuration may have serialized configurations imported for specific fields to avoid repeated HPO selection and thus reduce training time.
To create a fixed serialized configuration, proceed with the following steps:
- Put all serialized JSON files into CLASSPATH.
- Create a new
@ModelConfigurationclass. This class should import the default main generic configuration class where serialized configurations were created from. - Add the
resourcesproperty to the@Importannotation. Provide a list of inner@Import.Resourceannotations.
note
Each @Import.Resource annotation produces a configuration for one field and contains the following properties:
value— a path to a file with fixed serialized configuration.condition—@Filterannotation which contains a SpEL expression that produces a boolean value. This expression checks the field value to indicate whether a fixed serialized configuration needs to be applied.
The condition is optional. If it is not specified then fixed serialized configuration will be applied every time. This can be used for classification models as there is no field check.
Here's an example:
import com.workfusion.vds.nlp.hypermodel.ie.generic.config.GenericIeHypermodelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Filter;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Import;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
@ModelConfiguration
@Import(
configurations = {
@Import.Configuration(GenericIeHypermodelConfiguration.class)
},
resources = {
@Import.Resource(value="/path/to/file/for/date/field/parameters.json",
condition = @Filter(expression = "field.code eq 'invoice_date'")),
@Import.Resource(value="/path/to/file/for/amount/field/parameters.json",
condition = @Filter(expression = "field.code eq 'invoice_amount'"))
}
)
public class FixedConfiguration {
}
Depending on the condition expression result various configurations can be built:
- If each condition expression returns
false, the resulting configuration is built using the defaultGenericIeHypermodelConfigurationclass. - If one
conditionexpression returnstrue, the configuration is built using the serialized configuration from the correspondingvalueparameter. - If multiple
conditionexpressions returntrue, the configuration is built using the FIRST imported serialized configuration, all consequent serialized configurations are ignored.
note
The described configuration can have additional FixedConfiguration components. The resulting configuration will aggregate both the @Import.Resource configuration (if any) and FixedConfiguration.
Filtering Configuration Imports
Importing a configuration allows filtering out certain components, HPO in child configuration(-s), or even sub-child configurations, if any.
The following two examples display two cases: Example 1 with @Filter disabled, Example 2 with @Filter enabled.
Example #1
There are 2 configurations each containing some named components and HPO. ChildAnnotatorConfig is imported to ParentAnnotatorConfig with @Filter disabled. What is the result of the configured HPO in that case?
import com.workfusion.vds.sdk.api.hpo.Dimensions;
import com.workfusion.vds.sdk.api.hpo.ParameterSpace;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Import;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Named;
import com.workfusion.vds.sdk.api.nlp.annotator.Annotator;
@ModelConfiguration
class ChildAnnotatorConfig {
@Named("annotatorA")
public Annotator testAnnotatorA() {
return new AnnotatorA();
}
@Named("annotatorB")
public Annotator testAnnotatorB() {
return new AnnotatorB();
}
@Named("annotatorParameterSpace")
public ParameterSpace configureParameterSpace() {
return new ParameterSpace.Builder()
.add(Dimensions.optional("annotatorA"))
.add(Dimensions.required("annotatorB"))
.build();
}
}
@ModelConfiguration
@Import(configurations = {@Import.Configuration(ChildAnnotatorConfig.class)})
class ParentAnnotatorConfig {
@Named("annotatorC")
public Annotator testAnnotatorC() {
return new AnnotatorC();
}
@Named("additionalAnnotatorParameterSpace")
public ParameterSpace configureParameterSpace() {
return new ParameterSpace.Builder()
.add(Dimensions.required("annotatorC"))
.build();
}
}
HPO in ChildAnnotatorConfig is processed first, HPO in ParentAnnotatorConfig is processed next. The result is a merged configuration from both the child and parent configurations which contains the following components:
- Optional
annotatorAas a result of ChildAnnotatorConfig HPO. - Fixed
annotatorBas a result of ChildAnnotatorConfig HPO. - Fixed
annotatorCas a result of ParentAnnotatorConfig HPO.
Example #2
There are 2 configurations each containing some named components and HPO. ChildAnnotatorConfig is imported to ParentAnnotatorConfig but this time with enabled @Filter so the child's HPO is ignored. What is the result of the configured HPO in that case?
To enable the filter, use @Filter in the @Import annotation.
import com.workfusion.vds.sdk.api.hpo.Dimensions;
import com.workfusion.vds.sdk.api.hpo.ParameterSpace;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Filter;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Import;
import com.workfusion.vds.sdk.api.hypermodel.annotation.ModelConfiguration;
import com.workfusion.vds.sdk.api.hypermodel.annotation.Named;
import com.workfusion.vds.sdk.api.nlp.annotator.Annotator;
@ModelConfiguration
class ChildAnnotatorConfig {
@Named("annotatorA")
public Annotator testAnnotatorA() {
return new AnnotatorA();
}
@Named("annotatorB")
public Annotator testAnnotatorB() {
return new AnnotatorB();
}
@Named("annotatorParameterSpace")
public ParameterSpace configureParameterSpace() {
return new ParameterSpace.Builder()
.add(Dimensions.optional("annotatorA"))
.add(Dimensions.required("annotatorB"))
.build();
}
}
@ModelConfiguration
@Import(configurations = {
@Import.Configuration(value = ChildAnnotatorConfig.class, exclude = {@Filter(type = ParameterSpace.class)}),
})
class ParentAnnotatorConfig {
@Named("annotatorC")
public Annotator testAnnotatorC() {
return new AnnotatorC();
}
@Named("parentAnnotatorParameterSpace")
public ParameterSpace configureParameterSpace() {
return new ParameterSpace.Builder()
.add(Dimensions.selectOne("annotatorA", "annotatorB"))
.add(Dimensions.required("annotatorC"))
.build();
}
}
The resulting configuration contains the following components:
- Fixed annotatorC from ParentAnnotatorConfig HPO.
- Either annotatorA or
annotatorBfrom ParentAnnotatorConfig HPO. Child's HPO is ignored.
Advanced Configuration Components
Apart from regular components like Annotators, Feature Extractors and Post-Processors a model may contain fundamental components for advanced configuration. These components may require a deeper understanding of AutoML SDK. Furthermore, these components are not subject to HPO selection.
caution
Any of the following components can be declared only once, otherwise, errors may occur.
Advanced components include:
- HpoConfiguration
- Liblinear Classifier, Vowpal Wabbit Classifier
- PipelineConfiguration
HpoConfiguration
HpoConfiguration is a set of configurable global parameters for HPO. An instance is created via HpoConfiguration.Builder.
Here's an example of HpoConfiguration.
@Named("hpoConfig")
public HpoConfiguration hpoConfig(ConfigurationContext context) {
return new HpoConfiguration.Builder()
.timeLimit(1, TimeUnit.HOURS)
.maxExperimentsWithSameScore(10)
.targetScore(0.7)
.build();
}
For more information, refer to HpoConfiguration documentation.
Liblinear Classifier and Vowpal Wabbit Classifier
LiblinearClassifier and VWClassifier are utility classes to store possible training arguments of Liblinear and Vowpal Wabbit.
@Named("mlConfig")
public LiblinearClassifier mlConfig(){
return new LiblinearClassifier.Builder()
.solver(Solver.L2R_L2LOSS_SVC)
.quietMode()
.build();
}
warning
Only one classifier at a time can be used in a configuration. Otherwise, errors may occur.
For more information, refer to LIBSVM and Vowpal Wabbit documentation.
PipelineConfiguration
PipelineConfiguration is a set of parameters that are used to build a pipeline. The defined parameters remain unchanged across all configurations created for experiments.
The following pipelineConfiguration example sets the NORMALIZE_SCORE and CASE_SENSITIVE parameters to true.
@Named("pipelineConfiguration")
public PipelineConfiguration pipelineConfiguration() {
return new PipelineConfiguration.Builder()
.parameter(GenericPipelineConfiguration.NORMALIZE_SCORE, true)
.parameter(GenericPipelineConfiguration.CASE_SENSITIVE, true)
.build();
}
For more information, refer to PipelineConfiguration and GenericPipelineConfiguration documentation.