Skip to content

Commit cbb5bf3

Browse files
Merge branch 'main' of github.com:zhaochenyang20/sglang-diffusion-routing
2 parents 0456958 + 426cd1e commit cbb5bf3

17 files changed

Lines changed: 994 additions & 21 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: 🐞 Bug report
2+
description: Report a bug to help us reproduce and fix it.
3+
title: "[Bug] "
4+
labels: ['Bug']
5+
6+
body:
7+
- type: checkboxes
8+
attributes:
9+
label: Checklist
10+
options:
11+
- label: I searched related issues but found no solution.
12+
- label: The bug persists in the latest version.
13+
- label: Issues without environment info and a minimal reproducible demo are hard to resolve and may receive no feedback.
14+
- label: If this is not a bug report but a general question, please start a discussion in Issues. Otherwise, it will be closed.
15+
- label: Please use English. Otherwise, it will be closed.
16+
- type: textarea
17+
attributes:
18+
label: Describe the bug
19+
description: A clear, concise description of the bug.
20+
validations:
21+
required: true
22+
- type: textarea
23+
attributes:
24+
label: Reproduction
25+
description: Command/script run and configuration used.
26+
placeholder: Paste the command here.
27+
validations:
28+
required: true
29+
- type: textarea
30+
attributes:
31+
label: Environment
32+
description: |
33+
Provide your environment info, including:
34+
- OS version
35+
- Python version
36+
- sglang-diffusion-routing version (`pip show sglang-diffusion-routing`)
37+
- Related dependency versions (fastapi, httpx, uvicorn)
38+
placeholder: Paste environment output here.
39+
validations:
40+
required: true
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: 🚀 Feature request
2+
description: Suggest an idea for this project
3+
title: "[Feature] "
4+
5+
body:
6+
- type: checkboxes
7+
attributes:
8+
label: Checklist
9+
options:
10+
- label: If this is not a feature request but a general question, please start a discussion in Issues. Otherwise, it will be closed.
11+
- label: Please use English. Otherwise, it will be closed.
12+
- type: textarea
13+
attributes:
14+
label: Motivation
15+
description: |
16+
Clearly and concisely describe the feature's motivation.
17+
validations:
18+
required: true
19+
- type: textarea
20+
attributes:
21+
label: Related resources
22+
description: |
23+
Provide official releases or third-party implementations if available.

.github/pull_request_template.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!-- Thank you for your contribution! Please follow these guidelines to enhance your pull request. If anything is unclear, submit your PR and reach out to maintainers for assistance. -->
2+
3+
## Motivation
4+
5+
<!-- Describe the purpose and goals of this pull request. -->
6+
7+
## Modifications
8+
9+
<!-- Detail the changes made in this pull request. -->
10+
11+
## Accuracy Tests
12+
13+
<!-- If this pull request affects routing behavior or model outputs, provide accuracy test results. -->
14+
15+
## Benchmarking and Profiling
16+
17+
<!-- If this pull request impacts routing performance or throughput, provide benchmarking and profiling results. -->
18+
19+
## Checklist
20+
21+
- [ ] Format your code with `pre-commit run --all-files`.
22+
- [ ] Add or update unit tests if applicable.
23+
- [ ] Update documentation if applicable.
24+
- [ ] Provide accuracy and performance benchmark results if applicable.
25+
- [ ] Ensure all CI checks pass.
26+
27+
## Review Process
28+
29+
1. Get approvals from maintainers and other reviewers.
30+
2. Ensure all CI tests pass.
31+
3. After green CI and required approvals, ask maintainers to merge.

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ repos:
1717
rev: 5.13.2
1818
hooks:
1919
- id: isort
20+
args: ["--profile", "black"]
2021

2122
- repo: https://github.com/astral-sh/ruff-pre-commit
2223
rev: v0.11.7

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,30 @@ curl -X POST http://localhost:30081/update_weights_from_disk \
152152
-d '{"model_path": "Qwen/Qwen-Image-2512"}'
153153
```
154154

155+
### Auto-launch workers via YAML config
156+
157+
Instead of starting workers manually, you can let the router spawn and manage
158+
them through a launcher backend.
159+
160+
**Local subprocess launcher** (`examples/local_launcher.yaml`):
161+
162+
```bash
163+
sglang-d-router --port 30081 --launcher-config examples/local_launcher.yaml
164+
```
165+
166+
```yaml
167+
launcher:
168+
backend: local
169+
model: Qwen/Qwen-Image
170+
num_workers: 2
171+
num_gpus_per_worker: 1
172+
worker_base_port: 10090
173+
wait_timeout: 600
174+
```
175+
176+
Fields not set in the YAML fall back to defaults defined in each backend's
177+
config dataclass (see `LocalLauncherConfig`).
178+
155179
## Acknowledgment
156180

157181
This project is derived from [radixark/miles#544](https://github.com/radixark/miles/pull/544). Thanks to the original authors.

development.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
pip install -e .
77
```
88

