Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add start and stop instance method #9

Merged
merged 10 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pip install --upgrade together

# Usage

> 🚧 You will need to create a free account with [together.ai](https://api.together.xyz/) to obtain a Together API Key.

The Python Library requires your Together API Key to be configured. This key can be found in your Account's settings on the Playground. Simply click on and navigate to Profile Button > Settings > API Keys.

The API Key can be configured by either setting the `TOGETHER_API_KEY` environment variable, like this:
Expand All @@ -25,7 +27,26 @@ import together
together.api_key = "xxxxx"
```

> 🚧 You will need to start a model instance from the Playground before you can query it from the API
Once you've provided your API key, you can browse our list of available models:

```python
import together

# set your API key
together.api_key = "xxxxx"

# list available models and descriptons
models = together.Models.list()

# print the first model's name
print(models[0]['name'])
```

Let's start an instance of one of the models in the list above. You can also start an instance by clicking play on any model in the [models playground](https://api.together.xyz/playground).

```python
together.Models.start("togethercomputer/RedPajama-INCITE-7B-Base")
```

Once you've started a model instance, you can start querying:

Expand All @@ -47,6 +68,18 @@ output = together.Complete.create("Space robots", model="togethercomputer/RedPaj
print(output['output']['choices'][0]['text'])
```

Check which models have been started or stopped:

```python
together.Models.instances()
```

To stop your model instance:

```python
together.Models.stop("togethercomputer/RedPajama-INCITE-7B-Base")
```

## Chat

The `chat` command is a CLI-based chat application that can be used for back-and-forth conversations with models in a pre-defined format.
Expand Down Expand Up @@ -88,9 +121,19 @@ together --help
# list available models
together models list

# start a model
together models start togethercomputer/RedPajama-INCITE-7B-Base

# create completion
together complete "Space robots" -m togethercomputer/RedPajama-INCITE-7B-Base

# check which models are running
together models instances

# stop a model
together models stop togethercomputer/RedPajama-INCITE-7B-Base
```

## Contributing
1. Clone the repo and make your changes
2. Run `pip install together['quality']`
Expand Down
2 changes: 2 additions & 0 deletions src/together/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
api_base_complete = urllib.parse.urljoin(api_base, "/api/inference")
api_base_files = urllib.parse.urljoin(api_base, "/v1/files/")
api_base_finetune = urllib.parse.urljoin(api_base, "/v1/fine-tunes/")
api_base_instances = urllib.parse.urljoin(api_base, "instances/")

default_text_model = "togethercomputer/RedPajama-INCITE-7B-Chat"
default_image_model = "runwayml/stable-diffusion-v1-5"
Expand All @@ -34,6 +35,7 @@
"api_base_complete",
"api_base_files",
"api_base_finetune",
"api_base_instances",
"default_text_model",
"default_image_model",
"get_logger",
Expand Down
54 changes: 54 additions & 0 deletions src/together/commands/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ def add_parser(

_add_list(child_parsers)
_add_info(child_parsers)
_add_instances(child_parsers)
_add_start(child_parsers)
_add_stop(child_parsers)


def _add_list(
Expand Down Expand Up @@ -50,6 +53,39 @@ def _add_info(
subparser.set_defaults(func=_run_info)


def _add_instances(
parser: argparse._SubParsersAction[argparse.ArgumentParser],
) -> None:
subparser = parser.add_parser("instances")
subparser.set_defaults(func=_run_instances)
clam004 marked this conversation as resolved.
Show resolved Hide resolved


def _add_start(
parser: argparse._SubParsersAction[argparse.ArgumentParser],
) -> None:
subparser = parser.add_parser("start")
subparser.add_argument(
"model",
metavar="MODEL",
help="Proper Model API string name",
type=str,
)
subparser.set_defaults(func=_run_start)


def _add_stop(
parser: argparse._SubParsersAction[argparse.ArgumentParser],
) -> None:
subparser = parser.add_parser("stop")
subparser.add_argument(
"model",
metavar="MODEL",
help="Proper Model API string name",
type=str,
)
subparser.set_defaults(func=_run_stop)


def _run_list(args: argparse.Namespace) -> None:
models = Models()
response = models.list()
Expand Down Expand Up @@ -87,3 +123,21 @@ def _run_info(args: argparse.Namespace) -> None:
model_info = {key: i[key] for key in visible_keys if key in i}
print(json.dumps(model_info, indent=4))
break


def _run_instances(args: argparse.Namespace) -> None:
models = Models()
response = models.instances()
print(json.dumps(response, indent=4))
clam004 marked this conversation as resolved.
Show resolved Hide resolved


def _run_start(args: argparse.Namespace) -> None:
models = Models()
response = models.start(args.model)
print(json.dumps(response, indent=4))


def _run_stop(args: argparse.Namespace) -> None:
models = Models()
response = models.stop(args.model)
print(json.dumps(response, indent=4))
86 changes: 85 additions & 1 deletion src/together/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import urllib.parse
from typing import Any, List
from typing import Any, Dict, List

import requests

Expand Down Expand Up @@ -42,3 +42,87 @@ def list(self) -> List[Any]:
raise together.JSONError(e, http_status=response.status_code)

return response_list

@classmethod
def instances(self) -> Dict[str, bool]:
headers = {
"Authorization": f"Bearer {together.api_key}",
"accept": "application/json",
}
try:
response = requests.get(
together.api_base_instances,
headers=headers,
)
response.raise_for_status()
except requests.exceptions.RequestException as e:
logger.critical(f"Response error raised: {e}")
raise together.ResponseError(e)

try:
response_dict = response.json()
except Exception as e:
logger.critical(
f"JSON Error raised: {e}\nResponse status code = {response.status_code}"
)
raise together.JSONError(e, http_status=response.status_code)

return dict(response_dict)

@classmethod
def start(self, model: str) -> Dict[str, str]:
model_url = urllib.parse.urljoin(
together.api_base_instances, f"start?model={model}"
)
headers = {
"Authorization": f"Bearer {together.api_key}",
"accept": "application/json",
}
try:
response = requests.post(
model_url,
headers=headers,
)
response.raise_for_status()
except requests.exceptions.RequestException as e:
logger.critical(f"Response error raised: {e}")
raise together.ResponseError(e)

try:
response_dict = response.json()
except Exception as e:
logger.critical(
f"JSON Error raised: {e}\nResponse status code = {response.status_code}"
)
raise together.JSONError(e, http_status=response.status_code)

return dict(response_dict)

@classmethod
def stop(self, model: str) -> Dict[str, str]:
model_url = urllib.parse.urljoin(
together.api_base_instances, f"stop?model={model}"
)
headers = {
"Authorization": f"Bearer {together.api_key}",
"accept": "application/json",
}
try:
response = requests.post(
model_url,
headers=headers,
)
response.raise_for_status()
except requests.exceptions.RequestException as e:
logger.critical(f"Response error raised: {e}")
raise together.ResponseError(e)

try:
response_dict = response.json()
except Exception as e:
logger.critical(
f"JSON Error raised: {e}\nResponse status code = {response.status_code}"
)
raise together.JSONError(e, http_status=response.status_code)

return dict(response_dict)
Loading