oxidizr

App Listed

Trains GPT-style language models from a YAML config and a tokenized dataset: dense GQA transformers, Mamba 1, 2 and 3, MLA and MoE layers on CPU or CUDA. Runs the training loop, optimizer, checkpoints, evaluation and metrics on boostr, and builds speech corpora through voxr.

Checked · Sources

Downloads
27
Dependents
Not applicable
Stars
8
Forks
3
Contributors
2
Commits
127
Latest release
0.1.1 ·

About

From the project README ·

LLM training framework in Rust. Train models from a YAML config with no Python.

Trains GPT-style language models from a YAML config and a tokenized dataset. Supports dense GQA transformers, Mamba1, Mamba2, Mamba3, MLA, and MoE layers on CPU or CUDA, built on boostr.

Docs · Crate · Config · CLI · Example · Contributing

What is oxidizr

oxidizr trains a language model from two inputs:

  1. A YAML config that defines the architecture, optimizer, and training schedule.
  2. A tokenized dataset stored as a binary file of u32 tokens.

oxidizr runs the training loop, optimizer, checkpointing, and metrics. It writes checkpoints as .safetensors files and packages them for distribution.

  • Language: training runs in Rust on boostr and numr. Training needs no Python. Only the optional push command uses Python tools, through the hf CLI.
  • Hardware: CPU, and NVIDIA GPUs through the cuda feature. Multi-GPU on one machine needs cuda,nccl.
  • Serve a trained model with blazr.
  • Not supported yet: FSDP, ZeRO sharding, tensor parallelism, pipeline parallelism, and training across machines. blazr cannot serve Gated DeltaNet layers yet.
Read the full README
LayerConfig keysNotes
Dense GQA transformerkv_heads, with kv_latent_dim unsetGrouped-query attention with RoPE and RMSNorm
MLA (Multi-Head Latent Attention)kv_latent_dim, q_latent_dim, d_ropeCompressed KV cache
Mamba1mamba_layers, with mamba2_num_heads unsetSelective state-space layers
Mamba2mamba_layers, mamba2_*State Space Duality (SSD)
Mamba3mamba3_enabled: true, mamba2_*Trapezoidal discretization. Optional mamba3_complex_rope, mamba3_mimo_rank
MoE (Mixture of Experts)num_experts, experts_per_tok, shared_expert_enabledTop-k routing with a load-balance loss
Gated DeltaNetgdn_layers, gdnQwen3.5 / Qwen3-Next linear attention. Mixes with Mamba and attention layers. blazr cannot serve it yet. Tested on CPU only

Layers mix within one model. mamba_layers lists the SSM layer indices, and every other layer uses attention.

Mamba2 and Mamba3 require hidden_size * mamba2_expand == mamba2_num_heads * mamba2_head_dim. For example, 384 * 2 == 48 * 16.

Installation

oxidizr needs a Rust toolchain. It fetches boostr from crates.io. Clone and build:

git clone https://github.com/ml-rust/oxidizr
cd oxidizr
cargo build --release

Add --features cuda to the build for GPU support. The CUDA build uses the toolkit installed on the system.

Quick Start

Build the project, download the educational dataset, and start training:

git clone https://github.com/ml-rust/oxidizr
cd oxidizr
cargo build --release

pip install huggingface_hub   # only to download this dataset
hf download fs90/nano-start-data-bin --local-dir data/nano-start/tokenized --repo-type dataset

cargo run --release -- train -f models/nano-start/nano-start.yaml -d data/nano-start/tokenized/combined.bin

The default build trains on CPU. Checkpoints for this config go to ./checkpoints/nano-start.

To train on a GPU, build and run with --features cuda:

cargo run --release --features cuda -- train -f models/nano-start/nano-start.yaml -d data/nano-start/tokenized/combined.bin

After training, package the model. See Model Distribution.

Bring Your Own Config and Data

Write a Config

A config has two top-level keys: model and trainer. This dense GQA example is a complete starting point:

