LeetLLM
My PlanLearnGlossaryTracksPracticeBlog
LeetLLM

Your go-to resource for mastering AI & LLM systems.

Product

  • Learn
  • Glossary
  • Tracks
  • Practice
  • Blog
  • RSS

Legal

  • Terms of Service
  • Privacy Policy

© 2026 LeetLLM. All rights reserved.

All Topics
Your Progress
0%

0 of 177 articles completed

🛠️Computing Foundations0/9
Git, Shell, Linux for AIDocker for Reproducible AIPython for AI EngineeringNumPy and Tensor ShapesCUDA for ML TrainingMPS & Metal for ML on MacData Structures for AISQL and Data ModelingAlgorithms for ML Engineers
📊Math & Statistics0/8
Gradients and BackpropVectors, Matrices & TensorsLinear Algebra for MLAdam, Momentum, SchedulersProbability for Machine LearningStatistics and UncertaintyDistributions and SamplingHypothesis Tests, Intervals, and pass@k
📚Preparation & Prerequisites0/13
Neural Networks from ScratchCNNs from ScratchTraining & BackpropagationSoftmax, Cross-Entropy & OptimizationRNNs, LSTMs, GRUs, and Sequence ModelingAutoencoders and VAEsThe Transformer Architecture End-to-EndLanguage Modeling & Next TokensFrom GPT to Modern LLMsPrompt Engineering FundamentalsCalling LLM APIs in ProductionFirst AI App End-to-EndThe LLM Lifecycle
🧮ML Algorithms & Evaluation0/11
Linear Regression from ScratchLogistic Regression and MetricsDecision Trees, Forests, and BoostingReinforcement Learning BasicsValidation and LeakageClustering and PCACore Retrieval AlgorithmsDecoding AlgorithmsExperiment Design and A/B TestingPyTorch Training LoopsDataset Pipelines and Data Quality
📦Production ML Systems0/6
Feature Engineering for Production MLBatch and Streaming Feature PipelinesGradient Boosted Trees in ProductionRanking and Recommendation SystemsForecasting and Anomaly DetectionMonitoring Predictive Models
🧪Core LLM Foundations0/8
The Bitter Lesson & ComputeBPE, WordPiece, and SentencePieceStatic to Contextual EmbeddingsPerplexity & Model EvaluationFile Ingestion for AIChunking StrategiesLLM Benchmarks & LimitationsInstruction Tuning & Chat Templates
🧰Applied LLM Engineering0/24
Dimensionality Reduction for EmbeddingsCoT, ToT & Self-Consistency PromptingFunction Calling & Tool UseMCP & Tool Protocol StandardsContext EngineeringPrompt Injection DefenseResponsible AI GovernanceData Labeling and Human FeedbackEvaluating AI AgentsProduction RAG PipelinesHybrid Search: Dense + SparseReranking and Cross-Encoders for RAGRAG Evaluation for Reliable AnswersLLM-as-a-Judge EvaluationBias & Fairness in LLMsHallucination Detection & MitigationLLM Observability & MonitoringExperiment Tracking with MLflow and W&BPrompt Optimization with DSPyModel Versioning & DeploymentSemantic Caching & Cost OptimizationLLM Cost Engineering & Token EconomicsModel Gateways, Routing, and FallbacksDesign an Automated Support Agent
🎓Portfolio Capstones0/9
Capstone: Delivery ETA PredictionCapstone: Product RankingCapstone: Demand ForecastingCapstone: Image Damage ClassifierCapstone: Production ML PipelineCapstone: Document QACapstone: Eval DashboardCapstone: Fine-Tuned ClassifierCapstone: Reproducible ML Study
🧠Transformer Deep Dives0/8
Sentence Embeddings & Contrastive LossEmbedding Similarity & QuantizationScaled Dot-Product AttentionVision Transformers and Image EncodersPositional Encoding: RoPE & ALiBiLayer Normalization: Pre-LN vs Post-LNMechanistic InterpretabilityDecoding Strategies: Greedy to Nucleus
🧬Advanced Training & Adaptation0/16
Scaling Laws & Compute-Optimal TrainingPre-training Data at ScaleBuild GPT from Scratch LabJAX for PyTorch ResearchersContinued Pretraining for Domain ShiftSynthetic Data PipelinesSupervised Fine-Tuning PipelineMixed Precision TrainingDistributed Training: FSDP & ZeROLoRA & Parameter-Efficient TuningReward Modeling from Preference DataRLHF & DPO AlignmentConstitutional AI & Red TeamingRLVR & Verifiable RewardsKnowledge Distillation for LLMsModel Merging and Weight Interpolation
🤖Advanced Agents & Retrieval0/16
Vector DB Internals: HNSW & IVFAdvanced RAG: HyDE & Self-RAGGraphRAG & Knowledge GraphsRAG Security & Access ControlStructured Output GenerationReAct & Plan-and-ExecuteGuardrails & Safety FiltersCode Generation & SandboxingComputer-Use / GUI / Browser AgentsHuman-in-the-Loop Agent ArchitectureAI Coding Workflow with AgentsAgent Memory & PersistenceAgent Failure & RecoveryRecursive Language Models (RLM)Multi-Agent OrchestrationCapstone: Production Agent
⚡Inference & Production Scale0/19
Inference: TTFT, TPS & KV CacheMulti-Query & Grouped-Query AttentionKV Cache & PagedAttentionPrefix Caching and Prompt CachingFlashAttention & Memory EfficiencyContinuous Batching & SchedulingScaling LLM InferenceModel Parallelism for LLM InferenceModel Quantization: GPTQ, AWQ & GGUFLocal LLM DeploymentSLM Specialization & Edge DeploymentSpeculative DecodingLong Context Window ManagementMixture of Experts ArchitectureMamba & State Space ModelsReasoning & Test-Time ComputeAdvanced MLOps & DevOps for AIGPU Serving & AutoscalingA/B Testing for LLMs
🏗️System Design Capstones0/9
Content Moderation SystemCode Completion SystemMulti-Tenant LLM PlatformLLM-Powered Search EngineVision-Language Models & CLIPMultimodal LLM ArchitectureDiffusion Models: Images & TextReal-Time Voice AI AgentReasoning & Test-Time Compute
🎤AI Lab Interviewing0/4
AI Lab Coding Interview: Python SystemsAI Lab System Design InterviewAI Lab Behavioral InterviewAI Lab Technical Presentation
🔬Project Deep Dives0/17
Deep Dive - vLLMDeep Dive - SkyRLDeep Dive - FlashAttentionDeep Dive - FlashInferDeep Dive - DeepGEMMDeep Dive - NCCLDeep Dive - MegatronDeep Dive - DeepSpeedDeep Dive - RayDeep Dive - MLflowDeep Dive - PyTorchDeep Dive - TransformersDeep Dive - SGLangDeep Dive - slimeDeep Dive - DeepEPDeep Dive - TinkerDeep Dive - Light-PEFT
Back to Topics
LearnProject Deep DivesDeep Dive - Tinker
⚡HardFine-Tuning & Training

