together 1.5.17__py3-none-any.whl → 2.0.0a8__py3-none-any.whl
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/__init__.py +101 -63
- together/_base_client.py +1995 -0
- together/_client.py +1033 -0
- together/_compat.py +219 -0
- together/_constants.py +14 -0
- together/_exceptions.py +108 -0
- together/_files.py +123 -0
- together/_models.py +857 -0
- together/_qs.py +150 -0
- together/_resource.py +43 -0
- together/_response.py +830 -0
- together/_streaming.py +370 -0
- together/_types.py +260 -0
- together/_utils/__init__.py +64 -0
- together/_utils/_compat.py +45 -0
- together/_utils/_datetime_parse.py +136 -0
- together/_utils/_logs.py +25 -0
- together/_utils/_proxy.py +65 -0
- together/_utils/_reflection.py +42 -0
- together/_utils/_resources_proxy.py +24 -0
- together/_utils/_streams.py +12 -0
- together/_utils/_sync.py +58 -0
- together/_utils/_transform.py +457 -0
- together/_utils/_typing.py +156 -0
- together/_utils/_utils.py +421 -0
- together/_version.py +4 -0
- together/lib/.keep +4 -0
- together/lib/__init__.py +23 -0
- together/{cli → lib/cli}/api/endpoints.py +108 -75
- together/lib/cli/api/evals.py +588 -0
- together/{cli → lib/cli}/api/files.py +20 -17
- together/{cli/api/finetune.py → lib/cli/api/fine_tuning.py} +161 -120
- together/lib/cli/api/models.py +140 -0
- together/{cli → lib/cli}/api/utils.py +6 -7
- together/{cli → lib/cli}/cli.py +16 -24
- together/{constants.py → lib/constants.py} +17 -12
- together/lib/resources/__init__.py +11 -0
- together/lib/resources/files.py +999 -0
- together/lib/resources/fine_tuning.py +280 -0
- together/lib/resources/models.py +35 -0
- together/lib/types/__init__.py +13 -0
- together/lib/types/error.py +9 -0
- together/lib/types/fine_tuning.py +455 -0
- together/{utils → lib/utils}/__init__.py +6 -14
- together/{utils → lib/utils}/_log.py +11 -16
- together/lib/utils/files.py +628 -0
- together/lib/utils/serializer.py +10 -0
- together/{utils → lib/utils}/tools.py +19 -55
- together/resources/__init__.py +225 -33
- together/resources/audio/__init__.py +72 -21
- together/resources/audio/audio.py +198 -0
- together/resources/audio/speech.py +574 -122
- together/resources/audio/transcriptions.py +282 -0
- together/resources/audio/translations.py +256 -0
- together/resources/audio/voices.py +135 -0
- together/resources/batches.py +417 -0
- together/resources/chat/__init__.py +30 -21
- together/resources/chat/chat.py +102 -0
- together/resources/chat/completions.py +1063 -263
- together/resources/code_interpreter/__init__.py +33 -0
- together/resources/code_interpreter/code_interpreter.py +258 -0
- together/resources/code_interpreter/sessions.py +135 -0
- together/resources/completions.py +884 -225
- together/resources/embeddings.py +172 -68
- together/resources/endpoints.py +598 -395
- together/resources/evals.py +452 -0
- together/resources/files.py +398 -121
- together/resources/fine_tuning.py +1033 -0
- together/resources/hardware.py +181 -0
- together/resources/images.py +256 -108
- together/resources/jobs.py +214 -0
- together/resources/models.py +238 -90
- together/resources/rerank.py +190 -92
- together/resources/videos.py +374 -0
- together/types/__init__.py +65 -109
- together/types/audio/__init__.py +10 -0
- together/types/audio/speech_create_params.py +75 -0
- together/types/audio/transcription_create_params.py +54 -0
- together/types/audio/transcription_create_response.py +111 -0
- together/types/audio/translation_create_params.py +40 -0
- together/types/audio/translation_create_response.py +70 -0
- together/types/audio/voice_list_response.py +23 -0
- together/types/audio_speech_stream_chunk.py +16 -0
- together/types/autoscaling.py +13 -0
- together/types/autoscaling_param.py +15 -0
- together/types/batch_create_params.py +24 -0
- together/types/batch_create_response.py +14 -0
- together/types/batch_job.py +45 -0
- together/types/batch_list_response.py +10 -0
- together/types/chat/__init__.py +18 -0
- together/types/chat/chat_completion.py +60 -0
- together/types/chat/chat_completion_chunk.py +61 -0
- together/types/chat/chat_completion_structured_message_image_url_param.py +18 -0
- together/types/chat/chat_completion_structured_message_text_param.py +13 -0
- together/types/chat/chat_completion_structured_message_video_url_param.py +18 -0
- together/types/chat/chat_completion_usage.py +13 -0
- together/types/chat/chat_completion_warning.py +9 -0
- together/types/chat/completion_create_params.py +329 -0
- together/types/code_interpreter/__init__.py +5 -0
- together/types/code_interpreter/session_list_response.py +31 -0
- together/types/code_interpreter_execute_params.py +45 -0
- together/types/completion.py +42 -0
- together/types/completion_chunk.py +66 -0
- together/types/completion_create_params.py +138 -0
- together/types/dedicated_endpoint.py +44 -0
- together/types/embedding.py +24 -0
- together/types/embedding_create_params.py +31 -0
- together/types/endpoint_create_params.py +43 -0
- together/types/endpoint_list_avzones_response.py +11 -0
- together/types/endpoint_list_params.py +18 -0
- together/types/endpoint_list_response.py +41 -0
- together/types/endpoint_update_params.py +27 -0
- together/types/eval_create_params.py +263 -0
- together/types/eval_create_response.py +16 -0
- together/types/eval_list_params.py +21 -0
- together/types/eval_list_response.py +10 -0
- together/types/eval_status_response.py +100 -0
- together/types/evaluation_job.py +139 -0
- together/types/execute_response.py +108 -0
- together/types/file_delete_response.py +13 -0
- together/types/file_list.py +12 -0
- together/types/file_purpose.py +9 -0
- together/types/file_response.py +31 -0
- together/types/file_type.py +7 -0
- together/types/fine_tuning_cancel_response.py +194 -0
- together/types/fine_tuning_content_params.py +24 -0
- together/types/fine_tuning_delete_params.py +11 -0
- together/types/fine_tuning_delete_response.py +12 -0
- together/types/fine_tuning_list_checkpoints_response.py +21 -0
- together/types/fine_tuning_list_events_response.py +12 -0
- together/types/fine_tuning_list_response.py +199 -0
- together/types/finetune_event.py +41 -0
- together/types/finetune_event_type.py +33 -0
- together/types/finetune_response.py +177 -0
- together/types/hardware_list_params.py +16 -0
- together/types/hardware_list_response.py +58 -0
- together/types/image_data_b64.py +15 -0
- together/types/image_data_url.py +15 -0
- together/types/image_file.py +23 -0
- together/types/image_generate_params.py +85 -0
- together/types/job_list_response.py +47 -0
- together/types/job_retrieve_response.py +43 -0
- together/types/log_probs.py +18 -0
- together/types/model_list_response.py +10 -0
- together/types/model_object.py +42 -0
- together/types/model_upload_params.py +36 -0
- together/types/model_upload_response.py +23 -0
- together/types/rerank_create_params.py +36 -0
- together/types/rerank_create_response.py +36 -0
- together/types/tool_choice.py +23 -0
- together/types/tool_choice_param.py +23 -0
- together/types/tools_param.py +23 -0
- together/types/training_method_dpo.py +22 -0
- together/types/training_method_sft.py +18 -0
- together/types/video_create_params.py +86 -0
- together/types/video_job.py +57 -0
- together-2.0.0a8.dist-info/METADATA +680 -0
- together-2.0.0a8.dist-info/RECORD +164 -0
- {together-1.5.17.dist-info → together-2.0.0a8.dist-info}/WHEEL +1 -1
- together-2.0.0a8.dist-info/entry_points.txt +2 -0
- {together-1.5.17.dist-info → together-2.0.0a8.dist-info/licenses}/LICENSE +1 -1
- together/abstract/api_requestor.py +0 -729
- together/cli/api/chat.py +0 -276
- together/cli/api/completions.py +0 -119
- together/cli/api/images.py +0 -93
- together/cli/api/models.py +0 -55
- together/client.py +0 -176
- together/error.py +0 -194
- together/filemanager.py +0 -389
- together/legacy/__init__.py +0 -0
- together/legacy/base.py +0 -27
- together/legacy/complete.py +0 -93
- together/legacy/embeddings.py +0 -27
- together/legacy/files.py +0 -146
- together/legacy/finetune.py +0 -177
- together/legacy/images.py +0 -27
- together/legacy/models.py +0 -44
- together/resources/batch.py +0 -136
- together/resources/code_interpreter.py +0 -82
- together/resources/finetune.py +0 -1064
- together/together_response.py +0 -50
- together/types/abstract.py +0 -26
- together/types/audio_speech.py +0 -110
- together/types/batch.py +0 -53
- together/types/chat_completions.py +0 -197
- together/types/code_interpreter.py +0 -57
- together/types/common.py +0 -66
- together/types/completions.py +0 -107
- together/types/embeddings.py +0 -35
- together/types/endpoints.py +0 -123
- together/types/error.py +0 -16
- together/types/files.py +0 -90
- together/types/finetune.py +0 -398
- together/types/images.py +0 -44
- together/types/models.py +0 -45
- together/types/rerank.py +0 -43
- together/utils/api_helpers.py +0 -124
- together/utils/files.py +0 -425
- together/version.py +0 -6
- together-1.5.17.dist-info/METADATA +0 -525
- together-1.5.17.dist-info/RECORD +0 -69
- together-1.5.17.dist-info/entry_points.txt +0 -3
- /together/{abstract → lib/cli}/__init__.py +0 -0
- /together/{cli → lib/cli/api}/__init__.py +0 -0
- /together/{cli/api/__init__.py → py.typed} +0 -0
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import json
|
|
3
|
+
from typing import Any, Dict, List, Union, Literal, TypeVar, Callable, Optional, cast
|
|
4
|
+
from functools import wraps
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from tabulate import tabulate
|
|
8
|
+
|
|
9
|
+
from together import APIError, Together, TogetherError
|
|
10
|
+
from together._types import omit
|
|
11
|
+
from together.lib.utils.serializer import datetime_serializer
|
|
12
|
+
from together.types.eval_create_params import (
|
|
13
|
+
ParametersEvaluationScoreParameters,
|
|
14
|
+
ParametersEvaluationCompareParameters,
|
|
15
|
+
ParametersEvaluationClassifyParameters,
|
|
16
|
+
ParametersEvaluationScoreParametersJudge,
|
|
17
|
+
ParametersEvaluationCompareParametersJudge,
|
|
18
|
+
ParametersEvaluationClassifyParametersJudge,
|
|
19
|
+
ParametersEvaluationScoreParametersModelToEvaluate,
|
|
20
|
+
ParametersEvaluationClassifyParametersModelToEvaluate,
|
|
21
|
+
ParametersEvaluationCompareParametersModelAEvaluationModelRequest,
|
|
22
|
+
ParametersEvaluationCompareParametersModelBEvaluationModelRequest,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def print_api_error(e: Union[APIError, TogetherError]) -> None:
|
|
27
|
+
if isinstance(e, APIError):
|
|
28
|
+
error_details = cast(Dict[str, Any], e.body)["error"]["message"]
|
|
29
|
+
|
|
30
|
+
if error_details and ("credentials" in error_details.lower() or "authentication" in error_details.lower()):
|
|
31
|
+
click.echo("Error: Invalid API key or authentication failed", err=True)
|
|
32
|
+
else:
|
|
33
|
+
click.echo(f"Error: {error_details}", err=True)
|
|
34
|
+
|
|
35
|
+
click.echo(f"Error: {e}", err=True)
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def handle_api_errors(f: F) -> F:
|
|
43
|
+
"""Decorator to handle common API errors in CLI commands."""
|
|
44
|
+
|
|
45
|
+
@wraps(f)
|
|
46
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
47
|
+
try:
|
|
48
|
+
return f(*args, **kwargs)
|
|
49
|
+
except APIError as e:
|
|
50
|
+
print_api_error(e)
|
|
51
|
+
sys.exit(1)
|
|
52
|
+
except TogetherError as e:
|
|
53
|
+
print_api_error(e)
|
|
54
|
+
sys.exit(1)
|
|
55
|
+
except Exception as e:
|
|
56
|
+
click.echo(f"Error: An unexpected error occurred - {str(e)}", err=True)
|
|
57
|
+
sys.exit(1)
|
|
58
|
+
|
|
59
|
+
return wrapper # type: ignore
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@click.group()
|
|
63
|
+
@click.pass_context
|
|
64
|
+
def evals(ctx: click.Context) -> None:
|
|
65
|
+
"""Evals API commands"""
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@evals.command()
|
|
70
|
+
@click.pass_context
|
|
71
|
+
@click.option(
|
|
72
|
+
"--type",
|
|
73
|
+
type=click.Choice(["classify", "score", "compare"]),
|
|
74
|
+
required=True,
|
|
75
|
+
help="Type of evaluation to create.",
|
|
76
|
+
)
|
|
77
|
+
@click.option(
|
|
78
|
+
"--judge-model",
|
|
79
|
+
type=str,
|
|
80
|
+
required=True,
|
|
81
|
+
help="Name or URL of the judge model to use for evaluation.",
|
|
82
|
+
)
|
|
83
|
+
@click.option(
|
|
84
|
+
"--judge-model-source",
|
|
85
|
+
type=click.Choice(["serverless", "dedicated", "external"]),
|
|
86
|
+
required=True,
|
|
87
|
+
help="Source of the judge model.",
|
|
88
|
+
)
|
|
89
|
+
@click.option(
|
|
90
|
+
"--judge-external-api-token",
|
|
91
|
+
type=str,
|
|
92
|
+
required=False,
|
|
93
|
+
help="Optional external API token for the judge model.",
|
|
94
|
+
)
|
|
95
|
+
@click.option(
|
|
96
|
+
"--judge-external-base-url",
|
|
97
|
+
type=str,
|
|
98
|
+
required=False,
|
|
99
|
+
help="Optional external base URLs for the judge model.",
|
|
100
|
+
)
|
|
101
|
+
@click.option(
|
|
102
|
+
"--judge-system-template",
|
|
103
|
+
type=str,
|
|
104
|
+
required=True,
|
|
105
|
+
help="System template for the judge model.",
|
|
106
|
+
)
|
|
107
|
+
@click.option(
|
|
108
|
+
"--input-data-file-path",
|
|
109
|
+
type=str,
|
|
110
|
+
required=True,
|
|
111
|
+
help="Path to the input data file.",
|
|
112
|
+
)
|
|
113
|
+
@click.option(
|
|
114
|
+
"--model-field",
|
|
115
|
+
type=str,
|
|
116
|
+
help="Name of the field in the input file contaning text generated by the model."
|
|
117
|
+
"Can not be used when model-a-name and other model config parameters are specified",
|
|
118
|
+
)
|
|
119
|
+
@click.option(
|
|
120
|
+
"--model-to-evaluate",
|
|
121
|
+
type=str,
|
|
122
|
+
help="Model name when using the detailed config",
|
|
123
|
+
)
|
|
124
|
+
@click.option(
|
|
125
|
+
"--model-to-evaluate-source",
|
|
126
|
+
type=click.Choice(["serverless", "dedicated", "external"]),
|
|
127
|
+
help="Source of the model to evaluate.",
|
|
128
|
+
)
|
|
129
|
+
@click.option(
|
|
130
|
+
"--model-to-evaluate-external-api-token",
|
|
131
|
+
type=str,
|
|
132
|
+
help="Optional external API token for the model to evaluate.",
|
|
133
|
+
)
|
|
134
|
+
@click.option(
|
|
135
|
+
"--model-to-evaluate-external-base-url",
|
|
136
|
+
type=str,
|
|
137
|
+
help="Optional external base URL for the model to evaluate.",
|
|
138
|
+
)
|
|
139
|
+
@click.option(
|
|
140
|
+
"--model-to-evaluate-max-tokens",
|
|
141
|
+
type=int,
|
|
142
|
+
help="Max tokens for model-to-evaluate",
|
|
143
|
+
)
|
|
144
|
+
@click.option(
|
|
145
|
+
"--model-to-evaluate-temperature",
|
|
146
|
+
type=float,
|
|
147
|
+
help="Temperature for model-to-evaluate",
|
|
148
|
+
)
|
|
149
|
+
@click.option(
|
|
150
|
+
"--model-to-evaluate-system-template",
|
|
151
|
+
type=str,
|
|
152
|
+
help="System template for model-to-evaluate",
|
|
153
|
+
)
|
|
154
|
+
@click.option(
|
|
155
|
+
"--model-to-evaluate-input-template",
|
|
156
|
+
type=str,
|
|
157
|
+
help="Input template for model-to-evaluate",
|
|
158
|
+
)
|
|
159
|
+
@click.option(
|
|
160
|
+
"--labels",
|
|
161
|
+
type=str,
|
|
162
|
+
help="Classification labels - comma-separated list",
|
|
163
|
+
)
|
|
164
|
+
@click.option(
|
|
165
|
+
"--pass-labels",
|
|
166
|
+
type=str,
|
|
167
|
+
help="Labels considered as passing (required for classify type). A comma-separated list.",
|
|
168
|
+
)
|
|
169
|
+
@click.option(
|
|
170
|
+
"--min-score",
|
|
171
|
+
type=float,
|
|
172
|
+
help="Minimum score value (required for score type).",
|
|
173
|
+
)
|
|
174
|
+
@click.option(
|
|
175
|
+
"--max-score",
|
|
176
|
+
type=float,
|
|
177
|
+
help="Maximum score value (required for score type).",
|
|
178
|
+
)
|
|
179
|
+
@click.option(
|
|
180
|
+
"--pass-threshold",
|
|
181
|
+
type=float,
|
|
182
|
+
help="Threshold score for passing (required for score type).",
|
|
183
|
+
)
|
|
184
|
+
@click.option(
|
|
185
|
+
"--model-a-field",
|
|
186
|
+
type=str,
|
|
187
|
+
help="Name of the field in the input file containing text generated by Model A. \
|
|
188
|
+
Can not be used when model-a-name and other model config parameters are specified",
|
|
189
|
+
)
|
|
190
|
+
@click.option(
|
|
191
|
+
"--model-a",
|
|
192
|
+
type=str,
|
|
193
|
+
help="Model name or URL for model A when using detailed config.",
|
|
194
|
+
)
|
|
195
|
+
@click.option(
|
|
196
|
+
"--model-a-source",
|
|
197
|
+
type=click.Choice(["serverless", "dedicated", "external"]),
|
|
198
|
+
help="Source of model A.",
|
|
199
|
+
)
|
|
200
|
+
@click.option(
|
|
201
|
+
"--model-a-external-api-token",
|
|
202
|
+
type=str,
|
|
203
|
+
help="Optional external API token for model A.",
|
|
204
|
+
)
|
|
205
|
+
@click.option(
|
|
206
|
+
"--model-a-external-base-url",
|
|
207
|
+
type=str,
|
|
208
|
+
help="Optional external base URL for model A.",
|
|
209
|
+
)
|
|
210
|
+
@click.option(
|
|
211
|
+
"--model-a-max-tokens",
|
|
212
|
+
type=int,
|
|
213
|
+
help="Max tokens for model A.",
|
|
214
|
+
)
|
|
215
|
+
@click.option(
|
|
216
|
+
"--model-a-temperature",
|
|
217
|
+
type=float,
|
|
218
|
+
help="Temperature for model A.",
|
|
219
|
+
)
|
|
220
|
+
@click.option(
|
|
221
|
+
"--model-a-system-template",
|
|
222
|
+
type=str,
|
|
223
|
+
help="System template for model A.",
|
|
224
|
+
)
|
|
225
|
+
@click.option(
|
|
226
|
+
"--model-a-input-template",
|
|
227
|
+
type=str,
|
|
228
|
+
help="Input template for model A.",
|
|
229
|
+
)
|
|
230
|
+
@click.option(
|
|
231
|
+
"--model-b-field",
|
|
232
|
+
type=str,
|
|
233
|
+
help="Name of the field in the input file containing text generated by Model B.\
|
|
234
|
+
Can not be used when model-b-name and other model config parameters are specified",
|
|
235
|
+
)
|
|
236
|
+
@click.option(
|
|
237
|
+
"--model-b",
|
|
238
|
+
type=str,
|
|
239
|
+
help="Model name or URL for model B when using detailed config.",
|
|
240
|
+
)
|
|
241
|
+
@click.option(
|
|
242
|
+
"--model-b-source",
|
|
243
|
+
type=click.Choice(["serverless", "dedicated", "external"]),
|
|
244
|
+
help="Source of model B.",
|
|
245
|
+
)
|
|
246
|
+
@click.option(
|
|
247
|
+
"--model-b-external-api-token",
|
|
248
|
+
type=str,
|
|
249
|
+
help="Optional external API token for model B.",
|
|
250
|
+
)
|
|
251
|
+
@click.option(
|
|
252
|
+
"--model-b-external-base-url",
|
|
253
|
+
type=str,
|
|
254
|
+
help="Optional external base URL for model B.",
|
|
255
|
+
)
|
|
256
|
+
@click.option(
|
|
257
|
+
"--model-b-max-tokens",
|
|
258
|
+
type=int,
|
|
259
|
+
help="Max tokens for model B.",
|
|
260
|
+
)
|
|
261
|
+
@click.option(
|
|
262
|
+
"--model-b-temperature",
|
|
263
|
+
type=float,
|
|
264
|
+
help="Temperature for model B.",
|
|
265
|
+
)
|
|
266
|
+
@click.option(
|
|
267
|
+
"--model-b-system-template",
|
|
268
|
+
type=str,
|
|
269
|
+
help="System template for model B.",
|
|
270
|
+
)
|
|
271
|
+
@click.option(
|
|
272
|
+
"--model-b-input-template",
|
|
273
|
+
type=str,
|
|
274
|
+
help="Input template for model B.",
|
|
275
|
+
)
|
|
276
|
+
@handle_api_errors
|
|
277
|
+
def create(
|
|
278
|
+
ctx: click.Context,
|
|
279
|
+
type: Literal["classify", "score", "compare"],
|
|
280
|
+
judge_model: str,
|
|
281
|
+
judge_model_source: Literal["serverless", "dedicated", "external"],
|
|
282
|
+
judge_system_template: str,
|
|
283
|
+
judge_external_api_token: Optional[str],
|
|
284
|
+
judge_external_base_url: Optional[str],
|
|
285
|
+
input_data_file_path: str,
|
|
286
|
+
model_field: Optional[str],
|
|
287
|
+
model_to_evaluate: Optional[str],
|
|
288
|
+
model_to_evaluate_source: Optional[str],
|
|
289
|
+
model_to_evaluate_external_api_token: Optional[str],
|
|
290
|
+
model_to_evaluate_external_base_url: Optional[str],
|
|
291
|
+
model_to_evaluate_max_tokens: Optional[int],
|
|
292
|
+
model_to_evaluate_temperature: Optional[float],
|
|
293
|
+
model_to_evaluate_system_template: Optional[str],
|
|
294
|
+
model_to_evaluate_input_template: Optional[str],
|
|
295
|
+
labels: str,
|
|
296
|
+
pass_labels: str,
|
|
297
|
+
min_score: Optional[float],
|
|
298
|
+
max_score: Optional[float],
|
|
299
|
+
pass_threshold: Optional[float],
|
|
300
|
+
model_a_field: Optional[str],
|
|
301
|
+
model_a: Optional[str],
|
|
302
|
+
model_a_source: Optional[str],
|
|
303
|
+
model_a_external_api_token: Optional[str],
|
|
304
|
+
model_a_external_base_url: Optional[str],
|
|
305
|
+
model_a_max_tokens: Optional[int],
|
|
306
|
+
model_a_temperature: Optional[float],
|
|
307
|
+
model_a_system_template: Optional[str],
|
|
308
|
+
model_a_input_template: Optional[str],
|
|
309
|
+
model_b_field: Optional[str],
|
|
310
|
+
model_b: Optional[str],
|
|
311
|
+
model_b_source: Optional[str],
|
|
312
|
+
model_b_external_api_token: Optional[str],
|
|
313
|
+
model_b_external_base_url: Optional[str],
|
|
314
|
+
model_b_max_tokens: Optional[int],
|
|
315
|
+
model_b_temperature: Optional[float],
|
|
316
|
+
model_b_system_template: Optional[str],
|
|
317
|
+
model_b_input_template: Optional[str],
|
|
318
|
+
) -> None:
|
|
319
|
+
"""Create a new evaluation job"""
|
|
320
|
+
|
|
321
|
+
client: Together = ctx.obj
|
|
322
|
+
|
|
323
|
+
# Convert strings to lists for labels
|
|
324
|
+
labels_list = labels.split(",") if labels else None
|
|
325
|
+
pass_labels_list = pass_labels.split(",") if pass_labels else None
|
|
326
|
+
|
|
327
|
+
# Build model configurations
|
|
328
|
+
model_to_evaluate_final: Union[Dict[str, Any], None, str] = None
|
|
329
|
+
|
|
330
|
+
# Check if any config parameters are provided
|
|
331
|
+
config_params_provided = any(
|
|
332
|
+
[
|
|
333
|
+
model_to_evaluate,
|
|
334
|
+
model_to_evaluate_source,
|
|
335
|
+
model_to_evaluate_max_tokens,
|
|
336
|
+
model_to_evaluate_temperature,
|
|
337
|
+
model_to_evaluate_system_template,
|
|
338
|
+
model_to_evaluate_input_template,
|
|
339
|
+
]
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
if model_field:
|
|
343
|
+
# Simple mode: model_field is provided
|
|
344
|
+
if config_params_provided:
|
|
345
|
+
raise click.BadParameter(
|
|
346
|
+
"Cannot specify both --model-field and --model-to-evaluate-* parameters. "
|
|
347
|
+
"Use either --model-field alone if your input file has pre-generated responses, "
|
|
348
|
+
"or config parameters if you want to generate it on our end"
|
|
349
|
+
)
|
|
350
|
+
model_to_evaluate_final = model_field
|
|
351
|
+
elif config_params_provided:
|
|
352
|
+
# Config mode: config parameters are provided
|
|
353
|
+
model_to_evaluate_final = {
|
|
354
|
+
"model": model_to_evaluate,
|
|
355
|
+
"model_source": model_to_evaluate_source,
|
|
356
|
+
"max_tokens": model_to_evaluate_max_tokens,
|
|
357
|
+
"temperature": model_to_evaluate_temperature,
|
|
358
|
+
"system_template": model_to_evaluate_system_template,
|
|
359
|
+
"input_template": model_to_evaluate_input_template,
|
|
360
|
+
}
|
|
361
|
+
if model_to_evaluate_external_api_token:
|
|
362
|
+
model_to_evaluate_final["external_api_token"] = model_to_evaluate_external_api_token
|
|
363
|
+
if model_to_evaluate_external_base_url:
|
|
364
|
+
model_to_evaluate_final["external_base_url"] = model_to_evaluate_external_base_url
|
|
365
|
+
|
|
366
|
+
# Build model-a configuration
|
|
367
|
+
model_a_final: Union[Dict[str, Any], None, str] = None
|
|
368
|
+
model_a_config_params = [
|
|
369
|
+
model_a,
|
|
370
|
+
model_a_source,
|
|
371
|
+
model_a_max_tokens,
|
|
372
|
+
model_a_temperature,
|
|
373
|
+
model_a_system_template,
|
|
374
|
+
model_a_input_template,
|
|
375
|
+
]
|
|
376
|
+
|
|
377
|
+
if model_a_field is not None:
|
|
378
|
+
# Simple mode: model_a_field is provided
|
|
379
|
+
if any(model_a_config_params):
|
|
380
|
+
raise click.BadParameter(
|
|
381
|
+
"Cannot specify both --model-a-field and config parameters (--model-a-name, etc.). "
|
|
382
|
+
"Use either --model-a-field alone if your input file has pre-generated responses, "
|
|
383
|
+
"or config parameters if you want to generate it on our end"
|
|
384
|
+
)
|
|
385
|
+
model_a_final = model_a_field
|
|
386
|
+
elif any(model_a_config_params):
|
|
387
|
+
# Config mode: config parameters are provided
|
|
388
|
+
model_a_final = {
|
|
389
|
+
"model": model_a,
|
|
390
|
+
"model_source": model_a_source,
|
|
391
|
+
"max_tokens": model_a_max_tokens,
|
|
392
|
+
"temperature": model_a_temperature,
|
|
393
|
+
"system_template": model_a_system_template,
|
|
394
|
+
"input_template": model_a_input_template,
|
|
395
|
+
}
|
|
396
|
+
if model_a_external_api_token:
|
|
397
|
+
model_a_final["external_api_token"] = model_a_external_api_token
|
|
398
|
+
if model_a_external_base_url:
|
|
399
|
+
model_a_final["external_base_url"] = model_a_external_base_url
|
|
400
|
+
|
|
401
|
+
# Build model-b configuration
|
|
402
|
+
model_b_final: Union[Dict[str, Any], None, str] = None
|
|
403
|
+
model_b_config_params = [
|
|
404
|
+
model_b,
|
|
405
|
+
model_b_source,
|
|
406
|
+
model_b_max_tokens,
|
|
407
|
+
model_b_temperature,
|
|
408
|
+
model_b_system_template,
|
|
409
|
+
model_b_input_template,
|
|
410
|
+
]
|
|
411
|
+
|
|
412
|
+
if model_b_field is not None:
|
|
413
|
+
# Simple mode: model_b_field is provided
|
|
414
|
+
if any(model_b_config_params):
|
|
415
|
+
raise click.BadParameter(
|
|
416
|
+
"Cannot specify both --model-b-field and config parameters (--model-b-name, etc.). "
|
|
417
|
+
"Use either --model-b-field alone if your input file has pre-generated responses, "
|
|
418
|
+
"or config parameters if you want to generate it on our end"
|
|
419
|
+
)
|
|
420
|
+
model_b_final = model_b_field
|
|
421
|
+
elif any(model_b_config_params):
|
|
422
|
+
# Config mode: config parameters are provided
|
|
423
|
+
model_b_final = {
|
|
424
|
+
"model": model_b,
|
|
425
|
+
"model_source": model_b_source,
|
|
426
|
+
"max_tokens": model_b_max_tokens,
|
|
427
|
+
"temperature": model_b_temperature,
|
|
428
|
+
"system_template": model_b_system_template,
|
|
429
|
+
"input_template": model_b_input_template,
|
|
430
|
+
}
|
|
431
|
+
if model_b_external_api_token:
|
|
432
|
+
model_b_final["external_api_token"] = model_b_external_api_token
|
|
433
|
+
if model_b_external_base_url:
|
|
434
|
+
model_b_final["external_base_url"] = model_b_external_base_url
|
|
435
|
+
|
|
436
|
+
judge_config = _build_judge(
|
|
437
|
+
type, judge_model, judge_model_source, judge_system_template, judge_external_api_token, judge_external_base_url
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
if type == "classify":
|
|
441
|
+
response = client.evals.create(
|
|
442
|
+
type=type,
|
|
443
|
+
parameters=ParametersEvaluationClassifyParameters(
|
|
444
|
+
input_data_file_path=input_data_file_path,
|
|
445
|
+
judge=judge_config,
|
|
446
|
+
labels=labels_list or [],
|
|
447
|
+
pass_labels=pass_labels_list or [],
|
|
448
|
+
model_to_evaluate=cast(ParametersEvaluationClassifyParametersModelToEvaluate, model_to_evaluate_final),
|
|
449
|
+
),
|
|
450
|
+
)
|
|
451
|
+
elif type == "score":
|
|
452
|
+
if max_score is None or min_score is None or pass_threshold is None:
|
|
453
|
+
raise TogetherError("max_score, min_score, and pass_threshold are required for score type")
|
|
454
|
+
|
|
455
|
+
response = client.evals.create(
|
|
456
|
+
type="score",
|
|
457
|
+
parameters=ParametersEvaluationScoreParameters(
|
|
458
|
+
input_data_file_path=input_data_file_path,
|
|
459
|
+
judge=judge_config,
|
|
460
|
+
max_score=max_score,
|
|
461
|
+
min_score=min_score,
|
|
462
|
+
pass_threshold=pass_threshold,
|
|
463
|
+
model_to_evaluate=cast(ParametersEvaluationScoreParametersModelToEvaluate, model_to_evaluate_final),
|
|
464
|
+
),
|
|
465
|
+
)
|
|
466
|
+
elif type == "compare":
|
|
467
|
+
response = client.evals.create(
|
|
468
|
+
type=type,
|
|
469
|
+
parameters=ParametersEvaluationCompareParameters(
|
|
470
|
+
input_data_file_path=input_data_file_path,
|
|
471
|
+
judge=judge_config,
|
|
472
|
+
model_a=cast(ParametersEvaluationCompareParametersModelAEvaluationModelRequest, model_a_final),
|
|
473
|
+
model_b=cast(ParametersEvaluationCompareParametersModelBEvaluationModelRequest, model_b_final),
|
|
474
|
+
),
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
click.echo(json.dumps(response.model_dump(exclude_none=True), indent=4))
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
@evals.command()
|
|
481
|
+
@click.pass_context
|
|
482
|
+
@click.option(
|
|
483
|
+
"--status",
|
|
484
|
+
type=click.Choice(["pending", "queued", "running", "completed", "error", "user_error"]),
|
|
485
|
+
help="Filter by job status.",
|
|
486
|
+
)
|
|
487
|
+
@click.option(
|
|
488
|
+
"--limit",
|
|
489
|
+
type=int,
|
|
490
|
+
help="Limit number of results (max 100).",
|
|
491
|
+
)
|
|
492
|
+
def list(
|
|
493
|
+
ctx: click.Context,
|
|
494
|
+
status: Union[Literal["pending", "queued", "running", "completed", "error", "user_error"], None],
|
|
495
|
+
limit: Union[int, None],
|
|
496
|
+
) -> None:
|
|
497
|
+
"""List evals"""
|
|
498
|
+
|
|
499
|
+
client: Together = ctx.obj
|
|
500
|
+
|
|
501
|
+
response = client.evals.list(status=status or omit, limit=limit or omit)
|
|
502
|
+
|
|
503
|
+
display_list: List[Dict[str, Any]] = []
|
|
504
|
+
for job in response:
|
|
505
|
+
if job.parameters:
|
|
506
|
+
model = job.parameters.get("model_to_evaluate", "")
|
|
507
|
+
model_a = job.parameters.get("model_a", "")
|
|
508
|
+
model_b = job.parameters.get("model_b", "")
|
|
509
|
+
else:
|
|
510
|
+
model = ""
|
|
511
|
+
model_a = ""
|
|
512
|
+
model_b = ""
|
|
513
|
+
|
|
514
|
+
display_list.append(
|
|
515
|
+
{
|
|
516
|
+
"Workflow ID": job.workflow_id or "",
|
|
517
|
+
"Type": job.type,
|
|
518
|
+
"Status": job.status,
|
|
519
|
+
"Created At": job.created_at or 0,
|
|
520
|
+
"Model": model,
|
|
521
|
+
"Model A": model_a,
|
|
522
|
+
"Model B": model_b,
|
|
523
|
+
}
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
table = tabulate(display_list, headers="keys", tablefmt="grid", showindex=True)
|
|
527
|
+
click.echo(table)
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
@evals.command()
|
|
531
|
+
@click.pass_context
|
|
532
|
+
@click.argument("evaluation_id", type=str, required=True)
|
|
533
|
+
def retrieve(ctx: click.Context, evaluation_id: str) -> None:
|
|
534
|
+
"""Get details of a specific evaluation job"""
|
|
535
|
+
|
|
536
|
+
client: Together = ctx.obj
|
|
537
|
+
|
|
538
|
+
response = client.evals.retrieve(evaluation_id)
|
|
539
|
+
|
|
540
|
+
click.echo(json.dumps(response.model_dump(exclude_none=True), default=datetime_serializer, indent=4))
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
@evals.command()
|
|
544
|
+
@click.pass_context
|
|
545
|
+
@click.argument("evaluation_id", type=str, required=True)
|
|
546
|
+
def status(ctx: click.Context, evaluation_id: str) -> None:
|
|
547
|
+
"""Get the status and results of a specific evaluation job"""
|
|
548
|
+
|
|
549
|
+
client: Together = ctx.obj
|
|
550
|
+
|
|
551
|
+
response = client.evals.status(evaluation_id)
|
|
552
|
+
|
|
553
|
+
click.echo(json.dumps(response.model_dump(exclude_none=True), indent=4))
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
def _build_judge(
|
|
557
|
+
type: Literal["classify", "score", "compare"],
|
|
558
|
+
judge_model: str,
|
|
559
|
+
judge_model_source: Literal["serverless", "dedicated", "external"],
|
|
560
|
+
judge_system_template: str,
|
|
561
|
+
judge_external_api_token: Optional[str],
|
|
562
|
+
judge_external_base_url: Optional[str],
|
|
563
|
+
) -> ParametersEvaluationClassifyParametersJudge:
|
|
564
|
+
if type == "classify":
|
|
565
|
+
judge_config = ParametersEvaluationClassifyParametersJudge(
|
|
566
|
+
model=judge_model,
|
|
567
|
+
model_source=judge_model_source,
|
|
568
|
+
system_template=judge_system_template,
|
|
569
|
+
)
|
|
570
|
+
elif type == "score":
|
|
571
|
+
judge_config = ParametersEvaluationScoreParametersJudge(
|
|
572
|
+
model=judge_model,
|
|
573
|
+
model_source=judge_model_source,
|
|
574
|
+
system_template=judge_system_template,
|
|
575
|
+
)
|
|
576
|
+
elif type == "compare":
|
|
577
|
+
judge_config = ParametersEvaluationCompareParametersJudge(
|
|
578
|
+
model=judge_model,
|
|
579
|
+
model_source=judge_model_source,
|
|
580
|
+
system_template=judge_system_template,
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
if judge_external_api_token:
|
|
584
|
+
judge_config["external_api_token"] = judge_external_api_token
|
|
585
|
+
if judge_external_base_url:
|
|
586
|
+
judge_config["external_base_url"] = judge_external_base_url
|
|
587
|
+
|
|
588
|
+
return judge_config
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import pathlib
|
|
3
|
+
from typing import Any, Dict, List, get_args
|
|
3
4
|
from textwrap import wrap
|
|
4
5
|
|
|
5
6
|
import click
|
|
@@ -7,7 +8,9 @@ from tabulate import tabulate
|
|
|
7
8
|
|
|
8
9
|
from together import Together
|
|
9
10
|
from together.types import FilePurpose
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
# from together.utils import check_file, convert_bytes, convert_unix_timestamp
|
|
13
|
+
from ...utils import check_file, convert_bytes, convert_unix_timestamp
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
@click.group()
|
|
@@ -21,15 +24,13 @@ def files(ctx: click.Context) -> None:
|
|
|
21
24
|
@click.pass_context
|
|
22
25
|
@click.argument(
|
|
23
26
|
"file",
|
|
24
|
-
type=click.Path(
|
|
25
|
-
exists=True, file_okay=True, resolve_path=True, readable=True, dir_okay=False
|
|
26
|
-
),
|
|
27
|
+
type=click.Path(exists=True, file_okay=True, resolve_path=True, readable=True, dir_okay=False),
|
|
27
28
|
required=True,
|
|
28
29
|
)
|
|
29
30
|
@click.option(
|
|
30
31
|
"--purpose",
|
|
31
|
-
type=
|
|
32
|
-
default=
|
|
32
|
+
type=click.Choice(get_args(FilePurpose)),
|
|
33
|
+
default="fine-tune",
|
|
33
34
|
help="Purpose of file upload. Acceptable values in enum `together.types.FilePurpose`. Defaults to `fine-tunes`.",
|
|
34
35
|
)
|
|
35
36
|
@click.option(
|
|
@@ -37,7 +38,7 @@ def files(ctx: click.Context) -> None:
|
|
|
37
38
|
default=True,
|
|
38
39
|
help="Whether to check the file before uploading.",
|
|
39
40
|
)
|
|
40
|
-
def upload(ctx: click.Context, file: pathlib.Path, purpose:
|
|
41
|
+
def upload(ctx: click.Context, file: pathlib.Path, purpose: FilePurpose, check: bool) -> None:
|
|
41
42
|
"""Upload file"""
|
|
42
43
|
|
|
43
44
|
client: Together = ctx.obj
|
|
@@ -55,15 +56,13 @@ def list(ctx: click.Context) -> None:
|
|
|
55
56
|
|
|
56
57
|
response = client.files.list()
|
|
57
58
|
|
|
58
|
-
display_list = []
|
|
59
|
+
display_list: List[Dict[str, Any]] = []
|
|
59
60
|
for i in response.data or []:
|
|
60
61
|
display_list.append(
|
|
61
62
|
{
|
|
62
63
|
"File name": "\n".join(wrap(i.filename or "", width=30)),
|
|
63
64
|
"File ID": i.id,
|
|
64
|
-
"Size": convert_bytes(
|
|
65
|
-
float(str(i.bytes))
|
|
66
|
-
), # convert to string for mypy typing
|
|
65
|
+
"Size": convert_bytes(float(str(i.bytes))), # convert to string for mypy typing
|
|
67
66
|
"Created At": convert_unix_timestamp(i.created_at or 0),
|
|
68
67
|
"Line Count": i.line_count,
|
|
69
68
|
}
|
|
@@ -95,9 +94,15 @@ def retrieve_content(ctx: click.Context, id: str, output: str) -> None:
|
|
|
95
94
|
|
|
96
95
|
client: Together = ctx.obj
|
|
97
96
|
|
|
98
|
-
response = client.files.
|
|
97
|
+
response = client.files.content(id=id)
|
|
99
98
|
|
|
100
|
-
|
|
99
|
+
if output:
|
|
100
|
+
with open(output, "wb") as f:
|
|
101
|
+
f.write(response.read())
|
|
102
|
+
click.echo(f"File saved to {output}")
|
|
103
|
+
|
|
104
|
+
else:
|
|
105
|
+
click.echo(response.read().decode("utf-8"))
|
|
101
106
|
|
|
102
107
|
|
|
103
108
|
@files.command()
|
|
@@ -117,12 +122,10 @@ def delete(ctx: click.Context, id: str) -> None:
|
|
|
117
122
|
@click.pass_context
|
|
118
123
|
@click.argument(
|
|
119
124
|
"file",
|
|
120
|
-
type=click.Path(
|
|
121
|
-
exists=True, file_okay=True, resolve_path=True, readable=True, dir_okay=False
|
|
122
|
-
),
|
|
125
|
+
type=click.Path(exists=True, file_okay=True, resolve_path=True, readable=True, dir_okay=False),
|
|
123
126
|
required=True,
|
|
124
127
|
)
|
|
125
|
-
def check(
|
|
128
|
+
def check(_ctx: click.Context, file: pathlib.Path) -> None:
|
|
126
129
|
"""Check file for issues"""
|
|
127
130
|
|
|
128
131
|
report = check_file(file)
|