← back to Exo
[feat] Add an option to disable the worker (#1091)
839b67f318b6b5422b119b1a74e38883ca6f9ce1 · 2026-01-05 12:05:03 +0000 · Evan Quiney
## Motivation
Workerless machines can be used for networking without running any gpu
jobs - add a cli flag that adds this basic functionality.
## Changes
Adds the --no-worker cli flag
## Test Plan
### Manual Testing
Exo starts as expected
### Automated Testing
None
Files touched
Diff
commit 839b67f318b6b5422b119b1a74e38883ca6f9ce1
Author: Evan Quiney <evanev7@gmail.com>
Date: Mon Jan 5 12:05:03 2026 +0000
[feat] Add an option to disable the worker (#1091)
## Motivation
Workerless machines can be used for networking without running any gpu
jobs - add a cli flag that adds this basic functionality.
## Changes
Adds the --no-worker cli flag
## Test Plan
### Manual Testing
Exo starts as expected
### Automated Testing
None
---
src/exo/main.py | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/src/exo/main.py b/src/exo/main.py
index d6750a29..43d69aa5 100644
--- a/src/exo/main.py
+++ b/src/exo/main.py
@@ -28,7 +28,7 @@ from exo.worker.main import Worker
@dataclass
class Node:
router: Router
- worker: Worker
+ worker: Worker | None
election: Election # Every node participates in election, as we do want a node to become master even if it isn't a master candidate if no master candidates are present.
election_result_receiver: Receiver[ElectionResult]
master: Master | None
@@ -62,15 +62,19 @@ class Node:
else:
api = None
- worker = Worker(
- node_id,
- session_id,
- exo_shard_downloader(),
- connection_message_receiver=router.receiver(topics.CONNECTION_MESSAGES),
- global_event_receiver=router.receiver(topics.GLOBAL_EVENTS),
- local_event_sender=router.sender(topics.LOCAL_EVENTS),
- command_sender=router.sender(topics.COMMANDS),
- )
+ if not args.no_worker:
+ worker = Worker(
+ node_id,
+ session_id,
+ exo_shard_downloader(),
+ connection_message_receiver=router.receiver(topics.CONNECTION_MESSAGES),
+ global_event_receiver=router.receiver(topics.GLOBAL_EVENTS),
+ local_event_sender=router.sender(topics.LOCAL_EVENTS),
+ command_sender=router.sender(topics.COMMANDS),
+ )
+ else:
+ worker = None
+
# We start every node with a master
master = Master(
node_id,
@@ -100,8 +104,9 @@ class Node:
async with self._tg as tg:
signal.signal(signal.SIGINT, lambda _, __: self.shutdown())
tg.start_soon(self.router.run)
- tg.start_soon(self.worker.run)
tg.start_soon(self.election.run)
+ if self.worker:
+ tg.start_soon(self.worker.run)
if self.master:
tg.start_soon(self.master.run)
if self.api:
@@ -209,6 +214,7 @@ class Args(CamelCaseModel):
spawn_api: bool = False
api_port: PositiveInt = 52415
tb_only: bool = False
+ no_worker: bool = False
@classmethod
def parse(cls) -> Self:
@@ -246,6 +252,10 @@ class Args(CamelCaseModel):
dest="api_port",
default=52415,
)
+ parser.add_argument(
+ "--no-worker",
+ action="store_true",
+ )
args = parser.parse_args()
return cls(**vars(args)) # pyright: ignore[reportAny] - We are intentionally validating here, we can't do it statically
← 47b8e0ce feat: remember last launch settings (model, sharding, instan
·
back to Exo
·
feat(macos-app): add custom namespace UI for cluster isolati 4f6fcd9e →