Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
065cb2a
feat: update k8s deploy yamls to use binary/python3
hhzhang16 Jul 11, 2025
aee478c
config part working
tedzhouhk Jul 11, 2025
9455ad1
feat: add component type worker and bump image
hhzhang16 Jul 12, 2025
f3dd01a
fix: merge conflicts
mohammedabdulwahhab Jul 14, 2025
7de97ef
fix: using health checks exposed by dynamo-run
mohammedabdulwahhab Jul 14, 2025
16fd7f2
Merge branch 'main' of github.com:ai-dynamo/dynamo into hannahz/dep-2…
hhzhang16 Jul 14, 2025
3a29913
Merge branch 'hannahz/dep-216-create-deploy-crds-for-vllm_v1-example'…
hhzhang16 Jul 14, 2025
51835db
fix: check for message in logs
mohammedabdulwahhab Jul 14, 2025
39b377f
Merge branch 'hannahz/dep-216-create-deploy-crds-for-vllm_v1-example'…
mohammedabdulwahhab Jul 14, 2025
dddb45f
Merge branch 'hannahz/dep-216-create-deploy-crds-for-vllm_v1-example'…
tedzhouhk Jul 14, 2025
34bc79c
define apis
tedzhouhk Jul 14, 2025
8c22d14
update script
tedzhouhk Jul 14, 2025
9856dde
fix: add dynamodeployment lib
mohammedabdulwahhab Jul 14, 2025
61a215b
fix: working client lib
mohammedabdulwahhab Jul 14, 2025
5141334
fix: working client lib
mohammedabdulwahhab Jul 14, 2025
8e25a29
integrate with utils.dynamo_deployment
tedzhouhk Jul 15, 2025
1d87164
fix: port forward works
mohammedabdulwahhab Jul 15, 2025
aaf4544
Merge branch 'hzhou/profile_vllmv1_k8s' of https://github.com/ai-dyna…
mohammedabdulwahhab Jul 15, 2025
65dec07
pc
tedzhouhk Jul 15, 2025
0af209b
add dep; bug fix
tedzhouhk Jul 15, 2025
918733a
Merge branch 'main' of https://github.com/ai-dynamo/dynamo into hzhou…
tedzhouhk Jul 15, 2025
3f900ef
staging, port forward not working
tedzhouhk Jul 15, 2025
bd12d40
stage
tedzhouhk Jul 15, 2025
7ac43a9
Merge branch 'main' of https://github.com/ai-dynamo/dynamo into hzhou…
mohammedabdulwahhab Jul 15, 2025
9971acf
fix: running script
mohammedabdulwahhab Jul 16, 2025
a5d8aca
fix: fix
mohammedabdulwahhab Jul 16, 2025
7b1d99a
Merge branch 'main' of https://github.com/ai-dynamo/dynamo into hzhou…
tedzhouhk Jul 16, 2025
f8f9363
add logic to find a free port
tedzhouhk Jul 16, 2025
8e292f6
feat: add Kubernetes service account configuration for SLA profiling …
hhzhang16 Jul 17, 2025
d62731f
feat: use service DNS for interfacing with deployments when profiling…
hhzhang16 Jul 17, 2025
a1aea5a
Revert "feat: use service DNS for interfacing with deployments when p…
hhzhang16 Jul 17, 2025
06bfe3b
feat: use service DNS instead of port forwarding for K8s-deployed SLA…
hhzhang16 Jul 18, 2025
ff96b9e
add try-catch waiting for deployment
tedzhouhk Jul 18, 2025
5419885
Merge branch 'main' of https://github.com/ai-dynamo/dynamo into hzhou…
tedzhouhk Jul 21, 2025
d2b6b00
feat: clean up outlying DGDs upon SLA profiling failure (#2016)
hhzhang16 Jul 21, 2025
450d371
add debug info
tedzhouhk Jul 22, 2025
d8ffe1a
Merge branch 'hzhou/profile_vllmv1_k8s' of https://github.com/ai-dyna…
tedzhouhk Jul 22, 2025
769c98e
sla planner
tedzhouhk Jul 22, 2025
e726d43
add choices
tedzhouhk Jul 22, 2025
3663c5c
Merge branch 'main' of github.com:ai-dynamo/dynamo into hzhou/sla-pla…
hhzhang16 Jul 22, 2025
ff6c491
feat: vllm_v1 -> vllm and remove vllm_v0 from planner
hhzhang16 Jul 22, 2025
6ebfe73
feat: remove local connector from init
hhzhang16 Jul 22, 2025
fb89fc2
feat: remove LocalConnector from core
hhzhang16 Jul 22, 2025
047cecb
feat: rework prometheus file for planner deployment
hhzhang16 Jul 22, 2025
894f2e7
Merge branch 'main' of github.com:ai-dynamo/dynamo into hannahz/dep-2…
hhzhang16 Jul 23, 2025
cd268ca
Merge branch 'main' of github.com:ai-dynamo/dynamo into hzhou/sla-pla…
hhzhang16 Jul 23, 2025
0f5082c
deprecate old docs
tedzhouhk Jul 23, 2025
9751e65
Merge branch 'main' of https://github.com/ai-dynamo/dynamo into hzhou…
tedzhouhk Jul 23, 2025
c33713f
Merge branch 'hzhou/sla-planner-ux-refac' of github.com:ai-dynamo/dyn…
hhzhang16 Jul 24, 2025
33371db
feat: update prometheus to work
hhzhang16 Jul 24, 2025
60dd89d
feat: k8s connector scaling P/D in one call (#2103)
tedzhouhk Jul 25, 2025
61a5e9a
Merge branch 'main' of github.com:ai-dynamo/dynamo into hannahz/dep-2…
hhzhang16 Jul 25, 2025
41f1ca0
fix: vllm_v1 -> vllm
hhzhang16 Jul 25, 2025
1584cd0
feat: remove unneeded files
hhzhang16 Jul 25, 2025
dd3f161
docs: update docs
hhzhang16 Jul 25, 2025
97f3f88
fix: vllm config in profiler
hhzhang16 Jul 25, 2025
9b34ee9
feat: wip but tentatively working planner, with documentation
hhzhang16 Jul 25, 2025
eb56dbb
fi: use provided namespace for decode
hhzhang16 Jul 25, 2025
b68779d
feat: use k8s deployment info instead of hardcoding prometheus endpoint
hhzhang16 Jul 25, 2025
c8e394d
fix: if no requests have been made yet, don't try to access list
hhzhang16 Jul 25, 2025
1bbfd8d
feat: use SLAPLannerDefaults port
hhzhang16 Jul 25, 2025
ba6b5c1
docs: clean up sla planner deployment docs
hhzhang16 Jul 25, 2025
e533dda
feat: use DYNAMO_NAMESPACE env var instead of --namespace arg
hhzhang16 Jul 26, 2025
a548d74
feat: fixes for working planner
hhzhang16 Jul 26, 2025
f6af0d5
feat: skip adjustments if no traffic
hhzhang16 Jul 26, 2025
445fe74
docs: doc updates for planner deployment
hhzhang16 Jul 26, 2025
f0999da
Merge branch 'main' of github.com:ai-dynamo/dynamo into hannahz/dep-2…
hhzhang16 Jul 26, 2025
bab714c
feat: delete k8s.sh
hhzhang16 Jul 26, 2025
a29c397
docs: slight doc modification
hhzhang16 Jul 26, 2025
daa3c4e
update resources
tedzhouhk Jul 26, 2025
539ff3e
update readme
tedzhouhk Jul 26, 2025
f994128
feat: address coderabbit MR comments
hhzhang16 Jul 28, 2025
d44b042
Merge branch 'main' of github.com:ai-dynamo/dynamo into hannahz/dep-2…
hhzhang16 Jul 28, 2025
f601f88
fix pytest
tedzhouhk Jul 28, 2025
69d64dc
mypy
tedzhouhk Jul 28, 2025
1fdf3e9
feat: addressing MR comments
hhzhang16 Jul 28, 2025
bf58bd0
feat: addressing MR comments
hhzhang16 Jul 28, 2025
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
config part working
  • Loading branch information
tedzhouhk committed Jul 11, 2025
commit aee478c0d42811d0025961de7d222780a6f988a6
29 changes: 21 additions & 8 deletions benchmarks/profiler/profile_sla.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@
parser.add_argument(
"--backend",
type=str,
default="vllm_v0",
choices=["vllm_v0", "vllm_v1"],
help="backend type (currently only vllm is supported)",
default="vllm_v1",
choices=["vllm_v1"],
help="backend type, currently support [vllm_v1]",
)
parser.add_argument(
"--config", type=str, required=True, help="Path to the dynamo config file"
"--config", type=str, required=True, help="Path to the DynamoGraphDeployment config file"
)
parser.add_argument(
"--example-dir",
Expand All @@ -71,6 +71,18 @@
default="profiling_results",
help="Path to the output results directory",
)
parser.add_argument(
"--min-num-gpus-per-engine",
type=int,
default=1,
help="minimum number of GPUs per engine",
)
parser.add_argument(
"--max-num-gpus-per-engine",
type=int,
default=8,
help="maximum number of GPUs per engine",
)
parser.add_argument(
"--isl", type=int, default=3000, help="target input sequence length"
)
Expand Down Expand Up @@ -121,10 +133,11 @@
with open(args.config, "r") as f:
config = yaml.safe_load(f)

# Get the number of available GPUs
available_gpus = get_available_gpu_count()

profile_tp_size = [2**i for i in range(int(math.log2(available_gpus)) + 1)]
profile_tp_size = [
2**i
for i in range(int(math.log2(args.max_num_gpus_per_engine)) + 1)
if args.min_num_gpus_per_engine <= 2**i <= args.max_num_gpus_per_engine
]
logger.info(f"Profiling TP sizes: {profile_tp_size}")

os.makedirs(args.output_dir, exist_ok=True)
Expand Down
213 changes: 54 additions & 159 deletions benchmarks/profiler/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
# limitations under the License.

import logging
from copy import deepcopy
from typing import Literal

from utils.defaults import DEFAULT_MODEL_NAME, DYNAMO_RUN_DEFAULT_PORT
from dynamo.planner.defaults import WORKER_COMPONENT_NAMES

logger = logging.getLogger(__name__)
Expand All @@ -28,190 +30,84 @@
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)


class VllmV0ConfigModifier:
class VllmV1ConfigModifier:
@classmethod
def convert_config(cls, config: dict, target: Literal["prefill", "decode"]) -> dict:
config = config.copy()
config = deepcopy(config)

# disable planner
if "Planner" in config:
config["Planner"]["no-operation"] = True
if "Planner" in config["spec"]["services"]:
del config["spec"]["services"]["Planner"]

if target == "prefill":
if WORKER_COMPONENT_NAMES["vllm_v0"].prefill_worker in config:
# make PrefillWorker into VllmWorker
del config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker]
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker] = config[
WORKER_COMPONENT_NAMES["vllm_v0"].prefill_worker
]
del config[WORKER_COMPONENT_NAMES["vllm_v0"].prefill_worker]

