Quick start
vllm serve google/gemma-4-31B-it \ --enable-lora --lora-modules bandcentral=ai-and/termgrade-gemma4-31b-lora \ --max-lora-rank 32 --max-model-len 262144 \ --reasoning-parser gemma4 --tool-call-parser gemma4 --enable-auto-tool-choice \ --tensor-parallel-size 8 --trust-remote-code
Two settings that matter. Serve at 262144 context: at 128K, long agentic rollouts get
cut off and fail to parse, which costs roughly 10 points. And use the native gemma4 parser;
a qwen3_coder-style text parser costs roughly 20 points here.
Results
Table with columns: Terminal-Bench 2.1, vs base | Terminal-Bench 2.1 | vs base |
|---|
| this adapter | 46.1 | +3.1 |
gemma-4-31B-it base † | 43.0 | |
46.1 is the mean of seven evaluation runs on this checkpoint (four on the adapter, three on
the merged weights), at three attempts per task each, so 21 attempts per task.
Across five training runs
We trained the identical recipe five times end to end and evaluated every result:
Table with columns: mean, spread, all above base? | mean | spread | all above base? |
|---|
| five runs | 45.1 (+2.1) | 43.4–46.3, SD 1.2, SE 0.6 | yes |
t = 3.8 on four degrees of freedom, p ≈ 0.025. +2.1 is the mean of the five runs; +3.1 is this
particular checkpoint, which sits at the top of the range. There is no fixed random seed, so the
five are independent replicates of one configuration.
† 43.0 is Artificial Analysis' published figure.
Our own reproduction of the base came out at 42.7; we quote against 43.0 because using ours
would inflate every gain by 0.3. Their number is one three-repeat evaluation.
Training
GRPO++, which is GRPO with the DAPO modifications plus Dr.GRPO's advantage handling:
- No KL term, in the reward or as a loss
- Clip-Higher, asymmetric at 0.2 / 0.28
- Token-mean loss aggregation
- No std normalisation of advantages (mean-centre only)
- Dynamic sampling:
filter_groups drops zero-variance groups, up to 10 generation batches
- Fully on-policy: batch 16 = mini-batch 16, one update per step, 16 rollouts at temperature 0.6
- LoRA rank 32, alpha 64, all-linear · lr 1e-5 constant · binary reward · 5 updates ≈ one epoch
- Trained in a bash tool-calling scaffold, evaluated under Terminus-2, so the result
includes transfer across scaffolds
Seven hours on one 8×H200 node: roughly four training, three validating. Full configuration in training_config.yaml.
Limitations
One benchmark, five runs. We report the five-run average as the method's result rather than
this checkpoint's score.
The gain is uneven: it lands on long-horizon tasks where the base model used to run out
of turns, and is flat where it already finished.
A bigger training set didn't help. A corpus nearly five times the size, with the same base
and hyperparameters, landed within noise of this one. That matches the gradient-weight curve,
since p(1−p) is flat across the middle of its range.
Citation
If you use TermGrade, please cite:
@misc{calik2026termgrade, title = {{TermGrade}: 1k Graded Terminal Environments, 36k Trajectories, and the {RL} Run They Trained}, author = {Calik, Yagiz and Wu, Jianbo and Hara, Shimpei}, year = {2026}, month = oct, howpublished = {\url{https://www.aiand.com/newsroom/termgrade}}, note = {ai\& Research blog post}}