PyTorch training for Hermes LLMs (MAL-defined models, safetensors checkpoints served by hermes-llm)
Project description
hermes-train
PyTorch training for Hermes LLMs. Architectures are defined in MAL (the Rust-side
DSL in hermes-llm); this package trains them and emits safetensors checkpoints
that hermes-llm serves directly — the tensor naming contract is shared
(embedding.*, layers.{i}.attention.*, layers.{i}.feed_forward.*,
final_norm.*, lm_head.*).
Pipeline
# 1. Export the architecture from MAL (Rust side owns the parser)
hermes-llm export --model tiny --output config.json # preset
hermes-llm export --model my_model.mal --output config.json # or MAL file
# 2. Train a BPE tokenizer (optional — any HF tokenizer.json works)
hermes-train train-tokenizer --input data.jsonl --output tokenizer.json --vocab-size 32000
# 3. Train (bf16, Muon+AdamW, grad accumulation, resumable)
hermes-train train --config config.json --tokenizer tokenizer.json \
--data data.jsonl.zst --output checkpoints --batch-size 32 --epochs 1
# multi-GPU: same command under torchrun
torchrun --nproc-per-node 8 -m hermes_train.cli train --config config.json ...
# 4. DPO fine-tuning
hermes-train dpo --config config.json --tokenizer tokenizer.json \
--data prefs.jsonl --checkpoint checkpoints/weights.safetensors --output checkpoints-dpo
# 5. Serve with the Rust side
hermes-llm generate --checkpoint checkpoints/weights.safetensors \
--config config.json --tokenizer tokenizer.json --prompt "hello"
Training stack
- Precision: bf16 autocast with fp32 master weights (fp32 fallback on CPU/MPS)
- Optimizer: Muon (Newton–Schulz orthogonalized momentum) for 2D weight matrices, AdamW for embeddings/norms/head — the hybrid scheme used by Kimi K2 / GLM-scale runs
- Schedule: WSD (warmup–stable–decay, the 2026 default) or cosine via
--schedule; the flat plateau makes run extension and curricula sane - Data: JSONL with a
textfield;.gz/.zstsupported; documents are tokenized, EOS-joined and packed into fixed windows - Document masking (default on): attention is block-diagonal across
packed-document boundaries, SSM recurrent state resets at doc starts, and
the reference path uses a segment-aware causal conv — doc 2 is provably
independent of doc 1 (tested). The fused CUDA kernel (Mamba-1) has no
seq_idx, so under the fused path SSM state crosses boundaries (warned once); attention layers still mask correctly.--no-doc-maskingdisables. - Curriculum stages: repeat
-d— each file trains sequentially under one LR schedule, so with WSD the decay lands on your final (highest-quality / task-specific) stage - QK-Norm:
qk_norm: truein a MAL attention def adds per-head RMSNorm on Q/K before RoPE (OLMo2/Gemma-style stabilizer); tensorslayers.{i}.attention.{q,k}_norm.weightin both engines - Checkpoints:
weights.safetensors(Candle-compatible names) +training_state.json; Ctrl+C saves and exits,--resumecontinues - Distributed: DDP via
torchrun(gradient sync); FSDP is a planned upgrade
Hybrid Transformer + Mamba
MAL expresses heterogeneous layer stacks: blocks whose mixer is a Mamba-1
selective SSM instead of attention, cycled via pattern::
ssm my_ssm { state_dim: 16, conv_kernel: 4, expand: 2 }
block mamba_block { ssm: my_ssm, ffn: my_ffn, norm: rmsnorm { eps: 1e-5 } }
model hybrid { ..., pattern: [mamba_block, mamba_block, attn_block] }
The Mamba state is a compact persistent memory (fixed size, O(1)/token);
the attention layers provide exact retrieval. Training uses a reference fp32
scan by default; install the mamba extra (uv sync --extra mamba, CUDA
only) and the fused selective_scan_fn kernel is used automatically on CUDA.
SSM tensors live under layers.{i}.ssm.* (mamba-ssm naming) and load
directly into hermes-llm generate, which serves incrementally: prompt
prefill once, then one step per token (Mamba recurrent state + attention KV
cache — no full recompute).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hermes_train-1.8.56.tar.gz.
File metadata
- Download URL: hermes_train-1.8.56.tar.gz
- Upload date:
- Size: 101.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
977c140e8b2b6221405d08320e1a0299d4a311b3f7eb8f3ec0f0095ddec27d21
|
|
| MD5 |
a50a79614efc5a7778423cb32cedffb0
|
|
| BLAKE2b-256 |
0f53778ae45ca2cf5276cec130218164a023b92018436da84b74711ab413dada
|
File details
Details for the file hermes_train-1.8.56-py3-none-any.whl.
File metadata
- Download URL: hermes_train-1.8.56-py3-none-any.whl
- Upload date:
- Size: 25.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c10e036bc499ba00b8694ba2ff242d018677dd53f709fa3e4c14b4e8d6d5768
|
|
| MD5 |
0795348ce7075b9128ba46c6b723e713
|
|
| BLAKE2b-256 |
67df0dd42732157de38da6b616fb8ba13df9af9a2beee8e61e9e8018a48412fb
|