Skip to content

Supervised Learning

The cookbook provides a pipelined SFT training loop with configurable datasets, evaluation, and checkpointing.

Architecture

train.Config
├── model_name            which model to fine-tune
├── dataset_builder       SupervisedDatasetBuilder → SupervisedDataset
├── learning_rate          optimizer config (+ lr_schedule, adam_*)
├── evaluator_builders    what to measure during training
├── save_every / eval_every    checkpoint and eval cadence
└── lora_rank             LoRA adapter size

SupervisedDatasetBuilder
└── __call__() → (train_dataset, eval_dataset)
SupervisedDataset
├── get_batch(index) → list[tinker.Datum]
├── __len__() → number of batches
└── set_epoch(seed) → shuffle for next epoch

Key Components

tinker_cookbook.supervised.train.Config

The central configuration. Defines model, data, hyperparameters, and evaluation.

from tinker_cookbook.supervised import train

config = train.Config(
    log_path="~/logs/my-sft-run",
    model_name="Qwen/Qwen3-8B",
    dataset_builder=my_dataset_builder,
    learning_rate=1e-4,
    lora_rank=32,
    num_epochs=1,
    save_every=20,
    eval_every=10,
)
asyncio.run(train.main(config))

SupervisedDataset / SupervisedDatasetBuilder

A SupervisedDatasetBuilder is a config that constructs a SupervisedDataset. The dataset returns batches of tinker.Datum objects.

from tinker_cookbook.supervised.types import SupervisedDatasetBuilder, SupervisedDataset

class MyDatasetBuilder(SupervisedDatasetBuilder):
    def __call__(self) -> tuple[SupervisedDataset, SupervisedDataset | None]:
        return train_data, eval_data  # eval_data is optional

Built-in builders:

Builder Use case
SupervisedDatasetFromHFDataset Wrap a HuggingFace dataset with map_fn or flatmap_fn
StreamingSupervisedDatasetFromHFDataset Stream from HuggingFace (lower memory)
FromConversationFileBuilder Load from a JSONL file of chat conversations
ChatDatasetBuilder Base class for chat data — adds tokenizer + renderer

ChatDatasetBuilder

For chat-formatted data. Adds tokenizer and renderer properties from ChatDatasetBuilderCommonConfig:

from tinker_cookbook.supervised.types import ChatDatasetBuilder, ChatDatasetBuilderCommonConfig

class MyChats(ChatDatasetBuilder):
    common_config = ChatDatasetBuilderCommonConfig(
        model_name_for_tokenizer="Qwen/Qwen3-8B",
        renderer_name="qwen3",
        batch_size=8,
        max_length=4096,
    )

Training Loop

train.main(config) handles the full pipeline:

  1. Create ServiceClientTrainingClient
  2. Build dataset from config.dataset_builder
  3. For each epoch and batch:
    • forward_backward with the batch
    • optim_step
    • Run evaluators at eval_every intervals
    • Save checkpoints at save_every intervals
  4. Save final checkpoint

The loop pipelines requests for throughput — see Clock Cycles & Pipelining.

Next Steps