together 1.2.13__tar.gz → 1.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {together-1.2.13 → together-1.3.1}/PKG-INFO +2 -2
- {together-1.2.13 → together-1.3.1}/README.md +1 -1
- {together-1.2.13 → together-1.3.1}/pyproject.toml +1 -1
- {together-1.2.13 → together-1.3.1}/src/together/cli/api/finetune.py +55 -9
- {together-1.2.13 → together-1.3.1}/src/together/cli/api/images.py +12 -1
- together-1.3.1/src/together/cli/api/utils.py +21 -0
- {together-1.2.13 → together-1.3.1}/src/together/legacy/finetune.py +2 -2
- {together-1.2.13 → together-1.3.1}/src/together/resources/finetune.py +99 -11
- {together-1.2.13 → together-1.3.1}/src/together/types/__init__.py +2 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/finetune.py +18 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/images.py +3 -1
- {together-1.2.13 → together-1.3.1}/src/together/utils/__init__.py +2 -1
- {together-1.2.13 → together-1.3.1}/src/together/utils/_log.py +10 -0
- {together-1.2.13 → together-1.3.1}/LICENSE +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/__init__.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/abstract/__init__.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/abstract/api_requestor.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/cli/__init__.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/cli/api/__init__.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/cli/api/chat.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/cli/api/completions.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/cli/api/files.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/cli/api/models.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/cli/cli.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/client.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/constants.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/error.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/filemanager.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/legacy/__init__.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/legacy/base.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/legacy/complete.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/legacy/embeddings.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/legacy/files.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/legacy/images.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/legacy/models.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/__init__.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/chat/__init__.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/chat/completions.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/completions.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/embeddings.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/files.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/images.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/models.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/resources/rerank.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/together_response.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/abstract.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/chat_completions.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/common.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/completions.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/embeddings.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/error.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/files.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/models.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/types/rerank.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/utils/api_helpers.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/utils/files.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/utils/tools.py +0 -0
- {together-1.2.13 → together-1.3.1}/src/together/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: together
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: Python client for Together's Cloud Platform!
|
|
5
5
|
Home-page: https://github.com/togethercomputer/together-python
|
|
6
6
|
License: Apache-2.0
|
|
@@ -277,7 +277,7 @@ client.fine_tuning.create(
|
|
|
277
277
|
model = 'mistralai/Mixtral-8x7B-Instruct-v0.1',
|
|
278
278
|
n_epochs = 3,
|
|
279
279
|
n_checkpoints = 1,
|
|
280
|
-
batch_size =
|
|
280
|
+
batch_size = "max",
|
|
281
281
|
learning_rate = 1e-5,
|
|
282
282
|
suffix = 'my-demo-finetune',
|
|
283
283
|
wandb_api_key = '1a2b3c4d5e.......',
|
|
@@ -242,7 +242,7 @@ client.fine_tuning.create(
|
|
|
242
242
|
model = 'mistralai/Mixtral-8x7B-Instruct-v0.1',
|
|
243
243
|
n_epochs = 3,
|
|
244
244
|
n_checkpoints = 1,
|
|
245
|
-
batch_size =
|
|
245
|
+
batch_size = "max",
|
|
246
246
|
learning_rate = 1e-5,
|
|
247
247
|
suffix = 'my-demo-finetune',
|
|
248
248
|
wandb_api_key = '1a2b3c4d5e.......',
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import json
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from textwrap import wrap
|
|
6
|
+
from typing import Any, Literal
|
|
6
7
|
|
|
7
8
|
import click
|
|
8
9
|
from click.core import ParameterSource # type: ignore[attr-defined]
|
|
@@ -10,8 +11,9 @@ from rich import print as rprint
|
|
|
10
11
|
from tabulate import tabulate
|
|
11
12
|
|
|
12
13
|
from together import Together
|
|
13
|
-
from together.
|
|
14
|
+
from together.cli.api.utils import INT_WITH_MAX
|
|
14
15
|
from together.utils import finetune_price_to_dollars, log_warn, parse_timestamp
|
|
16
|
+
from together.types.finetune import DownloadCheckpointType, FinetuneTrainingLimits
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
_CONFIRMATION_MESSAGE = (
|
|
@@ -56,7 +58,7 @@ def fine_tuning(ctx: click.Context) -> None:
|
|
|
56
58
|
@click.option(
|
|
57
59
|
"--n-checkpoints", type=int, default=1, help="Number of checkpoints to save"
|
|
58
60
|
)
|
|
59
|
-
@click.option("--batch-size", type=
|
|
61
|
+
@click.option("--batch-size", type=INT_WITH_MAX, default="max", help="Train batch size")
|
|
60
62
|
@click.option("--learning-rate", type=float, default=1e-5, help="Learning rate")
|
|
61
63
|
@click.option(
|
|
62
64
|
"--lora/--no-lora",
|
|
@@ -93,7 +95,7 @@ def create(
|
|
|
93
95
|
n_epochs: int,
|
|
94
96
|
n_evals: int,
|
|
95
97
|
n_checkpoints: int,
|
|
96
|
-
batch_size: int,
|
|
98
|
+
batch_size: int | Literal["max"],
|
|
97
99
|
learning_rate: float,
|
|
98
100
|
lora: bool,
|
|
99
101
|
lora_r: int,
|
|
@@ -107,20 +109,64 @@ def create(
|
|
|
107
109
|
"""Start fine-tuning"""
|
|
108
110
|
client: Together = ctx.obj
|
|
109
111
|
|
|
112
|
+
training_args: dict[str, Any] = dict(
|
|
113
|
+
training_file=training_file,
|
|
114
|
+
model=model,
|
|
115
|
+
n_epochs=n_epochs,
|
|
116
|
+
validation_file=validation_file,
|
|
117
|
+
n_evals=n_evals,
|
|
118
|
+
n_checkpoints=n_checkpoints,
|
|
119
|
+
batch_size=batch_size,
|
|
120
|
+
learning_rate=learning_rate,
|
|
121
|
+
lora=lora,
|
|
122
|
+
lora_r=lora_r,
|
|
123
|
+
lora_dropout=lora_dropout,
|
|
124
|
+
lora_alpha=lora_alpha,
|
|
125
|
+
lora_trainable_modules=lora_trainable_modules,
|
|
126
|
+
suffix=suffix,
|
|
127
|
+
wandb_api_key=wandb_api_key,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
model_limits: FinetuneTrainingLimits = client.fine_tuning.get_model_limits(
|
|
131
|
+
model=model
|
|
132
|
+
)
|
|
133
|
+
|
|
110
134
|
if lora:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
135
|
+
if model_limits.lora_training is None:
|
|
136
|
+
raise click.BadParameter(
|
|
137
|
+
f"LoRA fine-tuning is not supported for the model `{model}`"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
default_values = {
|
|
141
|
+
"lora_r": model_limits.lora_training.max_rank,
|
|
142
|
+
"batch_size": model_limits.lora_training.max_batch_size,
|
|
143
|
+
"learning_rate": 1e-3,
|
|
144
|
+
}
|
|
145
|
+
for arg in default_values:
|
|
146
|
+
arg_source = ctx.get_parameter_source("arg") # type: ignore[attr-defined]
|
|
147
|
+
if arg_source == ParameterSource.DEFAULT:
|
|
148
|
+
training_args[arg] = default_values[arg_source]
|
|
149
|
+
|
|
150
|
+
if ctx.get_parameter_source("lora_alpha") == ParameterSource.DEFAULT: # type: ignore[attr-defined]
|
|
151
|
+
training_args["lora_alpha"] = training_args["lora_r"] * 2
|
|
116
152
|
else:
|
|
153
|
+
if model_limits.full_training is None:
|
|
154
|
+
raise click.BadParameter(
|
|
155
|
+
f"Full fine-tuning is not supported for the model `{model}`"
|
|
156
|
+
)
|
|
157
|
+
|
|
117
158
|
for param in ["lora_r", "lora_dropout", "lora_alpha", "lora_trainable_modules"]:
|
|
118
|
-
param_source =
|
|
159
|
+
param_source = ctx.get_parameter_source(param) # type: ignore[attr-defined]
|
|
119
160
|
if param_source != ParameterSource.DEFAULT:
|
|
120
161
|
raise click.BadParameter(
|
|
121
162
|
f"You set LoRA parameter `{param}` for a full fine-tuning job. "
|
|
122
163
|
f"Please change the job type with --lora or remove `{param}` from the arguments"
|
|
123
164
|
)
|
|
165
|
+
|
|
166
|
+
batch_size_source = ctx.get_parameter_source("batch_size") # type: ignore[attr-defined]
|
|
167
|
+
if batch_size_source == ParameterSource.DEFAULT:
|
|
168
|
+
training_args["batch_size"] = model_limits.full_training.max_batch_size
|
|
169
|
+
|
|
124
170
|
if n_evals <= 0 and validation_file:
|
|
125
171
|
log_warn(
|
|
126
172
|
"Warning: You have specified a validation file but the number of evaluation loops is set to 0. No evaluations will be performed."
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import pathlib
|
|
3
|
+
import requests
|
|
3
4
|
|
|
4
5
|
import click
|
|
5
6
|
from PIL import Image
|
|
@@ -70,8 +71,18 @@ def generate(
|
|
|
70
71
|
for i, choice in enumerate(response.data):
|
|
71
72
|
assert isinstance(choice, ImageChoicesData)
|
|
72
73
|
|
|
74
|
+
data = None
|
|
75
|
+
if choice.b64_json:
|
|
76
|
+
data = base64.b64decode(choice.b64_json)
|
|
77
|
+
elif choice.url:
|
|
78
|
+
data = requests.get(choice.url).content
|
|
79
|
+
|
|
80
|
+
if not data:
|
|
81
|
+
click.echo(f"Image [{i + 1}/{len(response.data)}] is empty")
|
|
82
|
+
continue
|
|
83
|
+
|
|
73
84
|
with open(f"{output}/{prefix}{choice.index}.png", "wb") as f:
|
|
74
|
-
f.write(
|
|
85
|
+
f.write(data)
|
|
75
86
|
|
|
76
87
|
click.echo(
|
|
77
88
|
f"Image [{i + 1}/{len(response.data)}] saved to {output}/{prefix}{choice.index}.png"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AutoIntParamType(click.ParamType):
|
|
7
|
+
name = "integer"
|
|
8
|
+
|
|
9
|
+
def convert(
|
|
10
|
+
self, value: str, param: click.Parameter | None, ctx: click.Context | None
|
|
11
|
+
) -> int | Literal["max"] | None:
|
|
12
|
+
if isinstance(value, int):
|
|
13
|
+
return value
|
|
14
|
+
|
|
15
|
+
if value == "max":
|
|
16
|
+
return "max"
|
|
17
|
+
|
|
18
|
+
self.fail("Invalid integer value: {value}")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
INT_WITH_MAX = AutoIntParamType()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import warnings
|
|
4
|
-
from typing import Any, Dict, List
|
|
4
|
+
from typing import Any, Dict, List, Literal
|
|
5
5
|
|
|
6
6
|
import together
|
|
7
7
|
from together.legacy.base import API_KEY_WARNING, deprecated
|
|
@@ -43,7 +43,7 @@ class Finetune:
|
|
|
43
43
|
model=model,
|
|
44
44
|
n_epochs=n_epochs,
|
|
45
45
|
n_checkpoints=n_checkpoints,
|
|
46
|
-
batch_size=batch_size,
|
|
46
|
+
batch_size=batch_size if isinstance(batch_size, int) else "max",
|
|
47
47
|
learning_rate=learning_rate,
|
|
48
48
|
suffix=suffix,
|
|
49
49
|
wandb_api_key=wandb_api_key,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from typing import Literal
|
|
4
5
|
|
|
5
6
|
from rich import print as rprint
|
|
6
7
|
|
|
@@ -13,6 +14,7 @@ from together.types import (
|
|
|
13
14
|
FinetuneListEvents,
|
|
14
15
|
FinetuneRequest,
|
|
15
16
|
FinetuneResponse,
|
|
17
|
+
FinetuneTrainingLimits,
|
|
16
18
|
FullTrainingType,
|
|
17
19
|
LoRATrainingType,
|
|
18
20
|
TogetherClient,
|
|
@@ -20,7 +22,7 @@ from together.types import (
|
|
|
20
22
|
TrainingType,
|
|
21
23
|
)
|
|
22
24
|
from together.types.finetune import DownloadCheckpointType
|
|
23
|
-
from together.utils import
|
|
25
|
+
from together.utils import log_warn_once, normalize_key
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
class FineTuning:
|
|
@@ -36,16 +38,17 @@ class FineTuning:
|
|
|
36
38
|
validation_file: str | None = "",
|
|
37
39
|
n_evals: int | None = 0,
|
|
38
40
|
n_checkpoints: int | None = 1,
|
|
39
|
-
batch_size: int |
|
|
41
|
+
batch_size: int | Literal["max"] = "max",
|
|
40
42
|
learning_rate: float | None = 0.00001,
|
|
41
43
|
lora: bool = False,
|
|
42
|
-
lora_r: int | None =
|
|
44
|
+
lora_r: int | None = None,
|
|
43
45
|
lora_dropout: float | None = 0,
|
|
44
|
-
lora_alpha: float | None =
|
|
46
|
+
lora_alpha: float | None = None,
|
|
45
47
|
lora_trainable_modules: str | None = "all-linear",
|
|
46
48
|
suffix: str | None = None,
|
|
47
49
|
wandb_api_key: str | None = None,
|
|
48
50
|
verbose: bool = False,
|
|
51
|
+
model_limits: FinetuneTrainingLimits | None = None,
|
|
49
52
|
) -> FinetuneResponse:
|
|
50
53
|
"""
|
|
51
54
|
Method to initiate a fine-tuning job
|
|
@@ -58,7 +61,7 @@ class FineTuning:
|
|
|
58
61
|
n_evals (int, optional): Number of evaluation loops to run. Defaults to 0.
|
|
59
62
|
n_checkpoints (int, optional): Number of checkpoints to save during fine-tuning.
|
|
60
63
|
Defaults to 1.
|
|
61
|
-
batch_size (int, optional): Batch size for fine-tuning. Defaults to
|
|
64
|
+
batch_size (int, optional): Batch size for fine-tuning. Defaults to max.
|
|
62
65
|
learning_rate (float, optional): Learning rate multiplier to use for training
|
|
63
66
|
Defaults to 0.00001.
|
|
64
67
|
lora (bool, optional): Whether to use LoRA adapters. Defaults to True.
|
|
@@ -72,17 +75,36 @@ class FineTuning:
|
|
|
72
75
|
Defaults to None.
|
|
73
76
|
verbose (bool, optional): whether to print the job parameters before submitting a request.
|
|
74
77
|
Defaults to False.
|
|
78
|
+
model_limits (FinetuneTrainingLimits, optional): Limits for the hyperparameters the model in Fine-tuning.
|
|
79
|
+
Defaults to None.
|
|
75
80
|
|
|
76
81
|
Returns:
|
|
77
82
|
FinetuneResponse: Object containing information about fine-tuning job.
|
|
78
83
|
"""
|
|
79
84
|
|
|
85
|
+
if batch_size == "max":
|
|
86
|
+
log_warn_once(
|
|
87
|
+
"Starting from together>=1.3.0, "
|
|
88
|
+
"the default batch size is set to the maximum allowed value for each model."
|
|
89
|
+
)
|
|
90
|
+
|
|
80
91
|
requestor = api_requestor.APIRequestor(
|
|
81
92
|
client=self._client,
|
|
82
93
|
)
|
|
83
94
|
|
|
95
|
+
if model_limits is None:
|
|
96
|
+
model_limits = self.get_model_limits(model=model)
|
|
97
|
+
|
|
84
98
|
training_type: TrainingType = FullTrainingType()
|
|
85
99
|
if lora:
|
|
100
|
+
if model_limits.lora_training is None:
|
|
101
|
+
raise ValueError(
|
|
102
|
+
"LoRA adapters are not supported for the selected model."
|
|
103
|
+
)
|
|
104
|
+
lora_r = (
|
|
105
|
+
lora_r if lora_r is not None else model_limits.lora_training.max_rank
|
|
106
|
+
)
|
|
107
|
+
lora_alpha = lora_alpha if lora_alpha is not None else lora_r * 2
|
|
86
108
|
training_type = LoRATrainingType(
|
|
87
109
|
lora_r=lora_r,
|
|
88
110
|
lora_alpha=lora_alpha,
|
|
@@ -90,6 +112,22 @@ class FineTuning:
|
|
|
90
112
|
lora_trainable_modules=lora_trainable_modules,
|
|
91
113
|
)
|
|
92
114
|
|
|
115
|
+
batch_size = (
|
|
116
|
+
batch_size
|
|
117
|
+
if batch_size != "max"
|
|
118
|
+
else model_limits.lora_training.max_batch_size
|
|
119
|
+
)
|
|
120
|
+
else:
|
|
121
|
+
if model_limits.full_training is None:
|
|
122
|
+
raise ValueError(
|
|
123
|
+
"Full training is not supported for the selected model."
|
|
124
|
+
)
|
|
125
|
+
batch_size = (
|
|
126
|
+
batch_size
|
|
127
|
+
if batch_size != "max"
|
|
128
|
+
else model_limits.full_training.max_batch_size
|
|
129
|
+
)
|
|
130
|
+
|
|
93
131
|
finetune_request = FinetuneRequest(
|
|
94
132
|
model=model,
|
|
95
133
|
training_file=training_file,
|
|
@@ -121,12 +159,6 @@ class FineTuning:
|
|
|
121
159
|
|
|
122
160
|
assert isinstance(response, TogetherResponse)
|
|
123
161
|
|
|
124
|
-
# TODO: Remove after next LoRA default change
|
|
125
|
-
log_warn(
|
|
126
|
-
"Some of the jobs run _directly_ from the together-python library might be trained using LoRA adapters. "
|
|
127
|
-
"The version range when this change occurred is from 1.2.3 to 1.2.6."
|
|
128
|
-
)
|
|
129
|
-
|
|
130
162
|
return FinetuneResponse(**response.data)
|
|
131
163
|
|
|
132
164
|
def list(self) -> FinetuneList:
|
|
@@ -305,6 +337,34 @@ class FineTuning:
|
|
|
305
337
|
size=file_size,
|
|
306
338
|
)
|
|
307
339
|
|
|
340
|
+
def get_model_limits(self, *, model: str) -> FinetuneTrainingLimits:
|
|
341
|
+
"""
|
|
342
|
+
Requests training limits for a specific model
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
model_name (str): Name of the model to get limits for
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
FinetuneTrainingLimits: Object containing training limits for the model
|
|
349
|
+
"""
|
|
350
|
+
|
|
351
|
+
requestor = api_requestor.APIRequestor(
|
|
352
|
+
client=self._client,
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
model_limits_response, _, _ = requestor.request(
|
|
356
|
+
options=TogetherRequest(
|
|
357
|
+
method="GET",
|
|
358
|
+
url="fine-tunes/models/limits",
|
|
359
|
+
params={"model_name": model},
|
|
360
|
+
),
|
|
361
|
+
stream=False,
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
model_limits = FinetuneTrainingLimits(**model_limits_response.data)
|
|
365
|
+
|
|
366
|
+
return model_limits
|
|
367
|
+
|
|
308
368
|
|
|
309
369
|
class AsyncFineTuning:
|
|
310
370
|
def __init__(self, client: TogetherClient) -> None:
|
|
@@ -493,3 +553,31 @@ class AsyncFineTuning:
|
|
|
493
553
|
"AsyncFineTuning.download not implemented. "
|
|
494
554
|
"Please use FineTuning.download function instead."
|
|
495
555
|
)
|
|
556
|
+
|
|
557
|
+
async def get_model_limits(self, *, model: str) -> FinetuneTrainingLimits:
|
|
558
|
+
"""
|
|
559
|
+
Requests training limits for a specific model
|
|
560
|
+
|
|
561
|
+
Args:
|
|
562
|
+
model_name (str): Name of the model to get limits for
|
|
563
|
+
|
|
564
|
+
Returns:
|
|
565
|
+
FinetuneTrainingLimits: Object containing training limits for the model
|
|
566
|
+
"""
|
|
567
|
+
|
|
568
|
+
requestor = api_requestor.APIRequestor(
|
|
569
|
+
client=self._client,
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
model_limits_response, _, _ = await requestor.arequest(
|
|
573
|
+
options=TogetherRequest(
|
|
574
|
+
method="GET",
|
|
575
|
+
url="fine-tunes/models/limits",
|
|
576
|
+
params={"model": model},
|
|
577
|
+
),
|
|
578
|
+
stream=False,
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
model_limits = FinetuneTrainingLimits(**model_limits_response.data)
|
|
582
|
+
|
|
583
|
+
return model_limits
|
|
@@ -29,6 +29,7 @@ from together.types.finetune import (
|
|
|
29
29
|
FullTrainingType,
|
|
30
30
|
LoRATrainingType,
|
|
31
31
|
TrainingType,
|
|
32
|
+
FinetuneTrainingLimits,
|
|
32
33
|
)
|
|
33
34
|
from together.types.images import (
|
|
34
35
|
ImageRequest,
|
|
@@ -71,4 +72,5 @@ __all__ = [
|
|
|
71
72
|
"LoRATrainingType",
|
|
72
73
|
"RerankRequest",
|
|
73
74
|
"RerankResponse",
|
|
75
|
+
"FinetuneTrainingLimits",
|
|
74
76
|
]
|
|
@@ -263,3 +263,21 @@ class FinetuneDownloadResult(BaseModel):
|
|
|
263
263
|
filename: str | None = None
|
|
264
264
|
# size in bytes
|
|
265
265
|
size: int | None = None
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
class FinetuneFullTrainingLimits(BaseModel):
|
|
269
|
+
max_batch_size: int
|
|
270
|
+
min_batch_size: int
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class FinetuneLoraTrainingLimits(FinetuneFullTrainingLimits):
|
|
274
|
+
max_rank: int
|
|
275
|
+
target_modules: List[str]
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class FinetuneTrainingLimits(BaseModel):
|
|
279
|
+
max_num_epochs: int
|
|
280
|
+
max_learning_rate: float
|
|
281
|
+
min_learning_rate: float
|
|
282
|
+
full_training: FinetuneFullTrainingLimits | None = None
|
|
283
|
+
lora_training: FinetuneLoraTrainingLimits | None = None
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from together.utils._log import log_debug, log_info, log_warn, logfmt
|
|
1
|
+
from together.utils._log import log_debug, log_info, log_warn, log_warn_once, logfmt
|
|
2
2
|
from together.utils.api_helpers import default_api_key, get_headers
|
|
3
3
|
from together.utils.files import check_file
|
|
4
4
|
from together.utils.tools import (
|
|
@@ -18,6 +18,7 @@ __all__ = [
|
|
|
18
18
|
"log_debug",
|
|
19
19
|
"log_info",
|
|
20
20
|
"log_warn",
|
|
21
|
+
"log_warn_once",
|
|
21
22
|
"logfmt",
|
|
22
23
|
"enforce_trailing_slash",
|
|
23
24
|
"normalize_key",
|
|
@@ -13,6 +13,8 @@ logger = logging.getLogger("together")
|
|
|
13
13
|
|
|
14
14
|
TOGETHER_LOG = os.environ.get("TOGETHER_LOG")
|
|
15
15
|
|
|
16
|
+
WARNING_MESSAGES_ONCE = set()
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
def _console_log_level() -> str | None:
|
|
18
20
|
if together.log in ["debug", "info"]:
|
|
@@ -59,3 +61,11 @@ def log_warn(message: str | Any, **params: Any) -> None:
|
|
|
59
61
|
msg = logfmt(dict(message=message, **params))
|
|
60
62
|
print(msg, file=sys.stderr)
|
|
61
63
|
logger.warn(msg)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def log_warn_once(message: str | Any, **params: Any) -> None:
|
|
67
|
+
msg = logfmt(dict(message=message, **params))
|
|
68
|
+
if msg not in WARNING_MESSAGES_ONCE:
|
|
69
|
+
print(msg, file=sys.stderr)
|
|
70
|
+
logger.warn(msg)
|
|
71
|
+
WARNING_MESSAGES_ONCE.add(msg)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|