# to profile prefill, we disable prefix caching
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker][
"enable-prefix-caching"
] = False
elif target == "decode":
if WORKER_COMPONENT_NAMES["vllm_v0"].prefill_worker in config:
del config[WORKER_COMPONENT_NAMES["vllm_v0"].prefill_worker]
# convert prefill worker into decode worker
config["spec"]["services"][WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker] = config["spec"]["services"][WORKER_COMPONENT_NAMES["vllm_v1"].prefill_worker]
del config["spec"]["services"][WORKER_COMPONENT_NAMES["vllm_v1"].prefill_worker]

# to profile prefill, we enable prefix caching to pass the prefill stage
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker][
"enable-prefix-caching"
] = True
args = config["spec"]["services"][WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker]["extraPodSpec"]["mainContainer"]["args"]

# set num workers to 1
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker]["ServiceArgs"][
"workers"
] = 1

# set PP to 1
if (
"pipeline-parallel-size"
in config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker]
and config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker][
"pipeline-parallel-size"
]
> 1
):
logger.warning("Currently we only support TP, setting PP to 1")
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker][
"pipeline-parallel-size"
] = 1

# always local prefill
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker][
"remote-prefill"
] = False
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker][
"conditional-disagg"
] = False
# remove --is-prefill-worker flag
args.remove("--is-prefill-worker")

