Connect to WiFi. Train large language models.
A clean Python SDK for model training, inference, and post-training experiments.
✨ What is PyTRIO?
PyTRIO lets you focus on the parts of post-training that matter—your data and algorithms—while the engine handles distributed execution, scheduling, fault tolerance, and GPU infrastructure.
Write your training loop on a CPU machine, choose a base model with one string, and keep full control of your loss function, optimizer, rollout strategy, and experiment logic.
- 🧪 Built for post-training: Run SFT, RL, preference optimization, and custom objectives
- ⚡ Async research: Keep working locally while training runs remotely
- 🚀 Managed scale: Train across GPUs without managing CUDA or clusters
- 🔁 Fast iteration: Sample fresh weights, checkpoint, and resume anytime
- 🔌 Application ready: Serve trained weights through OpenAI-compatible APIs
🚀 Train, then sample
Install the SDK and sign in with an API key from the Trio console:
pip install pytrio
trio login
The same training client can update LoRA weights and turn the latest policy into a sampler immediately:
import pytrio as trio
# Connect to the PyTRIO training engine.
service = trio.ServiceClient()
trainer = service.create_lora_training_client(
base_model="Qwen/Qwen3.5-4B",
rank=32,
)
tokenizer = trainer.get_tokenizer()
# Prepare one supervised training example.
tokens = tokenizer.encode(
"Question: what is Trio?\nAnswer: a model training platform."
)
batch = [
trio.Datum(
model_input=trio.ModelInput.from_ints(tokens[:-1]),
loss_fn_inputs={
"target_tokens": tokens[1:],
"weights": [1.0] * (len(tokens) - 1),
},
)
]
# Every step of the training loop stays in your hands.
for step in range(10):
trainer.forward_backward(batch, "cross_entropy").result()
trainer.optim_step(trio.AdamParams(learning_rate=1e-4)).result()
# Save the latest policy and sample from it immediately.
sampler = trainer.save_weights_and_get_sampling_client()
prompt_tokens = tokenizer.encode("Question: what is Trio?\nAnswer:")
result = sampler.sample(
prompt=trio.ModelInput.from_ints(prompt_tokens),
sampling_params=trio.SamplingParams(max_tokens=32, temperature=0.0),
num_samples=1,
).result()
print(result.sequences[0].text)
🎲 Rollouts in, policy updates out
PyTRIO keeps rollout generation and policy updates in one workflow. Sample multiple trajectories from the latest policy, score them with your reward function, then train directly from their tokens and logprobs:
question = "What is 6 * 8?"
prompt_tokens = tokenizer.encode(
f"Question: {question}\nReturn only the final numeric answer.\nAnswer:"
)
# Generate a group of rollouts from the latest policy.
rollouts = sampler.sample(
prompt=trio.ModelInput.from_ints(prompt_tokens),
sampling_params=trio.SamplingParams(max_tokens=8, temperature=0.7),
num_samples=4,
).result()
training_data = []
for sequence in rollouts.sequences:
reward = 2.0 if sequence.text.strip() == "48" else -1.0
completion_tokens = list(sequence.tokens)
tokens = prompt_tokens + completion_tokens
old_logprobs = (
[0.0] * len(prompt_tokens)
+ [0.0 if value is None else float(value) for value in sequence.logprobs]
)
advantages = [0.0] * len(prompt_tokens) + [reward] * len(completion_tokens)
training_data.append(
trio.Datum(
model_input=trio.ModelInput.from_ints(tokens[:-1]),
loss_fn_inputs={
"target_tokens": tokens[1:],
"logprobs": old_logprobs[1:],
"advantages": advantages[1:],
},
)
)
# Update the policy from rewarded rollouts.
trainer.forward_backward(
training_data,
loss_fn="importance_sampling",
).result()
trainer.optim_step(
trio.AdamParams(learning_rate=1e-5),
).result()
Refresh the sampler from the latest weights on every iteration to build an on-policy loop. The same primitives support SFT, PPO-style objectives, custom losses, checkpointing, and evaluation without hiding the algorithm behind a black box.
🧭 API primitives
| Goal | Start here |
|---|---|
| Connect to the training engine | trio.ServiceClient |
| Create and update a LoRA policy | trio.TrainingClient |
| Generate rollouts or compute logprobs | trio.SamplingClient |
| Define token, text, or image input | trio.ModelInput |
| Control rollout generation | trio.SamplingParams |
| Save, resume, and download checkpoints | trio.RestClient |
🔌 OpenAI-compatible inference
Move a trained policy into an application with a model identifier and the standard OpenAI client:
from openai import OpenAI
client = OpenAI(
base_url="https://pytrio.com/api/openai/v1",
api_key="TRIO_API_KEY",
)
response = client.chat.completions.create(
model="trio://your-model/your-version",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
Metadata
Release files for pytrio 0.2.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytrio-0.2.9.tar.gz | 136.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytrio-0.2.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 336.7 kB
Release files / pytrio-0.2.9.tar.gz
| Download URL | pytrio-0.2.9.tar.gz |
|---|---|
| Size | 136.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
109cfd84b2becb72ac358ef5d498c5084917f252f1889362b2d5e74f13b2d88a
|
|
BLAKE2b-256 checksum How to use checksums |
e3f9d433947fd980dd50288982f9ae9313f8833634ce68c24be49d5c5218c860
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.
Transparency logRelease files / pytrio-0.2.9-py3-none-any.whl
| Download URL | pytrio-0.2.9-py3-none-any.whl |
|---|---|
| Size | 200.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
09eb49535afd3fcf16b25643896224b77ca291e80552275c6693e348e4be3737
|
|
BLAKE2b-256 checksum How to use checksums |
a2327a319f0c826a83c4663b6c834f0543835b3c1c88d32b38c6b7274f8345eb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.
Transparency log