Deep Dive - Tinker

Read Tinker as a hosted LoRA post-training service: local control loops, remote GPU workers, token-level RL contracts, pipelined clock cycles, checkpoint export, and the boundaries that separate an SDK from infrastructure such as DeepEP.

36 min read
Learning path
Step 176 of 177 in the full curriculum
Deep Dive - DeepEPDeep Dive - Light-PEFT

Personalize this lesson

Adapt explanations and teaching visuals to your background and preferred voice.

Start by changing one part of a language model's behavior. Perhaps you have a reward function, a small dataset, or a tool-using environment. Operating a multi-node cluster would delay the test, while a high-level trainer could hide the tokens, log probabilities, and optimizer boundaries that determine whether the experiment is valid.

Tinker is Thinking Machines Lab's managed hosted low-rank adaptation (LoRA) service for this job. A Python process that you run locally builds prompts, environments, rewards, and loss inputs. Remote workers run the model's forward and backward passes, apply optimizer updates, and generate samples. The public software development kit (SDK) and Tinker Cookbook are Apache-2.0 open-source code; the hosted service, model catalog, data handling, and application programming interface (API) access are separate product and terms boundaries.[1]Reference 1Announcing Tinkerhttps://thinkingmachines.ai/news/announcing-tinker/[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed[3]Reference 3Tinker Cookbookhttps://github.com/thinking-machines-lab/tinker-cookbook/tree/0b5c01eaee49bdb0d476f4f383e1c0fb9aced590

This lesson follows one training update from your central processing unit (CPU) process to a remote worker and back. It treats four primitives as a contract: forward_backward, optim_step, sample, and save_state. It then builds the reinforcement learning (RL) path, explains clock-cycle pipelining, and ends with a comparison that keeps Tinker distinct from DeepEP. Tinker can expose training without asking you to build the cluster. DeepEP is a communication kernel and runtime component that you would operate inside such a cluster.

Tinker ownership boundary. Local code owns prompts, rewards, SDK calls, and the SamplingClient. The hosted service owns LoRA workers and checkpoints. Requests cross to remote forward and optimizer work; saved weights drive sampling, and token evidence returns to the local loop. Tinker ownership boundary. Local code owns prompts, rewards, SDK calls, and the SamplingClient. The hosted service owns LoRA workers and checkpoints. Requests cross to remote forward and optimizer work; saved weights drive sampling, and token evidence returns to the local loop.
Trace ownership across Tinker’s boundary: local code owns prompts and rewards, the hosted worker owns LoRA updates, and checkpointed sampler weights return token evidence.

Start with the boundary

Tinker has three names that look like one product but describe different surfaces.

SurfaceRoleWho operates itWhat you can change
Tinker serviceHosted worker pool, storage, scheduler, and model runtimeThinking Machines LabYour requests, data, loss choices, and loop timing
tinker SDKPython client, types, futures, command-line interface (CLI), and API conversion codeOpen-source contributors under Apache-2.0Client code, tests, adapters, and local orchestration
tinker-cookbookOpen recipes for supervised fine-tuning (SFT), RL, Direct Preference Optimization (DPO), distillation, evaluation, and exportOpen-source contributors under Apache-2.0Dataset builders, environments, reward functions, and recipes

The hosted service isn't the same thing as the GitHub repository. Cloning the SDK doesn't give you the worker pool, model weights, scheduler, storage, or failure-recovery system. Conversely, using the service doesn't require you to accept a fixed high-level RL trainer. The low-level calls are intentionally small.[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed

