discoveryspace
A discoveryspace describes a set of entities along with the experiments to apply to them. It has three parts:
- an
entityspace: theentitiesyou want to measure - a
measurementspace: the experiments used to measure them - a
samplestore: where the result of measurements onentitiesare stored
Note
For more details see concept of a Discovery Space
Quickstart¶
The quickest route to a valid discoveryspace is to start from the experiments you want to run. First, list the available experiments:
ado get experiments
┌───────┬──────────────────┬─────────────────────────────────────┬─────────┐
│ INDEX │ ACTUATOR ID │ EXPERIMENT ID │ VERSION │
├───────┼──────────────────┼─────────────────────────────────────┼─────────┤
│ 0 │ SFTTrainer │ finetune_full_benchmark-v1.0.0 │ None │
│ ... │ ... │ ... │ ... │
│ 11 │ custom_experi... │ nevergrad_opt_3d_test_func │ 1.0.0 │
│ ... │ ... │ ... │ ... │
│ 30 │ vllm_performance │ vllm-bench-endpoint │ 1.0.0 │
└───────┴──────────────────┴─────────────────────────────────────┴─────────┘
Then generate a discoveryspace YAML from the experiment you picked:
ado template space --from-experiment vllm-bench-endpoint --output-file space.yaml
See ado template for more options.
The generated YAML contains an entityspace holding every constitutive property the experiment requires (required input parameters), each with the full domain the experiment supports, and a measurementspace referencing the experiment.
Optional Properties
ado template does not add optional input parameters of the experiment to the entity space. You can do this manually as described in parameterizing experiments.
An example YAML file is:
entitySpace:
- identifier: request_rate
metadata:
description: The number of requests to send per second
propertyDomain:
domainRange:
- -1
- 1000
interval: 1
probabilityFunction:
identifier: uniform
propertyType: CONSTITUTIVE_PROPERTY_TYPE
- identifier: model
propertyDomain:
probabilityFunction:
identifier: uniform
values:
- meta-llama/Llama-3.1-8B-Instruct
- ibm-granite/granite-3.3-8b-instruct
- openai/gpt-oss-20b
propertyType: CONSTITUTIVE_PROPERTY_TYPE
- identifier: endpoint
propertyDomain:
probabilityFunction:
identifier: uniform
values:
- http://localhost:8000
propertyType: CONSTITUTIVE_PROPERTY_TYPE
experiments:
- actuatorIdentifier: vllm_performance
experimentIdentifier: vllm-bench-endpoint
experimentVersion: 1.0.0
metadata: {}
sampleStoreIdentifier: default
You can edit the YAML file e.g. narrow each propertyDomain to the values of interest. Validate the result at any point with:
ado create space -f space.yaml --dry-run
Then create the space:
ado create space -f space.yaml
Note
ado template outputs all the fields that have values including defaults and per-property metadata. These can be safely removed to create a more streamlined YAML. See defining property domains for more.
Structure of the discoveryspace YAML configuration¶
A discoveryspace configuration has four fields. An example is given below.
sampleStoreIdentifier: source_abc123 # OPTIONAL: The id of the sample store to use
entitySpace: # A list of constitutive properties
- identifier: my_property1 # The id of the first dimension/constitutive property of the space
propertyDomain: # Defines the values my_property1 can take
... # Property domain fields
- identifier: my_property2
propertyDomain:
...
experiments: # A list of experiments. The measurementspace of this discovery space
- actuatorIdentifier: someactuator # The id of the actuator that contains the experiment
experimentIdentifier: experiment_one # The id of the experiment to execute
experimentVersion: 1.0.0 # The version of the experiment. If omitted it means the version is "None"
metadata:
description: "This is an example discovery space"
name: exampleSpace
entitySpace: the dimensions of the space, one entry per constitutive property. See defining the entityspace.experiments: the experiments that make up themeasurementspace. See defining the measurementspace.sampleStoreIdentifier: thesamplestoreholding the data. Defaults todefaultif not given. See choosing the samplestore.metadata: aname, adescriptionand anylabelsyou want to attach to the space.
If there are errors or inconsistencies in the space definition the ado create space command will output an error.
Defining the entityspace¶
The entityspace is a list of constitutive properties, each with the domain of values it takes in this space. The set of entities in the space is the cartesian product of the domains of the constitutive properties in the entity space.
Defining property domains¶
The YAML for the constitutive properties in the entityspace has the following structure
identifier: model_name # The name of the property
propertyDomain: # The domain describes the values the property can take
variableType:# The type of the variable: CATEGORICAL_VARIABLE_TYPE, DISCRETE_VARIABLE_TYPE, CONTINUOUS_VARIABLE_TYPE or UNKNOWN_VARIABLE_TYPE
# The type defines what values the next fields can take.
values: # If the variable is CATEGORICAL_VARIABLE_TYPE this is a list of the categories
- # If the variable is DISCRETE_VARIABLE_TYPE this can be a list of discrete float or integer values it can take
domainRange: # If the variables is DISCRETE_VARIABLE_TYPE or CONTINUOUS_VARIABLE_TYPE this is the min inclusive, max exclusive range it can take
# If the variable is DISCRETE_VARIABLE_TYPE and values are given this must be compatible with the values
interval: # If the variable is DISCRETE_VARIABLE_TYPE this is the interval between the values.
# If given domainRange is required and values cannot be given
probabilityFunction: # Optional. The sampling distribution, for example uniform
As long as all constitutive properties are not "UNKNOWN_VARIABLE_TYPE" there is sufficient information to sample new entities from the entityspace description.
For more on property types, domains and probability functions see properties and domains.
Writing Short Constitutive Properties
You can often write the constitutive properties in a shorter form than output by ado template which is verbose by default.
- In many cases you do not need to specify the
variableTypeas it can be inferred. - The field
probabilityFunctionis not currently used so can be safely omitted. - The
metadatafields which are output byado templateare not required. The main reason to havemetadatais if you want to record why a certain domain was chosen.
Ensuring the entityspace and measurementspace are compatible¶
Experiments take entities as inputs and those entities must have values for various properties in order for the experiments to be able to process them. This means the domains of the properties in the entityspace must be compatible with the experiments - if not entities could be sampled that experiments in the measurementspace cannot measure.
For example, to see the input requirements of the experiment finetune_full_benchmark-v1.0.0 you can run:
ado describe experiment SFTTrainer.finetune_full_benchmark-v1.0.0
you will get output like
Identifier: SFTTrainer.finetune_full_benchmark-v1.0.0
Description: Measures the performance of full-finetuning a model for a given (GPU model, number GPUS, batch_size,
model_max_length, number nodes) combination.
Required Inputs:
Constitutive Properties:
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: model_name
Description: The huggingface name or path to the model
Domain:
Type: CATEGORICAL_VARIABLE_TYPE
Values: [
'allam-1-13b',
'granite-3-8b',
'llama3-8b',
... 37 more values ...
]
───────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: model_max_length
Description: The maximum context size. Dataset entries with more tokens they are truncated. Entri
are padded
Domain:
Type: DISCRETE_VARIABLE_TYPE
Interval: 1
Range: [1, 131073]
───────────────────────────────────────────────────────────────────────────────────────────────────
... 2 more required inputs ...
Optional Inputs and Default Values:
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: max_steps
Description: The number of optimization steps to perform. Set to -1 to respect num_train_epochs i
Domain:
Type: DISCRETE_VARIABLE_TYPE
Interval: 1
Range: [-1, 10001]
Default value: -1
───────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: torch_dtype
Description: The torch datatype to use
Domain:
Type: CATEGORICAL_VARIABLE_TYPE
Values: ['bfloat16', 'float16', 'float32']
Default value: 'bfloat16'
───────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: gpu_model
Description: The GPU model to use
Domain:
Type: CATEGORICAL_VARIABLE_TYPE
Values: [
None,
'NVIDIA-A100-SXM4-80GB',
'NVIDIA-H100-80GB-HBM3',
... 5 more values ...
]
Default value: None
───────────────────────────────────────────────────────────────────────────────────────────────────
... 22 more optional inputs ...
Outputs:
─────────────────────────────────────────────────────────────────────────────────────────────────────────
finetune_full_benchmark-v1.0.0-is_valid
finetune_full_benchmark-v1.0.0-dataset_tokens_per_second_per_gpu
finetune_full_benchmark-v1.0.0-train_runtime
... 20 more outputs ...
─────────────────────────────────────────────────────────────────────────────────────────────────────────
You can see the required inputs under the section Required Inputs and the optional inputs under Optional Inputs and Default Values. Parameterizing experiments explains how to use optional properties.
Defining the measurementspace¶
The experiments field lists the experiments that will be applied to the entities in the space. Each entry references an experiment provided by an actuator.
Referencing an experiment¶
An experiment reference has the following fields:
experiments:
- actuatorIdentifier: vllm_performance # The ACTUATOR ID column of "ado get experiments"
experimentIdentifier: vllm-bench-endpoint # The EXPERIMENT ID column of "ado get experiments"
experimentVersion: 1.0.0 # The VERSION column of "ado get experiments". Required if the referenced experiment has a version
parameterization: # Optional. Values to set for the experiment's optional inputs
- value: 30
property:
identifier: temperature
You can list as many experiments as you want. Each one contributes its target properties to the space, and each one is applied to every entity sampled by an explore operation.
Setting the experiment version¶
The experimentVersion field is for the version of the experiment, a MAJOR.MINOR.PATCH SemVer string. Set it to the value in the VERSION column of ado get experiments, which is also shown by ado get experiment $ID.
A reference resolves to the experiment whose version matches exactly, so omitting experimentVersion checks for an experiment whose version is None. Hence, experiments that declare a version require the field.
If you omit experimentVersion for an experiment that has a version you will get this error:
ERROR: Unknown experiment in configuration. This can be due to an actuator not being installed or if the referenced experiment is external: The vllm_performance actuator was found but a match to vllm_performance.vllm-bench-endpoint was not found using mode fully_qualified_version. Available versions in catalog: 1.0.0.
While if you supply a version that does not match the catalog you get:
ERROR: Experiment version mismatch in configuration: Algorithm version mismatch for experiment 'vllm-bench-endpoint' in catalog 'vllm_performance'. Reference requires version 'vllm-bench-endpoint@1.0.1' but catalog provides 'vllm-bench-endpoint@1.0.0'.
Experiment versions and memoization¶
Explore operations can be configured to memoize measurements: an entity that has already been measured by an experiment is not measured again, the existing results are reused.
The key used to identify if a requested experiment has already been applied to an entity is the experiment's major version parameterized identifier. This is made up of:
- the actuator identifier
- the experiment identifier
- the major version
- the parameterization.
So the results of vllm-bench-endpoint at version 1.0.0 are stored under the key vllm-bench-endpoint@v1, and the observed property for its request_throughput target property under this key is vllm-bench-endpoint@v1-request_throughput.
This means:
- Bumping the minor or patch version of an experiment does not affect results reuse, as
1.0.0and1.2.0share the same major version@v1. - Bumping the major version creates a new key for storing experiment results.
- Adding a version to a previously unversioned experiment creates a new key for storing experiment results.
- Each unique parameterization of an experiment has its own key
For the rules experiment authors follow when choosing a version see declaring an experiment version.
Parameterizing experiments¶
If an experiment has optional input properties you can define equivalent properties in the entity space. If you don't, the default value for the property will be used.
In addition, you can define your own custom parameterization of the experiment. For example, take the following experiment:
Identifier: robotic_lab.peptide_mineralization@1.0.0
Version: 1.0.0
Description: Measures adsorption of peptide lanthanide combinations
Required Inputs:
Constitutive Properties:
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: peptide_identifier
Description: The identifier of the peptide to use
Domain:
Type: CATEGORICAL_VARIABLE_TYPE
Values: ['test_peptide', 'test_peptide_new']
───────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: peptide_concentration
Description: The concentration of the peptide
Domain:
Type: DISCRETE_VARIABLE_TYPE
Values: [0.1, 0.4, 0.6, 0.8]
───────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: lanthanide_concentration
Description: The concentration of lanthanide
Domain:
Type: DISCRETE_VARIABLE_TYPE
Values: [0.1, 0.4, 0.6, 0.8]
───────────────────────────────────────────────────────────────────────────────────────────────────
Optional Inputs and Default Values:
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: temperature
Description: The temperature at which to execute the experiment
Domain:
Type: CONTINUOUS_VARIABLE_TYPE
Range: [0, 100]
Default value: 23
───────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: replicas
Description: How many replicas to average the adsorption_timeseries over
Domain:
Type: DISCRETE_VARIABLE_TYPE
Interval: 1
Range: [1, 4]
Default value: 1
───────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────────────────────────
Identifier: robot_identifier
Description: The identifier of the robot to use to perform the experiment
Domain:
Type: CATEGORICAL_VARIABLE_TYPE
Values: ['harry', 'hermione']
Default value: 'hermione'
───────────────────────────────────────────────────────────────────────────────────────────────────
Outputs:
─────────────────────────────────────────────────────────────────────────────────────────────────────────
peptide_mineralization@v1-adsorption_timeseries
peptide_mineralization@v1-adsorption_plateau_value
─────────────────────────────────────────────────────────────────────────────────────────────────────────
It has three optional properties: temperature, robot_identifier and replicas.
Note
Each parameterization defines a distinct experiment for the purposes of data reuse.
Example: Customizing an experiment¶
The default temperature is 23 degrees C, however imagine you want to run this experiment at 30 degrees C. You can define a discoveryspace like:
sampleStoreIdentifier: c04713
entitySpace:
- identifier: peptide_identifier
propertyDomain:
values: ["test_peptide"]
- identifier: peptide_concentration
propertyDomain:
values: [0.1, 0.4, 0.6, 0.8]
- identifier: lanthanide_concentration
propertyDomain:
values: [0.1, 0.4, 0.6, 0.8]
experiments:
- actuatorIdentifier: robotic_lab
experimentIdentifier: peptide_mineralization
experimentVersion: 1.0.0
parameterization:
- value: 30
property:
identifier: "temperature"
metadata:
description: Space for exploring the absorption properties of test_peptide
Example: Multiple customizations of the same experiment¶
You can add the multiple custom parameterizations of the same experiment e.g. one experiment that runs at 30 degrees C and another at 25 degrees.
sampleStoreIdentifier: c04713 # PUT REAL ID HERE
entitySpace:
- identifier: peptide_identifier
propertyDomain:
values: ["test_peptide"]
- identifier: peptide_concentration
propertyDomain:
values: [0.1, 0.4, 0.6, 0.8]
- identifier: lanthanide_concentration
propertyDomain:
values: [0.1, 0.4, 0.6, 0.8]
experiments:
- actuatorIdentifier: robotic_lab
experimentIdentifier: peptide_mineralization
experimentVersion: 1.0.0
parameterization:
- value: 30
property:
identifier: "temperature"
- actuatorIdentifier: robotic_lab
experimentIdentifier: peptide_mineralization
experimentVersion: 1.0.0
parameterization:
- value: 25
property:
identifier: "temperature"
metadata:
description: Space for exploring the absorption properties of test_peptide
Example: Using an optional property in the entityspace¶
Finally, if you want to scan a range of temperatures in your discovery space, the best would be to move this parameter into the entityspace:
sampleStoreIdentifier: c04713 # PUT REAL ID HERE
entitySpace:
- identifier: peptide_identifier
propertyDomain:
values: ["test_peptide"]
- identifier: peptide_concentration
propertyDomain:
values: [0.1, 0.4, 0.6, 0.8]
- identifier: lanthanide_concentration
propertyDomain:
values: [0.1, 0.4, 0.6, 0.8]
- identifier: temperature
propertyDomain:
domainRange: [20, 30]
interval: 1
experiments:
- actuatorIdentifier: robotic_lab
experimentIdentifier: peptide_mineralization
experimentVersion: 1.0.0
metadata:
description: Space for exploring the absorption properties of test_peptide
Here entities will be generated with a temperatures property that ranges from 20 to 30 degrees. When the experiment is run on the entity it will retrieve the value of the temperature from it rather than the Experiment.
Our toy example actuator contains the above examples. You can use it to experiment and explore custom parameterization.
Choosing the samplestore¶
Every discoveryspace stores its entities and measurement results in a samplestore. The sampleStoreIdentifier field holds its identifier and defaults to default, the per-project store which ado creates the first time it is used.
To see the existing stores run:
ado get samplestores
You can set the store from the command line instead of editing the YAML:
--use-default-sample-storeuses the project'sdefaultstore--new-sample-storecreates and uses a new, empty store--use-latest samplestoreuses the most recently created store--with store=$IDuses the store$ID--with store=FILE.yamlcreates the store described byFILE.yamland uses it. This is how you copy data into a new store at the same time as creating a space.--set sampleStoreIdentifier=$IDoverrides the field directly
--with, --new-sample-store and --use-latest samplestore take precedence over --use-default-sample-store, --set and the value in the YAML. See the samplestores documentation for more details on the store types and on the default store.
discoveryspaces and shared samplestores¶
Multiple discoveryspace resources can use the same samplestore resource. In this case you can think of the discoveryspace as a "view" on the samplestore contents, filtering just the entities that match its description.
To be more rigorous, given a discoveryspace there are two methods for applying this filter:
- Filter
entitiesthat were placed in thesamplestorevia an operation on thediscoveryspace - Filter
entitiesin thesamplestorethat match thediscoveryspace
To understand the difference in these two methods imagine two overlapping discoveryspaces, A and B, that use the same samplestore. If someone uses method (1) on discoveryspace A, they will only see the entities placed there by operations on discoveryspace A. However, if someone uses method (2) on discoveryspace A, they will see entities placed there via operations on both discoveryspace A and space B.
Shared samples stores also allow data to be reused across discoveryspaces, potentially accelerating explore operations. See the shared sample store documentation for further details.
Running operations on a discoveryspace¶
A discoveryspace defines a set of entities, and a set of experiments that can be applied to them. It also contains the results for the entities that have been measured so far - the measured entities.
There are then two high-level types of operations you can apply to a space
- explore operations, such as a random walk or a Bayesian optimization, sample
entitiesfrom theentityspace, apply the experiments in themeasurementspaceto them, and store the results in thesamplestore. This is how you add measured entities to thediscoveryspace. - non-explore operations process the measured entities in a space. For example calculating statistics, or comparing two spaces. These operations are called different names depending on what they do e.g. characterize, modify, compare.
See the operation documentation for how to configure and start one, and working with operators for the available operators.
Accessing measurement data¶
To see the measurement data collected by explore operations on a space use
ado show measurements space --use-latest
By default, this will output the entities and their measurements as a table. There are various option flags that control this behaviour e.g. output to a CSV file.
As described in shared samplestores there are two lists of entities this could show. The command above uses filter (1) - entities that were placed in the samplestore via an operation on the discoveryspace.
If you want to use filter (2) - entities in the samplestore that match the discoveryspace - use:
ado show measurements space --use-latest --include matching
Note
In both cases measurements on the entity will be filtered to be only those defined by the measurementspace of the discoveryspace
Two other options list the entities of a finite space that have no data yet
--include unmeasuredlistsentitiesdefined by thediscoveryspacewith no measurements from operations on it--include missinglistsentitiesdefined by thediscoveryspacewith no measurements in thesamplestore
Target vs observed property formats¶
Note
For the conceptual distinction between target and observed properties see Target and Observed Properties.
There are two formats the measurements can be output controlled by the --property-format option to show measurements
The observed format outputs one row per entity. The columns are constitutive property names and the observed property names i.e. they include both the experiment id and target property id. This ensures that with one row per entity there are no clashing column names.
The target format outputs one row per entity+experiment combination: so if there are two experiments in the Measurement Space then there will be two rows per entity. In this format the columns are constitutive property names and target property names.
Note
With property-format=target if the measurement space contains multiple experiments measuring different target properties, this will result in many empty fields in the table. This is because the column for a given target of one experiment will not have values in the rows corresponding to other experiments.
Accessing measurement data programmatically¶
Assuming you have your context in a file "my_context.yaml"
import yaml
from ado.metastore.project import ProjectContext
from ado.core.discoveryspace.space import DiscoverySpace
with open("my_context.yaml") as f:
c = ProjectContext.model_validate(yaml.safe_load(f))
space = DiscoverySpace.from_stored_configuration(
project_context=c, space_identifier="space_abc123"
)
# Get the sampled and measured entities. Returns a pandas DataFrame
table = space.measuredEntitiesTable()
# Get the matching. Returns a pandas DataFrame
table = space.matchingEntitiesTable()
Inspecting a discoveryspace¶
To list the spaces in your project:
ado get spaces
┌───────┬──────────────────────┬─────────────────────────────────────┬─────────┐
│ INDEX │ IDENTIFIER │ NAME │ AGE │
├───────┼──────────────────────┼─────────────────────────────────────┼─────────┤
│ 0 │ space-3b85e4-f60613 │ ml_multicloud_basic │ 371d7h │
│ 1 │ space-047b6a-f60613 │ rosenbrock_3d │ 367d7h │
│ 2 │ space-ab21b4-f60613 │ test_vllm_performance_space │ 366d0h │
└───────┴──────────────────────┴─────────────────────────────────────┴─────────┘
Add --details to include the DESCRIPTION and LABELS of each space. --filter and --label narrow the list, and --related-to restricts it to spaces related to another resource.
To retrieve the stored configuration of a space:
ado get space space-047b6a-f60613 -o yaml
ado show stats space reports what the space contains, counting the results of the operations run on it:
ado show stats space space-047b6a-f60613 -o yaml
space-047b6a-f60613:
AGE: 367d7h
ENTITIES_WITH_ALL_MEASUREMENTS: 28
ENTITIES_WITH_PARTIAL_MEASUREMENTS: 12
EXPERIMENTS: 1
EXPLORE_OPERATIONS: 1
MATCHING_ENTITIES: 148
MATCHING_ENTITIES_WITH_ALL_MEASUREMENTS: 148
MATCHING_WITH_MEASUREMENTS: 148
MEASURED_ENTITIES: 40
NAME: rosenbrock_3d
OPERATIONS: 1
SIZE_OF_ENTITY_SPACE: null
UNMEASURED_ENTITIES: .inf
The MEASURED_ENTITIES counts come from operations on this space, while the MATCHING_* counts cover every entity in the samplestore that matches the space - the two filters described in shared samplestores. SIZE_OF_ENTITY_SPACE and UNMEASURED_ENTITIES have values for finite spaces.
For a human-readable view of the entityspace, the measurementspace and the samplestore a space uses:
ado describe space space-047b6a-f60613
An example of this output is in the Discovery Space concepts page.
See the ado CLI reference for the full set of flags these commands accept.
Differences between input configuration YAML and stored configuration YAML¶
After creating a discoveryspace, if you ado get its YAML you will notice that the information output is different from the one you provided in input. This is because the list of experiment references set in the YAML is expanded into the full experiment definitions and stored with the discoveryspace.