|
31 | 31 |
|
32 | 32 | _CONFIRMATION_MESSAGE = ( |
33 | 33 | "You are about to create a fine-tuning job. " |
34 | | - "The cost of your job will be determined by the model size, the number of tokens " |
| 34 | + "The estimated price of this job is {price}. " |
| 35 | + "The actual cost of your job will be determined by the model size, the number of tokens " |
35 | 36 | "in the training file, the number of tokens in the validation file, the number of epochs, and " |
36 | | - "the number of evaluations. Visit https://www.together.ai/pricing to get a price estimate.\n" |
| 37 | + "the number of evaluations. Visit https://www.together.ai/pricing to learn more about pricing.\n" |
| 38 | + "{warning}" |
37 | 39 | "You can pass `-y` or `--confirm` to your command to skip this message.\n\n" |
38 | 40 | "Do you want to proceed?" |
39 | 41 | ) |
40 | 42 |
|
41 | | -_PRICE_ESTIMATION_CONFIRMATION_MESSAGE = ( |
42 | | - "The estimated price of the fine-tuning job is {} which is significantly " |
43 | | - "greater than your current credit limit and balance. " |
| 43 | +_WARNING_MESSAGE_INSUFFICIENT_FUNDS = ( |
| 44 | + "The estimated price of this job is significantly greater than your current credit limit and balance. " |
44 | 45 | "It will likely fail due to insufficient funds. " |
45 | 46 | "Please consider increasing your credit limit at https://api.together.xyz/settings/profile\n" |
46 | | - "You can pass `-y` or `--confirm` to your command to skip this message.\n\n" |
47 | | - "Do you want to proceed?" |
48 | 47 | ) |
49 | 48 |
|
50 | 49 |
|
@@ -368,52 +367,47 @@ def create( |
368 | 367 | "You have specified a number of evaluation loops but no validation file." |
369 | 368 | ) |
370 | 369 |
|
371 | | - if confirm or click.confirm(_CONFIRMATION_MESSAGE, default=True, show_default=True): |
372 | | - price_estimation_response = client.fine_tuning.estimate_price( |
373 | | - training_file=training_file, |
374 | | - validation_file=validation_file, |
375 | | - model=model, |
376 | | - n_epochs=n_epochs, |
377 | | - n_evals=n_evals, |
378 | | - training_type="lora" if lora else "full", |
379 | | - training_method=training_method, |
| 370 | + finetune_price_estimation_result = client.fine_tuning.estimate_price( |
| 371 | + training_file=training_file, |
| 372 | + validation_file=validation_file, |
| 373 | + model=model, |
| 374 | + n_epochs=n_epochs, |
| 375 | + n_evals=n_evals, |
| 376 | + training_type="lora" if lora else "full", |
| 377 | + training_method=training_method, |
| 378 | + ) |
| 379 | + |
| 380 | + price = click.style( |
| 381 | + f"${finetune_price_estimation_result.estimated_total_price:.2f}", |
| 382 | + bold=True, |
| 383 | + ) |
| 384 | + |
| 385 | + if not finetune_price_estimation_result.allowed_to_proceed: |
| 386 | + warning = click.style(_WARNING_MESSAGE_INSUFFICIENT_FUNDS, fg="red", bold=True) |
| 387 | + else: |
| 388 | + warning = "" |
| 389 | + |
| 390 | + confirmation_message = _CONFIRMATION_MESSAGE.format( |
| 391 | + price=price, |
| 392 | + warning=warning, |
| 393 | + ) |
| 394 | + |
| 395 | + if confirm or click.confirm(confirmation_message, default=True, show_default=True): |
| 396 | + response = client.fine_tuning.create( |
| 397 | + **training_args, |
| 398 | + verbose=True, |
380 | 399 | ) |
381 | | - proceed = ( |
382 | | - confirm |
383 | | - or price_estimation_response.allowed_to_proceed |
384 | | - or ( |
385 | | - not price_estimation_response.allowed_to_proceed |
386 | | - and click.confirm( |
387 | | - click.style( |
388 | | - _PRICE_ESTIMATION_CONFIRMATION_MESSAGE.format( |
389 | | - price_estimation_response.estimated_total_price |
390 | | - ), |
391 | | - fg="red", |
392 | | - bold=True, |
393 | | - ), |
394 | | - default=True, |
395 | | - show_default=True, |
396 | | - ) |
| 400 | + report_string = f"Successfully submitted a fine-tuning job {response.id}" |
| 401 | + if response.created_at is not None: |
| 402 | + created_time = datetime.strptime( |
| 403 | + response.created_at, "%Y-%m-%dT%H:%M:%S.%f%z" |
397 | 404 | ) |
398 | | - ) |
399 | | - if proceed: |
400 | | - response = client.fine_tuning.create( |
401 | | - **training_args, |
402 | | - verbose=True, |
| 405 | + # created_at reports UTC time, we use .astimezone() to convert to local time |
| 406 | + formatted_time = created_time.astimezone().strftime( |
| 407 | + "%m/%d/%Y, %H:%M:%S" |
403 | 408 | ) |
404 | | - report_string = f"Successfully submitted a fine-tuning job {response.id}" |
405 | | - if response.created_at is not None: |
406 | | - created_time = datetime.strptime( |
407 | | - response.created_at, "%Y-%m-%dT%H:%M:%S.%f%z" |
408 | | - ) |
409 | | - # created_at reports UTC time, we use .astimezone() to convert to local time |
410 | | - formatted_time = created_time.astimezone().strftime( |
411 | | - "%m/%d/%Y, %H:%M:%S" |
412 | | - ) |
413 | | - report_string += f" at {formatted_time}" |
414 | | - rprint(report_string) |
415 | | - else: |
416 | | - click.echo("No confirmation received, stopping job launch") |
| 409 | + report_string += f" at {formatted_time}" |
| 410 | + rprint(report_string) |
417 | 411 | else: |
418 | 412 | click.echo("No confirmation received, stopping job launch") |
419 | 413 |
|
|
0 commit comments