Skip to content

Commit 1815229

Browse files
committed
Add Subparsers
1 parent 4ccdd00 commit 1815229

2 files changed

Lines changed: 99 additions & 32 deletions

File tree

README.md

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,97 @@
11
# `sml`: Swiss AI Model Launch
22

3-
A CLI tool for launching AI models on HPC systems via FirecREST, a remote launcher, or SLURM commands.
3+
A CLI tool for launching AI models on HPC systems via FirecREST or SLURM commands.
44

55
## Install
66

7-
1. Regular use
8-
- SSH
7+
- SSH
98

10-
```bash
11-
pip install git+ssh://git@github.com/swiss-ai/model-launch.git
12-
```
9+
```bash
10+
pip install git+ssh://git@github.com/swiss-ai/model-launch.git
11+
```
1312

14-
- HTTPS (once public)
13+
- HTTPS
1514

16-
```bash
17-
pip install git+https://github.com/swiss-ai/model-launch.git
18-
```
15+
```bash
16+
pip install git+https://github.com/swiss-ai/model-launch.git
17+
```
1918

20-
2. Development
19+
## Usage
2120

22-
```bash
23-
git clone git@github.com:swiss-ai/model-launch.git && cd model-launch
24-
uv venv --python 3.12
25-
source .venv/bin/activate
26-
uv pip install -e ".[dev]"
27-
pre-commit install
28-
```
21+
### Quick Start
2922

30-
## Usage
23+
Just run:
24+
25+
```bash
26+
sml
27+
```
28+
29+
That's it. On first run, SML will guide you through a one-time setup. After that, running `sml` again will take you straight to launching a model.
3130

32-
### Initialization
31+
The rest of this section documents subcommands and CLI arguments for advanced or automated use cases.
3332

34-
The first time you run `sml` command, you will be prompted to do the initialization, which includes providing necessary credentials and configurations.
33+
### Subcommands
3534

36-
There is three ways to initialize the mean of launching commands for the CLI as listed below.
35+
| Command | Description |
36+
| ---------------- | -------------------------------------------------------- |
37+
| `sml init` | Initialize SML configuration |
38+
| `sml quickstart` | Launch a model with guided prompts |
39+
| `sml advanced` | Launch a model with advanced configuration (coming soon) |
3740

38-
- FirecREST: You will be able to run the CLI on your local machine and the CLI will use FirecREST to submit jobs. You will need to provide your FirecREST credentials during the initialization. If you don't have the credentials, you can follow the instructions in the [Appendix](#acquiring-firecrest-credentials) to acquire them.
41+
### Initialization (`sml init`)
42+
43+
Run `sml init` to configure SML. You will be prompted to provide necessary credentials and configurations.
44+
45+
There are three ways to initialize the launcher:
46+
47+
- FirecREST: Run the CLI on your local machine; jobs are submitted via FirecREST. You will need to provide your FirecREST credentials. If you don't have them, follow the instructions in the [Appendix](#acquiring-firecrest-credentials).
3948
- Remote Launcher: Not operational yet.
4049
- SLURM: Not operational yet.
4150

42-
For health check, you will be prompted to provide your CSCS API key. If you don't have the API key, you can follow the instructions in the [Appendix](#acquiring-cscs-api-key) to acquire it.
51+
For health check, you will be prompted to provide your CSCS API key. If you don't have the API key, follow the instructions in the [Appendix](#acquiring-cscs-api-key).
52+
53+
All prompts can be pre-filled via CLI arguments to skip interactive prompts:
54+
55+
| Argument | Description |
56+
| ------------------------------ | ------------------------------------------------------ |
57+
| `--launcher` | Job submission method (`firecrest`, `remote`, `slurm`) |
58+
| `--firecrest-url` | FirecREST API URL |
59+
| `--firecrest-token-uri` | FirecREST token URI |
60+
| `--firecrest-client-id` | FirecREST client ID |
61+
| `--firecrest-client-secret` | FirecREST client secret |
62+
| `--remote-launcher-address` | Remote launcher address (if using `remote`) |
63+
| `--remote-launcher-auth-token` | Remote launcher auth token (if using `remote`) |
64+
| `--cscs-api-key` | CSCS API key for health checks |
65+
| `--telemetry-endpoint` | Endpoint for telemetry reports |
66+
67+
### Launching a Model (`sml quickstart`)
4368

44-
### Launching a Model
69+
After completing initialization, run `sml quickstart` (or just `sml`). The CLI will guide you through selecting a model and providing the necessary launch configuration.
4570

