Skip to content

Commit bbd32e9

Browse files
author
Andrey Cheptsov
committed
Enable Vast community cloud by default and make it configurable.
Set Vast to include community offers by default for broader discovery, keep explicit opt-out support, and point uv to the matching gpuhunt branch. Made-with: Cursor
1 parent bfe44d3 commit bbd32e9

File tree

6 files changed

+101
-0
lines changed

6 files changed

+101
-0
lines changed

docs/docs/concepts/backends.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,4 +1211,23 @@ projects:
12111211

12121212
</div>
12131213

1214+
??? info "Community Cloud"
1215+
By default, `dstack` includes both Server Cloud (datacenter) and Community Cloud offers.
1216+
To restrict offers to Server Cloud only, set `community_cloud: false` in the backend settings.
1217+
1218+
<div editor-title="~/.dstack/server/config.yml">
1219+
1220+
```yaml
1221+
projects:
1222+
- name: main
1223+
backends:
1224+
- type: vastai
1225+
creds:
1226+
type: api_key
1227+
api_key: d75789f22f1908e0527c78a283b523dd73051c8c7d05456516fc91e9d4efd8c5
1228+
community_cloud: false
1229+
```
1230+
1231+
</div>
1232+
12141233
Also, the `vastai` backend supports on-demand instances only. Spot instance support coming soon.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ ignore-case = true
8080

8181
[tool.uv.sources]
8282
dstack-plugin-server = { path = "examples/plugins/example_plugin_server", editable = true }
83+
gpuhunt = { git = "https://github.com/dstackai/gpuhunt.git", branch = "feat/vastai-community-default" }
8384

8485
[tool.ruff]
8586
target-version = "py39"

src/dstack/_internal/core/backends/vastai/compute.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def __init__(self, config: VastAIConfig):
4343
self.catalog = gpuhunt.Catalog(balance_resources=False, auto_reload=False)
4444
self.catalog.add_provider(
4545
VastAIProvider(
46+
community_cloud=config.allow_community_cloud,
4647
extra_filters={
4748
"direct_port_count": {"gte": 1},
4849
"reliability2": {"gte": 0.9},

src/dstack/_internal/core/backends/vastai/models.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
from dstack._internal.core.models.common import CoreModel
66

7+
# TODO: Re-evaluate this default once Vast Server Cloud inventory improves for
8+
# CUDA-sensitive GPU families (e.g. H100 with strict cuda_max_good filtering).
9+
VASTAI_COMMUNITY_CLOUD_DEFAULT = True
10+
711

812
class VastAIAPIKeyCreds(CoreModel):
913
type: Annotated[Literal["api_key"], Field(description="The type of credentials")] = "api_key"
@@ -20,6 +24,15 @@ class VastAIBackendConfig(CoreModel):
2024
Optional[List[str]],
2125
Field(description="The list of VastAI regions. Omit to use all regions"),
2226
] = None
27+
community_cloud: Annotated[
28+
Optional[bool],
29+
Field(
30+
description=(
31+
"Whether Community Cloud offers can be suggested in addition to Server Cloud."
32+
f" Defaults to `{str(VASTAI_COMMUNITY_CLOUD_DEFAULT).lower()}`"
33+
)
34+
),
35+
] = None
2336

2437

2538
class VastAIBackendConfigWithCreds(VastAIBackendConfig):
@@ -35,3 +48,9 @@ class VastAIStoredConfig(VastAIBackendConfig):
3548

3649
class VastAIConfig(VastAIStoredConfig):
3750
creds: AnyVastAICreds
51+
52+
@property
53+
def allow_community_cloud(self) -> bool:
54+
if self.community_cloud is not None:
55+
return self.community_cloud
56+
return VASTAI_COMMUNITY_CLOUD_DEFAULT
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from unittest.mock import patch
2+
3+
from dstack._internal.core.backends.vastai.compute import VastAICompute
4+
from dstack._internal.core.backends.vastai.models import VastAIConfig, VastAICreds
5+
6+
7+
def _config(community_cloud=None) -> VastAIConfig:
8+
return VastAIConfig(creds=VastAICreds(api_key="test"), community_cloud=community_cloud)
9+
10+
11+
def test_vastai_compute_enables_community_cloud_by_default():
12+
with patch(
13+
"dstack._internal.core.backends.vastai.compute.VastAIProvider"
14+
) as vast_provider_cls, patch(
15+
"dstack._internal.core.backends.vastai.compute.gpuhunt.Catalog"
16+
) as catalog_cls:
17+
catalog_instance = catalog_cls.return_value
18+
VastAICompute(_config())
19+
vast_provider_cls.assert_called_once()
20+
assert vast_provider_cls.call_args.kwargs["community_cloud"] is True
21+
catalog_instance.add_provider.assert_called_once()
22+
23+
24+
def test_vastai_compute_can_enable_community_cloud():
25+
with patch(
26+
"dstack._internal.core.backends.vastai.compute.VastAIProvider"
27+
) as vast_provider_cls, patch(
28+
"dstack._internal.core.backends.vastai.compute.gpuhunt.Catalog"
29+
) as catalog_cls:
30+
catalog_instance = catalog_cls.return_value
31+
VastAICompute(_config(community_cloud=True))
32+
vast_provider_cls.assert_called_once()
33+
assert vast_provider_cls.call_args.kwargs["community_cloud"] is True
34+
catalog_instance.add_provider.assert_called_once()
35+
36+
37+
def test_vastai_compute_can_disable_community_cloud():
38+
with patch(
39+
"dstack._internal.core.backends.vastai.compute.VastAIProvider"
40+
) as vast_provider_cls, patch(
41+
"dstack._internal.core.backends.vastai.compute.gpuhunt.Catalog"
42+
) as catalog_cls:
43+
catalog_instance = catalog_cls.return_value
44+
VastAICompute(_config(community_cloud=False))
45+
vast_provider_cls.assert_called_once()
46+
assert vast_provider_cls.call_args.kwargs["community_cloud"] is False
47+
catalog_instance.add_provider.assert_called_once()

src/tests/_internal/core/backends/vastai/test_configurator.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,20 @@
88

99

1010
class TestVastAIConfigurator:
11+
def test_allow_community_cloud_default(self):
12+
config = VastAIBackendConfigWithCreds(creds=VastAICreds(api_key="valid"))
13+
backend = VastAIConfigurator().create_backend(project_name="main", config=config)
14+
loaded_config = VastAIConfigurator()._get_config(backend)
15+
assert loaded_config.allow_community_cloud is True
16+
17+
def test_allow_community_cloud_enabled(self):
18+
config = VastAIBackendConfigWithCreds(
19+
creds=VastAICreds(api_key="valid"), community_cloud=True
20+
)
21+
backend = VastAIConfigurator().create_backend(project_name="main", config=config)
22+
loaded_config = VastAIConfigurator()._get_config(backend)
23+
assert loaded_config.allow_community_cloud is True
24+
1125
def test_validate_config_valid(self):
1226
config = VastAIBackendConfigWithCreds(
1327
creds=VastAICreds(api_key="valid"),

0 commit comments

Comments
 (0)