Skip to content

[Presets] Support for dstack preset push and dstack preset pull - #4194

Open
peterschmidt85 wants to merge 7 commits into
masterfrom
preset-registry-push-pull
Open

[Presets] Support for dstack preset push and dstack preset pull#4194
peterschmidt85 wants to merge 7 commits into
masterfrom
preset-registry-push-pull

Conversation

@peterschmidt85

@peterschmidt85 peterschmidt85 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Push and pull

A preset created on one machine can now be used on another. Push it to the registry:

$ dstack preset push qwen38-27b-mi300x main/qwen38-27b-mi300x
OK

Then, on any other machine, pull it from the registry and export it to a service configuration:

$ dstack preset pull main/qwen38-27b-mi300x
OK

$ dstack preset export main/qwen38-27b-mi300x -f qwen38.dstack.yml
OK

$ dstack apply -f qwen38.dstack.yml

export writes the preset's patch files next to the configuration, so the service is applied
exactly as it was verified.

Push shares the verified service, its benchmark, and the hardware it was verified on. The
configuration, prompt, and trials that produced it stay on the machine that created it.

A pulled preset is used like any other, and is named <project>/<name>, which can never clash
with a preset of your own:

$ dstack preset list -a
 NAME                      ID                                    BASE              CONSTRAINTS      BENCHMARK                             STATUS           SUBMITTED
 main/qwen38-27b-mi300x    e7c8b170-8ca6-41cc-bfa9-ed1ba71c8c88  Qwen/Qwen3.8-27B  io=10K/1.5K c=4  tps/user=138 ttft=852ms ctx=1M        pulled           11 mins ago
 qwen38-27b-mi300x-crack2  6900d9d7                              Qwen/Qwen3.8-27B  io=10K/1.5K c=4  tps/user=138 ttft=852ms ctx=1M  ████  verified (4/15)  1 week ago

Its status is pulled, in the table above and in dstack preset get --json.

Pushing the same name again pushes a new preset that the name then points to; the previous one
stays available as <project>/<id>, which pull also accepts.

Registry

The registry is part of the dstack server. On dstack Sky, that is https://sky.dstack.ai. Push and
pull require membership in the project. If the server has no registry, both say so.

The server comes from the project's entry in ~/.dstack/config.yml. A project that is not there
falls back to dstack Sky; DSTACK_NO_SKY_FALLBACK turns the fallback off.

Note

The fallback is exactly the one dstack login applies.

Also here

  • dstack preset export no longer fails with IsADirectoryError when the preset mounts a
    directory in files.
  • Presets can be the target of events, and list_events filters by them, so a server with a
    registry can record who pushed what. The events table shows them and filters by them.

Breaking changes

  • dstack preset get --json reports the served model repository as repo instead of model, so
    base (the model family), repo (what the service loads), and service.model (what the
    endpoint serves it as) are now distinct.

Backward compatibility

  • Presets created by earlier versions are upgraded when read.

Note

The registry that push and pull talk to is implemented separately and is not part of this
PR.

Andrey Cheptsov and others added 7 commits August 23, 2026 14:24
Adds the client half of the preset registry: a preset is pushed to a
project as `<project>/<name>` and pulled anywhere else by name or ID.
Push carries the verified service, its benchmark, the hardware it was
verified on, and the preset's files; the creation session stays local.

Stored presets are now tagged by status, `verified` for a local creation
and `pulled` for a registry copy, and the served model repository is
reported as `repo` instead of `model`. Presets written by earlier
versions are upgraded when read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`PresetConfiguration` and its neighbours moved to `configurations.py`, but
the reference page still imported them from `core.models.presets`, which
failed the docs build.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`get_files` replaces `get_file`: one request returns every archive the
preset carries, framed by path and length, so a pull costs one round trip
and one preset lookup however many files there are.

The archives are also keyed by their path in the container now, which is
what `RunSpec` carries, so `PresetArchiveMapping` is gone and the envelope
is the same as a run's. Where each archive lands on disk is what the
preset's own `files` already say.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Presets can be the target of events, and `list_events` filters by them,
so a server extending dstack with a preset registry can record who pushed
what.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`files` may mount a directory, and exporting a preset carrying one failed
with `IsADirectoryError`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The events table rendered a preset target as `---`, and neither the type
filter nor the target ID filter knew about presets.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The presets docs cover pushing, pulling, and the registry behind them.
Traces move under Monitor presets, the intro is shorter, and the export
snippet matches what the command prints now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@peterschmidt85
peterschmidt85 marked this pull request as ready for review August 24, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant