Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions docs/deployment-configs.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ Validation loads the recipes and checks that they can share one frontend. Backen
The checked-in [deploy_models.sh](../scripts/deploy_models.sh) lists the complete active config set. Add a config path there, then run it. The deployment command owns frontend selection and trainer/inference updates:

~~~bash
./scripts/deploy_models.sh --app my-spindle --env dev --region us-west
./scripts/deploy_models.sh --app my-spindle --env dev
./scripts/deploy_models.sh --refresh-trainer qwen35-9b-lora-16k
./scripts/deploy_models.sh --refresh-inference qwen35-9b-lora-16k
~~~

Frontend, region, environment, secret names, and volume names default in `BaseConfig.platform`. Set them in the same Python config using dotted overrides:
Frontend, region, environment, secret names, and volume names default in `BaseConfig.platform`. `platform.modal.region` defaults to `None`, which leaves GPU placement unpinned (Modal schedules trainers and inference pools in any region); set it only to restrict placement. Set them in the same Python config using dotted overrides:

```python
from spindle.configs.gpt_oss_20b_lora_64k import Config as Parent
Expand Down
2 changes: 1 addition & 1 deletion src/spindle/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def _apply_overrides(values, overrides):
class BaseConfig:
platform = {
"frontend": "spindle",
"modal": {"environment": None, "region": "us-west"},
"modal": {"environment": None, "region": None},
"secrets": {
"api": "spindle-api",
"sampler_proxy": "spindle-proxy",
Expand Down
9 changes: 7 additions & 2 deletions src/spindle/providers/modal/deployment_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ def secrets_for(platform, *, training=False):
return result


def server_placement(region):
if region is None:
return {}
return {"routing_region": region, "compute_region": region}


def deployment_env(values):
"""Keep user environment overrides separate from Spindle's deployment wiring."""
if any(key.startswith("SPINDLE_") for key in values):
Expand Down Expand Up @@ -224,8 +230,7 @@ def build_rollout_app(deployment, pool, platform=None, *, image=None):
startup_timeout=recipe.inference_startup_timeout_s,
exit_grace_period=300,
port=8000,
routing_region=platform["modal"]["region"],
compute_region=platform["modal"]["region"],
**server_placement(platform["modal"]["region"]),
)
class Server:
@modal.enter()
Expand Down
2 changes: 0 additions & 2 deletions src/spindle/providers/modal/scoped.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ def register_sampler(
startup_timeout=1800,
exit_grace_period=120,
port=8000,
routing_region="us-west",
)
class Sampler:
sidecar = None
Expand Down Expand Up @@ -417,7 +416,6 @@ async def gateway():
timeout=1200,
secrets=[*telemetry_secrets, api_secret],
volumes={"/checkpoints": checkpoints},
routing_region="us-west",
)
@modal.concurrent(max_inputs=128)
@modal.asgi_app(requires_proxy_auth=False)
Expand Down
5 changes: 3 additions & 2 deletions tests/providers/test_deployment_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def test_trainer_declaration_and_executor_configuration(
app, trainer = deployment_apps.build_trainer_app(row, platform, image=image)
declaration, _ = app.functions["trainer"]
assert declaration["gpu"] == "H100:4"
assert declaration["region"] == "us-west"
assert declaration["region"] is None
assert declaration["max_containers"] is None
assert declaration["single_use_containers"] is True
assert declaration["image"] is image
Expand Down Expand Up @@ -127,7 +127,8 @@ def test_pool_starts_native_server_and_correct_sidecar(builders, monkeypatch, ki
)
assert settings["min_containers"] == 0
assert settings["target_concurrency"] == 16
assert settings["compute_region"] == "us-west"
assert "compute_region" not in settings
assert "routing_region" not in settings

calls, commands, stops = [], [], []
process = object()
Expand Down
Loading