The model catalog is a service capability, not a promise encoded in the Python package. It can change independently from an SDK commit. Current documentation describes LoRA fine-tuning for dense and mixture-of-experts (MoE) models and a catalog that changes over time.[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/ GLM-5.2 and DeepSeek-V4 need independent capability checks. Check the live response and model terms before designing a run around either name.

That distinction matters for frontier post-training. A model may fit the service's architecture adapter and still be absent from your account, restricted by third-party terms, or unavailable for a particular loss or input modality. Treat get_server_capabilities and the current model page as runtime evidence, not as static metadata in a blog post.

Local control plane, remote data plane

The phrase control plane here means the code that decides what should happen next. Your process can load a dataset, render a chat template, call an environment, grade an answer, compute group-relative advantages, select a loss, and decide when to checkpoint. It can also start many requests concurrently with asyncio.

The phrase data plane means the model-heavy work that the hosted workers execute. A worker pool receives serialized model inputs and loss tensors, runs distributed forward and backward computation, applies the optimizer state, and returns compact outputs. Sampling workers generate token IDs and optional log probabilities. Storage workers make named checkpoints addressable through tinker:// paths.

Diagram showing Local control, Hosted model path, Your process Python loop + dataset, and Environment + verifier reward + advantage. Diagram showing Local control, Hosted model path, Your process Python loop + dataset, and Environment + verifier reward + advantage.
Local control, Hosted model path, Your process Python loop + dataset, and Environment + verifier reward + advantage.

This split lets a reward function change without modifying distributed model code, but it creates failure surfaces. Local code can produce a malformed target tensor; remote workers can reject a model or run out of capacity; a sampler can use an older checkpoint than the trainer; a service retry can duplicate an operation unless request and checkpoint names are idempotent.

Ask, "Where does this state live?" Prompt rows, reward labels, and experiment configuration live in your loop. LoRA parameters, optimizer moments, and worker placement live in the service. A returned future is only a handle to remote progress. It isn't a local gradient tensor unless you explicitly request an output that contains one.

The four primitives

Treat each API operation as a state transition.

PrimitiveClientInputRemote effectReturned evidence
forward_backwardTrainingClientDatum list, loss name, optional configComputes loss and accumulates gradients for current adapter statePer-datum outputs, metrics, and a future
optim_stepTrainingClientAdam hyperparametersApplies accumulated gradients and advances adapter plus optimizer stateOptimizer metrics and a future
sampleSamplingClientTokenized prompt, count, sampling parametersGenerates one or more completions from a model snapshotToken IDs, stop reason, optional log probabilities
save_stateTrainingClientName, optional time to live (TTL), overwrite flagPersists train-resume checkpoint, optionally with optimizer state on loadtinker:// checkpoint path

The SDK also exposes save_weights_for_sampler and save_weights_and_get_sampling_client. Those operations publish a sampler-compatible adapter snapshot. save_state is about restoring training state; a sampler checkpoint is about evaluating or serving a chosen weight version. Don't use the two names interchangeably.

The four operations are asynchronous at the network boundary. Each returns a future-like object. The server still executes operations in an ordered clock-cycle schedule for a training client. Calling a method with an _async suffix changes how your local event loop waits; it doesn't turn the worker pool into an unbounded asynchronous parameter server.[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/

forward_backward receives a Datum

A Datum has model_input plus loss_fn_inputs. model_input is a token or multimodal sequence. loss_fn_inputs holds tensors needed by a named loss. For SFT, that commonly means target_tokens and weights. For RL, it can include sampled logprobs, advantages, target_tokens, and an action mask before cookbook code removes or consumes the mask.

The SDK chunks large lists before sending them. The pinned source uses a maximum of 1,024 datums per chunk and an estimated payload cap, then assigns sequence IDs so chunks are processed in the intended order. A long batch can therefore become multiple remote requests while still yielding one combined future result.[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed

The loss name is a protocol value. The pinned SDK declares cross_entropy, importance_sampling, ppo, cispo, and dro as supported loss identifiers. That list is not a guarantee that every model or service deployment enables every option. Validate against the current server capability and docs when a run starts.[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/

optim_step advances adapter state

optim_step consumes gradients accumulated by the preceding forward/backward work and updates trainable parameters with AdamW-equivalent behavior. The SDK documentation calls out a default weight decay of zero, which differs from some PyTorch defaults.[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed

The optimizer state stays remote. You don't download a Python optimizer object after every step. This keeps the loop small, but it means your checkpoint policy must explicitly preserve optimizer state when you need a faithful resume. Loading weights alone resets optimizer history; loading with optimizer restores the saved moments when the checkpoint contains them.

The operation ordering is part of correctness. An optimizer request submitted before its matching forward/backward result can still be valid because the service sequences requests for that training client. A separate client, a retry, or an accidental concurrent loop can violate the intended order. Use one owner for a training client and log request IDs and step numbers in your local loop.

sample returns evidence for learning

SamplingClient.sample accepts a ModelInput, number of completions, and SamplingParams. Each returned sequence includes generated token IDs and a stop reason. If requested, it includes one log probability per generated token. compute_logprobs can score prompt tokens for a separate comparison.

The decoded string is for a human or verifier. The token identifiers (IDs) and log probabilities are the learning evidence. If you decode and re-tokenize before constructing an RL Datum, a different tokenizer version or normalization rule can shift token boundaries. The reward may still look correct while the policy-gradient target points at the wrong positions.

num_samples is a group primitive. A math problem with eight independent completions gives a group over which the Cookbook centers rewards. Eight separate calls can work, but one grouped call makes the intended comparison and batching visible. Concurrent calls across different prompts add another axis of parallelism.[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/[3]Reference 3Tinker Cookbookhttps://github.com/thinking-machines-lab/tinker-cookbook/tree/0b5c01eaee49bdb0d476f4f383e1c0fb9aced590

save_state creates a recovery point

save_state("step-0042") stores a named training checkpoint. load_state restores model weights but not optimizer state. load_state_with_optimizer restores both when available. A TTL can make a checkpoint expire, and overwrite controls whether the name can be replaced.[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed

For evaluation or deployment, save sampler-compatible weights instead. The Cookbook's export path downloads the adapter, merges it with the base model when requested, and can build a parameter-efficient fine-tuning (PEFT) adapter directory or a standard Hugging Face model. The merged model is portable, but its base-model license and tokenizer terms still apply.

LoRA is the adaptation boundary

Tinker is a LoRA training service, not a full-parameter training service. LoRA keeps the frozen base matrix W0W_0W0​ and learns a low-rank update:

W=W0+αrBA.W = W_0 + \frac{\alpha}{r}BA.W=W0​+rα​BA.

Here AAA and BBB are small trainable matrices, rrr is the rank, and α\alphaα scales the update. The service stores and updates the adapter path while sharing the base model across runs. This is how a multi-tenant worker pool can serve many experiments without copying a full model and optimizer state for each run.[1]Reference 1Announcing Tinkerhttps://thinkingmachines.ai/news/announcing-tinker/[5]Reference 5LoRA Without Regrethttps://thinkingmachines.ai/blog/lora/

LoRA doesn't mean "small model." Tinker has documented support for large dense and MoE models, including trillion-parameter examples in its announcements. The memory savings come from the trainable state and optimizer path, not from making every base-model weight cheap to move. A huge model still needs a compatible hosted topology, checkpoint format, and model-specific adapter implementation.[6]Reference 6Tinker General Availabilityhttps://thinkingmachines.ai/news/tinker-general-availability/[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/

Rank changes capacity and memory. A larger rank can express a broader update but costs more adapter parameters and optimizer state. Training only attention, only a multilayer perceptron (MLP), or the unembedding layer changes which behavior can move. The create_lora_training_client options make those choices explicit. Don't compare runs with different target modules as if rank were the only variable.

LoRA also changes what "full control" means. You control the algorithm, data, reward, sampling schedule, and loss inputs. You don't control arbitrary base-weight tensors, kernel fusion, placement, or collective algorithms. That is a productive boundary for post-training research, but it isn't equivalent to owning the full training stack.

SFT first: a token-level contract

Start with a supervised example before adding rewards. A rendered conversation becomes an input sequence and a target sequence. A weight tensor marks which target positions contribute to cross-entropy. Prompt positions usually receive zero weight; assistant positions receive one or a chosen fractional weight.

For one datum, the core alignment is:

Positionmodel_inputtarget_tokensweightsTraining meaning
0prompt tokennext token0Context only
1prompt tokennext token0Context only
2assistant tokennext token1Update adapter
3assistant tokennext token1Update adapter

The arrays must share the expected shifted length. The Cookbook's conversation_to_datum helper handles renderer-specific role markers, target shifting, and response masks. Read that helper when a loss curve looks impossible. A one-token offset can produce a decreasing loss while training the model on the wrong targets.

The smallest SFT loop has one forward_backward and one optim_step. The Cookbook submits both before waiting so they can share a worker clock cycle. It repeats the pair while recording loss and evaluation metrics. A decrease in loss is evidence that the chosen weighted tokens are easier for the adapter to predict; it isn't evidence that a task reward improved.

RL: preserve tokens, logprobs, and credit

RL adds a second model interaction. The current policy samples a completion, an environment or verifier assigns reward, and the loop converts that evidence into a training datum. The reward function can be local and deterministic, a remote grader, a unit-test sandbox, or another model. Tinker doesn't choose it for you.

The Cookbook's basic Group Relative Policy Optimization (GRPO) path looks like this:

  1. Select a group of prompts.
  2. Sample several completions per prompt from current sampler weights.
  3. Grade every completion.
  4. Center rewards within each group: Ai=Ri−mean⁡(Rgroup)A_i = R_i - \operatorname{mean}(R_{group})Ai​=Ri​−mean(Rgroup​).
  5. Skip groups whose rewards are all equal because every advantage is zero.
  6. Build Datum objects with sampled log probabilities and token-aligned advantages.
  7. Submit forward_backward(..., loss_fn="importance_sampling").
  8. Submit optim_step with the chosen Adam parameters.
  9. Save and evaluate a sampler checkpoint.

The group baseline is a variance-reduction choice, not a universal reward definition. Code tasks might use unit-test pass rate, while tool-use environments can combine success, invalid-call penalties, and latency budgets. Preference models may return dense scores. The model sees a token-level signal only after your loop maps those outcomes into advantages and masks.

The RL datum shape

The Cookbook's trajectory converter emits one or more datums per trajectory. One trajectory can split when a later observation isn't a prefix of the sequence accumulated so far. That happens naturally with tool calls, branches, or context compaction.

The resulting loss_fn_inputs include:

FieldShape ideaSourceMeaning
target_tokensOne target per input positionShifted sampled sequenceToken to score
logprobsOne sampled logprob per targetSamplerBehavior-policy evidence
advantagesOne scalar copied across action tokensGroup rewardCredit assigned to action
maskZero for observation, one for actionTrajectory converterWhich positions are trainable

Observation positions receive zero logprob, zero advantage, and zero mask. Action positions receive the sampled logprob and trajectory advantage. A parse-error policy can set an action mask to zero while retaining the rest of the trajectory. That makes an invalid turn visible in metrics without teaching the model to reproduce malformed output.

The named loss consumes the fields it supports. importance_sampling compares current log probabilities with sampled behavior-policy log probabilities. Proximal Policy Optimization (ppo) adds clipping behavior. The cispo and dro losses use other importance and truncation choices. A custom loss can run on log probabilities through forward_backward_custom, but the SDK still translates your derivative into a backend-supported weighted cross-entropy pass.[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed[3]Reference 3Tinker Cookbookhttps://github.com/thinking-machines-lab/tinker-cookbook/tree/0b5c01eaee49bdb0d476f4f383e1c0fb9aced590

Logprob alignment is the hidden invariant

Suppose a sampler returns four response tokens and four log probabilities. The training input usually contains prompt context plus the response prefix, while the target array contains the response tokens shifted one position to the left. The prompt padding is deliberate. It keeps array positions aligned while assigning zero learning signal to context.

If the arrays differ by one token, an operation can fail loudly. Worse, if they have the same length after accidental padding, the operation can succeed while applying the wrong credit to every token. Log a short prefix of tokens, log probabilities, advantages, and masks for one group before launching a long run.

The reward should be reproducible enough to debug. Save the prompt ID, sampler checkpoint path, sampled tokens, stop reason, reward components, environment version, and advantage statistics. A reward value without that evidence can't tell you whether the model improved or the grader changed.

Tinker RL contract graph: prompt sampling yields tokens and log probabilities, grading yields group reward, a Datum builder creates centered advantages and masks, remote forward_backward and optim_step update the adapter, and a sampler checkpoint becomes the next policy. A token-mask matrix marks prompt positions zero and action positions one; an equation shows equal rewards produce zero advantage. Tinker RL contract graph: prompt sampling yields tokens and log probabilities, grading yields group reward, a Datum builder creates centered advantages and masks, remote forward_backward and optim_step update the adapter, and a sampler checkpoint becomes the next policy. A token-mask matrix marks prompt positions zero and action positions one; an equation shows equal rewards produce zero advantage.
Follow one RL contract from prompt to checkpoint. The mask matrix separates context from action tokens; centered rewards expose the zero-signal case before a remote update.

The pipeline clock

Tinker worker pools execute training clients in lock-step clock cycles. A cycle can include forward/backward work and an optimizer step for one or more LoRA models sharing the pool. Multi-tenancy keeps small batches from leaving the entire pool idle, but it also means a small request can observe latency shaped by the pool's schedule.[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/

The local future is a queueing tool. Submit work early, then await results after the requests have been admitted. The naive loop below often spans three cycles:

naive_clock_cycle.py
1fwd = await client.forward_backward_async(batch, "cross_entropy") 2await fwd.result_async() 3opt = await client.optim_step_async(adam_params) 4await opt.result_async()

The pipelined loop submits both operations before waiting:

pipelined_clock_cycle.py
1fwd = await client.forward_backward_async(batch, "cross_entropy") 2opt = await client.optim_step_async(adam_params) 3fwd_result = await fwd.result_async() 4opt_result = await opt.result_async()

The service can place both in one cycle because the training client preserves request order. For several batches, enqueue the next forward/backward plus optimizer pair before consuming the current result. The Cookbook's train_step uses this pattern and returns training log probabilities for diagnostics.[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/[3]Reference 3Tinker Cookbookhttps://github.com/thinking-machines-lab/tinker-cookbook/tree/0b5c01eaee49bdb0d476f4f383e1c0fb9aced590

Pipeline depth isn't free. A deeper queue can hide network latency and keep GPUs busy, but it can also increase the amount of local data waiting for a result and complicate failure handling. In RL, over-enqueueing samples can also increase policy lag. Keep a bounded number of in-flight groups and log the sampler checkpoint version against the trainer step.

Diagram showing Naive: miss cycles, Pipelined: share cycle, submit fwd/bwd cycle N, and wait result cycle N+1. Diagram showing Naive: miss cycles, Pipelined: share cycle, submit fwd/bwd cycle N, and wait result cycle N+1.
Naive: miss cycles, Pipelined: share cycle, submit fwd/bwd cycle N, and wait result cycle N+1.

The clock is not the same as GPU kernel overlap inside a model. A worker may overlap collective communication and matrix operations internally, while your client still misses a cycle by waiting before submitting the next request. Read both layers when tuning throughput.

Checkpoints and export paths

Tinker has three artifact states.

ArtifactPurposeRestores optimizer?Typical consumer
Training stateResume the same loopYes with load_state_with_optimizerTraining client
Sampler weightsEvaluate a chosen policy snapshotNot a training resumeSampling client, OpenAI-compatible adapter
Merged Hugging Face modelPortable base plus LoRA updateNo training historyvLLM, SGLang, Transformers, offline inference

The checkpoint name is part of your experiment schema. Include a run ID, step, dataset revision, and reward version in your own metadata even if the service accepts a shorter name. A checkpoint path says where the bytes are; it doesn't explain why that version should be trusted.

save_state can preserve a training resume point. save_weights_for_sampler makes a sampler path. save_weights_and_get_sampling_client combines save and client creation for a convenient evaluation step. The Cookbook's weights utilities download the adapter, build an HF model, build a PEFT adapter, or publish a checkpoint to a hub. Each export choice creates a new license and security review surface.[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/[3]Reference 3Tinker Cookbookhttps://github.com/thinking-machines-lab/tinker-cookbook/tree/0b5c01eaee49bdb0d476f4f383e1c0fb9aced590

Merging (W_0 + BA) turns an adapter into a standalone model directory. It doesn't make the base model license disappear. It also doesn't preserve the remote optimizer state. Keep the original tinker:// path and training metadata next to the exported model so a future evaluator can reproduce the exact adapter, base revision, tokenizer, and renderer.

Evaluation should use a fresh sampler client for the saved path or a path explicitly tied to the training client. Don't assume that a long-lived sampler automatically sees the latest adapter. A serving client built from an older path can produce plausible text from a stale policy and make a reward curve look flat.

API, service, and data boundaries

Both pinned source snapshots use Apache-2.0. That license lets you inspect, modify, and redistribute client and recipe code under its terms. It doesn't grant rights to Thinking Machines Lab's hosted service, third-party model weights, or every dataset copied into a recipe.[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed[3]Reference 3Tinker Cookbookhttps://github.com/thinking-machines-lab/tinker-cookbook/tree/0b5c01eaee49bdb0d476f4f383e1c0fb9aced590

The service terms describe Tinker as online services for hosting, training, fine-tuning, evaluating, storage, and related APIs. They distinguish customer datasets, hosted models, fine-tuned models, third-party model terms, and available weights. The service may add or remove model access, and third-party models remain subject to their own terms.[7]Reference 7Tinker Terms of Servicehttps://thinkingmachines.ai/legal/terms/

Your dataset is not automatically safe because the SDK serializes it. You are responsible for having the rights to send prompts, images, tool traces, and labels to a hosted service. The service terms grant the provider a limited license to access and process customer datasets to provide the service and comply with law. Personal-data deletion and export obligations depend on the applicable agreement and processing terms.[7]Reference 7Tinker Terms of Servicehttps://thinkingmachines.ai/legal/terms/

Keep secrets out of the dataset and logs. API keys belong in environment variables or a secret manager. Reward traces can contain private source code, credentials emitted by a tool, or user data. Redact before logging and set checkpoint retention explicitly. A sampler checkpoint can be as sensitive as the training data because the adapter may memorize rare examples.

Data residency, subprocess behavior, storage TTL, deletion, and enterprise commitments are product questions. Don't infer them from an open-source test or from a local tinker:// path. Ask the current service and agreement for the requirement your deployment needs.

Team, contributors, and governance

Tinker is built by Thinking Machines Lab. The company maintains the hosted service, SDK repository, Cookbook, documentation, model integrations, and customer-facing terms. The public repositories show the code and commit history, but a contributor count or a list of top contributors is only a snapshot. Use the pinned commit and the live repository history when attribution matters.

At review time, GitHub's contributor view for the SDK is led by danobi, andriigrynenko, dphuang2, and derek-tml. The Cookbook has a broader contributor set led by YujiaBao, joschu, nealwu, danobi, Tiiiger, and dphuang2. Treat that ordering as a live snapshot, not a governance hierarchy.[8]Reference 8Tinker Python SDK Contributorshttps://github.com/thinking-machines-lab/tinker/graphs/contributors[9]Reference 9Tinker Cookbook Contributorshttps://github.com/thinking-machines-lab/tinker-cookbook/graphs/contributors

The Cookbook's contribution guide asks contributors to run Ruff, Pyright, and tests, and describes an open-science workflow. Its code structure separates configuration builders from heavyweight datasets, environments, rollout strategies, and training loops. Those conventions are governance through code review and reproducibility rather than a formal foundation with independent technical steering.[3]Reference 3Tinker Cookbookhttps://github.com/thinking-machines-lab/tinker-cookbook/tree/0b5c01eaee49bdb0d476f4f383e1c0fb9aced590

QuestionEvidence to inspectSafe statement
Who owns hosted runtime?Thinking Machines Lab service terms and announcementsThinking Machines Lab operates the service
Who can change SDK code?GitHub repository permissions and review historyRepository maintainers and accepted contributors
What is licensed?LICENSE files at pinned commitsSDK and Cookbook source are Apache-2.0
Which models are available?Live capabilities and model docsCatalog is dynamic and model-specific
Who owns your data?Current service agreement and data processing addendum (DPA)Follow the contract, not an inference from GitHub

Don't call the SDK a community-governed replacement for the service. Its inspectable client and recipe layer depend on a company-operated API. That open-source boundary is valid, but it isn't the same governance model as a self-hosted distributed trainer.

Strengths

Low infrastructure burden

You can test a reward function, a custom loss, or an environment from a CPU-oriented development machine. Thinking Machines Lab handles scheduling, resource allocation, worker placement, and failure recovery for hosted runs. This turns the first experiment into a Python problem instead of a cluster bootstrap problem.[1]Reference 1Announcing Tinkerhttps://thinkingmachines.ai/news/announcing-tinker/

Low-level enough for research

forward_backward and sample expose the token and logprob evidence that many high-level trainers hide. You can implement GRPO-style relative rewards, PPO-like clipping, DPO data preparation, prompt distillation, or a custom logprob loss. The Cookbook provides a starting point without forcing every project into one environment abstraction.[1]Reference 1Announcing Tinkerhttps://thinkingmachines.ai/news/announcing-tinker/[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/

One path from SFT to RL

The same TrainingClient can run cross-entropy SFT and RL losses. The same SamplingClient can generate evaluation completions and behavior-policy traces. This reduces the number of adapters in a staged post-training project.

Large-model access without local replicas

LoRA lets a service share a frozen base model across training runs. The documented model range includes large dense and MoE models, and the general-availability announcement added Kimi K2 Thinking as a trillion-parameter example.[6]Reference 6Tinker General Availabilityhttps://thinkingmachines.ai/news/tinker-general-availability/[4]Reference 4Tinker Documentationhttps://tinker-docs.thinkingmachines.ai/ A researcher can test an idea on a small model, then check whether a large model is in the current catalog without rewriting the loop.

Portable artifacts

Sampler checkpoints can be evaluated through the SDK or an OpenAI-compatible interface. Cookbook utilities can download and merge adapters into Hugging Face layouts. You can move a successful experiment to an existing serving stack after validating tokenizer, license, and runtime compatibility.[6]Reference 6Tinker General Availabilityhttps://thinkingmachines.ai/news/tinker-general-availability/[3]Reference 3Tinker Cookbookhttps://github.com/thinking-machines-lab/tinker-cookbook/tree/0b5c01eaee49bdb0d476f4f383e1c0fb9aced590

Weaknesses and limits

Not full-parameter training

LoRA constrains the update space. A behavior that requires broad base-weight changes may not transfer, and a LoRA result doesn't answer full fine-tuning questions. If your research question is optimizer scaling, full-rank catastrophic forgetting, or expert-weight surgery, Tinker isn't the right primary system.

Hosted capacity and catalog are external state

Your code can be deterministic while service capacity, model availability, and scheduling latency change. A pinned SDK doesn't pin the remote runtime. Record capability responses and service metadata at run start.

Network latency shapes algorithm design

Every sample, grader, checkpoint, and training request crosses a boundary. A chatty environment can spend more time waiting on transport than grading. Batch prompts, use concurrency, and keep a bounded pipeline. API acceptance doesn't make secrets or high-cardinality debug payloads safe to send.

Staleness can accumulate silently

An RL sampler can continue using an older sampler checkpoint while training updates a newer adapter. A deep local queue can hide that mismatch. Include a policy version in each trajectory and reject or measure samples beyond your staleness budget.

Service terms still apply

An Apache-2.0 SDK doesn't turn a hosted run into a self-hosted run. Customer data, model weights, available checkpoints, and downstream use are governed by the current service agreement and third-party model licenses.[7]Reference 7Tinker Terms of Servicehttps://thinkingmachines.ai/legal/terms/

Failure recovery has a boundary

The service can recover worker failures, but your environment may not be idempotent. If a tool call charges money, mutates a repository, or sends a message, a retry can repeat the side effect. Give every external action an idempotency key and store a local trajectory receipt.

A runnable contract check

The following standard-library example doesn't call Tinker. It checks token alignment before a local adapter submits RL data. Its small scope fits a code review or preflight test.

check_tinker_rl_contract.py
1from dataclasses import dataclass 2 3@dataclass(frozen=True) 4class RLDatum: 5 input_tokens: tuple[int, ...] 6 target_tokens: tuple[int, ...] 7 sampled_logprobs: tuple[float, ...] 8 advantages: tuple[float, ...] 9 mask: tuple[float, ...] 10 11def validate(datum: RLDatum) -> None: 12 lengths = { 13 len(datum.input_tokens), 14 len(datum.target_tokens), 15 len(datum.sampled_logprobs), 16 len(datum.advantages), 17 len(datum.mask), 18 } 19 if len(lengths) != 1: 20 raise ValueError(f"unaligned lengths: {sorted(lengths)}") 21 if any(value not in (0.0, 1.0) for value in datum.mask): 22 raise ValueError("mask must contain only 0.0 or 1.0") 23 if any(mask == 0.0 and advantage != 0.0 for mask, advantage in zip(datum.mask, datum.advantages)): 24 raise ValueError("masked positions must have zero advantage") 25 26datum = RLDatum( 27 input_tokens=(10, 11, 12), 28 target_tokens=(11, 12, 13), 29 sampled_logprobs=(0.0, -0.4, -0.8), 30 advantages=(0.0, 0.0, 1.5), 31 mask=(0.0, 0.0, 1.0), 32) 33validate(datum) 34print("Tinker RL contract: valid")

Expected output:

text
1Tinker RL contract: valid

This check doesn't prove the reward is meaningful or that the model used the intended checkpoint. It catches shape and mask mistakes before a remote request spends GPU time.

Production failure modes

The happy path is short. Production debugging isn't. Start with the evidence closest to the token boundary.

SymptomLikely boundaryFirst checkDurable fix
Loss is NaNInput tensor or custom lossFinite target, weight, logprob, and advantage valuesReject non-finite rows before submission
Loss falls but reward doesn'tWrong target or reward alignmentDecode sampled tokens and inspect shifted targetsSave token-level fixture and renderer version
Reward is flat at zeroDegenerate groups or broken graderReward histogram and group varianceSkip constant groups and test verifier offline
Reward rises then collapsesStale policy or excessive updatePolicy version, Kullback-Leibler (KL) divergence, advantage scale, learning rateBound in-flight groups and tune update size
Requests are slow despite small dataMissed clock cyclesSubmission timestamps and cycle gapsSubmit forward/backward plus optimizer before await
Sample text doesn't changeStale sampler checkpointtinker:// path and save stepRebuild sampler client after save
Resume divergesOptimizer state omittedLoad method and checkpoint manifestUse load_state_with_optimizer for continuation
Exported model differsBase revision or tokenizer driftHash base files and tokenizer configPin base revision and preserve renderer metadata
Retry repeats external actionNon-idempotent environmentTool receipts and retry logsAdd idempotency keys and replay-safe adapters
API returns model unavailableCatalog or terms mismatchCapability response at run startFail fast with model and account evidence
Data appears in logsOver-broad telemetryRedacted request and artifact logsRemove secrets and set retention/TTL
Adapter loads but quality regressesUnsupported target modules or rankTraining-client config and evaluation matrixCompare rank and module scope explicitly

An actionable incident record contains the SDK commit, Cookbook commit, model identifier, capability response, base revision, tokenizer revision, renderer name, loss name and config, optimizer parameters, sampler checkpoint path, trajectory sample, reward components, and checkpoint path. Without those fields, a replay is guesswork.

Retry and idempotency

The SDK retries some transport failures through its client holder. A retry can be safe for a read, but a training request or external environment call needs a sequence contract. The pinned SDK assigns sequence IDs to training requests and preserves turn ordering across chunks. Your environment must add its own idempotency around side effects.[2]Reference 2Tinker Python SDKhttps://github.com/thinking-machines-lab/tinker/tree/3eb9e87d52efacede992931b1bb51d000b0c70ed

For evaluation, prefer pure functions and immutable fixtures. For a tool call, write a durable record before invoking the tool, then mark completion with the same operation ID. If the process crashes between those writes, replay can inspect the record instead of blindly repeating the action.

Catalog and model terms

A model string in a tutorial is not a production approval. The service can add or remove models. A third-party model can have a separate license, usage restriction, or attribution requirement. Query capabilities, retain the response, and link your run manifest to the model terms you accepted.[7]Reference 7Tinker Terms of Servicehttps://thinkingmachines.ai/legal/terms/

Source-reading map

Read the repositories in an order that follows one request instead of scanning every file.

SDK snapshot

  1. src/tinker/lib/public_interfaces/service_client.py: client creation, model capability calls, and the boundary between base and saved models.
  2. src/tinker/lib/public_interfaces/training_client.py: request sequencing, chunking, forward_backward, optim_step, save, and load behavior.
  3. src/tinker/lib/public_interfaces/sampling_client.py: sample, logprob options, multiprocessing, and sampler creation.
  4. src/tinker/types/datum.py: allowed tensor fields, shape checks, and serialization assumptions.
  5. src/tinker/proto/request_conv.py: how a Datum becomes a wire request.
  6. src/tinker/lib/api_future_impl.py: how remote completion and errors reach local code.
  7. src/tinker/resources/training.py and src/tinker/resources/sampling.py: HTTP endpoint names and response conversion.
  8. src/tinker/LICENSE and pyproject.toml: license, dependencies, and package identity.

The key path is TrainingClient._run_fwd_bwd to _take_turn to resources/training.py. That path explains why multiple chunks can be submitted concurrently while sequence IDs keep server order. The optimizer path uses the same turn counter. The sampler path is separate and can be created from a saved sampler checkpoint.

Cookbook snapshot

  1. tinker_cookbook/rl/types.py: Env, trajectories, transitions, stop reasons, and group notation.
  2. tinker_cookbook/rl/data_processing.py: advantage centering, trajectory splitting, masks, and datum assembly.
  3. tinker_cookbook/rl/train.py: clock-cycle pipeline, loss selection, training logprob diagnostics, and checkpoint hooks.
  4. tutorials/104_first_rl.py: the smallest readable GRPO-style loop.
  5. tutorials/103_async_patterns.py: concurrent sampling and group batching.
  6. tutorials/501_export_hf.py: adapter download, merge, and validation.
  7. CONTRIBUTING.md: builder conventions, async guidance, testing, and review expectations.
  8. LICENSE: Apache-2.0 grant for the cookbook source.

The source commits used here are 3eb9e87d52efacede992931b1bb51d000b0c70ed for tinker and 0b5c01eaee49bdb0d476f4f383e1c0fb9aced590 for tinker-cookbook. Future docs can change names, models, or supported losses. Pin the source before quoting line-level behavior.

Tinker versus DeepEP

Both projects matter for frontier-scale post-training, but they solve different problems.

DimensionTinkerDeepEP
Main jobHosted LoRA post-training API and recipe layerExpert-parallel communication library for MoE dispatch and combine
Primary userResearcher writing a local SFT or RL loopSystems engineer building a distributed MoE runtime
Compute ownershipThinking Machines Lab's managed workersYour cluster, accelerator fabric, and process groups
Core interfaceforward_backward, optim_step, sample, checkpointsDispatch/combine buffers, all-to-all transport, synchronization
Trainable stateLoRA adapter plus remote optimizer stateNo model-training policy or reward loop
RL abstractionRewards, trajectories, advantages, masks, loss namesNone. It moves expert tokens and gradients efficiently
Model supportService catalog and adapter integrationsRuntime and hardware constraints you configure
License boundaryApache-2.0 SDK/Cookbook plus hosted termsApache-2.0 source plus your infrastructure and model terms
Failure focusAPI retries, stale sampler, checkpoint, data and termsRank failure, collective hang, buffer capacity, network topology

DeepEP can sit below a self-hosted trainer that runs models like DeepSeek's MoE systems. It doesn't replace the RL loop. Tinker can help a researcher run a reward experiment on an available MoE model without assembling expert-parallel collectives. It doesn't expose DeepEP's dispatch buffers, RDMA tuning, or expert routing internals.

The projects complement each other in a curriculum. Tinker teaches the algorithm contract and service boundary. DeepEP teaches the communication contract that makes sparse expert training and inference fit a real cluster. Megatron or another distributed trainer connects both contracts into a full-parameter or adapter training runtime.

Don't benchmark them as alternatives. A hosted service's wall-clock latency and a communication kernel's tokens-per-second number answer different questions. Compare the total experiment cost and reproducibility boundary, not one operation's microbenchmark.

A practical reading exercise

Use a tiny deterministic task before trying a large model.

  1. Build one SFT datum with a prompt, target tokens, and response-only weights.
  2. Run one forward/backward call and print loss metrics.
  3. Submit optimizer and forward/backward requests together.
  4. Save a sampler checkpoint with a step name.
  5. Sample two completions from the saved path.
  6. Grade the completions with a pure function.
  7. Center rewards and inspect token-aligned advantages.
  8. Run the stdlib contract check above.
  9. Only then add asynchronous sampling or a real environment.

The exercise should produce a run manifest alongside reward numbers. Record the model identifier, rank, target modules, renderer, loss, optimizer settings, checkpoint path, sample tokens, reward list, group mean, and mask counts. A manifest lets another reader inspect every contract boundary; screenshots omit that evidence.

For a large model, scale one dimension at a time. Increase prompt length, group size, number of concurrent environments, adapter rank, or pipeline depth separately. A reward change after four simultaneous changes can't tell you which boundary moved.

Takeaways

  • Tinker is a Thinking Machines Lab managed hosted LoRA training and sampling service.
  • The SDK and Cookbook are Apache-2.0 source projects, not a self-hosted copy of the service.
  • forward_backward computes gradients, optim_step applies them, sample produces token evidence, and save_state creates a training recovery point.
  • RL correctness lives in token, target, logprob, advantage, and mask alignment.
  • Pipelining futures matters because the remote worker pool advances in clock cycles.
  • Sampler checkpoints and training checkpoints serve different consumers.
  • Model availability, data processing, third-party model terms, and retention require current service evidence.
  • DeepEP is complementary infrastructure for MoE communication, not an alternative to Tinker's RL API.

Mastery quiz

Complete the lesson

Mastery Check

Answer every question, then check your score. Score 75% or higher to mark this lesson complete.

1.What does Tinker manage that the Apache-2.0 SDK does not provide locally?
2.Which statement distinguishes Tinker from full-parameter training?
3.Why should an RL adapter preserve sampled token IDs and log probabilities?
4.What does a constant-reward GRPO group contribute?
5.Why submit forward_backward and optim_step before awaiting either result?
6.Which checkpoint should resume Adam moments?
7.Which statement about GLM-5.2 and DeepSeek-V4 support is safest?
8.What is DeepEP's responsibility compared with Tinker's?

8 questions remaining.

Next Step
Continue to Deep Dive - Light-PEFT

Tinker showed how a hosted service exposes LoRA updates, sampling, and checkpoints. Light-PEFT asks what compute PEFT still wastes, then learns which frozen backbone structures, adapter modules, and low-rank directions can be removed early.

PreviousDeep Dive - DeepEP
Share this article
XFacebookLinkedInBlueskyRedditHacker NewsEmail
References

Announcing Tinker

Thinking Machines Lab · 2025

Tinker Python SDK

Thinking Machines Lab · 2026

Tinker Cookbook

Thinking Machines Lab · 2026

Tinker Documentation

Thinking Machines Lab · 2026

LoRA Without Regret

Thinking Machines Lab · 2026

Tinker General Availability

Thinking Machines Lab · 2026

Tinker Terms of Service

Thinking Machines Lab · 2026

Tinker Python SDK Contributors

Tinker Contributors · 2026

Tinker Cookbook Contributors

Tinker Cookbook Contributors · 2026

Discussion

Questions and insights from fellow learners.

Discussion loads when you reach this section.