From ecaa4e6652bf0cc77aaa82ec67a39785f28eae44 Mon Sep 17 00:00:00 2001 From: ammar Date: Fri, 8 Mar 2024 15:21:36 +0000 Subject: [PATCH 1/9] setup fine_tuning.jobs parser boilerplate --- src/openai/cli/_api/_main.py | 3 ++- src/openai/cli/_api/fine_tuning/__init__.py | 13 +++++++++++++ src/openai/cli/_api/fine_tuning/jobs.py | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/openai/cli/_api/fine_tuning/__init__.py create mode 100644 src/openai/cli/_api/fine_tuning/jobs.py diff --git a/src/openai/cli/_api/_main.py b/src/openai/cli/_api/_main.py index fe5a5e6fc0..b04a3e52a4 100644 --- a/src/openai/cli/_api/_main.py +++ b/src/openai/cli/_api/_main.py @@ -2,7 +2,7 @@ from argparse import ArgumentParser -from . import chat, audio, files, image, models, completions +from . import chat, audio, files, image, models, completions, fine_tuning def register_commands(parser: ArgumentParser) -> None: @@ -14,3 +14,4 @@ def register_commands(parser: ArgumentParser) -> None: files.register(subparsers) models.register(subparsers) completions.register(subparsers) + fine_tuning.register(subparsers) diff --git a/src/openai/cli/_api/fine_tuning/__init__.py b/src/openai/cli/_api/fine_tuning/__init__.py new file mode 100644 index 0000000000..11a2dfccbd --- /dev/null +++ b/src/openai/cli/_api/fine_tuning/__init__.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING +from argparse import ArgumentParser + +from . import jobs + +if TYPE_CHECKING: + from argparse import _SubParsersAction + + +def register(subparser: _SubParsersAction[ArgumentParser]) -> None: + jobs.register(subparser) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py new file mode 100644 index 0000000000..4474bd30c5 --- /dev/null +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING +from argparse import ArgumentParser + +if TYPE_CHECKING: + from argparse import _SubParsersAction + + +def register(subparser: _SubParsersAction[ArgumentParser]) -> None: + sub = subparser.add_parser("fine_tuning.jobs.create") + sub = subparser.add_parser("fine_tuning.jobs.retrieve") + sub = subparser.add_parser("fine_tuning.jobs.list") + sub = subparser.add_parser("fine_tuning.jobs.cancel") + sub = subparser.add_parser("fine_tuning.jobs.list_events") + +class CLIFineTuningJobs: + pass \ No newline at end of file From cba04d5b78da8fe35393ddf92ba4877fb9d67ec0 Mon Sep 17 00:00:00 2001 From: ammar Date: Fri, 8 Mar 2024 15:25:19 +0000 Subject: [PATCH 2/9] add fine_tuning.jobs.retrieve --- src/openai/cli/_api/fine_tuning/jobs.py | 28 ++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py index 4474bd30c5..be96c6843a 100644 --- a/src/openai/cli/_api/fine_tuning/jobs.py +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -3,16 +3,42 @@ from typing import TYPE_CHECKING from argparse import ArgumentParser +from ..._utils import get_client, print_model +from ..._models import BaseModel +from ....types.fine_tuning import ( + FineTuningJob, +) + if TYPE_CHECKING: from argparse import _SubParsersAction def register(subparser: _SubParsersAction[ArgumentParser]) -> None: sub = subparser.add_parser("fine_tuning.jobs.create") + sub = subparser.add_parser("fine_tuning.jobs.retrieve") + sub.add_argument( + "-i", + "--id", + help="The ID of the fine-tuning job to retrieve.", + required=True, + ) + sub.set_defaults( + func=CLIFineTuningJobs.retrieve, args_model=CLIFineTuningJobsRetrieveArgs + ) + sub = subparser.add_parser("fine_tuning.jobs.list") sub = subparser.add_parser("fine_tuning.jobs.cancel") sub = subparser.add_parser("fine_tuning.jobs.list_events") + +class CLIFineTuningJobsRetrieveArgs(BaseModel): + id: str + class CLIFineTuningJobs: - pass \ No newline at end of file + @staticmethod + def retrieve(args: CLIFineTuningJobsRetrieveArgs) -> None: + fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.retrieve( + fine_tuning_job_id=args.id + ) + print_model(fine_tuning_job) \ No newline at end of file From d44dd66d0bb684628586d2850f4c299c7ac8fd80 Mon Sep 17 00:00:00 2001 From: ammar Date: Fri, 8 Mar 2024 15:46:09 +0000 Subject: [PATCH 3/9] add fine_tuning.jobs.list --- src/openai/cli/_api/fine_tuning/jobs.py | 31 ++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py index be96c6843a..97ab61d0f0 100644 --- a/src/openai/cli/_api/fine_tuning/jobs.py +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -4,7 +4,9 @@ from argparse import ArgumentParser from ..._utils import get_client, print_model +from ...._types import NOT_GIVEN, NotGivenOr from ..._models import BaseModel +from ....pagination import SyncCursorPage from ....types.fine_tuning import ( FineTuningJob, ) @@ -28,6 +30,19 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: ) sub = subparser.add_parser("fine_tuning.jobs.list") + sub.add_argument( + "-a", + "--after", + help="Identifier for the last job from the previous pagination request. If provided, only jobs created after this job will be returned.", + ) + sub.add_argument( + "-l", + "--limit", + help="Number of fine-tuning jobs to retrieve.", + type=int, + ) + sub.set_defaults(func=CLIFineTuningJobs.list, args_model=CLIFineTuningJobsListArgs) + sub = subparser.add_parser("fine_tuning.jobs.cancel") sub = subparser.add_parser("fine_tuning.jobs.list_events") @@ -35,10 +50,24 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: class CLIFineTuningJobsRetrieveArgs(BaseModel): id: str +class CLIFineTuningJobsListArgs(BaseModel): + after: NotGivenOr[str] = NOT_GIVEN + limit: NotGivenOr[int] = NOT_GIVEN + + class CLIFineTuningJobs: @staticmethod def retrieve(args: CLIFineTuningJobsRetrieveArgs) -> None: fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.retrieve( fine_tuning_job_id=args.id ) - print_model(fine_tuning_job) \ No newline at end of file + print_model(fine_tuning_job) + + @staticmethod + def list(args: CLIFineTuningJobsListArgs) -> None: + fine_tuning_jobs: SyncCursorPage[ + FineTuningJob + ] = get_client().fine_tuning.jobs.list( + after=args.after or NOT_GIVEN, limit=args.limit or NOT_GIVEN + ) + print_model(fine_tuning_jobs) \ No newline at end of file From 724a8eab4b4f41cf924db476ba30af48af7cb815 Mon Sep 17 00:00:00 2001 From: ammar Date: Fri, 8 Mar 2024 15:48:48 +0000 Subject: [PATCH 4/9] add fine_tuning.jobs.cancel --- src/openai/cli/_api/fine_tuning/jobs.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py index 97ab61d0f0..9497489759 100644 --- a/src/openai/cli/_api/fine_tuning/jobs.py +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -44,6 +44,16 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: sub.set_defaults(func=CLIFineTuningJobs.list, args_model=CLIFineTuningJobsListArgs) sub = subparser.add_parser("fine_tuning.jobs.cancel") + sub.add_argument( + "-i", + "--id", + help="The ID of the fine-tuning job to cancel.", + required=True, + ) + sub.set_defaults( + func=CLIFineTuningJobs.cancel, args_model=CLIFineTuningJobsCancelArgs + ) + sub = subparser.add_parser("fine_tuning.jobs.list_events") @@ -54,6 +64,8 @@ class CLIFineTuningJobsListArgs(BaseModel): after: NotGivenOr[str] = NOT_GIVEN limit: NotGivenOr[int] = NOT_GIVEN +class CLIFineTuningJobsCancelArgs(BaseModel): + id: str class CLIFineTuningJobs: @staticmethod @@ -70,4 +82,11 @@ def list(args: CLIFineTuningJobsListArgs) -> None: ] = get_client().fine_tuning.jobs.list( after=args.after or NOT_GIVEN, limit=args.limit or NOT_GIVEN ) - print_model(fine_tuning_jobs) \ No newline at end of file + print_model(fine_tuning_jobs) + + @staticmethod + def cancel(args: CLIFineTuningJobsCancelArgs) -> None: + fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.cancel( + fine_tuning_job_id=args.id + ) + print_model(fine_tuning_job) \ No newline at end of file From 80d38f7d9c9947970a62f3baa86bb3c9e028416a Mon Sep 17 00:00:00 2001 From: ammar Date: Fri, 8 Mar 2024 15:51:52 +0000 Subject: [PATCH 5/9] add fine_tuning.jobs.list_events --- src/openai/cli/_api/fine_tuning/jobs.py | 40 ++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py index 9497489759..d75d789edc 100644 --- a/src/openai/cli/_api/fine_tuning/jobs.py +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -9,6 +9,7 @@ from ....pagination import SyncCursorPage from ....types.fine_tuning import ( FineTuningJob, + FineTuningJobEvent, ) if TYPE_CHECKING: @@ -55,6 +56,26 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: ) sub = subparser.add_parser("fine_tuning.jobs.list_events") + sub.add_argument( + "-i", + "--id", + help="The ID of the fine-tuning job to list events for.", + required=True, + ) + sub.add_argument( + "-a", + "--after", + help="Identifier for the last event from the previous pagination request. If provided, only events created after this event will be returned.", + ) + sub.add_argument( + "-l", + "--limit", + help="Number of fine-tuning job events to retrieve.", + type=int, + ) + sub.set_defaults( + func=CLIFineTuningJobs.list_events, args_model=CLIFineTuningJobsListEventsArgs + ) class CLIFineTuningJobsRetrieveArgs(BaseModel): @@ -67,6 +88,12 @@ class CLIFineTuningJobsListArgs(BaseModel): class CLIFineTuningJobsCancelArgs(BaseModel): id: str +class CLIFineTuningJobsListEventsArgs(BaseModel): + id: str + after: NotGivenOr[str] = NOT_GIVEN + limit: NotGivenOr[int] = NOT_GIVEN + + class CLIFineTuningJobs: @staticmethod def retrieve(args: CLIFineTuningJobsRetrieveArgs) -> None: @@ -89,4 +116,15 @@ def cancel(args: CLIFineTuningJobsCancelArgs) -> None: fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.cancel( fine_tuning_job_id=args.id ) - print_model(fine_tuning_job) \ No newline at end of file + print_model(fine_tuning_job) + + @staticmethod + def list_events(args: CLIFineTuningJobsListEventsArgs) -> None: + fine_tuning_job_events: SyncCursorPage[ + FineTuningJobEvent + ] = get_client().fine_tuning.jobs.list_events( + fine_tuning_job_id=args.id, + after=args.after or NOT_GIVEN, + limit=args.limit or NOT_GIVEN, + ) + print_model(fine_tuning_job_events) \ No newline at end of file From e286d0f05fbeda2a08cac0e2b94b73ffac3e7b2d Mon Sep 17 00:00:00 2001 From: ammar Date: Fri, 8 Mar 2024 15:55:47 +0000 Subject: [PATCH 6/9] add fine_tuning.jobs.create without hyperparameter arg --- src/openai/cli/_api/fine_tuning/jobs.py | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py index d75d789edc..e693617d67 100644 --- a/src/openai/cli/_api/fine_tuning/jobs.py +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -18,6 +18,32 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: sub = subparser.add_parser("fine_tuning.jobs.create") + sub.add_argument( + "-m", + "--model", + help="The model to fine-tune.", + required=True, + ) + sub.add_argument( + "-F", + "--training-file", + help="The training file to fine-tune the model on.", + required=True, + ) + sub.add_argument( + "-s", + "--suffix", + help="A suffix to add to the fine-tuned model name.", + ) + sub.add_argument( + "-V", + "--validation-file", + help="The validation file to use for fine-tuning.", + ) + sub.set_defaults( + func=CLIFineTuningJobs.create, args_model=CLIFineTuningJobsCreateArgs + ) + sub = subparser.add_parser("fine_tuning.jobs.retrieve") sub.add_argument( @@ -77,6 +103,11 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: func=CLIFineTuningJobs.list_events, args_model=CLIFineTuningJobsListEventsArgs ) +class CLIFineTuningJobsCreateArgs(BaseModel): + model: str + training_file: str + suffix: NotGivenOr[str] = NOT_GIVEN + validation_file: NotGivenOr[str] = NOT_GIVEN class CLIFineTuningJobsRetrieveArgs(BaseModel): id: str @@ -95,6 +126,16 @@ class CLIFineTuningJobsListEventsArgs(BaseModel): class CLIFineTuningJobs: + @staticmethod + def create(args: CLIFineTuningJobsCreateArgs) -> None: + fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.create( + model=args.model, + training_file=args.training_file, + suffix=args.suffix, + validation_file=args.validation_file, + ) + print_model(fine_tuning_job) + @staticmethod def retrieve(args: CLIFineTuningJobsRetrieveArgs) -> None: fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.retrieve( From b26a01af3a0375e95ec13c7d24c6a52fbc3c9c15 Mon Sep 17 00:00:00 2001 From: ammar Date: Fri, 8 Mar 2024 16:11:58 +0000 Subject: [PATCH 7/9] add hyperparameters arg to fine_tuning.jobs.create --- src/openai/cli/_api/fine_tuning/jobs.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py index e693617d67..9519ff0025 100644 --- a/src/openai/cli/_api/fine_tuning/jobs.py +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -1,5 +1,6 @@ from __future__ import annotations +import json from typing import TYPE_CHECKING from argparse import ArgumentParser @@ -30,6 +31,12 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: help="The training file to fine-tune the model on.", required=True, ) + sub.add_argument( + "-H", + "--hyperparameters", + help="JSON string of hyperparameters to use for fine-tuning.", + type=str, + ) sub.add_argument( "-s", "--suffix", @@ -106,6 +113,7 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: class CLIFineTuningJobsCreateArgs(BaseModel): model: str training_file: str + hyperparameters: NotGivenOr[str] = NOT_GIVEN suffix: NotGivenOr[str] = NOT_GIVEN validation_file: NotGivenOr[str] = NOT_GIVEN @@ -128,14 +136,16 @@ class CLIFineTuningJobsListEventsArgs(BaseModel): class CLIFineTuningJobs: @staticmethod def create(args: CLIFineTuningJobsCreateArgs) -> None: + hyperparameters = json.loads(args.hyperparameters) if args.hyperparameters is not NOT_GIVEN else NOT_GIVEN fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.create( model=args.model, training_file=args.training_file, + hyperparameters=hyperparameters, suffix=args.suffix, validation_file=args.validation_file, ) print_model(fine_tuning_job) - + @staticmethod def retrieve(args: CLIFineTuningJobsRetrieveArgs) -> None: fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.retrieve( From fd7c39a6be916de5592ddf4a320c9bd99e83208b Mon Sep 17 00:00:00 2001 From: ammar Date: Fri, 8 Mar 2024 16:58:21 +0000 Subject: [PATCH 8/9] hyperparameters arg lint fix --- src/openai/cli/_api/fine_tuning/jobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py index 9519ff0025..13ffa0f820 100644 --- a/src/openai/cli/_api/fine_tuning/jobs.py +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -136,7 +136,7 @@ class CLIFineTuningJobsListEventsArgs(BaseModel): class CLIFineTuningJobs: @staticmethod def create(args: CLIFineTuningJobsCreateArgs) -> None: - hyperparameters = json.loads(args.hyperparameters) if args.hyperparameters is not NOT_GIVEN else NOT_GIVEN + hyperparameters = json.loads(str(args.hyperparameters)) if args.hyperparameters is not NOT_GIVEN else NOT_GIVEN fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.create( model=args.model, training_file=args.training_file, From d404dd17768d43d355709c3b6579dc6622ef0087 Mon Sep 17 00:00:00 2001 From: ammar Date: Sat, 9 Mar 2024 08:16:02 +0000 Subject: [PATCH 9/9] fix formatting --- src/openai/cli/_api/fine_tuning/jobs.py | 46 +++++++++---------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/src/openai/cli/_api/fine_tuning/jobs.py b/src/openai/cli/_api/fine_tuning/jobs.py index 13ffa0f820..806fa0f788 100644 --- a/src/openai/cli/_api/fine_tuning/jobs.py +++ b/src/openai/cli/_api/fine_tuning/jobs.py @@ -47,10 +47,7 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: "--validation-file", help="The validation file to use for fine-tuning.", ) - sub.set_defaults( - func=CLIFineTuningJobs.create, args_model=CLIFineTuningJobsCreateArgs - ) - + sub.set_defaults(func=CLIFineTuningJobs.create, args_model=CLIFineTuningJobsCreateArgs) sub = subparser.add_parser("fine_tuning.jobs.retrieve") sub.add_argument( @@ -59,9 +56,7 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: help="The ID of the fine-tuning job to retrieve.", required=True, ) - sub.set_defaults( - func=CLIFineTuningJobs.retrieve, args_model=CLIFineTuningJobsRetrieveArgs - ) + sub.set_defaults(func=CLIFineTuningJobs.retrieve, args_model=CLIFineTuningJobsRetrieveArgs) sub = subparser.add_parser("fine_tuning.jobs.list") sub.add_argument( @@ -84,9 +79,7 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: help="The ID of the fine-tuning job to cancel.", required=True, ) - sub.set_defaults( - func=CLIFineTuningJobs.cancel, args_model=CLIFineTuningJobsCancelArgs - ) + sub.set_defaults(func=CLIFineTuningJobs.cancel, args_model=CLIFineTuningJobsCancelArgs) sub = subparser.add_parser("fine_tuning.jobs.list_events") sub.add_argument( @@ -106,9 +99,8 @@ def register(subparser: _SubParsersAction[ArgumentParser]) -> None: help="Number of fine-tuning job events to retrieve.", type=int, ) - sub.set_defaults( - func=CLIFineTuningJobs.list_events, args_model=CLIFineTuningJobsListEventsArgs - ) + sub.set_defaults(func=CLIFineTuningJobs.list_events, args_model=CLIFineTuningJobsListEventsArgs) + class CLIFineTuningJobsCreateArgs(BaseModel): model: str @@ -117,16 +109,20 @@ class CLIFineTuningJobsCreateArgs(BaseModel): suffix: NotGivenOr[str] = NOT_GIVEN validation_file: NotGivenOr[str] = NOT_GIVEN + class CLIFineTuningJobsRetrieveArgs(BaseModel): id: str + class CLIFineTuningJobsListArgs(BaseModel): after: NotGivenOr[str] = NOT_GIVEN limit: NotGivenOr[int] = NOT_GIVEN + class CLIFineTuningJobsCancelArgs(BaseModel): id: str + class CLIFineTuningJobsListEventsArgs(BaseModel): id: str after: NotGivenOr[str] = NOT_GIVEN @@ -148,34 +144,26 @@ def create(args: CLIFineTuningJobsCreateArgs) -> None: @staticmethod def retrieve(args: CLIFineTuningJobsRetrieveArgs) -> None: - fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.retrieve( - fine_tuning_job_id=args.id - ) + fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.retrieve(fine_tuning_job_id=args.id) print_model(fine_tuning_job) - + @staticmethod def list(args: CLIFineTuningJobsListArgs) -> None: - fine_tuning_jobs: SyncCursorPage[ - FineTuningJob - ] = get_client().fine_tuning.jobs.list( + fine_tuning_jobs: SyncCursorPage[FineTuningJob] = get_client().fine_tuning.jobs.list( after=args.after or NOT_GIVEN, limit=args.limit or NOT_GIVEN ) print_model(fine_tuning_jobs) - + @staticmethod def cancel(args: CLIFineTuningJobsCancelArgs) -> None: - fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.cancel( - fine_tuning_job_id=args.id - ) + fine_tuning_job: FineTuningJob = get_client().fine_tuning.jobs.cancel(fine_tuning_job_id=args.id) print_model(fine_tuning_job) - + @staticmethod def list_events(args: CLIFineTuningJobsListEventsArgs) -> None: - fine_tuning_job_events: SyncCursorPage[ - FineTuningJobEvent - ] = get_client().fine_tuning.jobs.list_events( + fine_tuning_job_events: SyncCursorPage[FineTuningJobEvent] = get_client().fine_tuning.jobs.list_events( fine_tuning_job_id=args.id, after=args.after or NOT_GIVEN, limit=args.limit or NOT_GIVEN, ) - print_model(fine_tuning_job_events) \ No newline at end of file + print_model(fine_tuning_job_events)