# my-model.yaml
model:
  name: my-model
  hidden_size: 512
  num_layers: 8
  num_heads: 8
  kv_heads: 4              # Fewer KV heads than query heads (GQA)
  intermediate_size: 2048
  vocab_size: 100315
  tokenizer_vocab: cl100k_base   # Must match the tokenizer that produced the data
  max_seq_len: 512
  rope_theta: 10000.0

trainer:
  target_device: gpu
  learning_rate: 0.0003
  batch_size: 2
  gradient_accumulation: 1
  max_steps: 5000
  num_epochs: 2
  checkpoint_dir: "./checkpoints/my-model"
  log_interval: 10
  save_interval: 500
  max_checkpoints: 3
  load_balance_alpha: 0.0  # MoE auxiliary loss weight. Required. 0.0 disables it.

Run it:

cargo run --release -- train -f my-model.yaml -d data/my-dataset.bin

tokenizer_vocab is required. Set it to cl100k_base, o200k_base, llama3, deepseek_v3, or custom.

Key trainer fields:

FieldPurpose
learning_rate, batch_size, gradient_accumulationOptimizer step size and batch shape
max_steps, num_epochsTraining length
warmup_steps, lr_schedule, min_lr_ratioWarmup, then constant, cosine, linear or wsd decay. Logged rates are the rates each step applied
weight_decay, weight_decay_rule, no_decay_patternsAdamW decay coefficient, and the parameters it applies to. skip_1d (fresh-run default) skips norms, biases and SSM a_log/D. decay_all decays everything. skip_all decays nothing. A resume keeps the checkpoint's rule
checkpoint_dir, save_interval, max_checkpointsCheckpoint location, frequency, and retention (0 keeps all)
log_intervalSteps between metric updates. Each update reports tokens and tokens per second over every rank
metrics.peak_tflopsOne device's peak TFLOP/s. Set, the logs report MFU. Absent, no MFU
spike_guardLoss-spike guard: an EMA of the step loss over window steps. A loss z_threshold std above it after min_steps losses is a spike. action: skip skips its optimizer step, warn reports it. Absent, nothing changes
evalValidation on holdout_rows, holdout_fraction or a data_file, every interval steps over batches batches. early_stopping (patience, min_delta) stops the run cleanly. A new best writes the best checkpoint. Absent, nothing changes
target_devicegpu or cpu. The CLI --target-device overrides it
load_balance_alphaMoE load-balance loss weight

The full key reference is in docs/configuration.md.

Behavior changes that alter what an existing config trains:

  • MLA (kv_latent_dim) applies rope_scaling. It used to ignore it. A checkpoint trained before this change with kv_latent_dim and rope_scaling resumes with different rotary frequencies.
  • MLA refuses an explicit head_dim other than hidden_size / num_heads.
  • A fresh run with no weight_decay_rule uses skip_1d. A resume keeps the checkpoint's rule.

See Behavior Changes.

Sample Configs

Start from a file in models/. models/README.md describes each one. models/nano-start/nano-start.yaml is the educational hybrid model (Mamba2 + MLA + MoE).

Prepare the Data

oxidizr memory-maps a binary file of little-endian u32 tokens. The tokenizer must match model.tokenizer_vocab.

oxidizr tokenize writes that file from .txt and .jsonl inputs:

cargo run --release --features vocab-llama3 -- tokenize \
  -i data/raw -o data/my-dataset.bin --tokenizer llama3

A vocabulary name needs its vocab-* feature. A tokenizer.json path needs none. See Tokenization.

Pass the file with -d. Without -d, train generates 1,000,000 random tokens for a smoke test.

The oxidizr::data::create_dummy_data(vocab_size, total_tokens) function returns the same random tokens as a Vec<u32>.

CLI Reference

oxidizr <SUBCOMMAND> [OPTIONS]
SubcommandPurposeFeature
trainTrain a model. oxidizr -f <config> runs train without the subcommandnone
importConvert a HuggingFace checkpoint to an oxidizr checkpoint (-f, -m, -d, -o)none
mergeFold LoRA adapters into base weights (-f, -c, -o)none
packPackage a checkpoint for distributionnone
pushUpload a packaged model to the HuggingFace Hubhuggingface
prep-corpusBuild a packed speech-LM corpus from audio recordingsaudio

Common train flags:

FlagDefaultPurpose
-f, --config <FILE>models/nano.yamlYAML config
-d, --data <FILE>1,000,000 random tokensMemory-mapped u32 token file
--target-device <gpu|cpu>Config trainer.target_deviceDevice. A build without cuda runs on CPU
--batch-size, --seq-len, --grad-accum, --max-stepsConfigOverride the config value. --batch-size is the batch of one GPU
--resume <PATH|auto>NoneResume from a .safetensors checkpoint, or the latest one. Restores weights, optimizer state and data position
--gpus <IDS>Config trainer.distributed.gpu_ids, else the default GPUGPU ids, one data-parallel rank per id, for example 0,1. More than one id needs --features cuda,nccl
--sync-backend <single|cpu|nccl>Config trainer.distributed.backendGradient sync. NCCL is the only multi-GPU backend. cpu and an explicit single refuse more than one GPU
--prefetch <N>0Batches to prefetch on a background thread
--max-checkpoints <N>10Checkpoints to keep. 0 keeps all
--dtype <f32|f16|bf16>Config model.dtype (f32)Model precision
--checkpoint-dir <DIR>Config trainer.checkpoint_dirCheckpoint directory
--headlessOffPrint JSON metrics only. Use in CI, pipes, and non-interactive shells
--run-dir <DIR>$OXIDIZED_RUN_DIR, else ./runs/<timestamp>Directory for run.json, steps.json and evals.json

Every run writes run.json to its run directory when it ends, in both output modes. It records status (completed or failed), the error text of a failed run, the final step, the last loss, and start and end times. train exits with code 1 when the run failed. steps.json holds one JSON line per log interval and one for the first step of each session.

Without --headless, train shows a progress bar. Run oxidizr <SUBCOMMAND> --help for every flag. docs/cli.md documents each subcommand.

Model Distribution

Package a checkpoint, then upload it:

oxidizr pack --checkpoint latest      # Or: final, or a step number. Omit to pick interactively
cargo build --release --features huggingface
pip install huggingface_hub
oxidizr push --model hf/<username>/<model-name>

pack writes model.safetensors, config.json, and a generated README.md to hf/<username>/<model>/. It also copies training_config.json when the checkpoint has a run.json.

push runs the hf CLI, so hf must be on PATH. It accepts --private, -t, --token, and -y, --yes.

Put these values in a .env file, copied from .env.example:

HF_USERNAME=your-username
HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Get a token from the HuggingFace token page. See hf/README.md and docs/cli.md for the full flag list.

Multi-GPU Training

A build with --features cuda,nccl trains one model on several GPUs of one machine. This is data parallelism: every GPU holds a full replica.

cargo build --release --features cuda,nccl
./target/release/oxidizr train -f models/nano.yaml --gpus 0,1
  • --gpus 0,1 starts one rank per GPU, in one process. Rank i uses the i-th id. An id named twice is an error.
  • batch_size is the batch of one GPU. One optimizer step reads batch_size x GPUs x gradient_accumulation rows. Two GPUs at batch_size: 4 match one GPU at batch_size: 8 up to float rounding.
  • Each step sums the gradients of every GPU with one NCCL all-reduce. Every replica stays bit-equal.
  • Rank 0 alone prints, evaluates, and writes run.json, steps.json, evals.json and the checkpoints. Its early-stop decision reaches every rank.
  • A failure or panic on one GPU aborts the others. The run fails with the error of the rank that failed first.
  • The checkpoint meta records world_size. A resume needs the same GPU count. A checkpoint of another count is an error that names both counts.
  • --target-device cpu with more than one id is an error. A build without nccl refuses more than one id with the feature to add.

Not supported: FSDP, ZeRO sharding, tensor parallelism, pipeline parallelism, and more than one machine.

The CPU test suite runs every data-parallel path on in-process CPU ranks. The NCCL communicator, the NCCL abort, and the multi-GPU device setup are untested on real GPUs.

Tracking a Run

Each run keeps its own history in its run directory:

FileHolds
run.jsonOne record of the finished run
steps.jsonOne JSON object per log interval
evals.jsonOne JSON object per eval. Absent for a run without trainer.eval

