# Supervised Learning The cookbook provides a pipelined SFT training loop with configurable datasets, evaluation, and checkpointing. ## Architecture ```text 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. ```python 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. ```python 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`: ```python 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 `ServiceClient` → `TrainingClient` 1. Build dataset from `config.dataset_builder` 1. For each epoch and batch: - `forward_backward` with the batch - `optim_step` - Run evaluators at `eval_every` intervals - Save checkpoints at `save_every` intervals 1. Save final checkpoint The loop pipelines requests for throughput — see [Clock Cycles & Pipelining](https://tinker-docs.thinkingmachines.ai/tinker/under-the-hood/index.md). ## Next Steps - [sl_loop.py](https://github.com/thinking-machines-lab/tinker-cookbook/blob/main/tinker_cookbook/recipes/sl_loop.py) — minimal training loop without abstractions - [SL Hyperparameters](https://tinker-docs.thinkingmachines.ai/tutorials/advanced/sl-hyperparams/index.md) — choosing learning rate, rank, batch size - [Tutorials: Your First SFT](https://tinker-docs.thinkingmachines.ai/tutorials/basics/first-sft/index.md) — interactive walkthrough