Fine-Tuning
RactoGateway fine-tuning module.
Provides a production-grade multimodal training pipeline for OpenAI, Google Gemini, and Anthropic Claude.
Quick start:
from ractogateway.finetune import (
RactoDataset,
RactoTrainingExample,
RactoTrainingMessage,
OpenAIFineTuner,
GeminiFineTuner,
AnthropicFineTuner,
)
- class ractogateway.finetune.AnthropicFineTuner(api_key=None)[source]
Bases:
objectFine-tune Anthropic Claude models using the fine-tuning API.
- Parameters:
api_key (str | None) – Anthropic API key. Falls back to the
ANTHROPIC_API_KEYenvironment variable when not supplied.
Examples
End-to-end pipeline:
from ractogateway.finetune import RactoDataset, AnthropicFineTuner ds = RactoDataset.from_pairs( [("Summarise this: …", "The text discusses…")], system="You are a concise summariser.", ) tuner = AnthropicFineTuner() model = tuner.run_pipeline(ds, model="claude-3-haiku-20240307") print(model) # "claude-3-haiku-20240307:ft:org-xxx:suffix:abc123"
- create_job(training_file, model='claude-3-haiku-20240307', *, validation_file=None, suffix=None, hyperparameters=None)[source]
Submit a fine-tuning job.
- Parameters:
training_file (str) – File ID returned by
upload_dataset().model (str) – Base Claude model to fine-tune.
validation_file (str | None) – Optional validation file ID.
suffix (str | None) – Short label appended to the fine-tuned model name.
hyperparameters (dict | None) – Optional overrides, e.g.
{"n_epochs": 3}.
- Return type:
- Returns:
str – The fine-tuning job ID.
- run_pipeline(dataset, model='claude-3-haiku-20240307', *, validation_dataset=None, suffix=None, hyperparameters=None, poll_interval=60, verbose=True)[source]
Validate → upload → train → wait in a single call.
- Parameters:
dataset (RactoDataset) – Training examples.
model (str) – Base Claude model to fine-tune.
validation_dataset (RactoDataset | None) – Optional held-out validation set.
suffix (str | None) – Short label appended to the fine-tuned model name.
hyperparameters (dict | None) – Optional overrides, e.g.
{"n_epochs": 3}.poll_interval (int) – Seconds between status polls.
verbose (bool) – Print progress to stdout.
- Return type:
- Returns:
str – Fine-tuned model identifier — pass directly to
AnthropicDeveloperKit(model=...).- Raises:
ValueError – If dataset validation fails.
RuntimeError – If the fine-tuning job fails remotely.
- upload_dataset(dataset)[source]
Upload dataset as an Anthropic training file.
- Parameters:
dataset (RactoDataset) – The training examples to upload.
- Return type:
- Returns:
str – The Anthropic file ID used in
create_job().
- wait_for_completion(job_id, *, poll_interval=60, verbose=True)[source]
Block until a fine-tuning job finishes.
- Parameters:
job_id (str) – The job ID returned by
create_job().poll_interval (int) – Seconds between status-check API calls.
verbose (bool) – Print status lines to stdout.
- Return type:
- Returns:
str – Fine-tuned model name — pass directly to
AnthropicDeveloperKit(model=...).- Raises:
RuntimeError – If the job ends in
"failed"or"cancelled"state.
- class ractogateway.finetune.GeminiFineTuner(api_key=None)[source]
Bases:
objectFine-tune Google Gemini models using the Generative AI tuning API.
- Parameters:
api_key (str | None) – Google AI API key. Falls back to the
GEMINI_API_KEYenvironment variable when not supplied.
Examples
End-to-end pipeline:
from ractogateway.finetune import RactoDataset, GeminiFineTuner ds = RactoDataset.from_pairs( [("capital of France?", "Paris"), ("capital of Japan?", "Tokyo")], ) tuner = GeminiFineTuner() model_name = tuner.run_pipeline( ds, base_model="models/gemini-1.5-flash-001-tuning", display_name="geography-tutor", ) print(model_name) # "tunedModels/geography-tutor-abc123"
- create_job(dataset, base_model='models/gemini-1.5-flash-001-tuning', *, display_name='', epoch_count=5, batch_size=4, learning_rate=None)[source]
Start a Gemini supervised fine-tuning job.
- Parameters:
dataset (RactoDataset) – Training examples. Each example must be a single-turn text pair (
text_input/output). Examples with attachments or multi-turn conversations are not supported by this adapter — use Vertex AI for those.base_model (str) – Tuning-enabled Gemini model identifier.
display_name (str) – Human-readable label for the tuned model.
epoch_count (int) – Number of training epochs.
batch_size (int) – Training batch size.
learning_rate (float | None) – Learning rate.
Noneuses the provider default.
- Return type:
- Returns:
google.generativeai.types.TunedModel (operation-like object) – Pass to
wait_for_completion().- Raises:
ValueError – If the dataset fails validation, or if any examples are multimodal / multi-turn (unsupported by this adapter).
- delete_model(tuned_model_name)[source]
Permanently delete a tuned model from your project.
- Return type:
- run_pipeline(dataset, base_model='models/gemini-1.5-flash-001-tuning', *, display_name='', epoch_count=5, batch_size=4, learning_rate=None, poll_interval=60, verbose=True)[source]
Validate → create → wait in a single call.
- Parameters:
dataset (RactoDataset) – Text-pair training examples.
base_model (str) – Tuning-enabled Gemini model.
display_name (str) – Human-readable label for the tuned model.
epoch_count (int) – Training epochs.
batch_size (int) – Training batch size.
learning_rate (float | None) – Learning rate override.
poll_interval (int) – Seconds between status polls.
verbose (bool) – Print progress to stdout.
- Return type:
- Returns:
str – Tuned model name — pass to
GoogleDeveloperKit(model=...).
- wait_for_completion(operation, *, poll_interval=60, verbose=True)[source]
Block until a tuning operation finishes.
- Parameters:
operation (TuningOperation) – The object returned by
create_job().poll_interval (int) – Seconds between metadata checks.
verbose (bool) – Print progress to stdout.
- Return type:
- Returns:
str – Tuned model name (e.g.
"tunedModels/my-model-abc123"). Pass directly toGoogleDeveloperKit(model=...).- Raises:
RuntimeError – If the tuning job ends in a failed state.
- class ractogateway.finetune.OpenAIFineTuner(api_key=None, *, base_url=None)[source]
Bases:
objectFine-tune OpenAI models using the fine-tuning API.
- Parameters:
Examples
End-to-end pipeline (simplest usage):
from ractogateway.finetune import RactoDataset, OpenAIFineTuner ds = RactoDataset.from_pairs( [("What is Python?", "A high-level programming language.")], system="You are a Python tutor.", ) tuner = OpenAIFineTuner() model = tuner.run_pipeline(ds, model="gpt-4o-mini-2024-07-18") print(model) # "ft:gpt-4o-mini-2024-07-18:org::abc123"
- create_job(training_file, model='gpt-4o-mini-2024-07-18', *, validation_file=None, n_epochs='auto', batch_size='auto', learning_rate_multiplier='auto', suffix=None)[source]
Submit a fine-tuning job.
- Parameters:
training_file (str) – File ID returned by
upload_dataset().model (str) – Base model to fine-tune.
validation_file (str | None) – Optional validation file ID (also produced by
upload_dataset()).n_epochs (int | "auto") – Training epochs.
batch_size (int | "auto") – Per-device batch size.
learning_rate_multiplier (float | "auto") – Scales the default learning rate.
suffix (str | None) – Custom label appended to the fine-tuned model name.
- Return type:
- Returns:
str – The fine-tuning job ID (e.g.
"ftjob-abc123").
- run_pipeline(dataset, model='gpt-4o-mini-2024-07-18', *, validation_dataset=None, n_epochs='auto', batch_size='auto', learning_rate_multiplier='auto', suffix=None, poll_interval=30, verbose=True)[source]
Validate → upload → train → wait in a single call.
This is the recommended entry-point for most use cases.
- Parameters:
dataset (RactoDataset) – Training examples.
model (str) – Base model to fine-tune.
validation_dataset (RactoDataset | None) – Optional held-out validation set (uploaded separately).
n_epochs (int | float | "auto") – Training hyperparameters. Pass
"auto"to let OpenAI decide.batch_size (int | float | "auto") – Training hyperparameters. Pass
"auto"to let OpenAI decide.learning_rate_multiplier (int | float | "auto") – Training hyperparameters. Pass
"auto"to let OpenAI decide.suffix (str | None) – Short label appended to the fine-tuned model name.
poll_interval (int) – Seconds between status polls while waiting.
verbose (bool) – Print progress to stdout.
- Return type:
- Returns:
str – Fine-tuned model identifier — pass directly to
OpenAIDeveloperKit(model=...):kit = opd.OpenAIDeveloperKit(model=fine_tuned_model)
- Raises:
ValueError – If dataset validation fails.
RuntimeError – If the fine-tuning job fails remotely.
- upload_dataset(dataset)[source]
Upload dataset as an OpenAI training file.
- Parameters:
dataset (RactoDataset) – The training examples to upload.
- Return type:
- Returns:
str – The OpenAI file ID (e.g.
"file-abc123").
- wait_for_completion(job_id, *, poll_interval=30, verbose=True)[source]
Block until a fine-tuning job finishes.
- Parameters:
job_id (str) – The job ID returned by
create_job().poll_interval (int) – Seconds between status-check API calls.
verbose (bool) – Print status lines to stdout.
- Return type:
- Returns:
str – The fine-tuned model name ready for use in
OpenAILLMKit.- Raises:
RuntimeError – If the job ends in
"failed"or"cancelled"state.
- class ractogateway.finetune.RactoDataset(examples=None)[source]
Bases:
objectAn ordered collection of
RactoTrainingExampleobjects.This is the central data container for building, validating, splitting, and exporting fine-tuning datasets for any supported LLM provider.
- Parameters:
examples (list[RactoTrainingExample] | None) – Initial examples. An empty dataset is created when omitted.
Examples
Build from (user, assistant) pairs:
ds = RactoDataset.from_pairs( [ ("What is Python?", "Python is a high-level programming language."), ("What is a list?", "A list is a mutable ordered sequence."), ], system="You are a Python tutor.", )
Add multimodal examples manually:
ds.add( RactoTrainingExample.from_pair( user="Describe this image.", assistant="The image shows a flowchart with three decision nodes.", user_attachments=[RactoFile.from_path("diagram.png")], ) )
Export to JSONL for fine-tuning:
train_ds, val_ds = ds.split(0.8, seed=42) train_ds.export_jsonl("train.jsonl", provider="openai") val_ds.export_jsonl("val.jsonl", provider="openai")
- export_jsonl(path, provider='openai', *, overwrite=False)[source]
Write the dataset to a
.jsonlfile on disk.- Parameters:
path (str | Path) – Destination file path.
provider (str) – One of
"openai","anthropic","gemini".overwrite (bool) – When
False(default), raiseFileExistsErrorif the file already exists.
- Return type:
- Returns:
Path – The resolved path of the written file.
- classmethod from_jsonl(path, provider='openai')[source]
Load a JSONL dataset previously exported for provider.
Supports text-only OpenAI, Anthropic, and Gemini formats.
- Parameters:
- Return type:
- classmethod from_pairs(pairs, *, system='')[source]
Build a text-only dataset from
(user, assistant)pairs.
- shuffle(seed=None)[source]
Return a new dataset with examples in random order.
- Parameters:
seed (int | None) – Optional random seed for reproducibility.
- Return type:
- split(train_ratio=0.8, *, seed=None)[source]
Split into train and validation datasets.
- Parameters:
- Return type:
- Returns:
tuple[RactoDataset, RactoDataset] –
(train_dataset, validation_dataset)
- class ractogateway.finetune.RactoTrainingExample(messages)[source]
Bases:
objectA complete conversation used as one training record.
- Parameters:
messages (list[RactoTrainingMessage]) –
Ordered turns. Typical shapes:
Single-turn :
[user, assistant]With system :
[system, user, assistant]Multi-turn :
[system, user, assistant, user, assistant, …]
Examples
>>> ex = RactoTrainingExample.from_pair( ... user="What is 2 + 2?", ... assistant="4", ... system="You are a maths tutor.", ... )
>>> # Multimodal example (image + question) >>> ex = RactoTrainingExample.from_pair( ... user="Describe this chart.", ... assistant="The chart shows monthly revenue for Q4 2024.", ... user_attachments=[RactoFile.from_path("chart.png")], ... )
- classmethod from_conversation(turns)[source]
Build from a list of
(role, content)tuples.
- classmethod from_pair(user, assistant, *, system='', user_attachments=None)[source]
Create a single-turn (prompt → completion) training example.
- Parameters:
- Return type:
- to_anthropic_dict()[source]
Serialize to Anthropic fine-tuning JSONL record.
Output format:
{"system": "…", "messages": [{"role": "user", …}, …]}The
systemkey is only present when a system message exists.
- class ractogateway.finetune.RactoTrainingMessage(role, content, attachments=<factory>)[source]
Bases:
objectOne conversational turn inside a training example.
- Parameters:
- to_anthropic()[source]
Return an Anthropic-compatible message dict.
System messages should be lifted to the top-level
systemfield —RactoTrainingExample.to_anthropic_dict()handles this automatically.