9-
Run tests:
9+
Run CPU only tests:
1010

1111
```bash
1212
pip install pytest

examples/local_launcher.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
launcher:
2+
model: Qwen/Qwen-Image
3+
4+
num_workers: 8
5+
num_gpus_per_worker: 1
6+
worker_host: "127.0.0.1"
7+
worker_base_port: 10090
8+
9+
worker_extra_args: "--dit-cpu-offload false --text-encoder-cpu-offload false"
10+
11+
wait_timeout: 600

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ license = { text = "MIT" }
1212
dependencies = [
1313
"fastapi>=0.110",
1414
"httpx>=0.27",
15+
"omegaconf>=2.3",
1516
"uvicorn>=0.30",
1617
]
1718
classifiers = [

src/sglang_diffusion_routing/cli/main.py

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import argparse
77
import asyncio
88
import sys
9+
import threading
910

1011
from sglang_diffusion_routing import DiffusionRouter
12+
from sglang_diffusion_routing.launcher import config as _lcfg
1113

1214

1315
def _run_router_server(
1416
args: argparse.Namespace,
15-
worker_urls: list[str] | None = None,
17+
router: DiffusionRouter,
1618
log_prefix: str = "[router]",
1719
) -> None:
1820
try:
@@ -22,10 +24,7 @@ def _run_router_server(
2224
"uvicorn is required to run router. Install with: pip install uvicorn"
2325
) from exc
2426

25-
worker_urls = list(
26-
worker_urls if worker_urls is not None else args.worker_urls or []
27-
)
28-
router = DiffusionRouter(args, verbose=args.verbose)
27+
worker_urls = list(args.worker_urls or [])
2928
refresh_tasks = []
3029
for url in worker_urls:
3130
normalized_url = router.normalize_worker_url(url)
@@ -97,13 +96,52 @@ def _add_router_args(parser: argparse.ArgumentParser) -> None:
9796
parser.add_argument(
9897
"--log-level", type=str, default="info", help="Uvicorn log level."
9998
)
99+
parser.add_argument(
100+
"--launcher-config",
101+
type=str,
102+
default=None,
103+
dest="launcher_config",
104+
help="YAML config for launching router managed workers (see examples/local_launcher.yaml).",
105+
)
100106

101107

102108
def _handle_router(args: argparse.Namespace) -> int:
103-
_run_router_server(
104-
args, worker_urls=list(args.worker_urls), log_prefix="[sglang-d-router]"
105-
)
106-
return 0
109+
log_prefix, backend, router = "[sglang-d-router]", None, None
110+
111+
try:
112+
router = DiffusionRouter(args, verbose=args.verbose)
113+
if args.launcher_config is not None:
114+
launcher_cfg = _lcfg.load_launcher_config(args.launcher_config)
115+
wait_timeout = launcher_cfg.wait_timeout
116+
backend = _lcfg.create_backend(launcher_cfg)
117+
backend.launch()
118+
threading.Thread(
119+
target=backend.wait_ready_and_register,
120+
kwargs=dict(
121+
register_func=router.register_worker,
122+
timeout=wait_timeout,
123+
log_prefix=log_prefix,
124+
),
125+
daemon=True,
126+
).start()
127+
128+
_run_router_server(args, router=router, log_prefix=log_prefix)
129+
return 0
130+
finally:
131+
# TODO (mengyang, shuwen, chenyang): refactor the exit logic of router and backend.
132+
if router is not None:
133+
try:
134+
asyncio.run(router.client.aclose())
135+
except Exception as exc:
136+
print(
137+
f"{log_prefix} warning: failed to close router client: {exc}",
138+
file=sys.stderr,
139+
flush=True,
140+
)
141+
if backend is not None:
142+
print(f"{log_prefix} shutting down managed workers...", flush=True)
143+
backend.shutdown()
144+
print(f"{log_prefix} all managed workers terminated.", flush=True)
107145

108146

109147
def build_parser() -> argparse.ArgumentParser:
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""Launcher backends for spinning up SGLang diffusion workers.
2+
3+
Right now only supports local backend, which launches workers as local subprocesses.
4+
We leave this module for future extensions on slurm or kubernetes.
5+
"""
6+
7+
from sglang_diffusion_routing.launcher.backend import (
8+
LaunchedWorker,
9+
LauncherBackend,
10+
WorkerLaunchResult,
11+
)
12+
from sglang_diffusion_routing.launcher.config import (
13+
create_backend,
14+
load_launcher_config,
15+
)
16+
from sglang_diffusion_routing.launcher.local import LocalLauncher, LocalLauncherConfig
17+
18+
__all__ = [
19+
"LaunchedWorker",
20+
"LauncherBackend",
21+
"LocalLauncher",
22+
"LocalLauncherConfig",
23+
"WorkerLaunchResult",
24+
"create_backend",
25+
"load_launcher_config",
26+
]

0 commit comments

Comments
 (0)