LoRA Adapter
This recipe demonstrates the real MinT LoRA checkpoint workflow:
- Create a LoRA
TrainingClient. - Run one or more SFT steps with
forward_backward(..., loss_fn="cross_entropy"). - Save training state with
save_state(). - Save sampler weights with
save_weights_for_sampler(). - Create a
SamplingClientfrom the saved sampler weights and sample from it.
It does not export PEFT files or vLLM-ready local weights. There is no export_lora_to_peft() API in this recipe.
Use Case
- Checkpoint verification: Confirm a trained LoRA adapter can be saved and sampled.
- Short training demo: Run a minimal SFT step and inspect the saved checkpoint paths.
- MinT deployment path: Use MinT sampler weights through
create_sampling_client(). - API sanity check: Verify
save_state()andsave_weights_for_sampler()work for your account and model.
Core Training Step
The recipe builds a tiny arithmetic SFT batch and trains with the low-level TrainingClient API:
training_client = service_client.create_lora_training_client(
base_model="Qwen/Qwen3-0.6B",
rank=16,
train_mlp=True,
train_attn=True,
train_unembed=True,
)
tokenizer = training_client.get_tokenizer()
data = [process_sft_example(example, tokenizer) for example in generate_sft_examples()]
for step in range(1, SFT_STEPS + 1):
fb_result = training_client.forward_backward(
data,
loss_fn="cross_entropy",
).result()
loss = compute_cross_entropy(fb_result, data)
training_client.optim_step(types.AdamParams(learning_rate=5e-5)).result()
print(f"Step {step}: train_cross_entropy={loss:.6f}")Save Checkpoints
Two save APIs are shown:
state_checkpoint = training_client.save_state(
name="lora-adapter-state"
).result()
sampler_checkpoint = training_client.save_weights_for_sampler(
name="lora-adapter-sampler"
).result()The difference:
| API | Purpose |
|---|---|
save_state() | Saves training state. Use it for resume or inspection. |
save_weights_for_sampler() | Saves weights in a form that can be used by SamplingClient. |
Sample from Saved Weights
sampling_client = service_client.create_sampling_client(
model_path=sampler_checkpoint.path,
base_model="Qwen/Qwen3-0.6B",
)
result = sampling_client.sample(
prompt=types.ModelInput.from_ints(tokens=prompt_tokens),
num_samples=1,
sampling_params=types.SamplingParams(max_tokens=32, temperature=0.0),
).result()
response = tokenizer.decode(result.sequences[0].tokens).strip()View full source: https://github.com/MindLab-Research/mint-quickstart/blob/main/recipes/lora_adapter.py
Verified Run
Verified on MinT with Qwen/Qwen3-0.6B, one SFT step:
Step 1: train_cross_entropy=6.009224
State checkpoint: tinker://1cbd1a15-dc76-4c63-8683-e8df2a46a45c_0/weights/lora-adapter-state
Sampler weights: tinker://1cbd1a15-dc76-4c63-8683-e8df2a46a45c_0/sampler_weights/lora-adapter-sampler
Sampling from saved weights: successExample sample:
Prompt: Question: What is 4 + 5?
Answer:
Response: 9This recipe verifies MinT checkpoint and sampling APIs. If you need local PEFT/vLLM export, use a separate documented weight-export path once available; do not assume a fake export_lora_to_peft() API exists.
Why This Shape Works
TrainingClient
│ forward_backward(cross_entropy) + optim_step
▼
LoRA adapter state
├─ save_state() ───────────────▶ training/resume checkpoint
└─ save_weights_for_sampler() ─▶ sampler checkpoint
│
▼
create_sampling_client()
│
▼
sample()This is the minimal real checkpoint lifecycle for MinT LoRA adapters.