Training¶
mixturekit train fine-tunes a merged model with trl’s SFTTrainer. By default the experts
are frozen and only the routers (BTX, traditional) or the stitch layers (BTS) are
trained. With use_lora: true, LoRA adapters are also trained on the projections listed in
target_modules (by default q_proj, k_proj, v_proj and o_proj).
pip install "mixturekit[train]"
mixturekit train config_training.yaml
Data¶
A datasets table saved with save_to_disk(), with a messages column: a list of chat
turns {"role": ..., "content": ...}.
Configuration¶
Start from
mixture_training/config_training.yaml.
The keys are the ones of trl’s SFTConfig, plus the ones below.
Important
The templates of this file are Gemma’s. For Qwen, use response_template: "<|im_start|>assistant\n"
and instruction_template: "<|im_start|>user\n", or remove both. Routers alone usually need a
much larger learning rate than its 3.0e-6, e.g. 1e-4 to 1e-3.
Key |
Meaning |
|---|---|
|
The merged model, a directory or a Hub id |
|
The dataset of the previous step |
|
Where to save the trained model (or the LoRA adapters) |
|
|
|
Compute the loss on the responses only; remove both to train on whole sequences |
|
Used when the tokenizer has none |
|
Maximum sequence length |
The method is read from the merged model. The load balancing loss, weighted by the alpha of
the merged model, is added to the loss.
Several GPUs¶
accelerate launch --config_file mixture_training/deepspeed_config.yaml \
-m MixtureKit.train mixture_training/config_training.yaml
Set num_processes in deepspeed_config.yaml to the number of GPUs.
Output¶
The trained model is saved to output_dir with its modeling files, so it loads, trains
again and uploads like the merged model. With LoRA, merge the adapters into the model:
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
from MixtureKit.training import mark_trained
base = AutoModelForCausalLM.from_pretrained("models_merge/qwen3moe2x", trust_remote_code=True)
model = PeftModel.from_pretrained(base, output_dir).merge_and_unload()
model.save_pretrained("trained")
AutoTokenizer.from_pretrained(output_dir).save_pretrained("trained")
mark_trained("trained") # the model card then says the routers are trained
Your own training loop¶
A merged model is a transformers model: any trainer works. In training mode its outputs.loss
already includes the load balancing loss weighted by alpha. To change the weight:
model.set_load_balancing_alpha(0.02)
If a trainer computes the loss itself instead of using outputs.loss (e.g. trl 1.x with
compute_loss_func unset and its fused loss), pass it
compute_loss_func=MixtureKit.training.moe_loss_function(model); with trl, also set
loss_type="nll" in its SFTConfig (its default chunked loss bypasses the model outputs).
Note
trl 1.15 and later need Triton, available on Linux. On macOS, use an earlier trl version or your own training loop.