Repository navigation
feat(serve): Enhance multi-node deployment and worker configuration #457
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
Changes from 17 commits
84015cf
67d0a34
5bf0bba
360a28b
a6c3d43
64f2e1e
391c74c
34b6f5b
e347d6e
223dfdb
4beb782
792e732
6a7b9fe
a7eab00
00025b6
6bba5ed
eb88b6f
8429c1b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -127,7 +127,7 @@ def create_dependency_watcher( | |
| ) -> tuple[Watcher, CircusSocket, str]: | ||
| from bentoml.serving import create_watcher | ||
|
|
||
| num_workers, worker_envs = scheduler.get_worker_env(svc) | ||
| num_workers, resource_envs = scheduler.get_resource_envs(svc) | ||
| uri, socket = _get_server_socket(svc, uds_path, port_stack, backlog) | ||
| args = [ | ||
| "-m", | ||
|
|
@@ -141,8 +141,8 @@ def create_dependency_watcher( | |
| "$(CIRCUS.WID)", | ||
| ] | ||
|
|
||
| if worker_envs: | ||
| args.extend(["--worker-env", json.dumps(worker_envs)]) | ||
| if resource_envs: | ||
| args.extend(["--worker-env", json.dumps(resource_envs)]) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mohammedabdulwahhab , @ishandhanani - still a little confused on the plural here, we are passing the full list of resource_envs to a variable that is worker-env -> singular - is that right? its the full list for all workers that we pass here to a single process? - is this a global watcher watching all workers? |
||
|
|
||
| watcher = create_watcher( | ||
| name=f"service_{svc.name}", | ||
|
|
@@ -171,7 +171,7 @@ def create_dynamo_watcher( | |
| uri, socket = _get_server_socket(svc, uds_path, port_stack, backlog) | ||
|
|
||
| # Get worker configuration | ||
| num_workers, worker_envs = scheduler.get_worker_env(svc) | ||
| num_workers, resource_envs = scheduler.get_resource_envs(svc) | ||
|
|
||
| # Create Dynamo-specific worker args | ||
| args = [ | ||
|
|
@@ -184,8 +184,8 @@ def create_dynamo_watcher( | |
| "$(CIRCUS.WID)", | ||
| ] | ||
|
|
||
| if worker_envs: | ||
| args.extend(["--worker-env", json.dumps(worker_envs)]) | ||
| if resource_envs: | ||
| args.extend(["--worker-env", json.dumps(resource_envs)]) | ||
|
|
||
| # Update env to include ServiceConfig and service-specific environment variables | ||
| worker_env = env.copy() if env else {} | ||
|
|
@@ -315,7 +315,7 @@ def serve_http( | |
|
|
||
| if service_name and service_name != svc.name: | ||
| svc = svc.find_dependent_by_name(service_name) | ||
| num_workers, worker_envs = allocator.get_worker_env(svc) | ||
| num_workers, resource_envs = allocator.get_resource_envs(svc) | ||
| server_on_deployment(svc) | ||
| uds_path = tempfile.mkdtemp(prefix="bentoml-uds-") | ||
| try: | ||
|
|
@@ -419,8 +419,8 @@ def serve_http( | |
| *timeouts_args, | ||
| *timeout_args, | ||
| ] | ||
| if worker_envs: | ||
| server_args.extend(["--worker-env", json.dumps(worker_envs)]) | ||
| if resource_envs: | ||
| server_args.extend(["--worker-env", json.dumps(resource_envs)]) | ||
| if development_mode: | ||
| server_args.append("--development-mode") | ||
|
|
||
|
|
@@ -438,13 +438,37 @@ def serve_http( | |
| "--worker-id", | ||
| "$(CIRCUS.WID)", | ||
| ] | ||
| # resource_envs is the resource allocation (ie CUDA_VISIBLE_DEVICES) for each worker created by the allocator | ||
| # these resource_envs are passed to each individual worker's environment which is then set by the create_watcher | ||
|
ishandhanani marked this conversation as resolved.
Outdated
|
||
| if resource_envs: | ||
| args.extend(["--worker-env", json.dumps(resource_envs)]) | ||
| # env is the base bentoml environment variables. We make a copy and update it to add any service configurations and additional env vars | ||
| worker_env = env.copy() if env else {} | ||
|
ishandhanani marked this conversation as resolved.
|
||
|
|
||
| # Pass through the main service config | ||
| if "DYNAMO_SERVICE_CONFIG" in os.environ: | ||
|
ishandhanani marked this conversation as resolved.
|
||
| worker_env["DYNAMO_SERVICE_CONFIG"] = os.environ[ | ||
| "DYNAMO_SERVICE_CONFIG" | ||
| ] | ||
|
|
||
| # Get service-specific environment variables from DYNAMO_SERVICE_ENVS | ||
| if "DYNAMO_SERVICE_ENVS" in os.environ: | ||
| try: | ||
| service_envs = json.loads(os.environ["DYNAMO_SERVICE_ENVS"]) | ||
| if svc.name in service_envs: | ||
| service_args = service_envs[svc.name].get("ServiceArgs", {}) | ||
| if "envs" in service_args: | ||
|
ishandhanani marked this conversation as resolved.
|
||
| worker_env.update(service_args["envs"]) | ||
| except json.JSONDecodeError as e: | ||
| logger.warning(f"Failed to parse DYNAMO_SERVICE_ENVS: {e}") | ||
|
|
||
| watcher = create_watcher( | ||
| name=f"dynamo_service_{svc.name}", | ||
| args=args, | ||
| numprocesses=num_workers, | ||
| working_dir=str(bento_path.absolute()), | ||
| close_child_stdin=not development_mode, | ||
| env=env, # Dependency map will be injected by serve_http | ||
| env=worker_env, # Dependency map will be injected by serve_http | ||
| ) | ||
| watchers.append(watcher) | ||
| print(f"dynamo_service_{svc.name} entrypoint created") | ||
|
|
@@ -495,15 +519,15 @@ def serve_http( | |
| arbiter.start( | ||
| cb=lambda _: logger.info( # type: ignore | ||
| ( | ||
| "Starting Dynamo Service %s (%s/%s) listening on %s://%s:%d (Press CTRL+C to quit)" | ||
| "Starting Dynamo Service %s (Press CTRL+C to quit)" | ||
| if ( | ||
| hasattr(svc, "is_dynamo_component") | ||
| and svc.is_dynamo_component() | ||
| ) | ||
| else "Starting %s (Press CTRL+C to quit)" | ||
| ), | ||
| *( | ||
| (svc.name, *svc.dynamo_address(), scheme, log_host, port) | ||
| (svc.name,) | ||
| if ( | ||
| hasattr(svc, "is_dynamo_component") | ||
| and svc.is_dynamo_component() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.