@@ -286,34 +286,26 @@ def create(cls, args):
286
286
create_args ["validation_file" ] = cls ._get_or_upload (
287
287
args .validation_file , args .check_if_files_exist
288
288
)
289
- if args .model :
290
- create_args ["model" ] = args .model
291
- if args .n_epochs :
292
- create_args ["n_epochs" ] = args .n_epochs
293
- if args .batch_size :
294
- create_args ["batch_size" ] = args .batch_size
295
- if args .learning_rate_multiplier :
296
- create_args ["learning_rate_multiplier" ] = args .learning_rate_multiplier
297
- create_args ["use_packing" ] = args .use_packing
298
- if args .prompt_loss_weight :
299
- create_args ["prompt_loss_weight" ] = args .prompt_loss_weight
300
- if args .compute_classification_metrics :
301
- create_args [
302
- "compute_classification_metrics"
303
- ] = args .compute_classification_metrics
304
- if args .classification_n_classes :
305
- create_args ["classification_n_classes" ] = args .classification_n_classes
306
- if args .classification_positive_class :
307
- create_args [
308
- "classification_positive_class"
309
- ] = args .classification_positive_class
310
- if args .classification_betas :
311
- betas = [float (x ) for x in args .classification_betas .split ("," )]
312
- create_args ["classification_betas" ] = betas
289
+
290
+ for hparam in (
291
+ "model" ,
292
+ "n_epochs" ,
293
+ "batch_size" ,
294
+ "learning_rate_multiplier" ,
295
+ "prompt_loss_weight" ,
296
+ "use_packing" ,
297
+ "compute_classification_metrics" ,
298
+ "classification_n_classes" ,
299
+ "classification_positive_class" ,
300
+ "classification_betas" ,
301
+ ):
302
+ attr = getattr (args , hparam )
303
+ if attr is not None :
304
+ create_args [hparam ] = attr
313
305
314
306
resp = openai .FineTune .create (** create_args )
315
307
316
- if args .no_wait :
308
+ if args .no_follow :
317
309
print (resp )
318
310
return
319
311
@@ -345,20 +337,32 @@ def results(cls, args):
345
337
346
338
@classmethod
347
339
def events (cls , args ):
348
- if not args .stream :
349
- resp = openai .FineTune .list_events (id = args .id ) # type: ignore
350
- print (resp )
351
- return
340
+ if args .stream :
341
+ raise openai .error .OpenAIError (
342
+ message = (
343
+ "The --stream parameter is deprecated, use fine_tunes.follow "
344
+ "instead:\n \n "
345
+ " openai api fine_tunes.follow -i {id}\n " .format (id = args .id )
346
+ ),
347
+ )
348
+
349
+ resp = openai .FineTune .list_events (id = args .id ) # type: ignore
350
+ print (resp )
351
+
352
+ @classmethod
353
+ def follow (cls , args ):
352
354
cls ._stream_events (args .id )
353
355
354
356
@classmethod
355
357
def _stream_events (cls , job_id ):
356
358
def signal_handler (sig , frame ):
357
359
status = openai .FineTune .retrieve (job_id ).status
358
360
sys .stdout .write (
359
- "\n Stream interrupted. Job is still {status}. "
361
+ "\n Stream interrupted. Job is still {status}.\n "
362
+ "To resume the stream, run:\n \n "
363
+ " openai api fine_tunes.follow -i {job_id}\n \n "
360
364
"To cancel your job, run:\n \n "
361
- "openai api fine_tunes.cancel -i {job_id}\n " .format (
365
+ " openai api fine_tunes.cancel -i {job_id}\n \n " .format (
362
366
status = status , job_id = job_id
363
367
)
364
368
)
@@ -368,16 +372,24 @@ def signal_handler(sig, frame):
368
372
369
373
events = openai .FineTune .stream_events (job_id )
370
374
# TODO(rachel): Add a nifty spinner here.
371
- for event in events :
372
- sys .stdout .write (
373
- "[%s] %s"
374
- % (
375
- datetime .datetime .fromtimestamp (event ["created_at" ]),
376
- event ["message" ],
375
+ try :
376
+ for event in events :
377
+ sys .stdout .write (
378
+ "[%s] %s"
379
+ % (
380
+ datetime .datetime .fromtimestamp (event ["created_at" ]),
381
+ event ["message" ],
382
+ )
377
383
)
384
+ sys .stdout .write ("\n " )
385
+ sys .stdout .flush ()
386
+ except Exception :
387
+ sys .stdout .write (
388
+ "\n Stream interrupted (client disconnected).\n "
389
+ "To resume the stream, run:\n \n "
390
+ " openai api fine_tunes.follow -i {job_id}\n \n " .format (job_id = job_id )
378
391
)
379
- sys .stdout .write ("\n " )
380
- sys .stdout .flush ()
392
+ return
381
393
382
394
resp = openai .FineTune .retrieve (id = job_id )
383
395
status = resp ["status" ]
@@ -688,9 +700,9 @@ def help(args):
688
700
help = "The model to start fine-tuning from" ,
689
701
)
690
702
sub .add_argument (
691
- "--no_wait " ,
703
+ "--no_follow " ,
692
704
action = "store_true" ,
693
- help = "If set, returns immediately after creating the job. Otherwise, waits for the job to complete." ,
705
+ help = "If set, returns immediately after creating the job. Otherwise, streams events and waits for the job to complete." ,
694
706
)
695
707
sub .add_argument (
696
708
"--n_epochs" ,
@@ -727,7 +739,7 @@ def help(args):
727
739
dest = "use_packing" ,
728
740
help = "Disables the packing flag (see --use_packing for description)" ,
729
741
)
730
- sub .set_defaults (use_packing = True )
742
+ sub .set_defaults (use_packing = None )
731
743
sub .add_argument (
732
744
"--prompt_loss_weight" ,
733
745
type = float ,
@@ -741,6 +753,7 @@ def help(args):
741
753
help = "If set, we calculate classification-specific metrics such as accuracy "
742
754
"and F-1 score using the validation set at the end of every epoch." ,
743
755
)
756
+ sub .set_defaults (compute_classification_metrics = None )
744
757
sub .add_argument (
745
758
"--classification_n_classes" ,
746
759
type = int ,
@@ -755,10 +768,11 @@ def help(args):
755
768
)
756
769
sub .add_argument (
757
770
"--classification_betas" ,
771
+ type = float ,
772
+ nargs = "+" ,
758
773
help = "If this is provided, we calculate F-beta scores at the specified beta "
759
774
"values. The F-beta score is a generalization of F-1 score. This is only "
760
- "used for binary classification. The expected format is a comma-separated "
761
- "list - e.g. 1,1.5,2" ,
775
+ "used for binary classification." ,
762
776
)
763
777
sub .set_defaults (func = FineTune .create )
764
778
@@ -772,15 +786,21 @@ def help(args):
772
786
773
787
sub = subparsers .add_parser ("fine_tunes.events" )
774
788
sub .add_argument ("-i" , "--id" , required = True , help = "The id of the fine-tune job" )
789
+
790
+ # TODO(rachel): Remove this in 1.0
775
791
sub .add_argument (
776
792
"-s" ,
777
793
"--stream" ,
778
794
action = "store_true" ,
779
- help = "If set, events will be streamed until the job is done. Otherwise, "
795
+ help = "[DEPRECATED] If set, events will be streamed until the job is done. Otherwise, "
780
796
"displays the event history to date." ,
781
797
)
782
798
sub .set_defaults (func = FineTune .events )
783
799
800
+ sub = subparsers .add_parser ("fine_tunes.follow" )
801
+ sub .add_argument ("-i" , "--id" , required = True , help = "The id of the fine-tune job" )
802
+ sub .set_defaults (func = FineTune .follow )
803
+
784
804
sub = subparsers .add_parser ("fine_tunes.cancel" )
785
805
sub .add_argument ("-i" , "--id" , required = True , help = "The id of the fine-tune job" )
786
806
sub .set_defaults (func = FineTune .cancel )
0 commit comments