BASETEN_API_KEY instead of a Thinking Machines key, and cluster routing resolves to your Baseten org rather than a Tinker tenant.
Compatibility at a glance
Thebaseten-loops[tinker] extra installs a tinker namespace package so existing imports work unchanged. The table below shows where Loops and Tinker align and where they diverge.
Install the Tinker compatibility package
Addbaseten-loops with the [tinker] extra to your project. The extra pulls in baseten-loops-tinker, which provides the tinker namespace. If you don’t have a uv project yet, initialize one first:
import tinker works without modification:
Use with tinker-cookbook
tinker-cookbook depends on the original Thinking Machines tinker package. Without an override, installing tinker-cookbook first pulls in that package, and its files conflict with the tinker namespace provided by baseten-loops[tinker] when that extra is added later. The fix is to declare a uv override in pyproject.toml before installing any dependencies. There is no CLI command for this step.
Add the override first:
baseten-loops[tinker] extra provides the tinker namespace instead of the original package.
What’s the same
The training loop API is call-compatible with Tinker.forward, backward, optim_step, save_weights, and the sampling interface share the same method names, and the shared types (Datum, ModelInput, TensorData, SamplingParams, and AdamParams) are all available under tinker.types with the same field names.
What’s different
Loss inputs are one-dimensional
Keep everyloss_fn_inputs tensor one-dimensional, one value per token position. Loops reads the flat TensorData.data buffer and ignores any second dimension, so it does not support the (N, K) form Tinker uses for top-K soft targets in distillation. Recipes that build 1-D target_tokens, weights, logprobs, and advantages port unchanged; a recipe that builds (N, K) targets does not.
Image inputs must be inline
Tinker’sImageAssetPointerChunk references an image asset stored out of band. Loops ships the type so that tinker imports and ModelInput parsing resolve, but Baseten samplers don’t fetch out-of-band assets, so constructing one raises ValueError naming ImageChunk as the supported path. Recipes that read images from disk or memory and build ImageChunk values port unchanged; recipes that pass asset pointers do not.
Checkpoints come back as folders
Tinker returns a single archive URL for a checkpoint. Loops returns a folder of files behind paginated presigned URLs, because weight sync writes an unzipped folder rather than a compressed archive. Consumer code paginates using?page_token= and ?page_size= query parameters instead of downloading a single file. See GET /v1/loops/checkpoints/{checkpoint_id}/files for the route.
Authentication is a Baseten API key
SetBASETEN_API_KEY in your environment before constructing ServiceClient; the SDK reads it by default. Pass api_key=... only when you need to override the environment variable. The Thinking Machines key used by Tinker is not accepted. See API keys for how to generate one.
LoRA module selection is fixed per model family
Tinker lets you choose which module groups a LoRA adapter trains through thetrain_mlp, train_attn, and train_unembed flags on create_lora_training_client. Loops picks target modules server-side per model family: attention and MLP on, unembed off, for every supported family except Kimi K2.5 VL, which trains attention and unembed but not MLP. The compatibility package accepts these flags when they match your model family’s coverage and raises NotImplementedError at submission when they diverge, rather than silently ignoring them.
Cluster routing is per-org
Loops sessions resolve to the caller’s Baseten org and the cluster configured for that org. Tinker uses per-tenant scoping, where the tenant determines the cluster. In practice this means you don’t choose a cluster when creating a session. Your org’s configuration determines it automatically. To place workloads in a specific Baseten team, passteam="..." to ServiceClient; see Choose a team. Loops must be enabled for your organization before sessions can start; fill out the signup form to request access.
Run tinker-cookbook recipes on Loops
The cookbook recipes contain self-contained examples covering supervised fine-tuning, reinforcement learning from human feedback, distillation, and sampling. Recipes that build one-dimensional loss inputs run on Loops without modification; recipes that build(N, K) targets do not. See Loss inputs are one-dimensional. Running a recipe end to end is the fastest way to confirm that your environment is configured correctly and that the tinker namespace is resolving to the Loops compatibility package.