A build with --features tensorboard also writes TensorBoard event files of the training and eval scalars. --headless prints JSON metrics to stdout. --resume continues a run from its weights, optimizer state and data position.

Features

FeatureDefaultEnables
f16OnF16 and BF16 dtypes
cudaOffCUDA backend (boostr CubeCL), and GPU memory per process from NVML, loaded at run time
tensorboardOffTensorBoard event files of the training and eval scalars in the run directory
ncclOffMulti-GPU data parallelism over NCCL. Implies cuda
huggingfaceOffpush command
audioOffprep-corpus command, with the voxr corpus pipeline and the Whisper, NeuCodec, and Silero VAD models
vocab-<name>OffBundled tokenizer vocabulary for tokenize --tokenizer <name> and prep-corpus --tokenizer <name>
vocabsOffEvery bundled vocabulary

Bundled vocabulary names: cl100k, o200k, gpt-oss, phi4, olmo2, llama3, llama2, deepseek, qwen, glm, gemma2, gemma3, gemma4, kimi, mistral, modernbert.

Example: cargo build --release --features cuda,huggingface.

Development

See CONTRIBUTING.md for build, test, and lint commands, and the project layout.

Documentation: docs/README.md indexes the guides. docs/configuration.md is the config reference. docs/cli.md is the CLI reference. docs/architecture/overview.md describes the design.

Citation

