Skip to content

Add autoscaling metrics aggregation function#56871

Merged
zcin merged 7 commits intomasterfrom
SERVE-1102-abrar-agg_p4
Oct 9, 2025
Merged

Add autoscaling metrics aggregation function#56871
zcin merged 7 commits intomasterfrom
SERVE-1102-abrar-agg_p4

Conversation

@abrarsheikh
Copy link
Copy Markdown
Contributor

@abrarsheikh abrarsheikh commented Sep 24, 2025

Add support for min, max and time weighted average as aggregation function over timeseries data

Signed-off-by: abrar <abrar@anyscale.com>
@abrarsheikh abrarsheikh requested a review from a team as a code owner September 24, 2025 02:07
@abrarsheikh abrarsheikh added the go add ONLY when ready to merge, run all tests label Sep 24, 2025
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable feature by allowing the autoscaling metrics aggregation function to be configured. Users can now choose between 'mean', 'max', and 'min' aggregation, providing more flexibility for different use cases. The implementation is solid, with the introduction of a new AggregationFunction enum, an aggregate_timeseries utility, and updates to the AutoscalingConfig. The changes are also well-covered by new and updated tests. I have a few minor suggestions to improve the docstring, memory efficiency, and exception handling.

Signed-off-by: abrar <abrar@anyscale.com>
cursor[bot]

This comment was marked as outdated.

Signed-off-by: abrar <abrar@anyscale.com>
Signed-off-by: abrar <abrar@anyscale.com>
@abrarsheikh abrarsheikh requested a review from a team as a code owner September 24, 2025 04:19
@ray-gardener ray-gardener bot added serve Ray Serve Related Issue core Issues that should be addressed in Ray Core labels Sep 24, 2025
Comment on lines +342 to +355
def aggregate_timeseries(
timeseries: List[TimeStampedValue],
aggregation_function: AggregationFunction,
last_window_s: float = 1.0,
) -> Optional[float]:
"""Aggregate the values in a timeseries using a specified function."""
if aggregation_function == AggregationFunction.MEAN:
return time_weighted_average(timeseries, last_window_s=last_window_s)
elif aggregation_function == AggregationFunction.MAX:
return max(ts.value for ts in timeseries) if timeseries else None
elif aggregation_function == AggregationFunction.MIN:
return min(ts.value for ts in timeseries) if timeseries else None
else:
raise ValueError(f"Invalid aggregation function: {aggregation_function}")
Copy link
Copy Markdown
Contributor

@arcyleung arcyleung Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def aggregate_timeseries(
timeseries: List[TimeStampedValue],
aggregation_function: AggregationFunction,
last_window_s: float = 1.0,
) -> Optional[float]:
"""Aggregate the values in a timeseries using a specified function."""
if aggregation_function == AggregationFunction.MEAN:
return time_weighted_average(timeseries, last_window_s=last_window_s)
elif aggregation_function == AggregationFunction.MAX:
return max(ts.value for ts in timeseries) if timeseries else None
elif aggregation_function == AggregationFunction.MIN:
return min(ts.value for ts in timeseries) if timeseries else None
else:
raise ValueError(f"Invalid aggregation function: {aggregation_function}")
def aggregate_timeseries(
timeseries: List[TimeStampedValue],
aggregation_function: AggregationFunction,
last_window_s: float = 1.0,
) -> Optional[float]:
"""Aggregate the values in a timeseries using a specified function."""
if not timeseries:
return None
if aggregation_function == AggregationFunction.MEAN:
return time_weighted_average(timeseries, last_window_s=last_window_s)
elif aggregation_function == AggregationFunction.MAX:
# maybe cleaner to refactor to windowed min/max function, the same way _get_datapoints is doing it
window_start = datetime.now() - last_window_s
return max(ts.value for ts in timeseries if ts.timestamp > window_start )
elif aggregation_function == AggregationFunction.MIN:
window_start = datetime.now() - last_window_s
return min(ts.value for ts in timeseries if ts.timestamp > window_start )
else:
raise ValueError(f"Invalid aggregation function: {aggregation_function}")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont understand this suggestion can you elaborate what this does

window_start = datetime.now() - last_window_s
        return max(ts.value for ts in timeseries if ts.timestamp > window_start )

Copy link
Copy Markdown
Contributor

