# Tinker Quickstart ## Installation ```bash pip install tinker ``` ### Authentication ```bash tinker auth login ``` Or create an API key in the [Tinker Console](https://tinker.thinkingmachines.ai/keys?new_key=true) and set it as the `TINKER_API_KEY` environment variable. ### Billing Set up payment info in [Billing](https://tinker.thinkingmachines.ai/billing/), and see [Models & Pricing](https://tinker-docs.thinkingmachines.ai/tinker/models/index.md) for current training and sampling rates. ## Using Tinker SDK ### Create clients View active sessions in [Sessions](https://tinker.thinkingmachines.ai/sessions) in the Tinker Console. ```python import tinker service_client = tinker.ServiceClient() # Perform forward/backward passes and optimization training_client = service_client.create_lora_training_client( base_model="Qwen/Qwen3-8B", rank=16 ) # For generating completions from a base model sampling_client = service_client.create_sampling_client(base_model="Qwen/Qwen3-8B") # Convert text to/from tokens tokenizer = training_client.get_tokenizer() ``` ### Sampling ```python prompt = "The capital of France is" prompt_tokens = tokenizer.encode("The capital of France is") model_input = tinker.types.ModelInput.from_ints(prompt_tokens) params = tinker.types.SamplingParams(max_tokens=50, temperature=0.7, stop=["\n"]) # Decode the returned sample result = await sampling_client.sample_async( prompt=model_input, num_samples=1, sampling_params=params ) response = tokenizer.decode(result.sequences[0].tokens) print(response) # For a conversation-formatted prompt conversation_tokens = tokenizer.apply_chat_template( conversation=[{"role": "user", "content": "What is the capital of France?"}], add_generation_prompt=True, ) model_input = tinker.types.ModelInput.from_ints(conversation_tokens) result = await sampling_client.sample_async( prompt=model_input, num_samples=1, sampling_params=params ) response = tokenizer.decode(result.sequences[0].tokens) print(response) ``` ### Training See [Loss Functions](https://tinker-docs.thinkingmachines.ai/tinker/losses/index.md) for details about available loss functions, [LoRA Primer](https://tinker-docs.thinkingmachines.ai/tinker/lora-primer/index.md) for details about training with LoRA, and [Prepare Training Data](https://tinker-docs.thinkingmachines.ai/tinker/sdk-cheatsheet/#prepare-training-data) for guidance on constructing `Datum` objects. #### Supervised Fine-tuning (SFT) ```python completion_tokens = result.sequences[0].tokens full_sequence = prompt_tokens + completion_tokens n_prefix = len(prompt_tokens) - 1 datum = tinker.types.Datum( input=model_input, loss_fn_inputs = { # 0 to apply no loss, 1 to apply loss to token weights=[0.0] * n_prefix + [1.0] * len(completion_tokens), target_tokens=full_sequence[1:], # shifted by 1 from input } ) # Gradient computation fwd_bwd_result = training_client.forward_backward_async( data=[datum], loss_fn="cross_entropy" ) # Update model parameters optim_future = await training_client.optim_step_async( tinker.types.AdamParams(learning_rate=1e-4) ) await fwd_bwd_result.result_async() await optim_future.result_async() ``` #### Reinforcement Learning (RL) ```python rewards = [reward_fn(seq) for seq in result.sequences] mean = sum(rewards) / len(rewards) datums = [] for seq, reward in zip(result.sequences, rewards): completion_tokens = seq.tokens n_prefix = len(prompt_tokens) - 1 advantage = reward - mean full_sequence = prompt_tokens + completion_tokens datum = tinker.types.Datum( input=model_input, loss_fn_inputs={ "target_tokens": full_sequence[1:], # Selected token log probabilities in rollout # 0 for prompt tokens "logprobs": [0.0] * n_prefix + seq.logprobs, # per token advantages, 0 for prompt tokens "advantages": [0.0] * n_prefix + [advantage] * len(completion_tokens), }, ) datums.append(datum) fwd_bwd_result = await training_client.forward_backward_async( data=datums, loss_fn="importance_sampling", # "ppo", "cispo", "dro" ) optim_future = await training_client.optim_step_async( tinker.types.AdamParams(learning_rate=1e-4) ) await fwd_bwd_result.result_async() await optim_future.result_async() ``` ### Save and Load Checkpoints To view all saved checkpoints, go to [Checkpoints](https://tinker.thinkingmachines.ai/checkpoints) in the Tinker Console. ```python # Save a checkpoint that can be used to resume training training_checkpoint = await training_client.save_state_async( name="my-checkpoint", user_metadata={ "step": 1000, }, ) # Load the training checkpoint service_client.create_training_client_from_state(training_checkpoint.path) # Save a checkpoint that can be used for sampling sampling_checkpoint = await training_client.save_weights_for_sampler_async( name="my-sampler-checkpoint" ) # Load the sampling checkpoint service_client.create_sampling_client(model_path=sampling_checkpoint.path) # Open in the Tinker Playground print(sampling_checkpoint.get_playground_url()) ``` ## Additional Resources - [SDK Cheatsheet](https://tinker-docs.thinkingmachines.ai/tinker/sdk-cheatsheet/index.md) for quick access to common SDK operations. - [Tinker Cookbook](https://tinker-docs.thinkingmachines.ai/cookbook/index.md) for more advanced recipes and utility functions for common workflows. - [Tutorials](https://tinker-docs.thinkingmachines.ai/tutorials/index.md) for more examples and use cases.