From c533f29e2b94d5d9ca97ed50c181dae0fc2dcd7b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 19 Nov 2025 19:31:32 +0000
Subject: [PATCH 1/8] chore(api): Remove auto-generated fine_tuning.create
method from Python SDK
---
.stats.yml | 4 +-
api.md | 2 -
src/together/resources/fine_tuning.py | 315 +-----------------
src/together/types/__init__.py | 9 -
.../types/cosine_lr_scheduler_args_param.py | 15 -
.../types/fine_tuning_create_params.py | 133 --------
.../types/fine_tuning_create_response.py | 121 -------
.../types/full_training_type_param.py | 11 -
.../types/linear_lr_scheduler_args_param.py | 12 -
.../types/lo_ra_training_type_param.py | 19 --
src/together/types/lr_scheduler_param.py | 19 --
.../types/training_method_dpo_param.py | 21 --
.../types/training_method_sft_param.py | 18 -
tests/api_resources/test_fine_tuning.py | 143 --------
14 files changed, 3 insertions(+), 839 deletions(-)
delete mode 100644 src/together/types/cosine_lr_scheduler_args_param.py
delete mode 100644 src/together/types/fine_tuning_create_params.py
delete mode 100644 src/together/types/fine_tuning_create_response.py
delete mode 100644 src/together/types/full_training_type_param.py
delete mode 100644 src/together/types/linear_lr_scheduler_args_param.py
delete mode 100644 src/together/types/lo_ra_training_type_param.py
delete mode 100644 src/together/types/lr_scheduler_param.py
delete mode 100644 src/together/types/training_method_dpo_param.py
delete mode 100644 src/together/types/training_method_sft_param.py
diff --git a/.stats.yml b/.stats.yml
index 4a805cee..ae76cfce 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 45
+configured_endpoints: 44
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-57c68db188c5a4e69e16f99e7e4968f08f2dbf64e7e7d8f57f54f84669305189.yml
openapi_spec_hash: 4e707463a416fd079a6beeff1d1beecb
-config_hash: 566058c6cddd3fb076ade46bc5e78274
+config_hash: ff6223e5c6a73b836f4d70ea6d1f385f
diff --git a/api.md b/api.md
index 097dbf58..e4fa10a3 100644
--- a/api.md
+++ b/api.md
@@ -93,7 +93,6 @@ from together.types import (
LrScheduler,
TrainingMethodDpo,
TrainingMethodSft,
- FineTuningCreateResponse,
FineTuningListResponse,
FineTuningDeleteResponse,
FineTuningCancelResponse,
@@ -104,7 +103,6 @@ from together.types import (
Methods:
-- client.fine_tuning.create(\*\*params) -> FineTuningCreateResponse
- client.fine_tuning.retrieve(id) -> FineTune
- client.fine_tuning.list() -> FineTuningListResponse
- client.fine_tuning.delete(id, \*\*params) -> FineTuningDeleteResponse
diff --git a/src/together/resources/fine_tuning.py b/src/together/resources/fine_tuning.py
index 19ad2039..49e22f28 100644
--- a/src/together/resources/fine_tuning.py
+++ b/src/together/resources/fine_tuning.py
@@ -2,12 +2,11 @@
from __future__ import annotations
-from typing import Union
from typing_extensions import Literal
import httpx
-from ..types import fine_tuning_create_params, fine_tuning_delete_params, fine_tuning_download_params
+from ..types import fine_tuning_delete_params, fine_tuning_download_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -28,10 +27,8 @@
)
from .._base_client import make_request_options
from ..types.fine_tune import FineTune
-from ..types.lr_scheduler_param import LrSchedulerParam
from ..types.fine_tuning_list_response import FineTuningListResponse
from ..types.fine_tuning_cancel_response import FineTuningCancelResponse
-from ..types.fine_tuning_create_response import FineTuningCreateResponse
from ..types.fine_tuning_delete_response import FineTuningDeleteResponse
from ..types.fine_tuning_list_events_response import FineTuningListEventsResponse
from ..types.fine_tuning_list_checkpoints_response import FineTuningListCheckpointsResponse
@@ -59,155 +56,6 @@ def with_streaming_response(self) -> FineTuningResourceWithStreamingResponse:
"""
return FineTuningResourceWithStreamingResponse(self)
- def create(
- self,
- *,
- model: str,
- training_file: str,
- batch_size: Union[int, Literal["max"]] | Omit = omit,
- from_checkpoint: str | Omit = omit,
- from_hf_model: str | Omit = omit,
- hf_api_token: str | Omit = omit,
- hf_model_revision: str | Omit = omit,
- hf_output_repo_name: str | Omit = omit,
- learning_rate: float | Omit = omit,
- lr_scheduler: LrSchedulerParam | Omit = omit,
- max_grad_norm: float | Omit = omit,
- n_checkpoints: int | Omit = omit,
- n_epochs: int | Omit = omit,
- n_evals: int | Omit = omit,
- suffix: str | Omit = omit,
- train_on_inputs: Union[bool, Literal["auto"]] | Omit = omit,
- training_method: fine_tuning_create_params.TrainingMethod | Omit = omit,
- training_type: fine_tuning_create_params.TrainingType | Omit = omit,
- validation_file: str | Omit = omit,
- wandb_api_key: str | Omit = omit,
- wandb_base_url: str | Omit = omit,
- wandb_name: str | Omit = omit,
- wandb_project_name: str | Omit = omit,
- warmup_ratio: float | Omit = omit,
- weight_decay: float | Omit = omit,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> FineTuningCreateResponse:
- """
- Create a fine-tuning job with the provided model and training data.
-
- Args:
- model: Name of the base model to run fine-tune job on
-
- training_file: File-ID of a training file uploaded to the Together API
-
- batch_size: Number of training examples processed together (larger batches use more memory
- but may train faster). Defaults to "max". We use training optimizations like
- packing, so the effective batch size may be different than the value you set.
-
- from_checkpoint: The checkpoint identifier to continue training from a previous fine-tuning job.
- Format is `{$JOB_ID}` or `{$OUTPUT_MODEL_NAME}` or `{$JOB_ID}:{$STEP}` or
- `{$OUTPUT_MODEL_NAME}:{$STEP}`. The step value is optional; without it, the
- final checkpoint will be used.
-
- from_hf_model: The Hugging Face Hub repo to start training from. Should be as close as possible
- to the base model (specified by the `model` argument) in terms of architecture
- and size.
-
- hf_api_token: The API token for the Hugging Face Hub.
-
- hf_model_revision: The revision of the Hugging Face Hub model to continue training from. E.g.,
- hf_model_revision=main (default, used if the argument is not provided) or
- hf_model_revision='607a30d783dfa663caf39e06633721c8d4cfcd7e' (specific commit).
-
- hf_output_repo_name: The name of the Hugging Face repository to upload the fine-tuned model to.
-
- learning_rate: Controls how quickly the model adapts to new information (too high may cause
- instability, too low may slow convergence)
-
- lr_scheduler: The learning rate scheduler to use. It specifies how the learning rate is
- adjusted during training.
-
- max_grad_norm: Max gradient norm to be used for gradient clipping. Set to 0 to disable.
-
- n_checkpoints: Number of intermediate model versions saved during training for evaluation
-
- n_epochs: Number of complete passes through the training dataset (higher values may
- improve results but increase cost and risk of overfitting)
-
- n_evals: Number of evaluations to be run on a given validation set during training
-
- suffix: Suffix that will be added to your fine-tuned model name
-
- train_on_inputs: Whether to mask the user messages in conversational data or prompts in
- instruction data.
-
- training_method: The training method to use. 'sft' for Supervised Fine-Tuning or 'dpo' for Direct
- Preference Optimization.
-
- validation_file: File-ID of a validation file uploaded to the Together API
-
- wandb_api_key: Integration key for tracking experiments and model metrics on W&B platform
-
- wandb_base_url: The base URL of a dedicated Weights & Biases instance.
-
- wandb_name: The Weights & Biases name for your run.
-
- wandb_project_name: The Weights & Biases project for your run. If not specified, will use `together`
- as the project name.
-
- warmup_ratio: The percent of steps at the start of training to linearly increase the learning
- rate.
-
- weight_decay: Weight decay. Regularization parameter for the optimizer.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._post(
- "/fine-tunes",
- body=maybe_transform(
- {
- "model": model,
- "training_file": training_file,
- "batch_size": batch_size,
- "from_checkpoint": from_checkpoint,
- "from_hf_model": from_hf_model,
- "hf_api_token": hf_api_token,
- "hf_model_revision": hf_model_revision,
- "hf_output_repo_name": hf_output_repo_name,
- "learning_rate": learning_rate,
- "lr_scheduler": lr_scheduler,
- "max_grad_norm": max_grad_norm,
- "n_checkpoints": n_checkpoints,
- "n_epochs": n_epochs,
- "n_evals": n_evals,
- "suffix": suffix,
- "train_on_inputs": train_on_inputs,
- "training_method": training_method,
- "training_type": training_type,
- "validation_file": validation_file,
- "wandb_api_key": wandb_api_key,
- "wandb_base_url": wandb_base_url,
- "wandb_name": wandb_name,
- "wandb_project_name": wandb_project_name,
- "warmup_ratio": warmup_ratio,
- "weight_decay": weight_decay,
- },
- fine_tuning_create_params.FineTuningCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=FineTuningCreateResponse,
- )
-
def retrieve(
self,
id: str,
@@ -477,155 +325,6 @@ def with_streaming_response(self) -> AsyncFineTuningResourceWithStreamingRespons
"""
return AsyncFineTuningResourceWithStreamingResponse(self)
- async def create(
- self,
- *,
- model: str,
- training_file: str,
- batch_size: Union[int, Literal["max"]] | Omit = omit,
- from_checkpoint: str | Omit = omit,
- from_hf_model: str | Omit = omit,
- hf_api_token: str | Omit = omit,
- hf_model_revision: str | Omit = omit,
- hf_output_repo_name: str | Omit = omit,
- learning_rate: float | Omit = omit,
- lr_scheduler: LrSchedulerParam | Omit = omit,
- max_grad_norm: float | Omit = omit,
- n_checkpoints: int | Omit = omit,
- n_epochs: int | Omit = omit,
- n_evals: int | Omit = omit,
- suffix: str | Omit = omit,
- train_on_inputs: Union[bool, Literal["auto"]] | Omit = omit,
- training_method: fine_tuning_create_params.TrainingMethod | Omit = omit,
- training_type: fine_tuning_create_params.TrainingType | Omit = omit,
- validation_file: str | Omit = omit,
- wandb_api_key: str | Omit = omit,
- wandb_base_url: str | Omit = omit,
- wandb_name: str | Omit = omit,
- wandb_project_name: str | Omit = omit,
- warmup_ratio: float | Omit = omit,
- weight_decay: float | Omit = omit,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> FineTuningCreateResponse:
- """
- Create a fine-tuning job with the provided model and training data.
-
- Args:
- model: Name of the base model to run fine-tune job on
-
- training_file: File-ID of a training file uploaded to the Together API
-
- batch_size: Number of training examples processed together (larger batches use more memory
- but may train faster). Defaults to "max". We use training optimizations like
- packing, so the effective batch size may be different than the value you set.
-
- from_checkpoint: The checkpoint identifier to continue training from a previous fine-tuning job.
- Format is `{$JOB_ID}` or `{$OUTPUT_MODEL_NAME}` or `{$JOB_ID}:{$STEP}` or
- `{$OUTPUT_MODEL_NAME}:{$STEP}`. The step value is optional; without it, the
- final checkpoint will be used.
-
- from_hf_model: The Hugging Face Hub repo to start training from. Should be as close as possible
- to the base model (specified by the `model` argument) in terms of architecture
- and size.
-
- hf_api_token: The API token for the Hugging Face Hub.
-
- hf_model_revision: The revision of the Hugging Face Hub model to continue training from. E.g.,
- hf_model_revision=main (default, used if the argument is not provided) or
- hf_model_revision='607a30d783dfa663caf39e06633721c8d4cfcd7e' (specific commit).
-
- hf_output_repo_name: The name of the Hugging Face repository to upload the fine-tuned model to.
-
- learning_rate: Controls how quickly the model adapts to new information (too high may cause
- instability, too low may slow convergence)
-
- lr_scheduler: The learning rate scheduler to use. It specifies how the learning rate is
- adjusted during training.
-
- max_grad_norm: Max gradient norm to be used for gradient clipping. Set to 0 to disable.
-
- n_checkpoints: Number of intermediate model versions saved during training for evaluation
-
- n_epochs: Number of complete passes through the training dataset (higher values may
- improve results but increase cost and risk of overfitting)
-
- n_evals: Number of evaluations to be run on a given validation set during training
-
- suffix: Suffix that will be added to your fine-tuned model name
-
- train_on_inputs: Whether to mask the user messages in conversational data or prompts in
- instruction data.
-
- training_method: The training method to use. 'sft' for Supervised Fine-Tuning or 'dpo' for Direct
- Preference Optimization.
-
- validation_file: File-ID of a validation file uploaded to the Together API
-
- wandb_api_key: Integration key for tracking experiments and model metrics on W&B platform
-
- wandb_base_url: The base URL of a dedicated Weights & Biases instance.
-
- wandb_name: The Weights & Biases name for your run.
-
- wandb_project_name: The Weights & Biases project for your run. If not specified, will use `together`
- as the project name.
-
- warmup_ratio: The percent of steps at the start of training to linearly increase the learning
- rate.
-
- weight_decay: Weight decay. Regularization parameter for the optimizer.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._post(
- "/fine-tunes",
- body=await async_maybe_transform(
- {
- "model": model,
- "training_file": training_file,
- "batch_size": batch_size,
- "from_checkpoint": from_checkpoint,
- "from_hf_model": from_hf_model,
- "hf_api_token": hf_api_token,
- "hf_model_revision": hf_model_revision,
- "hf_output_repo_name": hf_output_repo_name,
- "learning_rate": learning_rate,
- "lr_scheduler": lr_scheduler,
- "max_grad_norm": max_grad_norm,
- "n_checkpoints": n_checkpoints,
- "n_epochs": n_epochs,
- "n_evals": n_evals,
- "suffix": suffix,
- "train_on_inputs": train_on_inputs,
- "training_method": training_method,
- "training_type": training_type,
- "validation_file": validation_file,
- "wandb_api_key": wandb_api_key,
- "wandb_base_url": wandb_base_url,
- "wandb_name": wandb_name,
- "wandb_project_name": wandb_project_name,
- "warmup_ratio": warmup_ratio,
- "weight_decay": weight_decay,
- },
- fine_tuning_create_params.FineTuningCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=FineTuningCreateResponse,
- )
-
async def retrieve(
self,
id: str,
@@ -879,9 +578,6 @@ class FineTuningResourceWithRawResponse:
def __init__(self, fine_tuning: FineTuningResource) -> None:
self._fine_tuning = fine_tuning
- self.create = to_raw_response_wrapper(
- fine_tuning.create,
- )
self.retrieve = to_raw_response_wrapper(
fine_tuning.retrieve,
)
@@ -910,9 +606,6 @@ class AsyncFineTuningResourceWithRawResponse:
def __init__(self, fine_tuning: AsyncFineTuningResource) -> None:
self._fine_tuning = fine_tuning
- self.create = async_to_raw_response_wrapper(
- fine_tuning.create,
- )
self.retrieve = async_to_raw_response_wrapper(
fine_tuning.retrieve,
)
@@ -941,9 +634,6 @@ class FineTuningResourceWithStreamingResponse:
def __init__(self, fine_tuning: FineTuningResource) -> None:
self._fine_tuning = fine_tuning
- self.create = to_streamed_response_wrapper(
- fine_tuning.create,
- )
self.retrieve = to_streamed_response_wrapper(
fine_tuning.retrieve,
)
@@ -972,9 +662,6 @@ class AsyncFineTuningResourceWithStreamingResponse:
def __init__(self, fine_tuning: AsyncFineTuningResource) -> None:
self._fine_tuning = fine_tuning
- self.create = async_to_streamed_response_wrapper(
- fine_tuning.create,
- )
self.retrieve = async_to_streamed_response_wrapper(
fine_tuning.retrieve,
)
diff --git a/src/together/types/__init__.py b/src/together/types/__init__.py
index 47e5c9c5..2c2c7c39 100644
--- a/src/together/types/__init__.py
+++ b/src/together/types/__init__.py
@@ -31,7 +31,6 @@
from .eval_update_params import EvalUpdateParams as EvalUpdateParams
from .file_list_response import FileListResponse as FileListResponse
from .full_training_type import FullTrainingType as FullTrainingType
-from .lr_scheduler_param import LrSchedulerParam as LrSchedulerParam
from .audio_create_params import AudioCreateParams as AudioCreateParams
from .batch_create_params import BatchCreateParams as BatchCreateParams
from .batch_list_response import BatchListResponse as BatchListResponse
@@ -63,22 +62,14 @@
from .embedding_create_params import EmbeddingCreateParams as EmbeddingCreateParams
from .completion_create_params import CompletionCreateParams as CompletionCreateParams
from .cosine_lr_scheduler_args import CosineLrSchedulerArgs as CosineLrSchedulerArgs
-from .full_training_type_param import FullTrainingTypeParam as FullTrainingTypeParam
from .linear_lr_scheduler_args import LinearLrSchedulerArgs as LinearLrSchedulerArgs
from .audio_speech_stream_chunk import AudioSpeechStreamChunk as AudioSpeechStreamChunk
-from .fine_tuning_create_params import FineTuningCreateParams as FineTuningCreateParams
from .fine_tuning_delete_params import FineTuningDeleteParams as FineTuningDeleteParams
from .fine_tuning_list_response import FineTuningListResponse as FineTuningListResponse
-from .lo_ra_training_type_param import LoRaTrainingTypeParam as LoRaTrainingTypeParam
-from .training_method_dpo_param import TrainingMethodDpoParam as TrainingMethodDpoParam
-from .training_method_sft_param import TrainingMethodSftParam as TrainingMethodSftParam
from .fine_tuning_cancel_response import FineTuningCancelResponse as FineTuningCancelResponse
-from .fine_tuning_create_response import FineTuningCreateResponse as FineTuningCreateResponse
from .fine_tuning_delete_response import FineTuningDeleteResponse as FineTuningDeleteResponse
from .fine_tuning_download_params import FineTuningDownloadParams as FineTuningDownloadParams
-from .cosine_lr_scheduler_args_param import CosineLrSchedulerArgsParam as CosineLrSchedulerArgsParam
from .endpoint_list_avzones_response import EndpointListAvzonesResponse as EndpointListAvzonesResponse
-from .linear_lr_scheduler_args_param import LinearLrSchedulerArgsParam as LinearLrSchedulerArgsParam
from .code_interpreter_execute_params import CodeInterpreterExecuteParams as CodeInterpreterExecuteParams
from .fine_tuning_list_events_response import FineTuningListEventsResponse as FineTuningListEventsResponse
from .fine_tuning_list_checkpoints_response import (
diff --git a/src/together/types/cosine_lr_scheduler_args_param.py b/src/together/types/cosine_lr_scheduler_args_param.py
deleted file mode 100644
index 73758e6b..00000000
--- a/src/together/types/cosine_lr_scheduler_args_param.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-__all__ = ["CosineLrSchedulerArgsParam"]
-
-
-class CosineLrSchedulerArgsParam(TypedDict, total=False):
- min_lr_ratio: Required[float]
- """The ratio of the final learning rate to the peak learning rate"""
-
- num_cycles: Required[float]
- """Number or fraction of cycles for the cosine learning rate scheduler"""
diff --git a/src/together/types/fine_tuning_create_params.py b/src/together/types/fine_tuning_create_params.py
deleted file mode 100644
index 2f34eb24..00000000
--- a/src/together/types/fine_tuning_create_params.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union
-from typing_extensions import Literal, Required, TypeAlias, TypedDict
-
-from .lr_scheduler_param import LrSchedulerParam
-from .full_training_type_param import FullTrainingTypeParam
-from .lo_ra_training_type_param import LoRaTrainingTypeParam
-from .training_method_dpo_param import TrainingMethodDpoParam
-from .training_method_sft_param import TrainingMethodSftParam
-
-__all__ = ["FineTuningCreateParams", "TrainingMethod", "TrainingType"]
-
-
-class FineTuningCreateParams(TypedDict, total=False):
- model: Required[str]
- """Name of the base model to run fine-tune job on"""
-
- training_file: Required[str]
- """File-ID of a training file uploaded to the Together API"""
-
- batch_size: Union[int, Literal["max"]]
- """
- Number of training examples processed together (larger batches use more memory
- but may train faster). Defaults to "max". We use training optimizations like
- packing, so the effective batch size may be different than the value you set.
- """
-
- from_checkpoint: str
- """The checkpoint identifier to continue training from a previous fine-tuning job.
-
- Format is `{$JOB_ID}` or `{$OUTPUT_MODEL_NAME}` or `{$JOB_ID}:{$STEP}` or
- `{$OUTPUT_MODEL_NAME}:{$STEP}`. The step value is optional; without it, the
- final checkpoint will be used.
- """
-
- from_hf_model: str
- """The Hugging Face Hub repo to start training from.
-
- Should be as close as possible to the base model (specified by the `model`
- argument) in terms of architecture and size.
- """
-
- hf_api_token: str
- """The API token for the Hugging Face Hub."""
-
- hf_model_revision: str
- """The revision of the Hugging Face Hub model to continue training from.
-
- E.g., hf_model_revision=main (default, used if the argument is not provided) or
- hf_model_revision='607a30d783dfa663caf39e06633721c8d4cfcd7e' (specific commit).
- """
-
- hf_output_repo_name: str
- """The name of the Hugging Face repository to upload the fine-tuned model to."""
-
- learning_rate: float
- """
- Controls how quickly the model adapts to new information (too high may cause
- instability, too low may slow convergence)
- """
-
- lr_scheduler: LrSchedulerParam
- """The learning rate scheduler to use.
-
- It specifies how the learning rate is adjusted during training.
- """
-
- max_grad_norm: float
- """Max gradient norm to be used for gradient clipping. Set to 0 to disable."""
-
- n_checkpoints: int
- """Number of intermediate model versions saved during training for evaluation"""
-
- n_epochs: int
- """
- Number of complete passes through the training dataset (higher values may
- improve results but increase cost and risk of overfitting)
- """
-
- n_evals: int
- """Number of evaluations to be run on a given validation set during training"""
-
- suffix: str
- """Suffix that will be added to your fine-tuned model name"""
-
- train_on_inputs: Union[bool, Literal["auto"]]
- """
- Whether to mask the user messages in conversational data or prompts in
- instruction data.
- """
-
- training_method: TrainingMethod
- """The training method to use.
-
- 'sft' for Supervised Fine-Tuning or 'dpo' for Direct Preference Optimization.
- """
-
- training_type: TrainingType
-
- validation_file: str
- """File-ID of a validation file uploaded to the Together API"""
-
- wandb_api_key: str
- """Integration key for tracking experiments and model metrics on W&B platform"""
-
- wandb_base_url: str
- """The base URL of a dedicated Weights & Biases instance."""
-
- wandb_name: str
- """The Weights & Biases name for your run."""
-
- wandb_project_name: str
- """The Weights & Biases project for your run.
-
- If not specified, will use `together` as the project name.
- """
-
- warmup_ratio: float
- """
- The percent of steps at the start of training to linearly increase the learning
- rate.
- """
-
- weight_decay: float
- """Weight decay. Regularization parameter for the optimizer."""
-
-
-TrainingMethod: TypeAlias = Union[TrainingMethodSftParam, TrainingMethodDpoParam]
-
-TrainingType: TypeAlias = Union[FullTrainingTypeParam, LoRaTrainingTypeParam]
diff --git a/src/together/types/fine_tuning_create_response.py b/src/together/types/fine_tuning_create_response.py
deleted file mode 100644
index d6e2aca0..00000000
--- a/src/together/types/fine_tuning_create_response.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Union, Optional
-from datetime import datetime
-from typing_extensions import Literal, TypeAlias
-
-from pydantic import Field as FieldInfo
-
-from .._models import BaseModel
-from .lr_scheduler import LrScheduler
-from .fine_tune_event import FineTuneEvent
-from .full_training_type import FullTrainingType
-from .lo_ra_training_type import LoRaTrainingType
-from .training_method_dpo import TrainingMethodDpo
-from .training_method_sft import TrainingMethodSft
-
-__all__ = ["FineTuningCreateResponse", "TrainingMethod", "TrainingType"]
-
-TrainingMethod: TypeAlias = Union[TrainingMethodSft, TrainingMethodDpo]
-
-TrainingType: TypeAlias = Union[FullTrainingType, LoRaTrainingType]
-
-
-class FineTuningCreateResponse(BaseModel):
- id: str
- """Unique identifier for the fine-tune job"""
-
- created_at: datetime
- """Creation timestamp of the fine-tune job"""
-
- status: Literal[
- "pending",
- "queued",
- "running",
- "compressing",
- "uploading",
- "cancel_requested",
- "cancelled",
- "error",
- "completed",
- ]
-
- updated_at: datetime
- """Last update timestamp of the fine-tune job"""
-
- batch_size: Optional[int] = None
- """Batch size used for training"""
-
- events: Optional[List[FineTuneEvent]] = None
- """Events related to this fine-tune job"""
-
- from_checkpoint: Optional[str] = None
- """Checkpoint used to continue training"""
-
- from_hf_model: Optional[str] = None
- """Hugging Face Hub repo to start training from"""
-
- hf_model_revision: Optional[str] = None
- """The revision of the Hugging Face Hub model to continue training from"""
-
- learning_rate: Optional[float] = None
- """Learning rate used for training"""
-
- lr_scheduler: Optional[LrScheduler] = None
- """Learning rate scheduler configuration"""
-
- max_grad_norm: Optional[float] = None
- """Maximum gradient norm for clipping"""
-
- model: Optional[str] = None
- """Base model used for fine-tuning"""
-
- x_model_output_name: Optional[str] = FieldInfo(alias="model_output_name", default=None)
-
- n_checkpoints: Optional[int] = None
- """Number of checkpoints saved during training"""
-
- n_epochs: Optional[int] = None
- """Number of training epochs"""
-
- n_evals: Optional[int] = None
- """Number of evaluations during training"""
-
- owner_address: Optional[str] = None
- """Owner address information"""
-
- suffix: Optional[str] = None
- """Suffix added to the fine-tuned model name"""
-
- token_count: Optional[int] = None
- """Count of tokens processed"""
-
- total_price: Optional[int] = None
- """Total price for the fine-tuning job"""
-
- training_file: Optional[str] = None
- """File-ID of the training file"""
-
- training_method: Optional[TrainingMethod] = None
- """Method of training used"""
-
- training_type: Optional[TrainingType] = None
- """Type of training used (full or LoRA)"""
-
- user_id: Optional[str] = None
- """Identifier for the user who created the job"""
-
- validation_file: Optional[str] = None
- """File-ID of the validation file"""
-
- wandb_name: Optional[str] = None
- """Weights & Biases run name"""
-
- wandb_project_name: Optional[str] = None
- """Weights & Biases project name"""
-
- warmup_ratio: Optional[float] = None
- """Ratio of warmup steps"""
-
- weight_decay: Optional[float] = None
- """Weight decay value used"""
diff --git a/src/together/types/full_training_type_param.py b/src/together/types/full_training_type_param.py
deleted file mode 100644
index 57950250..00000000
--- a/src/together/types/full_training_type_param.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["FullTrainingTypeParam"]
-
-
-class FullTrainingTypeParam(TypedDict, total=False):
- type: Required[Literal["Full"]]
diff --git a/src/together/types/linear_lr_scheduler_args_param.py b/src/together/types/linear_lr_scheduler_args_param.py
deleted file mode 100644
index 05931977..00000000
--- a/src/together/types/linear_lr_scheduler_args_param.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["LinearLrSchedulerArgsParam"]
-
-
-class LinearLrSchedulerArgsParam(TypedDict, total=False):
- min_lr_ratio: float
- """The ratio of the final learning rate to the peak learning rate"""
diff --git a/src/together/types/lo_ra_training_type_param.py b/src/together/types/lo_ra_training_type_param.py
deleted file mode 100644
index c554d910..00000000
--- a/src/together/types/lo_ra_training_type_param.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["LoRaTrainingTypeParam"]
-
-
-class LoRaTrainingTypeParam(TypedDict, total=False):
- lora_alpha: Required[int]
-
- lora_r: Required[int]
-
- type: Required[Literal["Lora"]]
-
- lora_dropout: float
-
- lora_trainable_modules: str
diff --git a/src/together/types/lr_scheduler_param.py b/src/together/types/lr_scheduler_param.py
deleted file mode 100644
index 30535c4a..00000000
--- a/src/together/types/lr_scheduler_param.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union
-from typing_extensions import Literal, Required, TypeAlias, TypedDict
-
-from .cosine_lr_scheduler_args_param import CosineLrSchedulerArgsParam
-from .linear_lr_scheduler_args_param import LinearLrSchedulerArgsParam
-
-__all__ = ["LrSchedulerParam", "LrSchedulerArgs"]
-
-LrSchedulerArgs: TypeAlias = Union[LinearLrSchedulerArgsParam, CosineLrSchedulerArgsParam]
-
-
-class LrSchedulerParam(TypedDict, total=False):
- lr_scheduler_type: Required[Literal["linear", "cosine"]]
-
- lr_scheduler_args: LrSchedulerArgs
diff --git a/src/together/types/training_method_dpo_param.py b/src/together/types/training_method_dpo_param.py
deleted file mode 100644
index cd776600..00000000
--- a/src/together/types/training_method_dpo_param.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["TrainingMethodDpoParam"]
-
-
-class TrainingMethodDpoParam(TypedDict, total=False):
- method: Required[Literal["dpo"]]
-
- dpo_beta: float
-
- dpo_normalize_logratios_by_length: bool
-
- dpo_reference_free: bool
-
- rpo_alpha: float
-
- simpo_gamma: float
diff --git a/src/together/types/training_method_sft_param.py b/src/together/types/training_method_sft_param.py
deleted file mode 100644
index 01c3cc15..00000000
--- a/src/together/types/training_method_sft_param.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["TrainingMethodSftParam"]
-
-
-class TrainingMethodSftParam(TypedDict, total=False):
- method: Required[Literal["sft"]]
-
- train_on_inputs: Required[Union[bool, Literal["auto"]]]
- """
- Whether to mask the user messages in conversational data or prompts in
- instruction data.
- """
diff --git a/tests/api_resources/test_fine_tuning.py b/tests/api_resources/test_fine_tuning.py
index a03b3a72..4a7a3104 100644
--- a/tests/api_resources/test_fine_tuning.py
+++ b/tests/api_resources/test_fine_tuning.py
@@ -15,7 +15,6 @@
FineTune,
FineTuningListResponse,
FineTuningCancelResponse,
- FineTuningCreateResponse,
FineTuningDeleteResponse,
FineTuningListEventsResponse,
FineTuningListCheckpointsResponse,
@@ -33,77 +32,6 @@
class TestFineTuning:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
- @parametrize
- def test_method_create(self, client: Together) -> None:
- fine_tuning = client.fine_tuning.create(
- model="model",
- training_file="training_file",
- )
- assert_matches_type(FineTuningCreateResponse, fine_tuning, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Together) -> None:
- fine_tuning = client.fine_tuning.create(
- model="model",
- training_file="training_file",
- batch_size=0,
- from_checkpoint="from_checkpoint",
- from_hf_model="from_hf_model",
- hf_api_token="hf_api_token",
- hf_model_revision="hf_model_revision",
- hf_output_repo_name="hf_output_repo_name",
- learning_rate=0,
- lr_scheduler={
- "lr_scheduler_type": "linear",
- "lr_scheduler_args": {"min_lr_ratio": 0},
- },
- max_grad_norm=0,
- n_checkpoints=0,
- n_epochs=0,
- n_evals=0,
- suffix="suffix",
- train_on_inputs=True,
- training_method={
- "method": "sft",
- "train_on_inputs": True,
- },
- training_type={"type": "Full"},
- validation_file="validation_file",
- wandb_api_key="wandb_api_key",
- wandb_base_url="wandb_base_url",
- wandb_name="wandb_name",
- wandb_project_name="wandb_project_name",
- warmup_ratio=0,
- weight_decay=0,
- )
- assert_matches_type(FineTuningCreateResponse, fine_tuning, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Together) -> None:
- response = client.fine_tuning.with_raw_response.create(
- model="model",
- training_file="training_file",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- fine_tuning = response.parse()
- assert_matches_type(FineTuningCreateResponse, fine_tuning, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Together) -> None:
- with client.fine_tuning.with_streaming_response.create(
- model="model",
- training_file="training_file",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- fine_tuning = response.parse()
- assert_matches_type(FineTuningCreateResponse, fine_tuning, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
@parametrize
def test_method_retrieve(self, client: Together) -> None:
fine_tuning = client.fine_tuning.retrieve(
@@ -385,77 +313,6 @@ class TestAsyncFineTuning:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
- @parametrize
- async def test_method_create(self, async_client: AsyncTogether) -> None:
- fine_tuning = await async_client.fine_tuning.create(
- model="model",
- training_file="training_file",
- )
- assert_matches_type(FineTuningCreateResponse, fine_tuning, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncTogether) -> None:
- fine_tuning = await async_client.fine_tuning.create(
- model="model",
- training_file="training_file",
- batch_size=0,
- from_checkpoint="from_checkpoint",
- from_hf_model="from_hf_model",
- hf_api_token="hf_api_token",
- hf_model_revision="hf_model_revision",
- hf_output_repo_name="hf_output_repo_name",
- learning_rate=0,
- lr_scheduler={
- "lr_scheduler_type": "linear",
- "lr_scheduler_args": {"min_lr_ratio": 0},
- },
- max_grad_norm=0,
- n_checkpoints=0,
- n_epochs=0,
- n_evals=0,
- suffix="suffix",
- train_on_inputs=True,
- training_method={
- "method": "sft",
- "train_on_inputs": True,
- },
- training_type={"type": "Full"},
- validation_file="validation_file",
- wandb_api_key="wandb_api_key",
- wandb_base_url="wandb_base_url",
- wandb_name="wandb_name",
- wandb_project_name="wandb_project_name",
- warmup_ratio=0,
- weight_decay=0,
- )
- assert_matches_type(FineTuningCreateResponse, fine_tuning, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncTogether) -> None:
- response = await async_client.fine_tuning.with_raw_response.create(
- model="model",
- training_file="training_file",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- fine_tuning = await response.parse()
- assert_matches_type(FineTuningCreateResponse, fine_tuning, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncTogether) -> None:
- async with async_client.fine_tuning.with_streaming_response.create(
- model="model",
- training_file="training_file",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- fine_tuning = await response.parse()
- assert_matches_type(FineTuningCreateResponse, fine_tuning, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
@parametrize
async def test_method_retrieve(self, async_client: AsyncTogether) -> None:
fine_tuning = await async_client.fine_tuning.retrieve(
From a6e3ad792393be978b123c87707afe779ef8df34 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 20 Nov 2025 16:14:46 +0000
Subject: [PATCH 2/8] feat(api): Change image creation signature to
`images.generate`
BREAKING CHANGE: For the TS SDK the `images.create` is now `images.generate`
---
.stats.yml | 2 +-
api.md | 2 +-
src/together/resources/images.py | 30 ++++++++---------
src/together/types/__init__.py | 2 +-
...ate_params.py => image_generate_params.py} | 4 +--
tests/api_resources/test_images.py | 32 +++++++++----------
6 files changed, 36 insertions(+), 36 deletions(-)
rename src/together/types/{image_create_params.py => image_generate_params.py} (96%)
diff --git a/.stats.yml b/.stats.yml
index ae76cfce..50b97bd9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 44
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-57c68db188c5a4e69e16f99e7e4968f08f2dbf64e7e7d8f57f54f84669305189.yml
openapi_spec_hash: 4e707463a416fd079a6beeff1d1beecb
-config_hash: ff6223e5c6a73b836f4d70ea6d1f385f
+config_hash: 2fabf9b1cee38923853fcfbad54500ca
diff --git a/api.md b/api.md
index e4fa10a3..b2ad5a50 100644
--- a/api.md
+++ b/api.md
@@ -145,7 +145,7 @@ from together.types import ImageDataB64, ImageDataURL, ImageFile
Methods:
-- client.images.create(\*\*params) -> ImageFile
+- client.images.generate(\*\*params) -> ImageFile
# Videos
diff --git a/src/together/resources/images.py b/src/together/resources/images.py
index 5ed51c84..bc7cb350 100644
--- a/src/together/resources/images.py
+++ b/src/together/resources/images.py
@@ -7,7 +7,7 @@
import httpx
-from ..types import image_create_params
+from ..types import image_generate_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -44,7 +44,7 @@ def with_streaming_response(self) -> ImagesResourceWithStreamingResponse:
"""
return ImagesResourceWithStreamingResponse(self)
- def create(
+ def generate(
self,
*,
model: Union[
@@ -59,7 +59,7 @@ def create(
disable_safety_checker: bool | Omit = omit,
guidance_scale: float | Omit = omit,
height: int | Omit = omit,
- image_loras: Iterable[image_create_params.ImageLora] | Omit = omit,
+ image_loras: Iterable[image_generate_params.ImageLora] | Omit = omit,
image_url: str | Omit = omit,
n: int | Omit = omit,
negative_prompt: str | Omit = omit,
@@ -140,7 +140,7 @@ def create(
"steps": steps,
"width": width,
},
- image_create_params.ImageCreateParams,
+ image_generate_params.ImageGenerateParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -169,7 +169,7 @@ def with_streaming_response(self) -> AsyncImagesResourceWithStreamingResponse:
"""
return AsyncImagesResourceWithStreamingResponse(self)
- async def create(
+ async def generate(
self,
*,
model: Union[
@@ -184,7 +184,7 @@ async def create(
disable_safety_checker: bool | Omit = omit,
guidance_scale: float | Omit = omit,
height: int | Omit = omit,
- image_loras: Iterable[image_create_params.ImageLora] | Omit = omit,
+ image_loras: Iterable[image_generate_params.ImageLora] | Omit = omit,
image_url: str | Omit = omit,
n: int | Omit = omit,
negative_prompt: str | Omit = omit,
@@ -265,7 +265,7 @@ async def create(
"steps": steps,
"width": width,
},
- image_create_params.ImageCreateParams,
+ image_generate_params.ImageGenerateParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -278,8 +278,8 @@ class ImagesResourceWithRawResponse:
def __init__(self, images: ImagesResource) -> None:
self._images = images
- self.create = to_raw_response_wrapper(
- images.create,
+ self.generate = to_raw_response_wrapper(
+ images.generate,
)
@@ -287,8 +287,8 @@ class AsyncImagesResourceWithRawResponse:
def __init__(self, images: AsyncImagesResource) -> None:
self._images = images
- self.create = async_to_raw_response_wrapper(
- images.create,
+ self.generate = async_to_raw_response_wrapper(
+ images.generate,
)
@@ -296,8 +296,8 @@ class ImagesResourceWithStreamingResponse:
def __init__(self, images: ImagesResource) -> None:
self._images = images
- self.create = to_streamed_response_wrapper(
- images.create,
+ self.generate = to_streamed_response_wrapper(
+ images.generate,
)
@@ -305,6 +305,6 @@ class AsyncImagesResourceWithStreamingResponse:
def __init__(self, images: AsyncImagesResource) -> None:
self._images = images
- self.create = async_to_streamed_response_wrapper(
- images.create,
+ self.generate = async_to_streamed_response_wrapper(
+ images.generate,
)
diff --git a/src/together/types/__init__.py b/src/together/types/__init__.py
index 2c2c7c39..5170a108 100644
--- a/src/together/types/__init__.py
+++ b/src/together/types/__init__.py
@@ -34,7 +34,6 @@
from .audio_create_params import AudioCreateParams as AudioCreateParams
from .batch_create_params import BatchCreateParams as BatchCreateParams
from .batch_list_response import BatchListResponse as BatchListResponse
-from .image_create_params import ImageCreateParams as ImageCreateParams
from .lo_ra_training_type import LoRaTrainingType as LoRaTrainingType
from .model_list_response import ModelListResponse as ModelListResponse
from .model_upload_params import ModelUploadParams as ModelUploadParams
@@ -50,6 +49,7 @@
from .hardware_list_params import HardwareListParams as HardwareListParams
from .batch_cancel_response import BatchCancelResponse as BatchCancelResponse
from .batch_create_response import BatchCreateResponse as BatchCreateResponse
+from .image_generate_params import ImageGenerateParams as ImageGenerateParams
from .job_retrieve_response import JobRetrieveResponse as JobRetrieveResponse
from .model_upload_response import ModelUploadResponse as ModelUploadResponse
from .video_create_response import VideoCreateResponse as VideoCreateResponse
diff --git a/src/together/types/image_create_params.py b/src/together/types/image_generate_params.py
similarity index 96%
rename from src/together/types/image_create_params.py
rename to src/together/types/image_generate_params.py
index e32137d0..4d0cd04b 100644
--- a/src/together/types/image_create_params.py
+++ b/src/together/types/image_generate_params.py
@@ -5,10 +5,10 @@
from typing import Union, Iterable
from typing_extensions import Literal, Required, TypedDict
-__all__ = ["ImageCreateParams", "ImageLora"]
+__all__ = ["ImageGenerateParams", "ImageLora"]
-class ImageCreateParams(TypedDict, total=False):
+class ImageGenerateParams(TypedDict, total=False):
model: Required[
Union[
Literal[
diff --git a/tests/api_resources/test_images.py b/tests/api_resources/test_images.py
index b1f2d2e3..a7a2d259 100644
--- a/tests/api_resources/test_images.py
+++ b/tests/api_resources/test_images.py
@@ -18,16 +18,16 @@ class TestImages:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@parametrize
- def test_method_create(self, client: Together) -> None:
- image = client.images.create(
+ def test_method_generate(self, client: Together) -> None:
+ image = client.images.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="cat floating in space, cinematic",
)
assert_matches_type(ImageFile, image, path=["response"])
@parametrize
- def test_method_create_with_all_params(self, client: Together) -> None:
- image = client.images.create(
+ def test_method_generate_with_all_params(self, client: Together) -> None:
+ image = client.images.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="cat floating in space, cinematic",
disable_safety_checker=True,
@@ -51,8 +51,8 @@ def test_method_create_with_all_params(self, client: Together) -> None:
assert_matches_type(ImageFile, image, path=["response"])
@parametrize
- def test_raw_response_create(self, client: Together) -> None:
- response = client.images.with_raw_response.create(
+ def test_raw_response_generate(self, client: Together) -> None:
+ response = client.images.with_raw_response.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="cat floating in space, cinematic",
)
@@ -63,8 +63,8 @@ def test_raw_response_create(self, client: Together) -> None:
assert_matches_type(ImageFile, image, path=["response"])
@parametrize
- def test_streaming_response_create(self, client: Together) -> None:
- with client.images.with_streaming_response.create(
+ def test_streaming_response_generate(self, client: Together) -> None:
+ with client.images.with_streaming_response.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="cat floating in space, cinematic",
) as response:
@@ -83,16 +83,16 @@ class TestAsyncImages:
)
@parametrize
- async def test_method_create(self, async_client: AsyncTogether) -> None:
- image = await async_client.images.create(
+ async def test_method_generate(self, async_client: AsyncTogether) -> None:
+ image = await async_client.images.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="cat floating in space, cinematic",
)
assert_matches_type(ImageFile, image, path=["response"])
@parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncTogether) -> None:
- image = await async_client.images.create(
+ async def test_method_generate_with_all_params(self, async_client: AsyncTogether) -> None:
+ image = await async_client.images.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="cat floating in space, cinematic",
disable_safety_checker=True,
@@ -116,8 +116,8 @@ async def test_method_create_with_all_params(self, async_client: AsyncTogether)
assert_matches_type(ImageFile, image, path=["response"])
@parametrize
- async def test_raw_response_create(self, async_client: AsyncTogether) -> None:
- response = await async_client.images.with_raw_response.create(
+ async def test_raw_response_generate(self, async_client: AsyncTogether) -> None:
+ response = await async_client.images.with_raw_response.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="cat floating in space, cinematic",
)
@@ -128,8 +128,8 @@ async def test_raw_response_create(self, async_client: AsyncTogether) -> None:
assert_matches_type(ImageFile, image, path=["response"])
@parametrize
- async def test_streaming_response_create(self, async_client: AsyncTogether) -> None:
- async with async_client.images.with_streaming_response.create(
+ async def test_streaming_response_generate(self, async_client: AsyncTogether) -> None:
+ async with async_client.images.with_streaming_response.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="cat floating in space, cinematic",
) as response:
From aa279076c524956e204cb68b7424048a4f93a17d Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 20 Nov 2025 17:43:58 +0000
Subject: [PATCH 3/8] feat(api): Change fine tuning download method to
`.create`
BREAKING CHANGE: Change Fine Tuning method name from `download()` to `content()` to align with other namespaces
---
.stats.yml | 2 +-
api.md | 2 +-
src/together/resources/fine_tuning.py | 26 +++++++--------
src/together/types/__init__.py | 2 +-
...arams.py => fine_tuning_content_params.py} | 4 +--
tests/api_resources/test_fine_tuning.py | 32 +++++++++----------
6 files changed, 34 insertions(+), 34 deletions(-)
rename src/together/types/{fine_tuning_download_params.py => fine_tuning_content_params.py} (86%)
diff --git a/.stats.yml b/.stats.yml
index 50b97bd9..508eee3b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 44
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-57c68db188c5a4e69e16f99e7e4968f08f2dbf64e7e7d8f57f54f84669305189.yml
openapi_spec_hash: 4e707463a416fd079a6beeff1d1beecb
-config_hash: 2fabf9b1cee38923853fcfbad54500ca
+config_hash: 13875c495340ee39d9ff60ab63480486
diff --git a/api.md b/api.md
index b2ad5a50..cfd70513 100644
--- a/api.md
+++ b/api.md
@@ -107,7 +107,7 @@ Methods:
- client.fine_tuning.list() -> FineTuningListResponse
- client.fine_tuning.delete(id, \*\*params) -> FineTuningDeleteResponse
- client.fine_tuning.cancel(id) -> FineTuningCancelResponse
-- client.fine_tuning.download(\*\*params) -> BinaryAPIResponse
+- client.fine_tuning.content(\*\*params) -> BinaryAPIResponse
- client.fine_tuning.list_checkpoints(id) -> FineTuningListCheckpointsResponse
- client.fine_tuning.list_events(id) -> FineTuningListEventsResponse
diff --git a/src/together/resources/fine_tuning.py b/src/together/resources/fine_tuning.py
index 49e22f28..024857ba 100644
--- a/src/together/resources/fine_tuning.py
+++ b/src/together/resources/fine_tuning.py
@@ -6,7 +6,7 @@
import httpx
-from ..types import fine_tuning_delete_params, fine_tuning_download_params
+from ..types import fine_tuning_delete_params, fine_tuning_content_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -185,7 +185,7 @@ def cancel(
cast_to=FineTuningCancelResponse,
)
- def download(
+ def content(
self,
*,
ft_id: str,
@@ -232,7 +232,7 @@ def download(
"checkpoint": checkpoint,
"checkpoint_step": checkpoint_step,
},
- fine_tuning_download_params.FineTuningDownloadParams,
+ fine_tuning_content_params.FineTuningContentParams,
),
),
cast_to=BinaryAPIResponse,
@@ -454,7 +454,7 @@ async def cancel(
cast_to=FineTuningCancelResponse,
)
- async def download(
+ async def content(
self,
*,
ft_id: str,
@@ -501,7 +501,7 @@ async def download(
"checkpoint": checkpoint,
"checkpoint_step": checkpoint_step,
},
- fine_tuning_download_params.FineTuningDownloadParams,
+ fine_tuning_content_params.FineTuningContentParams,
),
),
cast_to=AsyncBinaryAPIResponse,
@@ -590,8 +590,8 @@ def __init__(self, fine_tuning: FineTuningResource) -> None:
self.cancel = to_raw_response_wrapper(
fine_tuning.cancel,
)
- self.download = to_custom_raw_response_wrapper(
- fine_tuning.download,
+ self.content = to_custom_raw_response_wrapper(
+ fine_tuning.content,
BinaryAPIResponse,
)
self.list_checkpoints = to_raw_response_wrapper(
@@ -618,8 +618,8 @@ def __init__(self, fine_tuning: AsyncFineTuningResource) -> None:
self.cancel = async_to_raw_response_wrapper(
fine_tuning.cancel,
)
- self.download = async_to_custom_raw_response_wrapper(
- fine_tuning.download,
+ self.content = async_to_custom_raw_response_wrapper(
+ fine_tuning.content,
AsyncBinaryAPIResponse,
)
self.list_checkpoints = async_to_raw_response_wrapper(
@@ -646,8 +646,8 @@ def __init__(self, fine_tuning: FineTuningResource) -> None:
self.cancel = to_streamed_response_wrapper(
fine_tuning.cancel,
)
- self.download = to_custom_streamed_response_wrapper(
- fine_tuning.download,
+ self.content = to_custom_streamed_response_wrapper(
+ fine_tuning.content,
StreamedBinaryAPIResponse,
)
self.list_checkpoints = to_streamed_response_wrapper(
@@ -674,8 +674,8 @@ def __init__(self, fine_tuning: AsyncFineTuningResource) -> None:
self.cancel = async_to_streamed_response_wrapper(
fine_tuning.cancel,
)
- self.download = async_to_custom_streamed_response_wrapper(
- fine_tuning.download,
+ self.content = async_to_custom_streamed_response_wrapper(
+ fine_tuning.content,
AsyncStreamedBinaryAPIResponse,
)
self.list_checkpoints = async_to_streamed_response_wrapper(
diff --git a/src/together/types/__init__.py b/src/together/types/__init__.py
index 5170a108..bad1d48f 100644
--- a/src/together/types/__init__.py
+++ b/src/together/types/__init__.py
@@ -66,9 +66,9 @@
from .audio_speech_stream_chunk import AudioSpeechStreamChunk as AudioSpeechStreamChunk
from .fine_tuning_delete_params import FineTuningDeleteParams as FineTuningDeleteParams
from .fine_tuning_list_response import FineTuningListResponse as FineTuningListResponse
+from .fine_tuning_content_params import FineTuningContentParams as FineTuningContentParams
from .fine_tuning_cancel_response import FineTuningCancelResponse as FineTuningCancelResponse
from .fine_tuning_delete_response import FineTuningDeleteResponse as FineTuningDeleteResponse
-from .fine_tuning_download_params import FineTuningDownloadParams as FineTuningDownloadParams
from .endpoint_list_avzones_response import EndpointListAvzonesResponse as EndpointListAvzonesResponse
from .code_interpreter_execute_params import CodeInterpreterExecuteParams as CodeInterpreterExecuteParams
from .fine_tuning_list_events_response import FineTuningListEventsResponse as FineTuningListEventsResponse
diff --git a/src/together/types/fine_tuning_download_params.py b/src/together/types/fine_tuning_content_params.py
similarity index 86%
rename from src/together/types/fine_tuning_download_params.py
rename to src/together/types/fine_tuning_content_params.py
index 793d3a43..6da6ad00 100644
--- a/src/together/types/fine_tuning_download_params.py
+++ b/src/together/types/fine_tuning_content_params.py
@@ -4,10 +4,10 @@
from typing_extensions import Literal, Required, TypedDict
-__all__ = ["FineTuningDownloadParams"]
+__all__ = ["FineTuningContentParams"]
-class FineTuningDownloadParams(TypedDict, total=False):
+class FineTuningContentParams(TypedDict, total=False):
ft_id: Required[str]
"""Fine-tune ID to download. A string that starts with `ft-`."""
diff --git a/tests/api_resources/test_fine_tuning.py b/tests/api_resources/test_fine_tuning.py
index 4a7a3104..ad4f8a6a 100644
--- a/tests/api_resources/test_fine_tuning.py
+++ b/tests/api_resources/test_fine_tuning.py
@@ -177,9 +177,9 @@ def test_path_params_cancel(self, client: Together) -> None:
@parametrize
@pytest.mark.respx(base_url=base_url)
- def test_method_download(self, client: Together, respx_mock: MockRouter) -> None:
+ def test_method_content(self, client: Together, respx_mock: MockRouter) -> None:
respx_mock.get("/finetune/download").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- fine_tuning = client.fine_tuning.download(
+ fine_tuning = client.fine_tuning.content(
ft_id="ft_id",
)
assert fine_tuning.is_closed
@@ -189,9 +189,9 @@ def test_method_download(self, client: Together, respx_mock: MockRouter) -> None
@parametrize
@pytest.mark.respx(base_url=base_url)
- def test_method_download_with_all_params(self, client: Together, respx_mock: MockRouter) -> None:
+ def test_method_content_with_all_params(self, client: Together, respx_mock: MockRouter) -> None:
respx_mock.get("/finetune/download").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- fine_tuning = client.fine_tuning.download(
+ fine_tuning = client.fine_tuning.content(
ft_id="ft_id",
checkpoint="merged",
checkpoint_step=0,
@@ -203,10 +203,10 @@ def test_method_download_with_all_params(self, client: Together, respx_mock: Moc
@parametrize
@pytest.mark.respx(base_url=base_url)
- def test_raw_response_download(self, client: Together, respx_mock: MockRouter) -> None:
+ def test_raw_response_content(self, client: Together, respx_mock: MockRouter) -> None:
respx_mock.get("/finetune/download").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- fine_tuning = client.fine_tuning.with_raw_response.download(
+ fine_tuning = client.fine_tuning.with_raw_response.content(
ft_id="ft_id",
)
@@ -217,9 +217,9 @@ def test_raw_response_download(self, client: Together, respx_mock: MockRouter) -
@parametrize
@pytest.mark.respx(base_url=base_url)
- def test_streaming_response_download(self, client: Together, respx_mock: MockRouter) -> None:
+ def test_streaming_response_content(self, client: Together, respx_mock: MockRouter) -> None:
respx_mock.get("/finetune/download").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- with client.fine_tuning.with_streaming_response.download(
+ with client.fine_tuning.with_streaming_response.content(
ft_id="ft_id",
) as fine_tuning:
assert not fine_tuning.is_closed
@@ -458,9 +458,9 @@ async def test_path_params_cancel(self, async_client: AsyncTogether) -> None:
@parametrize
@pytest.mark.respx(base_url=base_url)
- async def test_method_download(self, async_client: AsyncTogether, respx_mock: MockRouter) -> None:
+ async def test_method_content(self, async_client: AsyncTogether, respx_mock: MockRouter) -> None:
respx_mock.get("/finetune/download").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- fine_tuning = await async_client.fine_tuning.download(
+ fine_tuning = await async_client.fine_tuning.content(
ft_id="ft_id",
)
assert fine_tuning.is_closed
@@ -470,9 +470,9 @@ async def test_method_download(self, async_client: AsyncTogether, respx_mock: Mo
@parametrize
@pytest.mark.respx(base_url=base_url)
- async def test_method_download_with_all_params(self, async_client: AsyncTogether, respx_mock: MockRouter) -> None:
+ async def test_method_content_with_all_params(self, async_client: AsyncTogether, respx_mock: MockRouter) -> None:
respx_mock.get("/finetune/download").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- fine_tuning = await async_client.fine_tuning.download(
+ fine_tuning = await async_client.fine_tuning.content(
ft_id="ft_id",
checkpoint="merged",
checkpoint_step=0,
@@ -484,10 +484,10 @@ async def test_method_download_with_all_params(self, async_client: AsyncTogether
@parametrize
@pytest.mark.respx(base_url=base_url)
- async def test_raw_response_download(self, async_client: AsyncTogether, respx_mock: MockRouter) -> None:
+ async def test_raw_response_content(self, async_client: AsyncTogether, respx_mock: MockRouter) -> None:
respx_mock.get("/finetune/download").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- fine_tuning = await async_client.fine_tuning.with_raw_response.download(
+ fine_tuning = await async_client.fine_tuning.with_raw_response.content(
ft_id="ft_id",
)
@@ -498,9 +498,9 @@ async def test_raw_response_download(self, async_client: AsyncTogether, respx_mo
@parametrize
@pytest.mark.respx(base_url=base_url)
- async def test_streaming_response_download(self, async_client: AsyncTogether, respx_mock: MockRouter) -> None:
+ async def test_streaming_response_content(self, async_client: AsyncTogether, respx_mock: MockRouter) -> None:
respx_mock.get("/finetune/download").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- async with async_client.fine_tuning.with_streaming_response.download(
+ async with async_client.fine_tuning.with_streaming_response.content(
ft_id="ft_id",
) as fine_tuning:
assert not fine_tuning.is_closed
From 921fa591a5a9c70f96d457a7b59749dfdfb6d4d6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 20 Nov 2025 18:06:22 +0000
Subject: [PATCH 4/8] feat(api): api update
---
.stats.yml | 4 ++--
src/together/resources/endpoints.py | 8 ++++++++
src/together/types/endpoint_create_params.py | 3 +++
tests/api_resources/test_endpoints.py | 2 ++
4 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 508eee3b..90900b36 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 44
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-57c68db188c5a4e69e16f99e7e4968f08f2dbf64e7e7d8f57f54f84669305189.yml
-openapi_spec_hash: 4e707463a416fd079a6beeff1d1beecb
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-b86f8e6c4674d1a7829ffa8ddff4bc93d21334d231e6a4d0fd734d411c07a4eb.yml
+openapi_spec_hash: 8af4975be6ae8f4655fa92fd26af9682
config_hash: 13875c495340ee39d9ff60ab63480486
diff --git a/src/together/resources/endpoints.py b/src/together/resources/endpoints.py
index db3b5c82..f591bb83 100644
--- a/src/together/resources/endpoints.py
+++ b/src/together/resources/endpoints.py
@@ -53,6 +53,7 @@ def create(
autoscaling: AutoscalingParam,
hardware: str,
model: str,
+ availability_zone: str | Omit = omit,
disable_prompt_cache: bool | Omit = omit,
disable_speculative_decoding: bool | Omit = omit,
display_name: str | Omit = omit,
@@ -78,6 +79,8 @@ def create(
model: The model to deploy on this endpoint
+ availability_zone: Create the endpoint in a specified availability zone (e.g., us-central-4b)
+
disable_prompt_cache: Whether to disable the prompt cache for this endpoint
disable_speculative_decoding: Whether to disable speculative decoding for this endpoint
@@ -105,6 +108,7 @@ def create(
"autoscaling": autoscaling,
"hardware": hardware,
"model": model,
+ "availability_zone": availability_zone,
"disable_prompt_cache": disable_prompt_cache,
"disable_speculative_decoding": disable_speculative_decoding,
"display_name": display_name,
@@ -343,6 +347,7 @@ async def create(
autoscaling: AutoscalingParam,
hardware: str,
model: str,
+ availability_zone: str | Omit = omit,
disable_prompt_cache: bool | Omit = omit,
disable_speculative_decoding: bool | Omit = omit,
display_name: str | Omit = omit,
@@ -368,6 +373,8 @@ async def create(
model: The model to deploy on this endpoint
+ availability_zone: Create the endpoint in a specified availability zone (e.g., us-central-4b)
+
disable_prompt_cache: Whether to disable the prompt cache for this endpoint
disable_speculative_decoding: Whether to disable speculative decoding for this endpoint
@@ -395,6 +402,7 @@ async def create(
"autoscaling": autoscaling,
"hardware": hardware,
"model": model,
+ "availability_zone": availability_zone,
"disable_prompt_cache": disable_prompt_cache,
"disable_speculative_decoding": disable_speculative_decoding,
"display_name": display_name,
diff --git a/src/together/types/endpoint_create_params.py b/src/together/types/endpoint_create_params.py
index 70330d81..8fdcbb07 100644
--- a/src/together/types/endpoint_create_params.py
+++ b/src/together/types/endpoint_create_params.py
@@ -20,6 +20,9 @@ class EndpointCreateParams(TypedDict, total=False):
model: Required[str]
"""The model to deploy on this endpoint"""
+ availability_zone: str
+ """Create the endpoint in a specified availability zone (e.g., us-central-4b)"""
+
disable_prompt_cache: bool
"""Whether to disable the prompt cache for this endpoint"""
diff --git a/tests/api_resources/test_endpoints.py b/tests/api_resources/test_endpoints.py
index bc7a6ad2..9a045680 100644
--- a/tests/api_resources/test_endpoints.py
+++ b/tests/api_resources/test_endpoints.py
@@ -42,6 +42,7 @@ def test_method_create_with_all_params(self, client: Together) -> None:
},
hardware="1x_nvidia_a100_80gb_sxm",
model="meta-llama/Llama-3-8b-chat-hf",
+ availability_zone="availability_zone",
disable_prompt_cache=True,
disable_speculative_decoding=True,
display_name="My Llama3 70b endpoint",
@@ -298,6 +299,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncTogether)
},
hardware="1x_nvidia_a100_80gb_sxm",
model="meta-llama/Llama-3-8b-chat-hf",
+ availability_zone="availability_zone",
disable_prompt_cache=True,
disable_speculative_decoding=True,
display_name="My Llama3 70b endpoint",
From 338c415d1cee04520413717ee821f47a64316211 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 20 Nov 2025 18:21:01 +0000
Subject: [PATCH 5/8] feat(api): Change rerank method signature
BREAKING CHANGE: Update method signature for reranking to `rerank.create()`
---
.stats.yml | 2 +-
api.md | 24 +-
src/together/_client.py | 174 +-------------
src/together/resources/__init__.py | 14 ++
src/together/resources/rerank.py | 226 ++++++++++++++++++
src/together/types/__init__.py | 4 +-
...rank_params.py => rerank_create_params.py} | 4 +-
..._response.py => rerank_create_response.py} | 4 +-
.../{test_client.py => test_rerank.py} | 62 ++---
9 files changed, 302 insertions(+), 212 deletions(-)
create mode 100644 src/together/resources/rerank.py
rename src/together/types/{client_rerank_params.py => rerank_create_params.py} (92%)
rename src/together/types/{rerank_response.py => rerank_create_response.py} (86%)
rename tests/api_resources/{test_client.py => test_rerank.py} (77%)
diff --git a/.stats.yml b/.stats.yml
index 90900b36..1e723030 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 44
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-b86f8e6c4674d1a7829ffa8ddff4bc93d21334d231e6a4d0fd734d411c07a4eb.yml
openapi_spec_hash: 8af4975be6ae8f4655fa92fd26af9682
-config_hash: 13875c495340ee39d9ff60ab63480486
+config_hash: b337cdd3c62dbd3383529592a029b347
diff --git a/api.md b/api.md
index cfd70513..13153257 100644
--- a/api.md
+++ b/api.md
@@ -1,15 +1,3 @@
-# Together
-
-Types:
-
-```python
-from together.types import RerankResponse
-```
-
-Methods:
-
-- client.rerank(\*\*params) -> RerankResponse
-
# Chat
## Completions
@@ -268,6 +256,18 @@ Methods:
- client.hardware.list(\*\*params) -> HardwareListResponse
+# Rerank
+
+Types:
+
+```python
+from together.types import RerankCreateResponse
+```
+
+Methods:
+
+- client.rerank.create(\*\*params) -> RerankCreateResponse
+
# Batches
Types:
diff --git a/src/together/_client.py b/src/together/_client.py
index 3bf16818..c190bba1 100644
--- a/src/together/_client.py
+++ b/src/together/_client.py
@@ -3,47 +3,31 @@
from __future__ import annotations
import os
-from typing import Any, Dict, Union, Mapping, Iterable
-from typing_extensions import Self, Literal, override
+from typing import Any, Mapping
+from typing_extensions import Self, override
import httpx
from . import _exceptions
from ._qs import Querystring
-from .types import client_rerank_params
from ._types import (
- Body,
Omit,
- Query,
- Headers,
Timeout,
NotGiven,
Transport,
ProxiesTypes,
RequestOptions,
- SequenceNotStr,
- omit,
not_given,
)
-from ._utils import (
- is_given,
- maybe_transform,
- get_async_library,
- async_maybe_transform,
-)
+from ._utils import is_given, get_async_library
from ._version import __version__
-from ._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
from .resources import (
jobs,
evals,
files,
images,
models,
+ rerank,
videos,
batches,
hardware,
@@ -58,11 +42,9 @@
DEFAULT_MAX_RETRIES,
SyncAPIClient,
AsyncAPIClient,
- make_request_options,
)
from .resources.chat import chat
from .resources.audio import audio
-from .types.rerank_response import RerankResponse
from .resources.code_interpreter import code_interpreter
__all__ = [
@@ -91,6 +73,7 @@ class Together(SyncAPIClient):
jobs: jobs.JobsResource
endpoints: endpoints.EndpointsResource
hardware: hardware.HardwareResource
+ rerank: rerank.RerankResource
batches: batches.BatchesResource
evals: evals.EvalsResource
with_raw_response: TogetherWithRawResponse
@@ -166,6 +149,7 @@ def __init__(
self.jobs = jobs.JobsResource(self)
self.endpoints = endpoints.EndpointsResource(self)
self.hardware = hardware.HardwareResource(self)
+ self.rerank = rerank.RerankResource(self)
self.batches = batches.BatchesResource(self)
self.evals = evals.EvalsResource(self)
self.with_raw_response = TogetherWithRawResponse(self)
@@ -244,68 +228,6 @@ def copy(
# client.with_options(timeout=10).foo.create(...)
with_options = copy
- def rerank(
- self,
- *,
- documents: Union[Iterable[Dict[str, object]], SequenceNotStr[str]],
- model: Union[Literal["Salesforce/Llama-Rank-v1"], str],
- query: str,
- rank_fields: SequenceNotStr[str] | Omit = omit,
- return_documents: bool | Omit = omit,
- top_n: int | Omit = omit,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> RerankResponse:
- """
- Query a reranker model
-
- Args:
- documents: List of documents, which can be either strings or objects.
-
- model: The model to be used for the rerank request.
-
- [See all of Together AI's rerank models](https://docs.together.ai/docs/serverless-models#rerank-models)
-
- query: The search query to be used for ranking.
-
- rank_fields: List of keys in the JSON Object document to rank by. Defaults to use all
- supplied keys for ranking.
-
- return_documents: Whether to return supplied documents with the response.
-
- top_n: The number of top results to return.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self.post(
- "/rerank",
- body=maybe_transform(
- {
- "documents": documents,
- "model": model,
- "query": query,
- "rank_fields": rank_fields,
- "return_documents": return_documents,
- "top_n": top_n,
- },
- client_rerank_params.ClientRerankParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=RerankResponse,
- )
-
@override
def _make_status_error(
self,
@@ -354,6 +276,7 @@ class AsyncTogether(AsyncAPIClient):
jobs: jobs.AsyncJobsResource
endpoints: endpoints.AsyncEndpointsResource
hardware: hardware.AsyncHardwareResource
+ rerank: rerank.AsyncRerankResource
batches: batches.AsyncBatchesResource
evals: evals.AsyncEvalsResource
with_raw_response: AsyncTogetherWithRawResponse
@@ -429,6 +352,7 @@ def __init__(
self.jobs = jobs.AsyncJobsResource(self)
self.endpoints = endpoints.AsyncEndpointsResource(self)
self.hardware = hardware.AsyncHardwareResource(self)
+ self.rerank = rerank.AsyncRerankResource(self)
self.batches = batches.AsyncBatchesResource(self)
self.evals = evals.AsyncEvalsResource(self)
self.with_raw_response = AsyncTogetherWithRawResponse(self)
@@ -507,68 +431,6 @@ def copy(
# client.with_options(timeout=10).foo.create(...)
with_options = copy
- async def rerank(
- self,
- *,
- documents: Union[Iterable[Dict[str, object]], SequenceNotStr[str]],
- model: Union[Literal["Salesforce/Llama-Rank-v1"], str],
- query: str,
- rank_fields: SequenceNotStr[str] | Omit = omit,
- return_documents: bool | Omit = omit,
- top_n: int | Omit = omit,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> RerankResponse:
- """
- Query a reranker model
-
- Args:
- documents: List of documents, which can be either strings or objects.
-
- model: The model to be used for the rerank request.
-
- [See all of Together AI's rerank models](https://docs.together.ai/docs/serverless-models#rerank-models)
-
- query: The search query to be used for ranking.
-
- rank_fields: List of keys in the JSON Object document to rank by. Defaults to use all
- supplied keys for ranking.
-
- return_documents: Whether to return supplied documents with the response.
-
- top_n: The number of top results to return.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self.post(
- "/rerank",
- body=await async_maybe_transform(
- {
- "documents": documents,
- "model": model,
- "query": query,
- "rank_fields": rank_fields,
- "return_documents": return_documents,
- "top_n": top_n,
- },
- client_rerank_params.ClientRerankParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=RerankResponse,
- )
-
@override
def _make_status_error(
self,
@@ -618,13 +480,10 @@ def __init__(self, client: Together) -> None:
self.jobs = jobs.JobsResourceWithRawResponse(client.jobs)
self.endpoints = endpoints.EndpointsResourceWithRawResponse(client.endpoints)
self.hardware = hardware.HardwareResourceWithRawResponse(client.hardware)
+ self.rerank = rerank.RerankResourceWithRawResponse(client.rerank)
self.batches = batches.BatchesResourceWithRawResponse(client.batches)
self.evals = evals.EvalsResourceWithRawResponse(client.evals)
- self.rerank = to_raw_response_wrapper(
- client.rerank,
- )
-
class AsyncTogetherWithRawResponse:
def __init__(self, client: AsyncTogether) -> None:
@@ -641,13 +500,10 @@ def __init__(self, client: AsyncTogether) -> None:
self.jobs = jobs.AsyncJobsResourceWithRawResponse(client.jobs)
self.endpoints = endpoints.AsyncEndpointsResourceWithRawResponse(client.endpoints)
self.hardware = hardware.AsyncHardwareResourceWithRawResponse(client.hardware)
+ self.rerank = rerank.AsyncRerankResourceWithRawResponse(client.rerank)
self.batches = batches.AsyncBatchesResourceWithRawResponse(client.batches)
self.evals = evals.AsyncEvalsResourceWithRawResponse(client.evals)
- self.rerank = async_to_raw_response_wrapper(
- client.rerank,
- )
-
class TogetherWithStreamedResponse:
def __init__(self, client: Together) -> None:
@@ -664,13 +520,10 @@ def __init__(self, client: Together) -> None:
self.jobs = jobs.JobsResourceWithStreamingResponse(client.jobs)
self.endpoints = endpoints.EndpointsResourceWithStreamingResponse(client.endpoints)
self.hardware = hardware.HardwareResourceWithStreamingResponse(client.hardware)
+ self.rerank = rerank.RerankResourceWithStreamingResponse(client.rerank)
self.batches = batches.BatchesResourceWithStreamingResponse(client.batches)
self.evals = evals.EvalsResourceWithStreamingResponse(client.evals)
- self.rerank = to_streamed_response_wrapper(
- client.rerank,
- )
-
class AsyncTogetherWithStreamedResponse:
def __init__(self, client: AsyncTogether) -> None:
@@ -689,13 +542,10 @@ def __init__(self, client: AsyncTogether) -> None:
self.jobs = jobs.AsyncJobsResourceWithStreamingResponse(client.jobs)
self.endpoints = endpoints.AsyncEndpointsResourceWithStreamingResponse(client.endpoints)
self.hardware = hardware.AsyncHardwareResourceWithStreamingResponse(client.hardware)
+ self.rerank = rerank.AsyncRerankResourceWithStreamingResponse(client.rerank)
self.batches = batches.AsyncBatchesResourceWithStreamingResponse(client.batches)
self.evals = evals.AsyncEvalsResourceWithStreamingResponse(client.evals)
- self.rerank = async_to_streamed_response_wrapper(
- client.rerank,
- )
-
Client = Together
diff --git a/src/together/resources/__init__.py b/src/together/resources/__init__.py
index 0d0a6958..cdcf732b 100644
--- a/src/together/resources/__init__.py
+++ b/src/together/resources/__init__.py
@@ -56,6 +56,14 @@
ModelsResourceWithStreamingResponse,
AsyncModelsResourceWithStreamingResponse,
)
+from .rerank import (
+ RerankResource,
+ AsyncRerankResource,
+ RerankResourceWithRawResponse,
+ AsyncRerankResourceWithRawResponse,
+ RerankResourceWithStreamingResponse,
+ AsyncRerankResourceWithStreamingResponse,
+)
from .videos import (
VideosResource,
AsyncVideosResource,
@@ -200,6 +208,12 @@
"AsyncHardwareResourceWithRawResponse",
"HardwareResourceWithStreamingResponse",
"AsyncHardwareResourceWithStreamingResponse",
+ "RerankResource",
+ "AsyncRerankResource",
+ "RerankResourceWithRawResponse",
+ "AsyncRerankResourceWithRawResponse",
+ "RerankResourceWithStreamingResponse",
+ "AsyncRerankResourceWithStreamingResponse",
"BatchesResource",
"AsyncBatchesResource",
"BatchesResourceWithRawResponse",
diff --git a/src/together/resources/rerank.py b/src/together/resources/rerank.py
new file mode 100644
index 00000000..b8a62735
--- /dev/null
+++ b/src/together/resources/rerank.py
@@ -0,0 +1,226 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Iterable
+from typing_extensions import Literal
+
+import httpx
+
+from ..types import rerank_create_params
+from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from .._utils import maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.rerank_create_response import RerankCreateResponse
+
+__all__ = ["RerankResource", "AsyncRerankResource"]
+
+
+class RerankResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> RerankResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/togethercomputer/together-py#accessing-raw-response-data-eg-headers
+ """
+ return RerankResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> RerankResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/togethercomputer/together-py#with_streaming_response
+ """
+ return RerankResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ documents: Union[Iterable[Dict[str, object]], SequenceNotStr[str]],
+ model: Union[Literal["Salesforce/Llama-Rank-v1"], str],
+ query: str,
+ rank_fields: SequenceNotStr[str] | Omit = omit,
+ return_documents: bool | Omit = omit,
+ top_n: int | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RerankCreateResponse:
+ """
+ Query a reranker model
+
+ Args:
+ documents: List of documents, which can be either strings or objects.
+
+ model: The model to be used for the rerank request.
+
+ [See all of Together AI's rerank models](https://docs.together.ai/docs/serverless-models#rerank-models)
+
+ query: The search query to be used for ranking.
+
+ rank_fields: List of keys in the JSON Object document to rank by. Defaults to use all
+ supplied keys for ranking.
+
+ return_documents: Whether to return supplied documents with the response.
+
+ top_n: The number of top results to return.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/rerank",
+ body=maybe_transform(
+ {
+ "documents": documents,
+ "model": model,
+ "query": query,
+ "rank_fields": rank_fields,
+ "return_documents": return_documents,
+ "top_n": top_n,
+ },
+ rerank_create_params.RerankCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=RerankCreateResponse,
+ )
+
+
+class AsyncRerankResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncRerankResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/togethercomputer/together-py#accessing-raw-response-data-eg-headers
+ """
+ return AsyncRerankResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncRerankResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/togethercomputer/together-py#with_streaming_response
+ """
+ return AsyncRerankResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ documents: Union[Iterable[Dict[str, object]], SequenceNotStr[str]],
+ model: Union[Literal["Salesforce/Llama-Rank-v1"], str],
+ query: str,
+ rank_fields: SequenceNotStr[str] | Omit = omit,
+ return_documents: bool | Omit = omit,
+ top_n: int | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RerankCreateResponse:
+ """
+ Query a reranker model
+
+ Args:
+ documents: List of documents, which can be either strings or objects.
+
+ model: The model to be used for the rerank request.
+
+ [See all of Together AI's rerank models](https://docs.together.ai/docs/serverless-models#rerank-models)
+
+ query: The search query to be used for ranking.
+
+ rank_fields: List of keys in the JSON Object document to rank by. Defaults to use all
+ supplied keys for ranking.
+
+ return_documents: Whether to return supplied documents with the response.
+
+ top_n: The number of top results to return.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/rerank",
+ body=await async_maybe_transform(
+ {
+ "documents": documents,
+ "model": model,
+ "query": query,
+ "rank_fields": rank_fields,
+ "return_documents": return_documents,
+ "top_n": top_n,
+ },
+ rerank_create_params.RerankCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=RerankCreateResponse,
+ )
+
+
+class RerankResourceWithRawResponse:
+ def __init__(self, rerank: RerankResource) -> None:
+ self._rerank = rerank
+
+ self.create = to_raw_response_wrapper(
+ rerank.create,
+ )
+
+
+class AsyncRerankResourceWithRawResponse:
+ def __init__(self, rerank: AsyncRerankResource) -> None:
+ self._rerank = rerank
+
+ self.create = async_to_raw_response_wrapper(
+ rerank.create,
+ )
+
+
+class RerankResourceWithStreamingResponse:
+ def __init__(self, rerank: RerankResource) -> None:
+ self._rerank = rerank
+
+ self.create = to_streamed_response_wrapper(
+ rerank.create,
+ )
+
+
+class AsyncRerankResourceWithStreamingResponse:
+ def __init__(self, rerank: AsyncRerankResource) -> None:
+ self._rerank = rerank
+
+ self.create = async_to_streamed_response_wrapper(
+ rerank.create,
+ )
diff --git a/src/together/types/__init__.py b/src/together/types/__init__.py
index bad1d48f..11c20cc9 100644
--- a/src/together/types/__init__.py
+++ b/src/together/types/__init__.py
@@ -18,7 +18,6 @@
from .image_data_b64 import ImageDataB64 as ImageDataB64
from .image_data_url import ImageDataURL as ImageDataURL
from .fine_tune_event import FineTuneEvent as FineTuneEvent
-from .rerank_response import RerankResponse as RerankResponse
from .completion_chunk import CompletionChunk as CompletionChunk
from .eval_list_params import EvalListParams as EvalListParams
from .execute_response import ExecuteResponse as ExecuteResponse
@@ -40,13 +39,13 @@
from .training_method_dpo import TrainingMethodDpo as TrainingMethodDpo
from .training_method_sft import TrainingMethodSft as TrainingMethodSft
from .video_create_params import VideoCreateParams as VideoCreateParams
-from .client_rerank_params import ClientRerankParams as ClientRerankParams
from .endpoint_list_params import EndpointListParams as EndpointListParams
from .eval_create_response import EvalCreateResponse as EvalCreateResponse
from .eval_status_response import EvalStatusResponse as EvalStatusResponse
from .eval_update_response import EvalUpdateResponse as EvalUpdateResponse
from .file_delete_response import FileDeleteResponse as FileDeleteResponse
from .hardware_list_params import HardwareListParams as HardwareListParams
+from .rerank_create_params import RerankCreateParams as RerankCreateParams
from .batch_cancel_response import BatchCancelResponse as BatchCancelResponse
from .batch_create_response import BatchCreateResponse as BatchCreateResponse
from .image_generate_params import ImageGenerateParams as ImageGenerateParams
@@ -58,6 +57,7 @@
from .endpoint_update_params import EndpointUpdateParams as EndpointUpdateParams
from .file_retrieve_response import FileRetrieveResponse as FileRetrieveResponse
from .hardware_list_response import HardwareListResponse as HardwareListResponse
+from .rerank_create_response import RerankCreateResponse as RerankCreateResponse
from .batch_retrieve_response import BatchRetrieveResponse as BatchRetrieveResponse
from .embedding_create_params import EmbeddingCreateParams as EmbeddingCreateParams
from .completion_create_params import CompletionCreateParams as CompletionCreateParams
diff --git a/src/together/types/client_rerank_params.py b/src/together/types/rerank_create_params.py
similarity index 92%
rename from src/together/types/client_rerank_params.py
rename to src/together/types/rerank_create_params.py
index c3334deb..03da2960 100644
--- a/src/together/types/client_rerank_params.py
+++ b/src/together/types/rerank_create_params.py
@@ -7,10 +7,10 @@
from .._types import SequenceNotStr
-__all__ = ["ClientRerankParams"]
+__all__ = ["RerankCreateParams"]
-class ClientRerankParams(TypedDict, total=False):
+class RerankCreateParams(TypedDict, total=False):
documents: Required[Union[Iterable[Dict[str, object]], SequenceNotStr[str]]]
"""List of documents, which can be either strings or objects."""
diff --git a/src/together/types/rerank_response.py b/src/together/types/rerank_create_response.py
similarity index 86%
rename from src/together/types/rerank_response.py
rename to src/together/types/rerank_create_response.py
index 73860249..8002027e 100644
--- a/src/together/types/rerank_response.py
+++ b/src/together/types/rerank_create_response.py
@@ -6,7 +6,7 @@
from .._models import BaseModel
from .chat.chat_completion_usage import ChatCompletionUsage
-__all__ = ["RerankResponse", "Result", "ResultDocument"]
+__all__ = ["RerankCreateResponse", "Result", "ResultDocument"]
class ResultDocument(BaseModel):
@@ -21,7 +21,7 @@ class Result(BaseModel):
relevance_score: float
-class RerankResponse(BaseModel):
+class RerankCreateResponse(BaseModel):
model: str
"""The model to be used for the rerank request."""
diff --git a/tests/api_resources/test_client.py b/tests/api_resources/test_rerank.py
similarity index 77%
rename from tests/api_resources/test_client.py
rename to tests/api_resources/test_rerank.py
index 691c42c4..72c587f4 100644
--- a/tests/api_resources/test_client.py
+++ b/tests/api_resources/test_rerank.py
@@ -9,17 +9,17 @@
from together import Together, AsyncTogether
from tests.utils import assert_matches_type
-from together.types import RerankResponse
+from together.types import RerankCreateResponse
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-class TestClient:
+class TestRerank:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
@parametrize
- def test_method_rerank(self, client: Together) -> None:
- client_ = client.rerank(
+ def test_method_create(self, client: Together) -> None:
+ rerank = client.rerank.create(
documents=[
{
"title": "bar",
@@ -41,11 +41,11 @@ def test_method_rerank(self, client: Together) -> None:
model="Salesforce/Llama-Rank-V1",
query="What animals can I find near Peru?",
)
- assert_matches_type(RerankResponse, client_, path=["response"])
+ assert_matches_type(RerankCreateResponse, rerank, path=["response"])
@parametrize
- def test_method_rerank_with_all_params(self, client: Together) -> None:
- client_ = client.rerank(
+ def test_method_create_with_all_params(self, client: Together) -> None:
+ rerank = client.rerank.create(
documents=[
{
"title": "bar",
@@ -70,11 +70,11 @@ def test_method_rerank_with_all_params(self, client: Together) -> None:
return_documents=True,
top_n=2,
)
- assert_matches_type(RerankResponse, client_, path=["response"])
+ assert_matches_type(RerankCreateResponse, rerank, path=["response"])
@parametrize
- def test_raw_response_rerank(self, client: Together) -> None:
- response = client.with_raw_response.rerank(
+ def test_raw_response_create(self, client: Together) -> None:
+ response = client.rerank.with_raw_response.create(
documents=[
{
"title": "bar",
@@ -99,12 +99,12 @@ def test_raw_response_rerank(self, client: Together) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- client_ = response.parse()
- assert_matches_type(RerankResponse, client_, path=["response"])
+ rerank = response.parse()
+ assert_matches_type(RerankCreateResponse, rerank, path=["response"])
@parametrize
- def test_streaming_response_rerank(self, client: Together) -> None:
- with client.with_streaming_response.rerank(
+ def test_streaming_response_create(self, client: Together) -> None:
+ with client.rerank.with_streaming_response.create(
documents=[
{
"title": "bar",
@@ -129,20 +129,20 @@ def test_streaming_response_rerank(self, client: Together) -> None:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- client_ = response.parse()
- assert_matches_type(RerankResponse, client_, path=["response"])
+ rerank = response.parse()
+ assert_matches_type(RerankCreateResponse, rerank, path=["response"])
assert cast(Any, response.is_closed) is True
-class TestAsyncClient:
+class TestAsyncRerank:
parametrize = pytest.mark.parametrize(
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
@parametrize
- async def test_method_rerank(self, async_client: AsyncTogether) -> None:
- client = await async_client.rerank(
+ async def test_method_create(self, async_client: AsyncTogether) -> None:
+ rerank = await async_client.rerank.create(
documents=[
{
"title": "bar",
@@ -164,11 +164,11 @@ async def test_method_rerank(self, async_client: AsyncTogether) -> None:
model="Salesforce/Llama-Rank-V1",
query="What animals can I find near Peru?",
)
- assert_matches_type(RerankResponse, client, path=["response"])
+ assert_matches_type(RerankCreateResponse, rerank, path=["response"])
@parametrize
- async def test_method_rerank_with_all_params(self, async_client: AsyncTogether) -> None:
- client = await async_client.rerank(
+ async def test_method_create_with_all_params(self, async_client: AsyncTogether) -> None:
+ rerank = await async_client.rerank.create(
documents=[
{
"title": "bar",
@@ -193,11 +193,11 @@ async def test_method_rerank_with_all_params(self, async_client: AsyncTogether)
return_documents=True,
top_n=2,
)
- assert_matches_type(RerankResponse, client, path=["response"])
+ assert_matches_type(RerankCreateResponse, rerank, path=["response"])
@parametrize
- async def test_raw_response_rerank(self, async_client: AsyncTogether) -> None:
- response = await async_client.with_raw_response.rerank(
+ async def test_raw_response_create(self, async_client: AsyncTogether) -> None:
+ response = await async_client.rerank.with_raw_response.create(
documents=[
{
"title": "bar",
@@ -222,12 +222,12 @@ async def test_raw_response_rerank(self, async_client: AsyncTogether) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- client = await response.parse()
- assert_matches_type(RerankResponse, client, path=["response"])
+ rerank = await response.parse()
+ assert_matches_type(RerankCreateResponse, rerank, path=["response"])
@parametrize
- async def test_streaming_response_rerank(self, async_client: AsyncTogether) -> None:
- async with async_client.with_streaming_response.rerank(
+ async def test_streaming_response_create(self, async_client: AsyncTogether) -> None:
+ async with async_client.rerank.with_streaming_response.create(
documents=[
{
"title": "bar",
@@ -252,7 +252,7 @@ async def test_streaming_response_rerank(self, async_client: AsyncTogether) -> N
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- client = await response.parse()
- assert_matches_type(RerankResponse, client, path=["response"])
+ rerank = await response.parse()
+ assert_matches_type(RerankCreateResponse, rerank, path=["response"])
assert cast(Any, response.is_closed) is True
From ef3bd5245ee254269653ff8e6db1651cfcf89c6d Mon Sep 17 00:00:00 2001
From: Blaine Kasten
Date: Fri, 21 Nov 2025 06:55:02 -0600
Subject: [PATCH 6/8] feat(api): Port finetuning create code from
together-python (#176)
---
src/together/lib/cli/api/fine_tuning.py | 22 +-
src/together/lib/resources/fine_tuning.py | 167 +++++-----
src/together/lib/types/fine_tuning.py | 370 +++++++++++++++++++++-
src/together/resources/fine_tuning.py | 347 ++++++++++++++++++++
tests/unit/test_fine_tuning_resources.py | 168 ++++++----
5 files changed, 908 insertions(+), 166 deletions(-)
diff --git a/src/together/lib/cli/api/fine_tuning.py b/src/together/lib/cli/api/fine_tuning.py
index ecf9ecd0..c116d352 100644
--- a/src/together/lib/cli/api/fine_tuning.py
+++ b/src/together/lib/cli/api/fine_tuning.py
@@ -20,7 +20,7 @@
from together.lib.cli.api.utils import INT_WITH_MAX, BOOL_WITH_AUTO
from together.lib.resources.files import DownloadManager
from together.lib.utils.serializer import datetime_serializer
-from together.lib.resources.fine_tuning import get_model_limits, create_fine_tuning_request
+from together.lib.resources.fine_tuning import get_model_limits
_CONFIRMATION_MESSAGE = (
"You are about to create a fine-tuning job. "
@@ -287,13 +287,7 @@ def create(
if from_checkpoint is not None:
model_name = from_checkpoint.split(":")[0]
- if model_name is None:
- raise click.BadParameter("You must specify a model or a checkpoint")
-
- model_limits = get_model_limits(
- client,
- model=model_name,
- )
+ model_limits = get_model_limits(client, str(model_name))
if lora:
if model_limits.lora_training is None:
@@ -304,9 +298,9 @@ def create(
}
for arg in default_values:
- arg_source = ctx.get_parameter_source("arg")
+ arg_source = ctx.get_parameter_source("arg") # type: ignore[attr-defined]
if arg_source == ParameterSource.DEFAULT:
- training_args[str(arg)] = default_values[str(arg_source)]
+ training_args[arg] = default_values[str(arg_source)]
if ctx.get_parameter_source("lora_alpha") == ParameterSource.DEFAULT: # type: ignore[attr-defined]
training_args["lora_alpha"] = training_args["lora_r"] * 2
@@ -330,18 +324,16 @@ def create(
raise click.BadParameter("You have specified a number of evaluation loops but no validation file.")
if confirm or click.confirm(_CONFIRMATION_MESSAGE, default=True, show_default=True):
- params = create_fine_tuning_request(
- model_limits=model_limits,
+ response = client.fine_tuning.create(
**training_args,
+ verbose=True,
)
- rprint("Submitting a fine-tuning job with the following parameters:", params)
- response = client.fine_tuning.create(**params)
report_string = f"Successfully submitted a fine-tuning job {response.id}"
# created_at reports UTC time, we use .astimezone() to convert to local time
formatted_time = response.created_at.astimezone().strftime("%m/%d/%Y, %H:%M:%S")
report_string += f" at {formatted_time}"
- click.echo(report_string)
+ rprint(report_string)
else:
click.echo("No confirmation received, stopping job launch")
diff --git a/src/together/lib/resources/fine_tuning.py b/src/together/lib/resources/fine_tuning.py
index d88de9dc..f4779191 100644
--- a/src/together/lib/resources/fine_tuning.py
+++ b/src/together/lib/resources/fine_tuning.py
@@ -1,27 +1,27 @@
from __future__ import annotations
-from typing import Any, Dict, Literal
-from typing_extensions import Union, TypeAlias
+from typing import TYPE_CHECKING, Literal
from rich import print as rprint
-from together import Together
-from together.types import (
- LrSchedulerParam,
- FullTrainingTypeParam,
- LoRaTrainingTypeParam,
- FineTuningCreateParams,
- TrainingMethodDpoParam,
- TrainingMethodSftParam,
- CosineLrSchedulerArgsParam,
- LinearLrSchedulerArgsParam,
-)
from together.lib.utils import log_warn_once
-from together.lib.types.fine_tuning import FinetuneTrainingLimits
-
-TrainingMethod: TypeAlias = Union[TrainingMethodSftParam, TrainingMethodDpoParam]
-TrainingType: TypeAlias = Union[FullTrainingTypeParam, LoRaTrainingTypeParam]
+if TYPE_CHECKING:
+ from together import Together, AsyncTogether
+from together.lib.types.fine_tuning import (
+ TrainingType,
+ FinetuneRequest,
+ FullTrainingType,
+ LoRATrainingType,
+ CosineLRScheduler,
+ LinearLRScheduler,
+ TrainingMethodDPO,
+ TrainingMethodSFT,
+ FinetuneLRScheduler,
+ CosineLRSchedulerArgs,
+ LinearLRSchedulerArgs,
+ FinetuneTrainingLimits,
+)
AVAILABLE_TRAINING_METHODS = {
"sft",
@@ -29,7 +29,7 @@
}
-def create_fine_tuning_request(
+def create_finetune_request(
model_limits: FinetuneTrainingLimits,
training_file: str,
model: str | None = None,
@@ -40,11 +40,11 @@ def create_fine_tuning_request(
batch_size: int | Literal["max"] = "max",
learning_rate: float | None = 0.00001,
lr_scheduler_type: Literal["linear", "cosine"] = "cosine",
- min_lr_ratio: float = 0.0,
+ min_lr_ratio: float | None = 0.0,
scheduler_num_cycles: float = 0.5,
warmup_ratio: float | None = None,
max_grad_norm: float = 1.0,
- weight_decay: float = 0.0,
+ weight_decay: float | None = 0.0,
lora: bool = False,
lora_r: int | None = None,
lora_dropout: float | None = 0,
@@ -66,7 +66,7 @@ def create_fine_tuning_request(
hf_model_revision: str | None = None,
hf_api_token: str | None = None,
hf_output_repo_name: str | None = None,
-) -> FineTuningCreateParams:
+) -> FinetuneRequest:
if model is not None and from_checkpoint is not None:
raise ValueError("You must specify either a model or a checkpoint to start a job from, not both")
@@ -87,7 +87,7 @@ def create_fine_tuning_request(
if warmup_ratio is None:
warmup_ratio = 0.0
- training_type: TrainingType = FullTrainingTypeParam(type="Full")
+ training_type: TrainingType = FullTrainingType()
if lora:
if model_limits.lora_training is None:
raise ValueError(f"LoRA adapters are not supported for the selected model ({model_or_checkpoint}).")
@@ -98,15 +98,12 @@ def create_fine_tuning_request(
lora_r = lora_r if lora_r is not None else model_limits.lora_training.max_rank
lora_alpha = lora_alpha if lora_alpha is not None else lora_r * 2
- training_type = LoRaTrainingTypeParam(
- type="Lora",
+ training_type = LoRATrainingType(
lora_r=lora_r,
lora_alpha=int(lora_alpha),
+ lora_dropout=lora_dropout or 0.0,
+ lora_trainable_modules=lora_trainable_modules or "all-linear",
)
- if lora_dropout is not None:
- training_type["lora_dropout"] = lora_dropout
- if lora_trainable_modules is not None:
- training_type["lora_trainable_modules"] = lora_trainable_modules
max_batch_size = model_limits.lora_training.max_batch_size
min_batch_size = model_limits.lora_training.min_batch_size
@@ -139,13 +136,13 @@ def create_fine_tuning_request(
if warmup_ratio > 1 or warmup_ratio < 0:
raise ValueError(f"Warmup ratio should be between 0 and 1 (got {warmup_ratio})")
- if min_lr_ratio > 1 or min_lr_ratio < 0:
+ if min_lr_ratio is not None and (min_lr_ratio > 1 or min_lr_ratio < 0):
raise ValueError(f"Min learning rate ratio should be between 0 and 1 (got {min_lr_ratio})")
if max_grad_norm < 0:
raise ValueError(f"Max gradient norm should be non-negative (got {max_grad_norm})")
- if weight_decay < 0:
+ if weight_decay is not None and (weight_decay < 0):
raise ValueError(f"Weight decay should be non-negative (got {weight_decay})")
if training_method not in AVAILABLE_TRAINING_METHODS:
@@ -154,10 +151,6 @@ def create_fine_tuning_request(
if train_on_inputs is not None and training_method != "sft":
raise ValueError("train_on_inputs is only supported for SFT training")
- if train_on_inputs is None and training_method == "sft":
- log_warn_once("train_on_inputs is not set for SFT training, it will be set to 'auto'")
- train_on_inputs = "auto"
-
if dpo_beta is not None and training_method != "dpo":
raise ValueError("dpo_beta is only supported for DPO training")
if dpo_normalize_logratios_by_length and training_method != "dpo":
@@ -174,24 +167,25 @@ def create_fine_tuning_request(
if not simpo_gamma >= 0.0:
raise ValueError(f"simpo_gamma should be non-negative (got {simpo_gamma})")
- lr_scheduler: LrSchedulerParam
+ lr_scheduler: FinetuneLRScheduler
if lr_scheduler_type == "cosine":
if scheduler_num_cycles <= 0.0:
raise ValueError(f"Number of cycles should be greater than 0 (got {scheduler_num_cycles})")
- lr_scheduler = LrSchedulerParam(
- lr_scheduler_type="cosine",
- lr_scheduler_args=CosineLrSchedulerArgsParam(min_lr_ratio=min_lr_ratio, num_cycles=scheduler_num_cycles),
+ lr_scheduler = CosineLRScheduler(
+ lr_scheduler_args=CosineLRSchedulerArgs(min_lr_ratio=min_lr_ratio, num_cycles=scheduler_num_cycles),
)
else:
- lr_scheduler = LrSchedulerParam(
- lr_scheduler_type="linear",
- lr_scheduler_args=LinearLrSchedulerArgsParam(min_lr_ratio=min_lr_ratio),
+ lr_scheduler = LinearLRScheduler(
+ lr_scheduler_args=LinearLRSchedulerArgs(min_lr_ratio=min_lr_ratio),
)
- training_method_cls: TrainingMethod | None = None
+ training_method_cls: TrainingMethodSFT | TrainingMethodDPO
if training_method == "sft":
- training_method_cls = TrainingMethodSftParam(method="sft", train_on_inputs=train_on_inputs or "auto")
+ if train_on_inputs is None:
+ log_warn_once("train_on_inputs is not set for SFT training, it will be set to 'auto'")
+ train_on_inputs = "auto"
+ training_method_cls = TrainingMethodSFT(train_on_inputs=train_on_inputs)
elif training_method == "dpo":
if simpo_gamma is not None and simpo_gamma > 0:
dpo_reference_free = True
@@ -204,59 +198,40 @@ def create_fine_tuning_request(
else:
dpo_reference_free = False
- training_method_cls = TrainingMethodDpoParam(
- method="dpo",
+ training_method_cls = TrainingMethodDPO(
+ dpo_beta=dpo_beta,
dpo_normalize_logratios_by_length=dpo_normalize_logratios_by_length,
dpo_reference_free=dpo_reference_free,
+ rpo_alpha=rpo_alpha,
+ simpo_gamma=simpo_gamma,
)
- if dpo_beta is not None:
- training_method_cls["dpo_beta"] = dpo_beta
- if rpo_alpha is not None:
- training_method_cls["rpo_alpha"] = rpo_alpha
- if simpo_gamma is not None:
- training_method_cls["simpo_gamma"] = simpo_gamma
-
- finetune_request = FineTuningCreateParams(
- model=model or "",
+
+ finetune_request = FinetuneRequest(
+ model=model,
training_file=training_file,
+ validation_file=validation_file,
n_epochs=n_epochs,
+ n_evals=n_evals,
+ n_checkpoints=n_checkpoints,
batch_size=batch_size,
+ learning_rate=learning_rate or 0.00001,
lr_scheduler=lr_scheduler,
warmup_ratio=warmup_ratio,
max_grad_norm=max_grad_norm,
- weight_decay=weight_decay,
+ weight_decay=weight_decay or 0.0,
training_type=training_type,
+ suffix=suffix,
+ wandb_key=wandb_api_key,
+ wandb_base_url=wandb_base_url,
+ wandb_project_name=wandb_project_name,
+ wandb_name=wandb_name,
+ training_method=training_method_cls, # pyright: ignore[reportPossiblyUnboundVariable]
+ from_checkpoint=from_checkpoint,
+ from_hf_model=from_hf_model,
+ hf_model_revision=hf_model_revision,
+ hf_api_token=hf_api_token,
+ hf_output_repo_name=hf_output_repo_name,
)
- if validation_file is not None:
- finetune_request["validation_file"] = validation_file
- if n_evals is not None:
- finetune_request["n_evals"] = n_evals
- if n_checkpoints is not None:
- finetune_request["n_checkpoints"] = n_checkpoints
- if learning_rate is not None:
- finetune_request["learning_rate"] = learning_rate
- if suffix is not None:
- finetune_request["suffix"] = suffix
- if wandb_api_key is not None:
- finetune_request["wandb_api_key"] = wandb_api_key
- if wandb_base_url is not None:
- finetune_request["wandb_base_url"] = wandb_base_url
- if wandb_project_name is not None:
- finetune_request["wandb_project_name"] = wandb_project_name
- if wandb_name is not None:
- finetune_request["wandb_name"] = wandb_name
- if training_method_cls is not None:
- finetune_request["training_method"] = training_method_cls
- if from_checkpoint is not None:
- finetune_request["from_checkpoint"] = from_checkpoint
- if from_hf_model is not None:
- finetune_request["from_hf_model"] = from_hf_model
- if hf_model_revision is not None:
- finetune_request["hf_model_revision"] = hf_model_revision
- if hf_api_token is not None:
- finetune_request["hf_api_token"] = hf_api_token
- if hf_output_repo_name is not None:
- finetune_request["hf_output_repo_name"] = hf_output_repo_name
return finetune_request
@@ -283,5 +258,23 @@ def get_model_limits(client: Together, model: str) -> FinetuneTrainingLimits:
return response
-def not_none_kwargs(**kwargs: Any) -> Dict[str, Any]:
- return {k: v for k, v in kwargs.items() if v is not None}
+async def async_get_model_limits(client: AsyncTogether, model: str) -> FinetuneTrainingLimits:
+ """
+ Requests training limits for a specific model
+
+ Args:
+ model_name (str): Name of the model to get limits for
+
+ Returns:
+ FinetuneTrainingLimits: Object containing training limits for the model
+ """
+
+ response = await client.get(
+ "/fine-tunes/models/limits",
+ cast_to=FinetuneTrainingLimits,
+ options={
+ "params": {"model_name": model},
+ },
+ )
+
+ return response
diff --git a/src/together/lib/types/fine_tuning.py b/src/together/lib/types/fine_tuning.py
index 7c42d58b..55327e5a 100644
--- a/src/together/lib/types/fine_tuning.py
+++ b/src/together/lib/types/fine_tuning.py
@@ -1,8 +1,128 @@
-from typing import Any, List, Optional
+from enum import Enum
+from typing import Any, List, Union, Literal, Optional
+from datetime import datetime
+from typing_extensions import TypeAlias
+
+from pydantic import Field, StrictBool
from ..._models import BaseModel
+class FinetuneJobStatus(str, Enum):
+ """
+ Possible fine-tune job status
+ """
+
+ STATUS_PENDING = "pending"
+ STATUS_QUEUED = "queued"
+ STATUS_RUNNING = "running"
+ STATUS_COMPRESSING = "compressing"
+ STATUS_UPLOADING = "uploading"
+ STATUS_CANCEL_REQUESTED = "cancel_requested"
+ STATUS_CANCELLED = "cancelled"
+ STATUS_ERROR = "error"
+ STATUS_USER_ERROR = "user_error"
+ STATUS_COMPLETED = "completed"
+
+
+class FinetuneEventType(str, Enum):
+ """
+ Fine-tune job event types
+ """
+
+ JOB_PENDING = "JOB_PENDING"
+ JOB_START = "JOB_START"
+ JOB_STOPPED = "JOB_STOPPED"
+ MODEL_DOWNLOADING = "MODEL_DOWNLOADING"
+ MODEL_DOWNLOAD_COMPLETE = "MODEL_DOWNLOAD_COMPLETE"
+ TRAINING_DATA_DOWNLOADING = "TRAINING_DATA_DOWNLOADING"
+ TRAINING_DATA_DOWNLOAD_COMPLETE = "TRAINING_DATA_DOWNLOAD_COMPLETE"
+ VALIDATION_DATA_DOWNLOADING = "VALIDATION_DATA_DOWNLOADING"
+ VALIDATION_DATA_DOWNLOAD_COMPLETE = "VALIDATION_DATA_DOWNLOAD_COMPLETE"
+ WANDB_INIT = "WANDB_INIT"
+ TRAINING_START = "TRAINING_START"
+ CHECKPOINT_SAVE = "CHECKPOINT_SAVE"
+ BILLING_LIMIT = "BILLING_LIMIT"
+ EPOCH_COMPLETE = "EPOCH_COMPLETE"
+ EVAL_COMPLETE = "EVAL_COMPLETE"
+ TRAINING_COMPLETE = "TRAINING_COMPLETE"
+ MODEL_COMPRESSING = "COMPRESSING_MODEL"
+ MODEL_COMPRESSION_COMPLETE = "MODEL_COMPRESSION_COMPLETE"
+ MODEL_UPLOADING = "MODEL_UPLOADING"
+ MODEL_UPLOAD_COMPLETE = "MODEL_UPLOAD_COMPLETE"
+ MODEL_UPLOADING_TO_HF = "MODEL_UPLOADING_TO_HF"
+ MODEL_UPLOAD_TO_HF_COMPLETE = "MODEL_UPLOAD_TO_HF_COMPLETE"
+ JOB_COMPLETE = "JOB_COMPLETE"
+ JOB_ERROR = "JOB_ERROR"
+ JOB_USER_ERROR = "JOB_USER_ERROR"
+ CANCEL_REQUESTED = "CANCEL_REQUESTED"
+ JOB_RESTARTED = "JOB_RESTARTED"
+ REFUND = "REFUND"
+ WARNING = "WARNING"
+
+
+class FinetuneEventLevels(str, Enum):
+ """
+ Fine-tune job event status levels
+ """
+
+ NULL = ""
+ INFO = "Info"
+ WARNING = "Warning"
+ ERROR = "Error"
+ LEGACY_INFO = "info"
+ LEGACY_IWARNING = "warning"
+ LEGACY_IERROR = "error"
+
+
+class FinetuneEvent(BaseModel):
+ """
+ Fine-tune event type
+ """
+
+ # object type
+ object: Literal["fine-tune-event"]
+ # created at datetime stamp
+ created_at: Union[str, None] = None
+ # event log level
+ level: Union[FinetuneEventLevels, None] = None
+ # event message string
+ message: Union[str, None] = None
+ # event type
+ type: Union[FinetuneEventType, None] = None
+ # optional: model parameter count
+ param_count: Union[int, None] = None
+ # optional: dataset token count
+ token_count: Union[int, None] = None
+ # optional: weights & biases url
+ wandb_url: Union[str, None] = None
+ # event hash
+ hash: Union[str, None] = None
+
+
+class FullTrainingType(BaseModel):
+ """
+ Training type for full fine-tuning
+ """
+
+ type: Union[Literal["Full"], Literal[""]] = "Full"
+
+
+class LoRATrainingType(BaseModel):
+ """
+ Training type for LoRA adapters training
+ """
+
+ lora_r: int
+ lora_alpha: int
+ lora_dropout: float = 0.0
+ lora_trainable_modules: str = "all-linear"
+ type: Literal["Lora"] = "Lora"
+
+
+TrainingType: TypeAlias = Union[FullTrainingType, LoRATrainingType]
+
+
class FinetuneFullTrainingLimits(BaseModel):
max_batch_size: int
max_batch_size_dpo: int = -1
@@ -21,9 +141,257 @@ class FinetuneLoraTrainingLimits(FinetuneFullTrainingLimits):
target_modules: List[str]
+class TrainingMethodSFT(BaseModel):
+ """
+ Training method type for SFT training
+ """
+
+ method: Literal["sft"] = "sft"
+ train_on_inputs: Union[StrictBool, Literal["auto"]] = "auto"
+
+
+class TrainingMethodDPO(BaseModel):
+ """
+ Training method type for DPO training
+ """
+
+ method: Literal["dpo"] = "dpo"
+ dpo_beta: Union[float, None] = None
+ dpo_normalize_logratios_by_length: bool = False
+ dpo_reference_free: bool = False
+ rpo_alpha: Union[float, None] = None
+ simpo_gamma: Union[float, None] = None
+
+
+TrainingMethod: TypeAlias = Union[TrainingMethodSFT, TrainingMethodDPO]
+
+
class FinetuneTrainingLimits(BaseModel):
max_num_epochs: int
max_learning_rate: float
min_learning_rate: float
full_training: Optional[FinetuneFullTrainingLimits] = None
lora_training: Optional[FinetuneLoraTrainingLimits] = None
+
+
+class LinearLRSchedulerArgs(BaseModel):
+ min_lr_ratio: Union[float, None] = 0.0
+
+
+class CosineLRSchedulerArgs(BaseModel):
+ min_lr_ratio: Union[float, None] = 0.0
+ num_cycles: Union[float, None] = 0.5
+
+
+class LinearLRScheduler(BaseModel):
+ lr_scheduler_type: Literal["linear"] = "linear"
+ lr_scheduler_args: Union[LinearLRSchedulerArgs, None] = None
+
+
+class CosineLRScheduler(BaseModel):
+ lr_scheduler_type: Literal["cosine"] = "cosine"
+ lr_scheduler_args: Union[CosineLRSchedulerArgs, None] = None
+
+
+# placeholder for old fine-tuning jobs with no lr_scheduler_type specified
+class EmptyLRScheduler(BaseModel):
+ lr_scheduler_type: Literal[""]
+ lr_scheduler_args: None = None
+
+
+FinetuneLRScheduler: TypeAlias = Union[LinearLRScheduler, CosineLRScheduler, EmptyLRScheduler]
+
+
+class FinetuneResponse(BaseModel):
+ """
+ Fine-tune API response type
+ """
+
+ id: str
+ """Unique identifier for the fine-tune job"""
+
+ created_at: datetime
+ """Creation timestamp of the fine-tune job"""
+
+ status: Optional[FinetuneJobStatus] = None
+ """Status of the fine-tune job"""
+
+ updated_at: datetime
+ """Last update timestamp of the fine-tune job"""
+
+ batch_size: Optional[int] = None
+ """Batch size used for training"""
+
+ events: Optional[List[FinetuneEvent]] = None
+ """Events related to this fine-tune job"""
+
+ from_checkpoint: Optional[str] = None
+ """Checkpoint used to continue training"""
+
+ from_hf_model: Optional[str] = None
+ """Hugging Face Hub repo to start training from"""
+
+ hf_model_revision: Optional[str] = None
+ """The revision of the Hugging Face Hub model to continue training from"""
+
+ learning_rate: Optional[float] = None
+ """Learning rate used for training"""
+
+ lr_scheduler: Optional[FinetuneLRScheduler] = None
+ """Learning rate scheduler configuration"""
+
+ max_grad_norm: Optional[float] = None
+ """Maximum gradient norm for clipping"""
+
+ model: Optional[str] = None
+ """Base model used for fine-tuning"""
+
+ output_name: Optional[str] = Field(alias="model_output_name")
+ """Output model name"""
+
+ adapter_output_name: Optional[str]
+ """Adapter output name"""
+
+ n_checkpoints: Optional[int] = None
+ """Number of checkpoints saved during training"""
+
+ n_epochs: Optional[int] = None
+ """Number of training epochs"""
+
+ n_evals: Optional[int] = None
+ """Number of evaluations during training"""
+
+ owner_address: Optional[str] = None
+ """Owner address information"""
+
+ suffix: Optional[str] = None
+ """Suffix added to the fine-tuned model name"""
+
+ token_count: Optional[int] = None
+ """Count of tokens processed"""
+
+ total_price: Optional[int] = None
+ """Total price for the fine-tuning job"""
+
+ training_file: Optional[str] = None
+ """File-ID of the training file"""
+
+ training_method: Optional[TrainingMethod] = None
+ """Method of training used"""
+
+ training_type: Optional[TrainingType] = None
+ """Type of training used (full or LoRA)"""
+
+ user_id: Optional[str] = None
+ """Identifier for the user who created the job"""
+
+ validation_file: Optional[str] = None
+ """File-ID of the validation file"""
+
+ wandb_name: Optional[str] = None
+ """Weights & Biases run name"""
+
+ wandb_project_name: Optional[str] = None
+ """Weights & Biases project name"""
+
+ wandb_base_url: Union[str, None] = None
+ """Weights & Biases base URL"""
+
+ wandb_url: Union[str, None] = None
+ """Weights & Biases job URL"""
+
+ warmup_ratio: Optional[float] = None
+ """Ratio of warmup steps"""
+
+ weight_decay: Optional[float] = None
+ """Weight decay value used"""
+
+ eval_steps: Union[int, None] = None
+ """number of steps between evals"""
+
+ job_id: Optional[str] = None
+ """Job ID"""
+
+ param_count: Optional[int] = None
+ """Model parameter count"""
+
+ total_steps: Optional[int] = None
+ """Total number of training steps"""
+
+ steps_completed: Union[int, None] = None
+ """Number of steps completed (incrementing counter)"""
+
+ epochs_completed: Union[int, None] = None
+ """Number of epochs completed (incrementing counter)"""
+
+ evals_completed: Union[int, None] = None
+ """Number of evaluation loops completed (incrementing counter)"""
+
+ queue_depth: Union[int, None] = None
+ """Place in job queue (decrementing counter)"""
+
+ # # training file metadata
+ training_file_num_lines: Optional[int] = Field(None, alias="TrainingFileNumLines")
+ training_file_size: Optional[int] = Field(None, alias="TrainingFileSize")
+ train_on_inputs: Union[StrictBool, Literal["auto"], None] = "auto"
+
+ @classmethod
+ def validate_training_type(cls, v: TrainingType) -> TrainingType:
+ if v.type == "Full" or v.type == "":
+ return FullTrainingType(**v.model_dump())
+ elif v.type == "Lora":
+ return LoRATrainingType(**v.model_dump())
+ else:
+ raise ValueError("Unknown training type")
+
+
+class FinetuneRequest(BaseModel):
+ """
+ Fine-tune request type
+ """
+
+ # training file ID
+ training_file: str
+ # validation file id
+ validation_file: Union[str, None] = None
+ # base model string
+ model: Union[str, None] = None
+ # number of epochs to train for
+ n_epochs: int
+ # training learning rate
+ learning_rate: float
+ # learning rate scheduler type and args
+ lr_scheduler: Union[LinearLRScheduler, CosineLRScheduler, None] = None
+ # learning rate warmup ratio
+ warmup_ratio: float
+ # max gradient norm
+ max_grad_norm: float
+ # weight decay
+ weight_decay: float
+ # number of checkpoints to save
+ n_checkpoints: Union[int, None] = None
+ # number of evaluation loops to run
+ n_evals: Union[int, None] = None
+ # training batch size
+ batch_size: Union[int, Literal["max"], None] = None
+ # up to 40 character suffix for output model name
+ suffix: Union[str, None] = None
+ # weights & biases api key
+ wandb_key: Union[str, None] = None
+ # weights & biases base url
+ wandb_base_url: Union[str, None] = None
+ # wandb project name
+ wandb_project_name: Union[str, None] = None
+ # wandb run name
+ wandb_name: Union[str, None] = None
+ # training type
+ training_type: Union[TrainingType, None] = None
+ # training method
+ training_method: Union[TrainingMethodSFT, TrainingMethodDPO] = Field(default_factory=TrainingMethodSFT)
+ # from step
+ from_checkpoint: Union[str, None] = None
+ from_hf_model: Union[str, None] = None
+ hf_model_revision: Union[str, None] = None
+ # hf related fields
+ hf_api_token: Union[str, None] = None
+ hf_output_repo_name: Union[str, None] = None
diff --git a/src/together/resources/fine_tuning.py b/src/together/resources/fine_tuning.py
index 024857ba..72ce96dc 100644
--- a/src/together/resources/fine_tuning.py
+++ b/src/together/resources/fine_tuning.py
@@ -5,6 +5,7 @@
from typing_extensions import Literal
import httpx
+from rich import print as rprint
from ..types import fine_tuning_delete_params, fine_tuning_content_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
@@ -27,6 +28,8 @@
)
from .._base_client import make_request_options
from ..types.fine_tune import FineTune
+from ..lib.types.fine_tuning import FinetuneResponse, FinetuneTrainingLimits
+from ..lib.resources.fine_tuning import get_model_limits, async_get_model_limits, create_finetune_request
from ..types.fine_tuning_list_response import FineTuningListResponse
from ..types.fine_tuning_cancel_response import FineTuningCancelResponse
from ..types.fine_tuning_delete_response import FineTuningDeleteResponse
@@ -56,6 +59,178 @@ def with_streaming_response(self) -> FineTuningResourceWithStreamingResponse:
"""
return FineTuningResourceWithStreamingResponse(self)
+ def create(
+ self,
+ *,
+ training_file: str,
+ model: str | None = None,
+ n_epochs: int = 1,
+ validation_file: str | None = "",
+ n_evals: int | None = 0,
+ n_checkpoints: int | None = 1,
+ batch_size: int | Literal["max"] = "max",
+ learning_rate: float | None = 0.00001,
+ lr_scheduler_type: Literal["linear", "cosine"] = "cosine",
+ min_lr_ratio: float = 0.0,
+ scheduler_num_cycles: float = 0.5,
+ warmup_ratio: float = 0.0,
+ max_grad_norm: float = 1.0,
+ weight_decay: float = 0.0,
+ lora: bool = True,
+ lora_r: int | None = None,
+ lora_dropout: float | None = 0,
+ lora_alpha: float | None = None,
+ lora_trainable_modules: str | None = "all-linear",
+ suffix: str | None = None,
+ wandb_api_key: str | None = None,
+ wandb_base_url: str | None = None,
+ wandb_project_name: str | None = None,
+ wandb_name: str | None = None,
+ verbose: bool = False,
+ model_limits: FinetuneTrainingLimits | None = None,
+ train_on_inputs: bool | Literal["auto"] | None = None,
+ training_method: str = "sft",
+ dpo_beta: float | None = None,
+ dpo_normalize_logratios_by_length: bool = False,
+ rpo_alpha: float | None = None,
+ simpo_gamma: float | None = None,
+ from_checkpoint: str | None = None,
+ from_hf_model: str | None = None,
+ hf_model_revision: str | None = None,
+ hf_api_token: str | None = None,
+ hf_output_repo_name: str | None = None,
+ ) -> FinetuneResponse:
+ """
+ Method to initiate a fine-tuning job
+
+ Args:
+ training_file (str): File-ID of a file uploaded to the Together API
+ model (str, optional): Name of the base model to run fine-tune job on
+ n_epochs (int, optional): Number of epochs for fine-tuning. Defaults to 1.
+ validation file (str, optional): File ID of a file uploaded to the Together API for validation.
+ n_evals (int, optional): Number of evaluation loops to run. Defaults to 0.
+ n_checkpoints (int, optional): Number of checkpoints to save during fine-tuning.
+ Defaults to 1.
+ batch_size (int or "max"): Batch size for fine-tuning. Defaults to max.
+ learning_rate (float, optional): Learning rate multiplier to use for training
+ Defaults to 0.00001.
+ lr_scheduler_type (Literal["linear", "cosine"]): Learning rate scheduler type. Defaults to "cosine".
+ min_lr_ratio (float, optional): Min learning rate ratio of the initial learning rate for
+ the learning rate scheduler. Defaults to 0.0.
+ scheduler_num_cycles (float, optional): Number or fraction of cycles for the cosine learning rate scheduler. Defaults to 0.5.
+ warmup_ratio (float, optional): Warmup ratio for the learning rate scheduler.
+ max_grad_norm (float, optional): Max gradient norm. Defaults to 1.0, set to 0 to disable.
+ weight_decay (float, optional): Weight decay. Defaults to 0.0.
+ lora (bool, optional): Whether to use LoRA adapters. Defaults to True.
+ lora_r (int, optional): Rank of LoRA adapters. Defaults to 8.
+ lora_dropout (float, optional): Dropout rate for LoRA adapters. Defaults to 0.
+ lora_alpha (float, optional): Alpha for LoRA adapters. Defaults to 8.
+ lora_trainable_modules (str, optional): Trainable modules for LoRA adapters. Defaults to "all-linear".
+ suffix (str, optional): Up to 40 character suffix that will be added to your fine-tuned model name.
+ Defaults to None.
+ wandb_api_key (str, optional): API key for Weights & Biases integration.
+ Defaults to None.
+ wandb_base_url (str, optional): Base URL for Weights & Biases integration.
+ Defaults to None.
+ wandb_project_name (str, optional): Project name for Weights & Biases integration.
+ Defaults to None.
+ wandb_name (str, optional): Run name for Weights & Biases integration.
+ Defaults to None.
+ verbose (bool, optional): whether to print the job parameters before submitting a request.
+ Defaults to False.
+ model_limits (FinetuneTrainingLimits, optional): Limits for the hyperparameters the model in Fine-tuning.
+ Defaults to None.
+ train_on_inputs (bool or "auto", optional): Whether to mask the user messages in conversational data or prompts in instruction data.
+ "auto" will automatically determine whether to mask the inputs based on the data format.
+ For datasets with the "text" field (general format), inputs will not be masked.
+ For datasets with the "messages" field (conversational format) or "prompt" and "completion" fields
+ (Instruction format), inputs will be masked.
+ Defaults to None, or "auto" if training_method is "sft" (set in create_finetune_request).
+ training_method (str, optional): Training method. Defaults to "sft".
+ Supported methods: "sft", "dpo".
+ dpo_beta (float, optional): DPO beta parameter. Defaults to None.
+ dpo_normalize_logratios_by_length (bool): Whether or not normalize logratios by sample length. Defaults to False,
+ rpo_alpha (float, optional): RPO alpha parameter of DPO training to include NLL in the loss. Defaults to None.
+ simpo_gamma: (float, optional): SimPO gamma parameter. Defaults to None.
+ from_checkpoint (str, optional): The checkpoint identifier to continue training from a previous fine-tuning job.
+ The format: {$JOB_ID/$OUTPUT_MODEL_NAME}:{$STEP}.
+ The step value is optional, without it the final checkpoint will be used.
+ from_hf_model (str, optional): The Hugging Face Hub repo to start training from.
+ Should be as close as possible to the base model (specified by the `model` argument) in terms of architecture and size.
+ hf_model_revision (str, optional): The revision of the Hugging Face Hub model to continue training from. Defaults to None.
+ Example: hf_model_revision=None (defaults to the latest revision in `main`) or
+ hf_model_revision="607a30d783dfa663caf39e06633721c8d4cfcd7e" (specific commit).
+ hf_api_token (str, optional): API key for the Hugging Face Hub. Defaults to None.
+ hf_output_repo_name (str, optional): HF repo to upload the fine-tuned model to. Defaults to None.
+
+ Returns:
+ FinetuneResponse: Object containing information about fine-tuning job.
+ """
+
+ if model_limits is None:
+ model_name = None
+ # mypy doesn't understand that model or from_checkpoint is not None
+ if model is not None:
+ model_name = model
+ elif from_checkpoint is not None:
+ model_name = from_checkpoint.split(":")[0]
+ else:
+ # this branch is unreachable, but mypy doesn't know that
+ pass
+ model_limits = get_model_limits(self._client, str(model_name))
+
+ finetune_request = create_finetune_request(
+ model_limits=model_limits,
+ training_file=training_file,
+ model=model,
+ n_epochs=n_epochs,
+ validation_file=validation_file,
+ n_evals=n_evals,
+ n_checkpoints=n_checkpoints,
+ batch_size=batch_size,
+ learning_rate=learning_rate,
+ lr_scheduler_type=lr_scheduler_type,
+ min_lr_ratio=min_lr_ratio,
+ scheduler_num_cycles=scheduler_num_cycles,
+ warmup_ratio=warmup_ratio,
+ max_grad_norm=max_grad_norm,
+ weight_decay=weight_decay,
+ lora=lora,
+ lora_r=lora_r,
+ lora_dropout=lora_dropout,
+ lora_alpha=lora_alpha,
+ lora_trainable_modules=lora_trainable_modules,
+ suffix=suffix,
+ wandb_api_key=wandb_api_key,
+ wandb_base_url=wandb_base_url,
+ wandb_project_name=wandb_project_name,
+ wandb_name=wandb_name,
+ train_on_inputs=train_on_inputs,
+ training_method=training_method,
+ dpo_beta=dpo_beta,
+ dpo_normalize_logratios_by_length=dpo_normalize_logratios_by_length,
+ rpo_alpha=rpo_alpha,
+ simpo_gamma=simpo_gamma,
+ from_checkpoint=from_checkpoint,
+ from_hf_model=from_hf_model,
+ hf_model_revision=hf_model_revision,
+ hf_api_token=hf_api_token,
+ hf_output_repo_name=hf_output_repo_name,
+ )
+
+ if verbose:
+ rprint(
+ "Submitting a fine-tuning job with the following parameters:",
+ finetune_request,
+ )
+ parameter_payload = finetune_request.model_dump(exclude_none=True)
+
+ return self._client.post(
+ "/fine-tunes",
+ body=parameter_payload,
+ cast_to=FinetuneResponse,
+ )
+
def retrieve(
self,
id: str,
@@ -325,6 +500,178 @@ def with_streaming_response(self) -> AsyncFineTuningResourceWithStreamingRespons
"""
return AsyncFineTuningResourceWithStreamingResponse(self)
+ async def create(
+ self,
+ *,
+ training_file: str,
+ model: str | None = None,
+ n_epochs: int = 1,
+ validation_file: str | None = "",
+ n_evals: int | None = 0,
+ n_checkpoints: int | None = 1,
+ batch_size: int | Literal["max"] = "max",
+ learning_rate: float | None = 0.00001,
+ lr_scheduler_type: Literal["linear", "cosine"] = "cosine",
+ min_lr_ratio: float = 0.0,
+ scheduler_num_cycles: float = 0.5,
+ warmup_ratio: float = 0.0,
+ max_grad_norm: float = 1.0,
+ weight_decay: float = 0.0,
+ lora: bool = True,
+ lora_r: int | None = None,
+ lora_dropout: float | None = 0,
+ lora_alpha: float | None = None,
+ lora_trainable_modules: str | None = "all-linear",
+ suffix: str | None = None,
+ wandb_api_key: str | None = None,
+ wandb_base_url: str | None = None,
+ wandb_project_name: str | None = None,
+ wandb_name: str | None = None,
+ verbose: bool = False,
+ model_limits: FinetuneTrainingLimits | None = None,
+ train_on_inputs: bool | Literal["auto"] | None = None,
+ training_method: str = "sft",
+ dpo_beta: float | None = None,
+ dpo_normalize_logratios_by_length: bool = False,
+ rpo_alpha: float | None = None,
+ simpo_gamma: float | None = None,
+ from_checkpoint: str | None = None,
+ from_hf_model: str | None = None,
+ hf_model_revision: str | None = None,
+ hf_api_token: str | None = None,
+ hf_output_repo_name: str | None = None,
+ ) -> FinetuneResponse:
+ """
+ Method to initiate a fine-tuning job
+
+ Args:
+ training_file (str): File-ID of a file uploaded to the Together API
+ model (str, optional): Name of the base model to run fine-tune job on
+ n_epochs (int, optional): Number of epochs for fine-tuning. Defaults to 1.
+ validation file (str, optional): File ID of a file uploaded to the Together API for validation.
+ n_evals (int, optional): Number of evaluation loops to run. Defaults to 0.
+ n_checkpoints (int, optional): Number of checkpoints to save during fine-tuning.
+ Defaults to 1.
+ batch_size (int or "max"): Batch size for fine-tuning. Defaults to max.
+ learning_rate (float, optional): Learning rate multiplier to use for training
+ Defaults to 0.00001.
+ lr_scheduler_type (Literal["linear", "cosine"]): Learning rate scheduler type. Defaults to "cosine".
+ min_lr_ratio (float, optional): Min learning rate ratio of the initial learning rate for
+ the learning rate scheduler. Defaults to 0.0.
+ scheduler_num_cycles (float, optional): Number or fraction of cycles for the cosine learning rate scheduler. Defaults to 0.5.
+ warmup_ratio (float, optional): Warmup ratio for the learning rate scheduler.
+ max_grad_norm (float, optional): Max gradient norm. Defaults to 1.0, set to 0 to disable.
+ weight_decay (float, optional): Weight decay. Defaults to 0.0.
+ lora (bool, optional): Whether to use LoRA adapters. Defaults to True.
+ lora_r (int, optional): Rank of LoRA adapters. Defaults to 8.
+ lora_dropout (float, optional): Dropout rate for LoRA adapters. Defaults to 0.
+ lora_alpha (float, optional): Alpha for LoRA adapters. Defaults to 8.
+ lora_trainable_modules (str, optional): Trainable modules for LoRA adapters. Defaults to "all-linear".
+ suffix (str, optional): Up to 40 character suffix that will be added to your fine-tuned model name.
+ Defaults to None.
+ wandb_api_key (str, optional): API key for Weights & Biases integration.
+ Defaults to None.
+ wandb_base_url (str, optional): Base URL for Weights & Biases integration.
+ Defaults to None.
+ wandb_project_name (str, optional): Project name for Weights & Biases integration.
+ Defaults to None.
+ wandb_name (str, optional): Run name for Weights & Biases integration.
+ Defaults to None.
+ verbose (bool, optional): whether to print the job parameters before submitting a request.
+ Defaults to False.
+ model_limits (FinetuneTrainingLimits, optional): Limits for the hyperparameters the model in Fine-tuning.
+ Defaults to None.
+ train_on_inputs (bool or "auto", optional): Whether to mask the user messages in conversational data or prompts in instruction data.
+ "auto" will automatically determine whether to mask the inputs based on the data format.
+ For datasets with the "text" field (general format), inputs will not be masked.
+ For datasets with the "messages" field (conversational format) or "prompt" and "completion" fields
+ (Instruction format), inputs will be masked.
+ Defaults to None, or "auto" if training_method is "sft" (set in create_finetune_request).
+ training_method (str, optional): Training method. Defaults to "sft".
+ Supported methods: "sft", "dpo".
+ dpo_beta (float, optional): DPO beta parameter. Defaults to None.
+ dpo_normalize_logratios_by_length (bool): Whether or not normalize logratios by sample length. Defaults to False,
+ rpo_alpha (float, optional): RPO alpha parameter of DPO training to include NLL in the loss. Defaults to None.
+ simpo_gamma: (float, optional): SimPO gamma parameter. Defaults to None.
+ from_checkpoint (str, optional): The checkpoint identifier to continue training from a previous fine-tuning job.
+ The format: {$JOB_ID/$OUTPUT_MODEL_NAME}:{$STEP}.
+ The step value is optional, without it the final checkpoint will be used.
+ from_hf_model (str, optional): The Hugging Face Hub repo to start training from.
+ Should be as close as possible to the base model (specified by the `model` argument) in terms of architecture and size.
+ hf_model_revision (str, optional): The revision of the Hugging Face Hub model to continue training from. Defaults to None.
+ Example: hf_model_revision=None (defaults to the latest revision in `main`) or
+ hf_model_revision="607a30d783dfa663caf39e06633721c8d4cfcd7e" (specific commit).
+ hf_api_token (str, optional): API key for the Hugging Face Hub. Defaults to None.
+ hf_output_repo_name (str, optional): HF repo to upload the fine-tuned model to. Defaults to None.
+
+ Returns:
+ FinetuneResponse: Object containing information about fine-tuning job.
+ """
+
+ if model_limits is None:
+ model_name = None
+ # mypy doesn't understand that model or from_checkpoint is not None
+ if model is not None:
+ model_name = model
+ elif from_checkpoint is not None:
+ model_name = from_checkpoint.split(":")[0]
+ else:
+ # this branch is unreachable, but mypy doesn't know that
+ pass
+ model_limits = await async_get_model_limits(self._client, str(model_name))
+
+ finetune_request = create_finetune_request(
+ model_limits=model_limits,
+ training_file=training_file,
+ model=model,
+ n_epochs=n_epochs,
+ validation_file=validation_file,
+ n_evals=n_evals,
+ n_checkpoints=n_checkpoints,
+ batch_size=batch_size,
+ learning_rate=learning_rate,
+ lr_scheduler_type=lr_scheduler_type,
+ min_lr_ratio=min_lr_ratio,
+ scheduler_num_cycles=scheduler_num_cycles,
+ warmup_ratio=warmup_ratio,
+ max_grad_norm=max_grad_norm,
+ weight_decay=weight_decay,
+ lora=lora,
+ lora_r=lora_r,
+ lora_dropout=lora_dropout,
+ lora_alpha=lora_alpha,
+ lora_trainable_modules=lora_trainable_modules,
+ suffix=suffix,
+ wandb_api_key=wandb_api_key,
+ wandb_base_url=wandb_base_url,
+ wandb_project_name=wandb_project_name,
+ wandb_name=wandb_name,
+ train_on_inputs=train_on_inputs,
+ training_method=training_method,
+ dpo_beta=dpo_beta,
+ dpo_normalize_logratios_by_length=dpo_normalize_logratios_by_length,
+ rpo_alpha=rpo_alpha,
+ simpo_gamma=simpo_gamma,
+ from_checkpoint=from_checkpoint,
+ from_hf_model=from_hf_model,
+ hf_model_revision=hf_model_revision,
+ hf_api_token=hf_api_token,
+ hf_output_repo_name=hf_output_repo_name,
+ )
+
+ if verbose:
+ rprint(
+ "Submitting a fine-tuning job with the following parameters:",
+ finetune_request,
+ )
+ parameter_payload = finetune_request.model_dump(exclude_none=True)
+
+ return await self._client.post(
+ "/fine-tunes",
+ body=parameter_payload,
+ cast_to=FinetuneResponse,
+ )
+
async def retrieve(
self,
id: str,
diff --git a/tests/unit/test_fine_tuning_resources.py b/tests/unit/test_fine_tuning_resources.py
index 235f0afa..a8803ae4 100644
--- a/tests/unit/test_fine_tuning_resources.py
+++ b/tests/unit/test_fine_tuning_resources.py
@@ -1,11 +1,15 @@
+from typing import Union, Literal
+
import pytest
from together.lib.types.fine_tuning import (
+ FullTrainingType,
+ LoRATrainingType,
FinetuneTrainingLimits,
FinetuneFullTrainingLimits,
FinetuneLoraTrainingLimits,
)
-from together.lib.resources.fine_tuning import create_fine_tuning_request
+from together.lib.resources.fine_tuning import create_finetune_request
_MODEL_NAME = "meta-llama/Meta-Llama-3.1-8B-Instruct-Reference"
_TRAINING_FILE = "file-7dbce5e9-7993-4520-9f3e-a7ece6c39d84"
@@ -31,71 +35,88 @@
def test_simple_request():
- request = create_fine_tuning_request(
+ request = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
)
- assert request["model"] == _MODEL_NAME
- assert request["training_file"] == _TRAINING_FILE
- assert "learning_rate" in request
- assert request["learning_rate"] > 0
- assert "n_epochs" in request
- assert request["n_epochs"] > 0
- assert "warmup_ratio" in request
- assert request["warmup_ratio"] == 0.0
- assert "training_type" in request
- assert request["training_type"]["type"] == "Full"
- assert "batch_size" in request
- assert _MODEL_LIMITS.full_training is not None
- assert request["batch_size"] == "max"
+ assert request.model == _MODEL_NAME
+ assert request.training_file == _TRAINING_FILE
+ assert request.learning_rate > 0
+ assert request.n_epochs > 0
+ assert request.warmup_ratio == 0.0
+ assert request.training_type is not None
+ assert request.training_type.type == "Full"
+ assert request.batch_size == "max"
def test_validation_file():
- request = create_fine_tuning_request(
+ request = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
validation_file=_VALIDATION_FILE,
)
- assert request["training_file"] == _TRAINING_FILE
- assert "validation_file" in request
- assert request["validation_file"] == _VALIDATION_FILE
+ assert request.training_file == _TRAINING_FILE
+ assert request.validation_file == _VALIDATION_FILE
def test_no_training_file():
with pytest.raises(TypeError, match="missing 1 required positional argument: 'training_file'"):
- _ = create_fine_tuning_request( # type: ignore
+ _ = create_finetune_request( # type: ignore
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
)
def test_lora_request():
- request = create_fine_tuning_request(
+ request = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
lora=True,
)
- assert "training_type" in request
- assert request["training_type"]["type"] == "Lora"
+ assert isinstance(request.training_type, LoRATrainingType)
+ assert request.training_type.type == "Lora"
assert _MODEL_LIMITS.lora_training is not None
- assert request["training_type"]["lora_r"] == _MODEL_LIMITS.lora_training.max_rank
- assert request["training_type"]["lora_alpha"] == _MODEL_LIMITS.lora_training.max_rank * 2
- assert "lora_dropout" in request["training_type"]
- assert request["training_type"]["lora_dropout"] == 0.0
- assert "lora_trainable_modules" in request["training_type"]
- assert request["training_type"]["lora_trainable_modules"] == "all-linear"
- assert "batch_size" in request
- assert request["batch_size"] == "max"
+ assert request.training_type.lora_r == _MODEL_LIMITS.lora_training.max_rank
+ assert request.training_type.lora_alpha == _MODEL_LIMITS.lora_training.max_rank * 2
+ assert request.training_type.lora_dropout == 0.0
+ assert request.training_type.lora_trainable_modules == "all-linear"
+ assert request.batch_size == "max"
+
+
+@pytest.mark.parametrize("lora_dropout", [-1, 0, 0.5, 1.0, 10.0])
+def test_lora_request_with_lora_dropout(lora_dropout: float):
+ if 0 <= lora_dropout < 1:
+ request = create_finetune_request(
+ model_limits=_MODEL_LIMITS,
+ model=_MODEL_NAME,
+ training_file=_TRAINING_FILE,
+ lora=True,
+ lora_dropout=lora_dropout,
+ )
+ assert isinstance(request.training_type, LoRATrainingType)
+ assert request.training_type.lora_dropout == lora_dropout
+ else:
+ with pytest.raises(
+ ValueError,
+ match=r"LoRA dropout must be in \[0, 1\) range.",
+ ):
+ create_finetune_request(
+ model_limits=_MODEL_LIMITS,
+ model=_MODEL_NAME,
+ training_file=_TRAINING_FILE,
+ lora=True,
+ lora_dropout=lora_dropout,
+ )
def test_dpo_request_lora():
- request = create_fine_tuning_request(
+ request = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -103,21 +124,18 @@ def test_dpo_request_lora():
lora=True,
)
- assert "training_type" in request
- assert request["training_type"]["type"] == "Lora"
+ assert isinstance(request.training_type, LoRATrainingType)
+ assert request.training_type.type == "Lora"
assert _MODEL_LIMITS.lora_training is not None
- assert request["training_type"]["lora_r"] == _MODEL_LIMITS.lora_training.max_rank
- assert request["training_type"]["lora_alpha"] == _MODEL_LIMITS.lora_training.max_rank * 2
- assert "lora_dropout" in request["training_type"]
- assert request["training_type"]["lora_dropout"] == 0.0
- assert "lora_trainable_modules" in request["training_type"]
- assert request["training_type"]["lora_trainable_modules"] == "all-linear"
- assert "batch_size" in request
- assert request["batch_size"] == "max"
+ assert request.training_type.lora_r == _MODEL_LIMITS.lora_training.max_rank
+ assert request.training_type.lora_alpha == _MODEL_LIMITS.lora_training.max_rank * 2
+ assert request.training_type.lora_dropout == 0.0
+ assert request.training_type.lora_trainable_modules == "all-linear"
+ assert request.batch_size == "max"
def test_dpo_request():
- request = create_fine_tuning_request(
+ request = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -125,23 +143,20 @@ def test_dpo_request():
lora=False,
)
- assert "training_type" in request
- assert request["training_type"]["type"] == "Full"
- assert "batch_size" in request
- assert _MODEL_LIMITS.full_training is not None
- assert request["batch_size"] == "max"
+ assert isinstance(request.training_type, FullTrainingType)
+ assert request.training_type.type == "Full"
+ assert request.batch_size == "max"
def test_from_checkpoint_request():
- request = create_fine_tuning_request(
+ request = create_finetune_request(
model_limits=_MODEL_LIMITS,
training_file=_TRAINING_FILE,
from_checkpoint=_FROM_CHECKPOINT,
)
- assert request["model"] == ""
- assert "from_checkpoint" in request
- assert request["from_checkpoint"] == _FROM_CHECKPOINT
+ assert request.model is None
+ assert request.from_checkpoint == _FROM_CHECKPOINT
def test_both_from_checkpoint_model_name():
@@ -149,7 +164,7 @@ def test_both_from_checkpoint_model_name():
ValueError,
match="You must specify either a model or a checkpoint to start a job from, not both",
):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -159,7 +174,7 @@ def test_both_from_checkpoint_model_name():
def test_no_from_checkpoint_no_model_name():
with pytest.raises(ValueError, match="You must specify either a model or a checkpoint"):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
training_file=_TRAINING_FILE,
)
@@ -178,7 +193,7 @@ def test_batch_size_limit(batch_size: int, use_lora: bool):
f"Requested batch size of {batch_size} is higher that the maximum allowed value of {max_batch_size}"
)
with pytest.raises(ValueError, match=error_message):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -191,7 +206,7 @@ def test_batch_size_limit(batch_size: int, use_lora: bool):
f"Requested batch size of {batch_size} is lower that the minimum allowed value of {min_batch_size}"
)
with pytest.raises(ValueError, match=error_message):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -202,7 +217,7 @@ def test_batch_size_limit(batch_size: int, use_lora: bool):
def test_non_lora_model():
with pytest.raises(ValueError, match="LoRA adapters are not supported for the selected model."):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=FinetuneTrainingLimits(
max_num_epochs=20,
max_learning_rate=1.0,
@@ -222,7 +237,7 @@ def test_non_lora_model():
def test_non_full_model():
with pytest.raises(ValueError, match="Full training is not supported for the selected model."):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=FinetuneTrainingLimits(
max_num_epochs=20,
max_learning_rate=1.0,
@@ -245,7 +260,7 @@ def test_non_full_model():
@pytest.mark.parametrize("warmup_ratio", [-1.0, 2.0])
def test_bad_warmup(warmup_ratio: float):
with pytest.raises(ValueError, match="Warmup ratio should be between 0 and 1"):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -256,7 +271,7 @@ def test_bad_warmup(warmup_ratio: float):
@pytest.mark.parametrize("min_lr_ratio", [-1.0, 2.0])
def test_bad_min_lr_ratio(min_lr_ratio: float):
with pytest.raises(ValueError, match="Min learning rate ratio should be between 0 and 1"):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -267,7 +282,7 @@ def test_bad_min_lr_ratio(min_lr_ratio: float):
@pytest.mark.parametrize("max_grad_norm", [-1.0, -0.01])
def test_bad_max_grad_norm(max_grad_norm: float):
with pytest.raises(ValueError, match="Max gradient norm should be non-negative"):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -278,7 +293,7 @@ def test_bad_max_grad_norm(max_grad_norm: float):
@pytest.mark.parametrize("weight_decay", [-1.0, -0.01])
def test_bad_weight_decay(weight_decay: float):
with pytest.raises(ValueError, match="Weight decay should be non-negative"):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
@@ -288,9 +303,36 @@ def test_bad_weight_decay(weight_decay: float):
def test_bad_training_method():
with pytest.raises(ValueError, match="training_method must be one of .*"):
- _ = create_fine_tuning_request(
+ _ = create_finetune_request(
model_limits=_MODEL_LIMITS,
model=_MODEL_NAME,
training_file=_TRAINING_FILE,
training_method="NON_SFT",
)
+
+
+@pytest.mark.parametrize("train_on_inputs", [True, False, "auto", None])
+def test_train_on_inputs_for_sft(train_on_inputs: Union[bool, Literal["auto"], None]):
+ request = create_finetune_request(
+ model_limits=_MODEL_LIMITS,
+ model=_MODEL_NAME,
+ training_file=_TRAINING_FILE,
+ training_method="sft",
+ train_on_inputs=train_on_inputs,
+ )
+ assert request.training_method.method == "sft"
+ if isinstance(train_on_inputs, bool):
+ assert request.training_method.train_on_inputs is train_on_inputs
+ else:
+ assert request.training_method.train_on_inputs == "auto"
+
+
+def test_train_on_inputs_not_supported_for_dpo():
+ with pytest.raises(ValueError, match="train_on_inputs is only supported for SFT training"):
+ _ = create_finetune_request(
+ model_limits=_MODEL_LIMITS,
+ model=_MODEL_NAME,
+ training_file=_TRAINING_FILE,
+ training_method="dpo",
+ train_on_inputs=True,
+ )
From 35422cb1eef730a04117d83c8df08442461f5ec1 Mon Sep 17 00:00:00 2001
From: Blaine Kasten
Date: Fri, 21 Nov 2025 08:58:40 -0600
Subject: [PATCH 7/8] chore: Fix examples
---
examples/fine_tuning.py | 2 +-
examples/image.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/examples/fine_tuning.py b/examples/fine_tuning.py
index 3d731939..d32a4b85 100644
--- a/examples/fine_tuning.py
+++ b/examples/fine_tuning.py
@@ -26,5 +26,5 @@
print(e)
# download the model
-downloaded = client.fine_tuning.download(ft_id=fine_tune_id)
+downloaded = client.fine_tuning.content(ft_id=fine_tune_id)
print(downloaded)
diff --git a/examples/image.py b/examples/image.py
index 596d92e3..e6f26316 100644
--- a/examples/image.py
+++ b/examples/image.py
@@ -5,7 +5,7 @@
client = Together(api_key="04cf1e314be9c686cd14b3881f5c4ad76505af4c93a8d3fe6ef62337114d1d51")
-image = client.images.create(
+image = client.images.generate(
model="runwayml/stable-diffusion-v1-5",
prompt="space robots",
n=1,
From 0fe20a89aa7d5d0a061f52d0816b4ce6b32d800c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 21 Nov 2025 14:58:58 +0000
Subject: [PATCH 8/8] release: 2.0.0-alpha.1
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 24 ++++++++++++++++++++++++
pyproject.toml | 2 +-
src/together/_version.py | 2 +-
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index f4710698..6e011e8a 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.1.0-alpha.28"
+ ".": "2.0.0-alpha.1"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c6284d2..9478df67 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,29 @@
# Changelog
+## 2.0.0-alpha.1 (2025-11-21)
+
+Full Changelog: [v0.1.0-alpha.28...v2.0.0-alpha.1](https://github.com/togethercomputer/together-py/compare/v0.1.0-alpha.28...v2.0.0-alpha.1)
+
+### ⚠ BREAKING CHANGES
+
+* **api:** Update method signature for reranking to `rerank.create()`
+* **api:** Change Fine Tuning method name from `download()` to `content()` to align with other namespaces
+* **api:** For the TS SDK the `images.create` is now `images.generate`
+
+### Features
+
+* **api:** api update ([921fa59](https://github.com/togethercomputer/together-py/commit/921fa591a5a9c70f96d457a7b59749dfdfb6d4d6))
+* **api:** Change fine tuning download method to `.create` ([aa27907](https://github.com/togethercomputer/together-py/commit/aa279076c524956e204cb68b7424048a4f93a17d))
+* **api:** Change image creation signature to `images.generate` ([a6e3ad7](https://github.com/togethercomputer/together-py/commit/a6e3ad792393be978b123c87707afe779ef8df34))
+* **api:** Change rerank method signature ([338c415](https://github.com/togethercomputer/together-py/commit/338c415d1cee04520413717ee821f47a64316211))
+* **api:** Port finetuning create code from together-python ([#176](https://github.com/togethercomputer/together-py/issues/176)) ([ef3bd52](https://github.com/togethercomputer/together-py/commit/ef3bd5245ee254269653ff8e6db1651cfcf89c6d))
+
+
+### Chores
+
+* **api:** Remove auto-generated fine_tuning.create method from Python SDK ([c533f29](https://github.com/togethercomputer/together-py/commit/c533f29e2b94d5d9ca97ed50c181dae0fc2dcd7b))
+* Fix examples ([35422cb](https://github.com/togethercomputer/together-py/commit/35422cb1eef730a04117d83c8df08442461f5ec1))
+
## 0.1.0-alpha.28 (2025-11-18)
Full Changelog: [v0.1.0-alpha.27...v0.1.0-alpha.28](https://github.com/togethercomputer/together-py/compare/v0.1.0-alpha.27...v0.1.0-alpha.28)
diff --git a/pyproject.toml b/pyproject.toml
index 856c537e..b39dfdf9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "together"
-version = "0.1.0-alpha.28"
+version = "2.0.0-alpha.1"
description = "The official Python library for the together API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/together/_version.py b/src/together/_version.py
index 3fc7787f..a5854438 100644
--- a/src/together/_version.py
+++ b/src/together/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "together"
-__version__ = "0.1.0-alpha.28" # x-release-please-version
+__version__ = "2.0.0-alpha.1" # x-release-please-version