@landscapepainter landscapepainter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! By the way, do we need to add any tests that check how the autoscaling behavior changes based on used aggregation_function value? I assume the number of scaled replicas can change based on aggregation_function either being min, max, or mean.

def aggregate_timeseries(
timeseries: List[TimeStampedValue],
aggregation_function: AggregationFunction,
last_window_s: float = 1.0,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we set the default value of last_window_s to be 1.0? Was wondering the implication of it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in reality we are not depending on default value. The value basically decided how much to weight the last data point. 1 is safe default.

Signed-off-by: abrar <abrar@anyscale.com>
Copy link
Copy Markdown
Contributor

@akyang-anyscale akyang-anyscale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we support percentiles too?

@abrarsheikh
Copy link
Copy Markdown
Contributor Author

Should we support percentiles too?

ok to leave it for the future?

@akyang-anyscale
Copy link
Copy Markdown
Contributor

Should we support percentiles too?

ok to leave it for the future?

yeah that's fine

@zcin zcin merged commit f07db71 into master Oct 9, 2025
6 checks passed
@zcin zcin deleted the SERVE-1102-abrar-agg_p4 branch October 9, 2025 23:21
pavitrabhalla pushed a commit to superserve-ai/ray that referenced this pull request Oct 10, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
Signed-off-by: Pavitra Bhalla <pavitra@rayai.com>
joshkodi pushed a commit to joshkodi/ray that referenced this pull request Oct 13, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
Signed-off-by: Josh Kodi <joshkodi@gmail.com>
ArturNiederfahrenhorst pushed a commit to ArturNiederfahrenhorst/ray that referenced this pull request Oct 13, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
harshit-anyscale pushed a commit that referenced this pull request Oct 15, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
justinyeh1995 pushed a commit to justinyeh1995/ray that referenced this pull request Oct 20, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
xinyuangui2 pushed a commit to xinyuangui2/ray that referenced this pull request Oct 22, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
Signed-off-by: xgui <xgui@anyscale.com>
elliot-barn pushed a commit that referenced this pull request Oct 23, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
Signed-off-by: elliot-barn <elliot.barnwell@anyscale.com>
nrghosh added a commit to nrghosh/ray that referenced this pull request Nov 10, 2025
PR ray-project#56871 introduced the AggregationFunction enum for autoscaling
metrics aggregation. However, the serve build command's YAML serialization
path was not updated to handle Enum objects, causing RepresenterError when
serializing AggregationFunction enum values in autoscaling config.

This fix adds a helper function that recursively converts Enum objects
to their string values before YAML dump, ensuring proper serialization
of all enum types in the configuration.

Fixes ray-project#58485

Signed-off-by: Nikhil Ghosh <nikhil@anyscale.com>
landscapepainter pushed a commit to landscapepainter/ray that referenced this pull request Nov 17, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
Aydin-ab pushed a commit to Aydin-ab/ray-aydin that referenced this pull request Nov 19, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
Signed-off-by: Aydin Abiar <aydin@anyscale.com>
abrarsheikh pushed a commit that referenced this pull request Nov 19, 2025
…on enum (#58509)

PR #56871 introduced the AggregationFunction enum for autoscaling
metrics aggregation. However, the serve build command's YAML
serialization path was not updated to handle Enum objects, causing
RepresenterError when serializing AggregationFunction enum values in
autoscaling config.

ex. `yaml.representer.RepresenterError: ('cannot represent an object',
<AggregationFunction.MEAN: 'mean'>)`

This fix adds 
1. a helper function that recursively converts Enum objects to their
string values before YAML dump, ensuring proper serialization of all
enum types in the configuration.
2. a test that
(a) Creates a temporary output YAML file
(b) Reads the config from that file
(c) Verifies that AggregationFunction.MEAN is correctly serialized as
"mean" (string)

Fixes #58485

---------

Signed-off-by: Nikhil Ghosh <nikhil@anyscale.com>
Signed-off-by: Nikhil G <nrghosh@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
400Ping pushed a commit to 400Ping/ray that referenced this pull request Nov 21, 2025
…on enum (ray-project#58509)

PR ray-project#56871 introduced the AggregationFunction enum for autoscaling
metrics aggregation. However, the serve build command's YAML
serialization path was not updated to handle Enum objects, causing
RepresenterError when serializing AggregationFunction enum values in
autoscaling config.

ex. `yaml.representer.RepresenterError: ('cannot represent an object',
<AggregationFunction.MEAN: 'mean'>)`

This fix adds 
1. a helper function that recursively converts Enum objects to their
string values before YAML dump, ensuring proper serialization of all
enum types in the configuration.
2. a test that
(a) Creates a temporary output YAML file
(b) Reads the config from that file
(c) Verifies that AggregationFunction.MEAN is correctly serialized as
"mean" (string)

Fixes ray-project#58485

---------

Signed-off-by: Nikhil Ghosh <nikhil@anyscale.com>
Signed-off-by: Nikhil G <nrghosh@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
ykdojo pushed a commit to ykdojo/ray that referenced this pull request Nov 27, 2025
…on enum (ray-project#58509)

PR ray-project#56871 introduced the AggregationFunction enum for autoscaling
metrics aggregation. However, the serve build command's YAML
serialization path was not updated to handle Enum objects, causing
RepresenterError when serializing AggregationFunction enum values in
autoscaling config.

ex. `yaml.representer.RepresenterError: ('cannot represent an object',
<AggregationFunction.MEAN: 'mean'>)`

This fix adds
1. a helper function that recursively converts Enum objects to their
string values before YAML dump, ensuring proper serialization of all
enum types in the configuration.
2. a test that
(a) Creates a temporary output YAML file
(b) Reads the config from that file
(c) Verifies that AggregationFunction.MEAN is correctly serialized as
"mean" (string)

Fixes ray-project#58485

---------

Signed-off-by: Nikhil Ghosh <nikhil@anyscale.com>
Signed-off-by: Nikhil G <nrghosh@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: YK <1811651+ykdojo@users.noreply.github.com>
SheldonTsen pushed a commit to SheldonTsen/ray that referenced this pull request Dec 1, 2025
…on enum (ray-project#58509)

PR ray-project#56871 introduced the AggregationFunction enum for autoscaling
metrics aggregation. However, the serve build command's YAML
serialization path was not updated to handle Enum objects, causing
RepresenterError when serializing AggregationFunction enum values in
autoscaling config.

ex. `yaml.representer.RepresenterError: ('cannot represent an object',
<AggregationFunction.MEAN: 'mean'>)`

This fix adds 
1. a helper function that recursively converts Enum objects to their
string values before YAML dump, ensuring proper serialization of all
enum types in the configuration.
2. a test that
(a) Creates a temporary output YAML file
(b) Reads the config from that file
(c) Verifies that AggregationFunction.MEAN is correctly serialized as
"mean" (string)

Fixes ray-project#58485

---------

Signed-off-by: Nikhil Ghosh <nikhil@anyscale.com>
Signed-off-by: Nikhil G <nrghosh@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Future-Outlier pushed a commit to Future-Outlier/ray that referenced this pull request Dec 7, 2025
Add support for min, max and time weighted average as aggregation
function over timeseries data

---------

Signed-off-by: abrar <abrar@anyscale.com>
Signed-off-by: Future-Outlier <eric901201@gmail.com>
peterxcli pushed a commit to peterxcli/ray that referenced this pull request Feb 25, 2026
…on enum (ray-project#58509)

PR ray-project#56871 introduced the AggregationFunction enum for autoscaling
metrics aggregation. However, the serve build command's YAML
serialization path was not updated to handle Enum objects, causing
RepresenterError when serializing AggregationFunction enum values in
autoscaling config.

ex. `yaml.representer.RepresenterError: ('cannot represent an object',
<AggregationFunction.MEAN: 'mean'>)`

This fix adds
1. a helper function that recursively converts Enum objects to their
string values before YAML dump, ensuring proper serialization of all
enum types in the configuration.
2. a test that
(a) Creates a temporary output YAML file
(b) Reads the config from that file
(c) Verifies that AggregationFunction.MEAN is correctly serialized as
"mean" (string)

Fixes ray-project#58485

---------

Signed-off-by: Nikhil Ghosh <nikhil@anyscale.com>
Signed-off-by: Nikhil G <nrghosh@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: peterxcli <peterxcli@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Issues that should be addressed in Ray Core go add ONLY when ready to merge, run all tests serve Ray Serve Related Issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants