Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
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
2 changes: 2 additions & 0 deletions deploy/dynamo/sdk/src/dynamo/sdk/cli/serve_dynamo.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from typing import Any

import click
import uvloop

from dynamo.runtime import DistributedRuntime, dynamo_endpoint, dynamo_worker
from dynamo.sdk import dynamo_context
Expand Down Expand Up @@ -186,6 +187,7 @@ async def worker(runtime: DistributedRuntime):
logger.error(f"[{run_id}] Error in Dynamo component setup: {str(e)}")
raise

uvloop.install()
Comment thread
ryanolson marked this conversation as resolved.
asyncio.run(worker())


Expand Down
22 changes: 22 additions & 0 deletions deploy/dynamo/sdk/src/dynamo/sdk/cli/serving.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,28 @@ def serve_http(
"--worker-id",
"$(CIRCUS.WID)",
]
# Allows us to run a single dynamo service with multiple GPU workers
Comment thread
ishandhanani marked this conversation as resolved.
Outdated
Comment thread
ishandhanani marked this conversation as resolved.
Outdated
if worker_envs:
args.extend(["--worker-env", json.dumps(worker_envs)])
Comment thread
ishandhanani marked this conversation as resolved.
Outdated
worker_env = env.copy() if env else {}
Comment thread
ishandhanani marked this conversation as resolved.

# Pass through the main service config
if "DYNAMO_SERVICE_CONFIG" in os.environ:
Comment thread
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:
Comment thread
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,
Expand Down
45 changes: 45 additions & 0 deletions examples/llm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,51 @@ curl localhost:8000/v1/chat/completions -H "Content-Type: application/json"

```

### Multinode Examples

#### Single node sized models
You can deploy our example architectures on multiple nodes via NATS/ETCD based discovery and communication. Here's an example of deploying disaggregated serving on 2 nodes

##### Disaggregated Deployment with KV Routing
Node 1: Frontend, Processor, Router, 8 Decode
Node 2: 8 Prefill

**Step 1**: Start NATS/ETCD on your head node. Ensure you have the correct firewall rules to allow communication between the nodes as you will need the NATS/ETCD endpoints to be accessible by node 2.
```bash
# node 1
cd deploy
docker compose -d
Comment thread
ishandhanani marked this conversation as resolved.
Outdated
```

**Step 2**: Create the inference graph for this deployment. The easiest way to do this is to remove the `.link(PrefillWorker)` from the `disagg_router.py` file.

```python
# graphs/disag_router.py
# imports...
Frontend.link(Processor).link(Router).link(VllmWorker)
Comment thread
nnshah1 marked this conversation as resolved.
```

**Step 3**: Start the frontend, processor, router, and 8 VllmWorkers on node 1.
```bash
# node 1
cd /workspace/examples/llm
dynamo serve graphs.disagg_router:Frontend -f ./configs/disagg_router.yaml --VllmWorker.ServiceArgs.workers=8
```

**Step 4**: Start 8 PrefillWorkers on node 2.
Since we only want to start the `PrefillWorker` on node 2, you can simply run just the PrefillWorker component directly.

```bash
# node 2
export NATS_SERVER = '<your-nats-server-address>'
export ETCD_ENDPOINTS = '<your-etcd-endpoints-address>'

cd /workspace/examples/llm
dynamo serve components.prefill_worker:PrefillWorker -f ./configs/disagg_router.yaml --PrefillWorker.ServiceArgs.workers=8
Comment thread
ishandhanani marked this conversation as resolved.
```

You can now use the same curl request from above to interact with your deployment!

### Close deployment

Kill all dynamo processes managed by circusd.
Expand Down
18 changes: 9 additions & 9 deletions examples/llm/configs/disagg_router.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ VllmWorker:

# TODO - set all of these but model as default
PrefillWorker:
model: deepseek-ai/DeepSeek-R1-Distill-Llama-8B
kv-transfer-config: '{"kv_connector":"DynamoNixlConnector"}'
block-size: 64
max-model-len: 16384
max-num-batched-tokens: 16384
ServiceArgs:
workers: 1
resources:
gpu: 1
model: deepseek-ai/DeepSeek-R1-Distill-Llama-8B
kv-transfer-config: '{"kv_connector":"DynamoNixlConnector"}'
block-size: 64
max-model-len: 16384
max-num-batched-tokens: 16384
ServiceArgs:
workers: 1
resources:
gpu: 1
Comment thread
ishandhanani marked this conversation as resolved.
Outdated