46-
After completing the initialization, you can simply run the `sml` command. The CLI will guide you through the process of launching a model, which includes selecting a model, providing necessary information for the launch, and confirming the launch.
71+
All prompts can be pre-filled via CLI arguments to skip interactive prompts:
72+
73+
| Argument | Description |
74+
| ----------------------- | -------------------------------------------- |
75+
| `--firecrest-system` | Target HPC system to launch on |
76+
| `--firecrest-partition` | SLURM partition to use |
77+
| `--model` | Model to launch (`<vendor>::<model>`) |
78+
| `--framework` | Inference framework to use |
79+
| `--workers` | Number of workers |
80+
| `--use-router` | Load balance across workers (`yes`, `no`) |
81+
| `--time` | Job time limit (`HH:MM:SS`) |
4782

4883
## Development
4984

85+
### Setting Up Development Environment
86+
87+
```bash
88+
git clone git@github.com:swiss-ai/model-launch.git && cd model-launch
89+
uv venv --python 3.12
90+
source .venv/bin/activate
91+
uv pip install -e ".[dev]"
92+
pre-commit install
93+
```
94+
5095
### Testing Environment
5196

5297
For writing the unit tests, you have to create a `.test.sh` file in the root of the repository with the following content:
@@ -62,6 +107,8 @@ export FIRECREST_PARTITION=normal
62107
export CSCS_API_KEY=<your-api-key>
63108
```
64109

110+
This file will be sourced when running the tests with `make test`, and the environment variables will be available for the tests.
111+
65112
### Common Commands
66113

67114
There is a `Makefile` with common development commands.
@@ -94,7 +141,7 @@ There is a `Makefile` with common development commands.
94141

95142
### Acquiring FirecREST Credentials
96143

97-
Please follow the instructions in the [FirecREST documentation](https://docs.cscs.ch/services/devportal/#manage-your-applications) to acquire the necessary credentials for authentication.
144+
Please follow the instructions in the [FirecREST documentation](https://docs.cscs.ch/services/devportal/#manage-your-applications) to acquire the necessary credentials for authentication from [Developer Portal](https://developer.svc.cscs.ch/devportal/apis).
98145

99146
### Acquiring CSCS API Key
100147

src/swiss_ai_model_launch/cli/main.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,19 @@ def _build_parser() -> argparse.ArgumentParser:
129129
prog="sml",
130130
description="Swiss AI Model Launcher",
131131
)
132-
InitConfig().add_to_parser(parser)
133-
_make_firecrest_launcher_config().add_to_parser(parser)
134-
_make_launch_request_config().add_to_parser(parser)
132+
subparsers = parser.add_subparsers(dest="subcommand", required=False)
133+
134+
init_parser = subparsers.add_parser("init", help="Initialize SML configuration")
135+
InitConfig().add_to_parser(init_parser)
136+
137+
quickstart_parser = subparsers.add_parser(
138+
"quickstart", help="Launch a model with guided prompts"
139+
)
140+
_make_firecrest_launcher_config().add_to_parser(quickstart_parser)
141+
_make_launch_request_config().add_to_parser(quickstart_parser)
142+
143+
subparsers.add_parser("advanced", help="Launch a model with advanced configuration")
144+
135145
return parser
136146

137147

@@ -302,9 +312,9 @@ async def _get_frameworks(
302312
)
303313

304314

305-
async def _main(args: argparse.Namespace) -> None:
315+
async def _run_quickstart(args: argparse.Namespace) -> None:
306316
if not InitConfig.exists():
307-
await _run_initial_configuration_wizard(args)
317+
print("SML is not configured. Run `sml init` first.")
308318
return
309319

310320
config = InitConfig.load()
@@ -345,6 +355,16 @@ async def _monitor() -> None:
345355
await LiveDisplay(state).run(_monitor())
346356

347357

358+
async def _main(args: argparse.Namespace) -> None:
359+
subcommand = args.subcommand or ("quickstart" if InitConfig.exists() else "init")
360+
if subcommand == "init":
361+
await _run_initial_configuration_wizard(args)
362+
elif subcommand == "quickstart":
363+
await _run_quickstart(args)
364+
elif subcommand == "advanced":
365+
raise NotImplementedError("Advanced configuration is not yet implemented.")
366+
367+
348368
def main() -> None:
349369
args = _build_parser().parse_args()
350370
asyncio.run(_main(args))

0 commit comments

Comments
 (0)