Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Deployment Graph] Move Deployment creation outside to build function #26129

Merged
merged 5 commits into from
Jul 5, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
revert ray.remote paths
  • Loading branch information
jiaodong committed Jun 27, 2022
commit 760e86bccd4a6546b40196d07597efb1d91a46ab
26 changes: 6 additions & 20 deletions python/ray/serve/deployment_graph_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from ray.serve.json_serde import DAGNodeEncoder
from ray.serve.handle import RayServeLazySyncHandle
from ray.serve.schema import DeploymentSchema
from ray.serve.config import DeploymentConfig


from ray.dag import (
Expand Down Expand Up @@ -176,25 +175,12 @@ def replace_with_handle(node):
apply_fn=replace_with_handle,
)

if "deployment_schema" in dag_node._bound_other_args_to_resolve:
# ClassNode is created via bind on serve.deployment decorated class
# with no serve specific configs.
deployment_schema: DeploymentSchema = dag_node._bound_other_args_to_resolve[
"deployment_schema"
]
deployment_shell: Deployment = schema_to_deployment(deployment_schema)
else:
# ClassNode is created via bind on ray.remote decorated class with
# no serve specific configs.
deployment_shell: Deployment = Deployment(
dag_node._body,
deployment_name,
DeploymentConfig(),
init_args=replaced_deployment_init_args,
init_kwargs=replaced_deployment_init_kwargs,
ray_actor_options=dag_node.get_options(),
_internal=True,
)
# ClassNode is created via bind on serve.deployment decorated class
# with no serve specific configs.
deployment_schema: DeploymentSchema = dag_node._bound_other_args_to_resolve[
"deployment_schema"
]
deployment_shell: Deployment = schema_to_deployment(deployment_schema)

# Prefer user specified name to override the generated one.
if (
Expand Down
15 changes: 8 additions & 7 deletions python/ray/serve/tests/resources/test_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
from typing import TypeVar

import ray
from ray import serve

RayHandleLike = TypeVar("RayHandleLike")
NESTED_HANDLE_KEY = "nested_handle"


@ray.remote
@serve.deployment
class ClassHello:
def __init__(self):
pass
Expand All @@ -20,7 +21,7 @@ def hello(self):
return "hello"


@ray.remote
@serve.deployment
class Model:
def __init__(self, weight: int, ratio: float = None):
self.weight = weight
Expand All @@ -34,7 +35,7 @@ def __call__(self, request):
return self.ratio * self.weight * input_data


@ray.remote
@serve.deployment
class Combine:
def __init__(
self,
Expand All @@ -51,7 +52,7 @@ def __call__(self, req):
return sum(ray.get([r1_ref, r2_ref]))


@ray.remote
@serve.deployment
class Counter:
def __init__(self, val):
self.val = val
Expand All @@ -63,17 +64,17 @@ def inc(self, inc):
self.val += inc


@ray.remote
@serve.deployment
def fn_hello():
return "hello"


@ray.remote
@serve.deployment
def fn(val, incr=0):
return val + incr


@ray.remote
@serve.deployment
def combine(m1_output, m2_output, kwargs_output=0):
return m1_output + m2_output + kwargs_output

Expand Down
42 changes: 5 additions & 37 deletions python/ray/serve/tests/test_deployment_graph_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,43 +77,11 @@ def test_simple_single_class(serve_instance):
)


def test_single_class_with_valid_ray_options(serve_instance):
with InputNode() as dag_input:
model = Model.options(num_cpus=1, memory=1000).bind(2, ratio=0.3)
ray_dag = model.forward.bind(dag_input)

with _DAGNodeNameGenerator() as node_name_generator:
serve_root_dag = ray_dag.apply_recursive(
lambda node: transform_ray_dag_to_serve_dag(node, node_name_generator)
)
deployments = extract_deployments_from_serve_dag(serve_root_dag)
assert len(deployments) == 1
deployments[0].deploy()
_validate_consistent_python_output(
deployments[0], ray_dag, deployments[0].name, input=1, output=0.6
)

deployment = serve.get_deployment(deployments[0].name)
assert deployment.ray_actor_options.get("num_cpus") == 1
assert deployment.ray_actor_options.get("memory") == 1000
assert deployment.ray_actor_options.get("runtime_env") == {}


def test_single_class_with_invalid_deployment_options(serve_instance):
with InputNode() as dag_input:
model = Model.options(name="my_deployment").bind(2, ratio=0.3)
ray_dag = model.forward.bind(dag_input)

with _DAGNodeNameGenerator() as node_name_generator:
serve_root_dag = ray_dag.apply_recursive(
lambda node: transform_ray_dag_to_serve_dag(node, node_name_generator)
)
deployments = extract_deployments_from_serve_dag(serve_root_dag)
assert len(deployments) == 1
with pytest.raises(
ValueError, match="Specifying 'name' in ray_actor_options is not allowed"
):
deployments[0].deploy()
with pytest.raises(TypeError, match="name must be a string"):
with InputNode() as dag_input:
model = Model.options(name=123).bind(2, ratio=0.3)
_ = model.forward.bind(dag_input)


def test_func_class_with_class_method_dag(serve_instance):
Expand All @@ -127,7 +95,7 @@ def test_func_class_with_class_method_dag(serve_instance):
serve_executor_root_dag = serve_root_dag.apply_recursive(
transform_serve_dag_to_serve_executor_dag
)
assert len(deployments) == 2
assert len(deployments) == 3
for deployment in deployments:
deployment.deploy()

Expand Down