Fine-Tuning
Create fine-tuning jobs, monitor training progress, and deploy fine-tuned models.
Overview
The Fine-Tuning resource provides:
- Job creation from a base model and training dataset
- Real-time training progress and metrics monitoring
- Cost estimation before starting a job
- Hardware and base model discovery
- Deployment of completed fine-tuned models
All fine-tuning methods are accessed through client.fine_tuning.
Creating a Job
Basic Job
from strongly import Strongly
client = Strongly()
job = client.fine_tuning.create_job({
"name": "customer-support-v1",
"base_model": "gpt-4o-mini-2024-07-18",
"training_dataset": "dataset-abc123",
"description": "Fine-tuned on customer support conversations",
})
print(f"Job created: {job.name} (ID: {job.id})")
print(f"Status: {job.status}")
print(f"Base model: {job.base_model}")
With Hyperparameters and Validation
from strongly import Strongly
client = Strongly()
job = client.fine_tuning.create_job({
"name": "code-assistant-v2",
"base_model": "gpt-4o-mini-2024-07-18",
"training_dataset": "dataset-train-456",
"validation_file": "dataset-val-789",
"description": "Code completion model trained on internal repos",
"suffix": "code-assist",
"hyperparameters": {
"n_epochs": 3,
"batch_size": 4,
"learning_rate_multiplier": 0.1,
},
})
print(f"Job ID: {job.id}")
print(f"Status: {job.status}")
Cost Estimation
Estimate the cost and time before starting a job:
from strongly import Strongly
client = Strongly()
estimate = client.fine_tuning.estimate_cost(
base_model="gpt-4o-mini-2024-07-18",
dataset_size=10000,
)
print(f"Base model: {estimate.base_model}")
print(f"Dataset size: {estimate.dataset_size} examples")
print(f"Estimated cost: {estimate.currency} {estimate.estimated_cost:.2f}")
print(f"Estimated time: {estimate.estimated_time_minutes:.0f} minutes")
Discovering Base Models and Hardware
Available Base Models
from strongly import Strongly
client = Strongly()
base_models = client.fine_tuning.base_models()
for model in base_models:
print(f" {model}")
Available Hardware
from strongly import Strongly
client = Strongly()
hardware = client.fine_tuning.hardware()
for hw in hardware:
print(f" {hw}")
Monitoring Progress
Job Stats
Get a summary of all fine-tuning jobs by status:
from strongly import Strongly
client = Strongly()
stats = client.fine_tuning.stats()
print(f"Total jobs: {stats.total}")
print(f"Running: {stats.running}")
print(f"Completed: {stats.completed}")
print(f"Failed: {stats.failed}")
print(f"Queued: {stats.queued}")
Listing Jobs
from strongly import Strongly
client = Strongly()
# List all jobs
for job in client.fine_tuning.list_jobs():
print(f"{job.name} — {job.status}")
# Filter by status
for job in client.fine_tuning.list_jobs(status="running"):
print(f"{job.name}: started at {job.started_at}")
# Filter by base model
for job in client.fine_tuning.list_jobs(base_model="gpt-4o-mini-2024-07-18"):
print(f"{job.name} — {job.status}")
# Search by name
for job in client.fine_tuning.list_jobs(search="customer"):
print(f"{job.name} (ID: {job.id})")
Tracking a Job
Poll a running job until it completes:
from strongly import Strongly
import time
client = Strongly()
job = client.fine_tuning.create_job({
"name": "sentiment-classifier",
"base_model": "gpt-4o-mini-2024-07-18",
"training_dataset": "dataset-sentiment-001",
})
job_id = job.id
while True:
job = client.fine_tuning.retrieve_job(job_id)
print(f"Status: {job.status}")
if job.metrics:
print(f" Metrics: {job.metrics}")
if job.status in ("completed", "failed"):
break
time.sleep(30)
if job.status == "completed":
print(f"Training complete. Result model: {job.result_model}")
print(f"Trained tokens: {job.trained_tokens}")
else:
print(f"Training failed: {job.error}")
Job Logs and Metrics
from strongly import Strongly
client = Strongly()
# Get training logs
logs = client.fine_tuning.job_logs("job-abc123", lines=50)
print(logs)
# Get training metrics (loss curves, accuracy, etc.)
metrics = client.fine_tuning.job_metrics("job-abc123")
print(metrics)
Job Lifecycle
Stopping a Job
Cancel a running job:
from strongly import Strongly
client = Strongly()
client.fine_tuning.stop_job("job-abc123")
print("Job stopped")
Restarting a Job
Restart a stopped or failed job:
from strongly import Strongly
client = Strongly()
client.fine_tuning.restart_job("job-abc123")
print("Job restarted")
Deleting a Job
from strongly import Strongly
client = Strongly()
client.fine_tuning.delete_job("job-abc123")
print("Job deleted")
Deploying a Fine-Tuned Model
After a job completes, deploy the resulting model so it can be used for inference:
from strongly import Strongly
import time
client = Strongly()
# Check the job is complete
job = client.fine_tuning.retrieve_job("job-abc123")
if job.status != "completed":
print(f"Job is not complete (status: {job.status})")
else:
print(f"Result model: {job.result_model}")
# Deploy the fine-tuned model
client.fine_tuning.deploy_model("job-abc123")
print("Deployment started")
# Use the deployed model for inference
response = client.ai.inference.chat_completion(
model=job.result_model,
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.content)
Method Reference
| Method | Description | Returns |
|---|---|---|
list_jobs(*, status=None, base_model=None, search=None, limit=50) | List fine-tuning jobs | SyncPaginator[FineTuningJob] |
stats() | Get job count summary | FineTuningStats |
base_models() | List available base models | List[dict] |
hardware() | List available hardware options | List[dict] |
estimate_cost(*, base_model, dataset_size, **kwargs) | Estimate job cost and time | FineTuningCostEstimate |
create_job(body) | Create a new fine-tuning job | FineTuningJob |
retrieve_job(job_id) | Get a job by ID | FineTuningJob |
delete_job(job_id) | Delete a job | dict |
stop_job(job_id) | Stop a running job | dict |
restart_job(job_id) | Restart a stopped/failed job | dict |
deploy_model(job_id, **kwargs) | Deploy the fine-tuned model | dict |
job_logs(job_id, *, lines=None, since=None) | Get training logs | dict |
job_metrics(job_id) | Get training metrics | dict |
Response Models
FineTuningJob Fields
| Field | Type | Description |
|---|---|---|
id | str | Unique job identifier |
name | str | Job display name |
base_model | str | Base model used for fine-tuning |
status | str | Current status (queued, running, completed, failed, stopped) |
description | str | Human-readable description |
owner | str | Owner user ID |
organization_id | str | Owning organization |
training_dataset | str | Training dataset identifier |
training_file | str | Training file reference |
validation_file | str | Validation file reference |
hyperparameters | dict | Training hyperparameters (n_epochs, batch_size, learning_rate_multiplier) |
result_model | str | Identifier of the fine-tuned model (set on completion) |
trained_tokens | int | Total tokens processed during training |
error | str | Error message (if job failed) |
metrics | dict | Training metrics (loss, accuracy, etc.) |
started_at | str | Training start timestamp |
finished_at | str | Training end timestamp |
created_at | str | Job creation timestamp |
updated_at | str | Last update timestamp |
FineTuningStats Fields
| Field | Type | Description |
|---|---|---|
total | int | Total fine-tuning jobs |
running | int | Currently running jobs |
completed | int | Successfully completed jobs |
failed | int | Failed jobs |
queued | int | Jobs waiting to start |
FineTuningCostEstimate Fields
| Field | Type | Description |
|---|---|---|
base_model | str | Base model for the estimate |
dataset_size | int | Number of training examples |
estimated_cost | float | Estimated cost |
estimated_time_minutes | float | Estimated training time in minutes |
currency | str | Currency code (default: "USD") |
create_job Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
name | str | Yes | Job display name |
base_model | str | Yes | Base model to fine-tune |
training_dataset | str | Yes | Training dataset identifier |
description | str | No | Job description |
validation_file | str | No | Validation dataset for evaluation |
hyperparameters | dict | No | Training hyperparameters |
suffix | str | No | Suffix appended to the fine-tuned model name |
Complete Example
from strongly import Strongly
import time
def main():
client = Strongly()
# --- Check current stats ---
print("=== Fine-Tuning Stats ===")
stats = client.fine_tuning.stats()
print(f"Total: {stats.total}, Running: {stats.running}, Completed: {stats.completed}")
# --- Discover available base models ---
print("\n=== Available Base Models ===")
base_models = client.fine_tuning.base_models()
for model in base_models:
print(f" {model}")
# --- Discover available hardware ---
print("\n=== Available Hardware ===")
hardware = client.fine_tuning.hardware()
for hw in hardware:
print(f" {hw}")
# --- Estimate cost ---
print("\n=== Cost Estimate ===")
estimate = client.fine_tuning.estimate_cost(
base_model="gpt-4o-mini-2024-07-18",
dataset_size=5000,
)
print(f"Cost: {estimate.currency} {estimate.estimated_cost:.2f}")
print(f"Time: {estimate.estimated_time_minutes:.0f} minutes")
# --- Create a fine-tuning job ---
print("\n=== Creating Job ===")
job = client.fine_tuning.create_job({
"name": "support-agent-v1",
"base_model": "gpt-4o-mini-2024-07-18",
"training_dataset": "dataset-support-001",
"description": "Fine-tuned on customer support conversations",
"suffix": "support",
"hyperparameters": {
"n_epochs": 3,
"batch_size": 4,
"learning_rate_multiplier": 0.1,
},
})
job_id = job.id
print(f"Job ID: {job_id}")
print(f"Status: {job.status}")
# --- Monitor progress ---
print("\n=== Monitoring Progress ===")
while True:
job = client.fine_tuning.retrieve_job(job_id)
print(f" Status: {job.status}")
if job.metrics:
print(f" Metrics: {job.metrics}")
if job.status in ("completed", "failed", "stopped"):
break
time.sleep(30)
if job.status == "failed":
print(f"\nTraining failed: {job.error}")
# View logs for debugging
logs = client.fine_tuning.job_logs(job_id, lines=50)
print(f"Logs: {logs}")
return
print(f"\nTraining complete!")
print(f"Result model: {job.result_model}")
print(f"Trained tokens: {job.trained_tokens}")
print(f"Duration: {job.started_at} to {job.finished_at}")
# --- View training metrics ---
print("\n=== Training Metrics ===")
metrics = client.fine_tuning.job_metrics(job_id)
print(metrics)
# --- Deploy the fine-tuned model ---
print("\n=== Deploying Model ===")
client.fine_tuning.deploy_model(job_id)
print("Deployment started")
# --- Use the fine-tuned model ---
print("\n=== Using Fine-Tuned Model ===")
response = client.ai.inference.chat_completion(
model=job.result_model,
messages=[
{"role": "user", "content": "How do I reset my password?"},
],
)
print(f"Response: {response.content}")
# --- List all completed jobs ---
print("\n=== Completed Jobs ===")
for j in client.fine_tuning.list_jobs(status="completed"):
print(f" {j.name} — {j.result_model} ({j.finished_at})")
if __name__ == "__main__":
main()