return config
# disable prefix caching
if "--enable-prefix-caching" in args:
args.remove("--enable-prefix-caching")
if "--no-enable-prefix-caching" not in args:
args.append("--no-enable-prefix-caching")

@classmethod
def set_config_tp_size(cls, config: dict, tp_size: int):
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker][
"tensor-parallel-size"
] = tp_size
config[WORKER_COMPONENT_NAMES["vllm_v0"].decode_worker]["ServiceArgs"][
"resources"
]["gpu"] = tp_size
return config

@classmethod
def get_model_name(cls, config: dict) -> str:
if "Common" in config and "served_model_name" in config["Common"]:
return config["Common"]["served_model_name"]
else:
return config["Frontend"]["served_model_name"]

@classmethod
def get_port(cls, config: dict) -> int:
if "Common" in config and "port" in config["Common"]:
return config["Common"]["port"]
else:
return config["Frontend"]["port"]

@classmethod
def get_kv_cache_size_from_dynamo_log(cls, dynamo_log_fn: str) -> int:
try:
with open(dynamo_log_fn, "r") as f:
for line in f:
if "Maximum concurrency for" in line:
line = line.strip().split("Maximum concurrency for ")[1]
token_count = int(line.split(" tokens per request: ")[0])
concurrency = float(line.split(" tokens per request: ")[1][:-1])

