[Presets] Add PD Disaggregation Support - #4227
Conversation
…tem prompt Cover node groups (tasks) and replica groups (services) in the dstack and dstack-prototyping skills and the preset system prompt: replica/job targeting for logs/attach/ssh, SSH alias naming, cluster placement for PD, per-group sleep-infinity for prototyping, and the groups-based trial.json format. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
peterschmidt85
left a comment
There was a problem hiding this comment.
I pushed changes to skills/dstack/SKILL.md, skills/dstack-prototyping/SKILL.md, and the preset system prompt to make the language around PD disaggregation (node groups / replica groups, replica and job targeting) sharper and more explicit.
| destination.write_text(yaml.safe_dump(service.model_dump(mode="json"), sort_keys=False)) | ||
| destination.write_text( | ||
| yaml.safe_dump( | ||
| service.model_dump(mode="json", context={"keep_groups": True}), |
There was a problem hiding this comment.
No keep_groups should be needed. Instead, ensure that when a service is serialized, it uses the new groups syntax for replica groups — and not the old one. Then neither this call nor PresetStore.save needs a context flag.
There was a problem hiding this comment.
keep_groups was added because _serialize_legacy_replica_groups dumps the new groups layout as the old replicas/count layout, for CLIs released before groups existed . Preset files are written by that same serializer, so they inherited the old layout too, and the context flag was the way to opt them out.
Unit we remove _serialize_legacy_replica_groups , the alternative I propose is to convert in the preset writers instead.
# store.py
def to_groups_syntax(service: dict[str, Any]) -> dict[str, Any]:
""" If replicas/count (old layout) exists convert
replicas to groups and count to replicas (new layout)"""
if not isinstance(service.get("replicas"), list):
return service
result: dict[str, Any] = {}
for key, value in service.items():
if key != "replicas":
result[key] = value
continue
result["groups"] = [
{("replicas" if k == "count" else k): v for k, v in group.items()}
for group in value
]
return result
# store.py — PresetStore.save
document = preset.model_dump(mode="json")
document["service"] = to_groups_syntax(document["service"])
content = yaml.safe_dump(document, sort_keys=False)
# export.py
destination.write_text(
yaml.safe_dump(to_groups_syntax(service.model_dump(mode="json")), sort_keys=False)
)
configurations.py then goes back untouched — no SerializationInfo, no context.
What we can't do is remove _serialize_legacy_replica_groups itself because an old CLI runs dstack apply -f with replicas/count; the new server normalises that into groups on parse via _normalize_legacy_replica_groups, then replies with a RunPlan. Without the serializer that reply carries groups, and responses are parsed with validate_extra_ignore, so the old CLI silently drops it. The old CLI returns a service with neither replicas nor groups. The run becomes wrong.
Plan: deprecate replicas/count in the next release, warning when a user's YAML uses it client-side, then drop _serialize_legacy_replica_groups once pre-groups CLIs are unsupported.
There was a problem hiding this comment.
I am sending a separate PR to resolve this issue. The PR will drop _serialize_legacy_replica_groups and use patching instead.
There was a problem hiding this comment.
This PR #4248 resolves above issue and should be merged first.
|
Could you make the PD description in the PR shorter but clearer (if possible)? What to include:
Also, please update the docs — remove "Doesn't support PD disaggregation (coming soon)" from |
…fault wording Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conducted tests with
Multi-Node PD
Fleet Used
Backend: Nebius
Preset Used
PD disaggregation multi-node results
Trial Summary
trial-4 was choosen for service. TTFT cap was not meet.
Task To Service conversion
The conversion from
trials/4/task.dstack.ymltoservice/2/service.dstack.ymlis correct. The task uses node groups and service uses replica groups. Minor Correction need in prototyping skill: We need to drop startup_order: workers-first from the service YAML — that option only orders master vs workers inside a multi-node task, and on a service it is unused.Non-PD
NON PD works as expected
Preset Used
Trial Summary
Task To Service conversion
Worked as expected.