@software{oxidizr,
  author = {Farhan Syah},
  title = {oxidizr: A Rust-based LLM training framework},
  year = {2025},
  url = {https://github.com/ml-rust/oxidizr}
}

Contributing

Contributions are welcome. See CONTRIBUTING.md for conventions and checks.

Questions and design discussion happen on Discord.

License

Licensed under Apache-2.0. See LICENSE.

Runs on
CUDA
What shows it
  • CUDA: oxidizr feature cuda
Native code
Optional
  • Binds native code: nvml-wrapper-sys (feature cuda)
Python bindings
No Python binding crate found
License
Apache-2.0

Compare with similar projects

Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days.

oxidizr beside the projects that share a topic with it
ProjectDownloadsDependentsStarsLatest releaseRuns on (GPU)Native codeLicense
oxidizr This page App Listed

Trains GPT-style language models from a YAML config and a tokenized dataset: dense GQA transformers, Mamba 1, 2 and 3, MLA and MoE layers on CPU or CUDA. Runs the training loop, optimizer, checkpoints, evaluation and metrics on boostr, and builds speech corpora through voxr.

27 downloads over 30 days Not applicable 8 0.1.1 CUDA Binds native code: nvml-wrapper-sys (feature cuda) Apache-2.0
boostr Listed

ML framework on numr for training and inference on CPU, CUDA and WebGPU: attention, quantization, inference scheduling and distributed execution. Models include LLaMA, Mamba2, Qwen3.5, Whisper, Kokoro, VITS, VoxCPM2, Silero VAD, CLAP and super-resolution. Loads SafeTensors and GGUF.

1,265 downloads over 30 days 7 20 0.11.2 CUDA, WebGPU Binds native code: ring (feature distributed) Apache-2.0
web-rwkv Listed

An implementation of the RWKV language model in pure WebGPU.

444 downloads over 30 days 3 360 0.10.20 WebGPU Binds native code: tracy-client-sys (feature trace) Apache-2.0 OR MIT
rustyml Listed

Machine learning models, neural networks, metrics, and data utilities in Rust

59 downloads over 30 days 0 345 0.17.0 GPU support unknown No native code found MIT
rust-lstm Listed

A complete LSTM neural network library with training capabilities, multiple optimizers, and peephole variants.

15 downloads over 30 days 0 24 0.10.0 GPU support unknown No native code found MIT
RustTensor App Listed Dormant

A learning-focused, high-performance tensor computation library built from scratch in Rust, featuring automatic differentiation and CPU/CUDA backends.

Not measured Not applicable 79 Not measured Not measured Not measured MIT
Why ListedNo archive, New or Featured rule places it, so it is Listed.

What it lacks for Featured

  • The check holds no value for Homebrew installs on request over 365 days, Repology repository families, Docker pull growth over 90 days. A gate that lacks its signal does not pass.

What else the check found

  • The last activity is on 6 Nov 2026, 3 days ago. The rules expect an update within 365 days. Dormancy rule

Not measured: Homebrew installs on request over 365 days, Repology repository families, Docker pull growth over 90 days.

Check notes

  • the latest release was packaged from a dirty working tree

Exact rules: Listed, Featured app. The check on applied thresholds version 9.

Every rule outcome, as the check records it
  • expected-interval: app: E = 365 days
  • dormancy: last activity 2026-11-06, 3 days ago, E = 365: active
  • featured: not featured: unknown homebrew_on_request_365d, repology_families, docker_pull_growth_90d
  • listed: listed: no archive, new or featured rule applies

Measurements and sources

Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.

Sources6 sources
Adoption0 binary downloads per release4 not measured
Adoption measurements
SignalValueSourceFetchedCounts
Active dependentsNot measuredYes
New dependents (365 days)Not measuredYes
Peak active dependentsNot measuredYes
Active dependents as a share of the peakNot measuredYes
Binary downloads per release0GitHub releasesYes
MaintenanceLatest human commit: 3 days ago4 not measured
Maintenance measurements
SignalValueSourceFetchedCounts
Latest human commit2026-11-06GitHub repositoryYes
Latest release2026-11-06GitHub releasesYes
First release2025-12-04crates.io database dumpYes
Latest version0.1.1crates.io database dumpNo
Days the oldest outside issue waits for a reply0GitHub repositoryYes
Maintainer replies over 365 days0GitHub repositoryYes
Repository archivedfalseGitHub repositoryYes
Repository gonefalseGitHub repositoryYes
Release commit or manifest in the repotruecrates.io packageNo
Published docsNot measuredYes
Latest release fails cargo checkNot measuredYes
Build check dateNot measuredYes
Build check toolchainNot measuredYes
SecurityNot measured
Security measurements
SignalValueSourceFetchedCounts
Unpatched vulnerabilities past the grace windowNot measuredYes
RustSec unmaintained advisoryNot measuredYes
Deprecation noticeNot measuredYes
Deprecated requirementNot measuredYes
Distribution3 releases, 27 downloads over 30 days6 not measured
Distribution measurements
SignalValueSourceFetchedCounts
Releases3crates.io database dumpNo
Downloads over 30 days27crates.io database dumpNo
Binary downloads over the last 3 releases0GitHub releasesYes
Homebrew installs on request over 365 daysNot measuredYes
Repology repository familiesNot measuredYes
Docker pull growth over 90 daysNot measuredYes
Docker pulls at the growth baselineNot measuredYes
Every version a prereleasefalsecrates.io database dumpYes
Every version 0.0.xfalsecrates.io database dumpYes
Every version yankedNot measuredYes
Crate deleted from crates.ioNot measuredYes
Repository8 stars, 3 forks, 2 contributors, 127 commits. Stars alone never qualify a project.
Repository measurements
SignalValueSourceFetchedCounts
GitHub stars8GitHub repositoryYes — one part of the repository route
GitHub forks3GitHub repositoryYes — one part of the repository route
Contributors with a GitHub account2GitHub contributorsYes — one part of the repository route
Commits on the default branch127GitHub repositoryNo
Repository's main crate left out of the entrynonecrates.io database dumpYes
Facts that never count
Facts that never count measurements
SignalValueSourceFetchedCounts
LicenseApache-2.0crates.io database dumpNo
Runs on, from listed crates and their direct dependenciesCUDAcrates.io database dumpNo
What shows each backendCUDA: oxidizr feature cudacrates.io database dumpNo
Native code, from listed crates and their dependenciesBinds native code: nvml-wrapper-sys (feature cuda)crates.io database dumpNo
Python bindings, from direct dependencies of listed cratesNo Python binding crate foundcrates.io database dumpNo
Crates that depend on a listed crate directlyNot measuredNo

Corrections and review history

Report a correction

No correction applies to this entry.

Judgments

A judgment enters only through an approved issue and a merged pull request.

No judgment applies to this entry.