logger.info(
f"Found KV cache info: {token_count} x {concurrency} = {int(token_count * concurrency)}"
)
return int(token_count * concurrency)
except Exception as e:
logger.warning(
f"Failed to parse KV cache size from line: {line}. Error: {e}"
)
return 0


class VllmV1ConfigModifier:
@classmethod
def convert_config(cls, config: dict, target: Literal["prefill", "decode"]) -> dict:
config = config.copy()

# disable planner
if "Planner" in config:
config["Planner"]["no-operation"] = True

# turn-off disagg
config["SimpleLoadBalancer"]["enable_disagg"] = False

if target == "prefill":
if WORKER_COMPONENT_NAMES["vllm_v1"].prefill_worker in config:
# make VllmPrefillWorker into VllmDecodeWorker
del config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker]
config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker] = config[
WORKER_COMPONENT_NAMES["vllm_v1"].prefill_worker
]
del config[WORKER_COMPONENT_NAMES["vllm_v1"].prefill_worker]

# to profile prefill, we disable prefix caching
config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker][
"enable-prefix-caching"
] = False
elif target == "decode":
if WORKER_COMPONENT_NAMES["vllm_v1"].prefill_worker in config:
del config[WORKER_COMPONENT_NAMES["vllm_v1"].prefill_worker]
# delete prefill worker
del config["spec"]["services"][WORKER_COMPONENT_NAMES["vllm_v1"].prefill_worker]

# to profile prefill, we enable prefix caching to pass the prefill stage
config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker][
"enable-prefix-caching"
] = True
args = config["spec"]["services"][WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker]["extraPodSpec"]["mainContainer"]["args"]

# enable prefix caching
if "--enable-prefix-caching" not in args:
args.append("--enable-prefix-caching")
if "--no-enable-prefix-caching" in args:
args.remove("--no-enable-prefix-caching")

# set num workers to 1
config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker]["ServiceArgs"][
"workers"
] = 1

# set PP to 1
if (
"pipeline-parallel-size"
in config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker]
and config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker][
"pipeline-parallel-size"
]
> 1
):
logger.warning("Currently we only support TP, setting PP to 1")
config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker][
"pipeline-parallel-size"
] = 1
decode_worker_config = config["spec"]["services"][WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker]
decode_worker_config["replicas"] = 1

return config

@classmethod
def set_config_tp_size(cls, config: dict, tp_size: int):
config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker][
"tensor-parallel-size"
] = tp_size
config[WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker]["ServiceArgs"][
"resources"
]["gpu"] = tp_size
config = deepcopy(config)

args = config["spec"]["services"][WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker]["extraPodSpec"]["mainContainer"]["args"]

try:
idx = args.index("--tensor-parallel-size")
args[idx + 1] = str(tp_size)
except ValueError:
args.append("--tensor-parallel-size")
args.append(str(tp_size))

return config

@classmethod
def get_model_name(cls, config: dict) -> str:
if "Common" in config and "served_model_name" in config["Common"]:
return config["Common"]["served_model_name"]
else:
return config["Frontend"]["served_model_name"]
worker_name = WORKER_COMPONENT_NAMES["vllm_v1"].decode_worker
args = config["spec"]["services"][worker_name]["extraPodSpec"]["mainContainer"]["args"]

for i, arg in enumerate(args):
if arg == "--model" and i + 1 < len(args):
return args[i + 1]

logger.warning(f"Model name not found in configuration args, using default model name: {DEFAULT_MODEL_NAME}")
return DEFAULT_MODEL_NAME

@classmethod
def get_port(cls, config: dict) -> int:
if "Common" in config and "port" in config["Common"]:
return config["Common"]["port"]
else:
return config["Frontend"]["port"]
args = config["spec"]["services"]["Frontend"]["extraPodSpec"]["mainContainer"]["args"]
for arg in args:
if arg.startswith("port="):
return int(arg.split("=")[1])
logger.warning(f"Port not found in configuration args, using default port: {DYNAMO_RUN_DEFAULT_PORT}")
return DYNAMO_RUN_DEFAULT_PORT

@classmethod
def get_kv_cache_size_from_dynamo_log(cls, dynamo_log_fn: str) -> int:
Expand All @@ -237,6 +133,5 @@ def get_kv_cache_size_from_dynamo_log(cls, dynamo_log_fn: str) -> int:


CONFIG_MODIFIERS = {
"vllm_v0": VllmV0ConfigModifier,
"vllm_v1": VllmV1ConfigModifier,
}
3 changes: 3 additions & 0 deletions benchmarks/profiler/utils/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@
450,
500,
]

DEFAULT_MODEL_NAME = "Qwen/Qwen3-0.6B"
DYNAMO_RUN_DEFAULT_PORT = 8080