|
6 | 6 | from together.together_response import TogetherResponse
|
7 | 7 | from together.types import (
|
8 | 8 | ModelObject,
|
| 9 | + ModelUploadRequest, |
| 10 | + ModelUploadResponse, |
9 | 11 | TogetherClient,
|
10 | 12 | TogetherRequest,
|
11 | 13 | )
|
@@ -85,6 +87,64 @@ def list(
|
85 | 87 |
|
86 | 88 | return models
|
87 | 89 |
|
| 90 | + def upload( |
| 91 | + self, |
| 92 | + *, |
| 93 | + model_name: str, |
| 94 | + model_source: str, |
| 95 | + model_type: str = "model", |
| 96 | + hf_token: str | None = None, |
| 97 | + description: str | None = None, |
| 98 | + base_model: str | None = None, |
| 99 | + lora_model: str | None = None, |
| 100 | + ) -> ModelUploadResponse: |
| 101 | + """ |
| 102 | + Upload a custom model or adapter from Hugging Face or S3. |
| 103 | +
|
| 104 | + Args: |
| 105 | + model_name (str): The name to give to your uploaded model |
| 106 | + model_source (str): The source location of the model (Hugging Face repo or S3 path) |
| 107 | + model_type (str, optional): Whether the model is a full model or an adapter. Defaults to "model". |
| 108 | + hf_token (str, optional): Hugging Face token (if uploading from Hugging Face) |
| 109 | + description (str, optional): A description of your model |
| 110 | + base_model (str, optional): The base model to use for an adapter if setting it to run against a serverless pool. Only used for model_type "adapter". |
| 111 | + lora_model (str, optional): The lora pool to use for an adapter if setting it to run against, say, a dedicated pool. Only used for model_type "adapter". |
| 112 | +
|
| 113 | + Returns: |
| 114 | + ModelUploadResponse: Object containing upload job information |
| 115 | + """ |
| 116 | + requestor = api_requestor.APIRequestor( |
| 117 | + client=self._client, |
| 118 | + ) |
| 119 | + |
| 120 | + data = { |
| 121 | + "model_name": model_name, |
| 122 | + "model_source": model_source, |
| 123 | + "model_type": model_type, |
| 124 | + } |
| 125 | + |
| 126 | + if hf_token is not None: |
| 127 | + data["hf_token"] = hf_token |
| 128 | + if description is not None: |
| 129 | + data["description"] = description |
| 130 | + if base_model is not None: |
| 131 | + data["base_model"] = base_model |
| 132 | + if lora_model is not None: |
| 133 | + data["lora_model"] = lora_model |
| 134 | + |
| 135 | + response, _, _ = requestor.request( |
| 136 | + options=TogetherRequest( |
| 137 | + method="POST", |
| 138 | + url="models", |
| 139 | + params=data, |
| 140 | + ), |
| 141 | + stream=False, |
| 142 | + ) |
| 143 | + |
| 144 | + assert isinstance(response, TogetherResponse) |
| 145 | + |
| 146 | + return ModelUploadResponse.from_api_response(response.data) |
| 147 | + |
88 | 148 |
|
89 | 149 | class AsyncModels(ModelsBase):
|
90 | 150 | async def list(
|
@@ -132,3 +192,61 @@ async def list(
|
132 | 192 | models.sort(key=lambda x: x.id.lower())
|
133 | 193 |
|
134 | 194 | return models
|
| 195 | + |
| 196 | + async def upload( |
| 197 | + self, |
| 198 | + *, |
| 199 | + model_name: str, |
| 200 | + model_source: str, |
| 201 | + model_type: str = "model", |
| 202 | + hf_token: str | None = None, |
| 203 | + description: str | None = None, |
| 204 | + base_model: str | None = None, |
| 205 | + lora_model: str | None = None, |
| 206 | + ) -> ModelUploadResponse: |
| 207 | + """ |
| 208 | + Upload a custom model or adapter from Hugging Face or S3. |
| 209 | +
|
| 210 | + Args: |
| 211 | + model_name (str): The name to give to your uploaded model |
| 212 | + model_source (str): The source location of the model (Hugging Face repo or S3 path) |
| 213 | + model_type (str, optional): Whether the model is a full model or an adapter. Defaults to "model". |
| 214 | + hf_token (str, optional): Hugging Face token (if uploading from Hugging Face) |
| 215 | + description (str, optional): A description of your model |
| 216 | + base_model (str, optional): The base model to use for an adapter if setting it to run against a serverless pool. Only used for model_type "adapter". |
| 217 | + lora_model (str, optional): The lora pool to use for an adapter if setting it to run against, say, a dedicated pool. Only used for model_type "adapter". |
| 218 | +
|
| 219 | + Returns: |
| 220 | + ModelUploadResponse: Object containing upload job information |
| 221 | + """ |
| 222 | + requestor = api_requestor.APIRequestor( |
| 223 | + client=self._client, |
| 224 | + ) |
| 225 | + |
| 226 | + data = { |
| 227 | + "model_name": model_name, |
| 228 | + "model_source": model_source, |
| 229 | + "model_type": model_type, |
| 230 | + } |
| 231 | + |
| 232 | + if hf_token is not None: |
| 233 | + data["hf_token"] = hf_token |
| 234 | + if description is not None: |
| 235 | + data["description"] = description |
| 236 | + if base_model is not None: |
| 237 | + data["base_model"] = base_model |
| 238 | + if lora_model is not None: |
| 239 | + data["lora_model"] = lora_model |
| 240 | + |
| 241 | + response, _, _ = await requestor.arequest( |
| 242 | + options=TogetherRequest( |
| 243 | + method="POST", |
| 244 | + url="models", |
| 245 | + params=data, |
| 246 | + ), |
| 247 | + stream=False, |
| 248 | + ) |
| 249 | + |
| 250 | + assert isinstance(response, TogetherResponse) |
| 251 | + |
| 252 | + return ModelUploadResponse.from_api_response(response.data) |
0 commit comments