Skip to content

Commit a72d268

Browse files
authored
Avoid using the same port number for autoscaler works (#15966)
* dont hardcode port in python server * add another chglog
1 parent 346e936 commit a72d268

File tree

4 files changed

+17
-17
lines changed

4 files changed

+17
-17
lines changed

examples/app_server_with_auto_scaler/app.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# ! pip install torch torchvision
12
from typing import Any, List
23

34
import torch
@@ -22,10 +23,10 @@ class BatchResponse(BaseModel):
2223
class PyTorchServer(L.app.components.PythonServer):
2324
def __init__(self, *args, **kwargs):
2425
super().__init__(
25-
port=L.app.utilities.network.find_free_network_port(),
2626
input_type=BatchRequestModel,
2727
output_type=BatchResponse,
28-
cloud_compute=L.CloudCompute("gpu"),
28+
*args,
29+
**kwargs,
2930
)
3031

3132
def setup(self):
@@ -57,30 +58,32 @@ def scale(self, replicas: int, metrics: dict) -> int:
5758
"""The default scaling logic that users can override."""
5859
# scale out if the number of pending requests exceeds max batch size.
5960
max_requests_per_work = self.max_batch_size
60-
pending_requests_per_running_or_pending_work = metrics["pending_requests"] / (
61-
replicas + metrics["pending_works"]
62-
)
63-
if pending_requests_per_running_or_pending_work >= max_requests_per_work:
61+
pending_requests_per_work = metrics["pending_requests"] / (replicas + metrics["pending_works"])
62+
if pending_requests_per_work >= max_requests_per_work:
6463
return replicas + 1
6564

6665
# scale in if the number of pending requests is below 25% of max_requests_per_work
6766
min_requests_per_work = max_requests_per_work * 0.25
68-
pending_requests_per_running_work = metrics["pending_requests"] / replicas
69-
if pending_requests_per_running_work < min_requests_per_work:
67+
pending_requests_per_work = metrics["pending_requests"] / replicas
68+
if pending_requests_per_work < min_requests_per_work:
7069
return replicas - 1
7170

7271
return replicas
7372

7473

7574
app = L.LightningApp(
7675
MyAutoScaler(
76+
# work class and args
7777
PyTorchServer,
78-
min_replicas=2,
78+
cloud_compute=L.CloudCompute("gpu"),
79+
# autoscaler specific args
80+
min_replicas=1,
7981
max_replicas=4,
8082
autoscale_interval=10,
8183
endpoint="predict",
8284
input_type=RequestModel,
8385
output_type=Any,
8486
timeout_batching=1,
87+
max_batch_size=8,
8588
)
8689
)

src/lightning_app/CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
1313

1414
### Changed
1515

16-
-
16+
- Changed the default port of `PythonServer` from `7777` to a free port at runtime ([#15966](https://github.com/Lightning-AI/lightning/pull/15966))
1717

1818
- Remove the `AutoScaler` dependency `aiohttp` from the base requirements ([#15971](https://github.com/Lightning-AI/lightning/pull/15971))
1919

@@ -30,7 +30,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
3030

3131
### Fixed
3232

33-
-
33+
- Fixed `AutoScaler` failing due to port collision across works ([#15966](https://github.com/Lightning-AI/lightning/pull/15966))
3434

3535

3636
## [1.8.4] - 2022-12-08

src/lightning_app/components/auto_scaler.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,8 @@ def workers(self) -> List[LightningWork]:
450450
def create_work(self) -> LightningWork:
451451
"""Replicates a LightningWork instance with args and kwargs provided via ``__init__``."""
452452
# TODO: Remove `start_with_flow=False` for faster initialization on the cloud
453-
return self._work_cls(*self._work_args, **self._work_kwargs, start_with_flow=False)
453+
self._work_kwargs.update(dict(start_with_flow=False))
454+
return self._work_cls(*self._work_args, **self._work_kwargs)
454455

455456
def add_work(self, work) -> str:
456457
"""Adds a new LightningWork instance.

src/lightning_app/components/serve/python_server.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,13 @@ class PythonServer(LightningWork, abc.ABC):
7575
@requires(["torch", "lightning_api_access"])
7676
def __init__( # type: ignore
7777
self,
78-
host: str = "127.0.0.1",
79-
port: int = 7777,
8078
input_type: type = _DefaultInputData,
8179
output_type: type = _DefaultOutputData,
8280
**kwargs,
8381
):
8482
"""The PythonServer Class enables to easily get your machine learning server up and running.
8583
8684
Arguments:
87-
host: Address to be used for running the server.
88-
port: Port to be used to running the server.
8985
input_type: Optional `input_type` to be provided. This needs to be a pydantic BaseModel class.
9086
The default data type is good enough for the basic usecases and it expects the data
9187
to be a json object that has one key called `payload`
@@ -129,7 +125,7 @@ def predict(self, request):
129125
...
130126
>>> app = LightningApp(SimpleServer())
131127
"""
132-
super().__init__(parallel=True, host=host, port=port, **kwargs)
128+
super().__init__(parallel=True, **kwargs)
133129
if not issubclass(input_type, BaseModel):
134130
raise TypeError("input_type must be a pydantic BaseModel class")
135131
if not issubclass(output_type, BaseModel):

0 commit comments

Comments
 (0)