[FEATURE REQUEST]: When creating experiments using the Service API it would be nice to be able to pass parameter constraints as objects rather than as strings
CompRhys opened this issue · 4 comments
Motivation
If we want to use a SumConstraint
it is not directly possible with the Service API. Whilst possible to write it out manually as a string it's somewhat awkward. Is there some serialization reason for the constraint to be expressed as a string only?
Describe the solution you'd like to see implemented in Ax.
Locally I can get the behaviour I want by changing https://github.com/facebook/Ax/blob/81bb9de5aed6b47113232422deb5c725095fc398/ax/service/utils/instantiation.py#L733C1-L735C10 to:
typed_parameter_constraints = [
cls.constraint_from_str(c, parameter_map) if isinstance(c, str) else c
for c in parameter_constraints
]
if any(not isinstance(c, ParameterConstraint) for c in typed_parameter_constraints):
raise ValueError("Parameter constraints must be of type ParameterConstraint")
Describe any alternatives you've considered to the above solution.
No response
Is this related to an existing issue in Ax or another repository? If so please include links to those Issues here.
No response
Code of Conduct
- I agree to follow Ax's Code of Conduct
Hi CompRhys, thank you for opening this feature request!
The decision to allow only string specification of parameter constraints for the service API was made intentionally, and is not related to serialization but instead about the API design.
The decision was made so that when calling the Service API, users would not need to interface with the Ax ParameterConstraint objects themselves. Instead, ParameterConstraints would be dealt with behind the scenes only.
Let me know if you have any other questions, thanks!
How about changing/defining the __str__
or __repr__
of the ParameterConstraint
objects such that I could instantiate the object I want and then call str(sum_constraint)
to get the string to give to the service API. It's a bit roundabout but would maybe be a way to avoid potential errors from hardcoding?
Hi, thanks for the suggestion!
I think the risk of errors from hardcoding is relatively low, and I would continue to recommend specifying SumConstraint as a string.
The Service API wiki has an example of using a SumConstrant https://ax.dev/tutorials/gpei_hartmann_service.html#2.-Set-up-experiment
It is done as parameter_constraints=["x1 + x2 <= 2.0"],
Please give this a try for your usecase first, and if there is a specific reason that using strings is not suitable for your usecase, please let me know.
For examples like x1 + x2 <= 2.0
there's no risk to hard coding but that's the trivial example we have various chemical names with easy to overlook things like ring positions in proof reading so makes no sense to write out the string explicitly in config anywhere. The obvious thing to do is write a function but that function essentially has the same interface as the already existing objects hence the issue about why it's necessary to hide the internals by only taking string inputs.
def get_SumConstraint_str(
parameters,
is_upper_bound=True,
bound=1.0,
):
lhs = " + ".join([parameter.name for parameter in parameters])
symbol = "<=" if is_upper_bound else ">="
return f"{lhs} {symbol} {bound}"