unsloth/scripts
Daniel Han ab37acd5e0 flex: fair comparison -- benchmark LoRA active, not merged
Previous bf16 + LoRA rank 32 runs called `peft_model.merge_and_unload()`,
which bakes LoRA into the base weights and destroys the adapter. Every
subsequent forward is then plain bf16 with no LoRA-active cost -- one
matmul per projection. vLLM's LoRARequest path keeps LoRA dynamic (base
matmul + rank-r adapter matmuls + add), which is what GRPO actually needs
because the adapter has to be updateable between rollouts and training
steps.

Adds `--no_merge_lora` flag and runs the honest comparison:

| Backend                        | tok/s best | vs vLLM |
|--------------------------------|-----------:|--------:|
| vLLM (LoRARequest)             |       7775 |   100 % |
| flex -- LoRA merged (prior)    |       5744 |    74 % |
| flex -- LoRA active (no merge) |       2683 |    35 % |

The 74 % number in the earlier writeup was only meaningful if you can eat
the merge/unmerge cost between rollouts and training steps (which is not
free). The real flex-vs-vLLM gap under GRPO semantics is ~35 %, not 72 %.

vLLM wins its dynamic-LoRA number via Punica-style fused kernels that
avoid the extra matmul roundtrip. flex has no equivalent and runs
base + LoRA_A + LoRA_B as three separate matmuls per projection.

Writeup updated.
2026-04-21 02:22:48 +00:00
..
benchmarks flex: fair comparison -- benchmark LoRA active, not merged 2026-04-21 02:22:48 +00:00
enforce_kwargs_spacing.py Formatting & bug fixes (#3563) 2025-11-07 06:00:22 -08:00
install_gemma4_mlx.sh Move gemma4 script (#4994) 2026-04-12 23:41:15 -07:00
install_qwen3_6_mlx.sh Add qwen3.6 script (#5084) 2026-04-17 01:21:30 -07:00
run_ruff_format.py Formatting & bug fixes (#3563) 2025-11-07 06:00:22 -08:00