Instructions to use dexmac/doomgemma-e2b-lora with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use dexmac/doomgemma-e2b-lora with PEFT:
Task type is invalid.
- Laya
How to use dexmac/doomgemma-e2b-lora with Laya:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
LoRA adapter, model card and training history
Browse files- README.md +110 -0
- adapter_config.json +46 -0
- adapter_model.safetensors +3 -0
- best_epoch.json +7 -0
- training_history.json +33 -0
README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: gemma
|
| 3 |
+
base_model: google/gemma-4-E2B-it
|
| 4 |
+
library_name: peft
|
| 5 |
+
tags:
|
| 6 |
+
- lora
|
| 7 |
+
- peft
|
| 8 |
+
- doom
|
| 9 |
+
- vizdoom
|
| 10 |
+
- freedoom
|
| 11 |
+
- decision-model
|
| 12 |
+
- system-one
|
| 13 |
+
- laya
|
| 14 |
+
- gemma
|
| 15 |
+
language:
|
| 16 |
+
- en
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
# doomGemma — Gemma 4 E2B LoRA for doomLaya decisions
|
| 20 |
+
|
| 21 |
+
A LoRA adapter that turns **Gemma 4 E2B** into a typed decision model for the
|
| 22 |
+
[doomLaya](https://github.com/azalio/doomLaya) FreeDoom agent. It was trained on
|
| 23 |
+
**exactly the same 979 labelled questions** that were used to train
|
| 24 |
+
[Laya v3](https://huggingface.co/azalio/laya-doom-v3) (a 421M "System One" encoder),
|
| 25 |
+
so the two can be compared on equal data.
|
| 26 |
+
|
| 27 |
+
The model does not play by itself. The doomLaya agent turns the game state into text
|
| 28 |
+
(health, weapons, visible enemies with ids and distances, items, doors) and asks two
|
| 29 |
+
multiple-choice questions, `command` and `weapon`; an executor aims, plans paths and
|
| 30 |
+
presses buttons. **All choices belong to the model.**
|
| 31 |
+
|
| 32 |
+
## Results (RTX 4070, 25 Sep 2026)
|
| 33 |
+
|
| 34 |
+
130 held-out validation questions of doomLaya v3:
|
| 35 |
+
|
| 36 |
+
| model | command | weapon | ECE (raw) |
|
| 37 |
+
|---|---|---|---|
|
| 38 |
+
| Gemma 4 E2B, zero-shot | 0.51 | 0.78 | 0.38 |
|
| 39 |
+
| Laya v3 (azalio/laya-doom-v3) | 0.725 | 0.98 | 0.06 |
|
| 40 |
+
| **this adapter (Q8_0 GGUF, via llama.cpp)** | **0.96** | **1.00** | **0.04** |
|
| 41 |
+
|
| 42 |
+
FreeDoom **MAP01**, skill 3, 180 s limit, seeds 48–53 (none used for training or validation):
|
| 43 |
+
|
| 44 |
+
| player | exits | mean time | range | deaths |
|
| 45 |
+
|---|---|---|---|---|
|
| 46 |
+
| Laya v3 | 6/6 | 59.5 s | 42.9–71.0 s | 0 |
|
| 47 |
+
| **this adapter** | 6/6 | 60.0 s | 56.6–64.2 s | 0 |
|
| 48 |
+
| rule-based teacher that produced the labels | 6/6 | 81.6 s | 64.5–124.9 s | 1 |
|
| 49 |
+
|
| 50 |
+
The models exit faster than the rule-based teacher because they imitate it imperfectly
|
| 51 |
+
and pick up fewer items; the teacher does not optimise time-to-exit.
|
| 52 |
+
|
| 53 |
+
Latency on the same RTX 4070, same 1,416 recorded game packets:
|
| 54 |
+
|
| 55 |
+
| setup | p50 | p99 |
|
| 56 |
+
|---|---|---|
|
| 57 |
+
| Laya v3, its own server | 23 ms | 25 ms |
|
| 58 |
+
| this adapter, llama.cpp Q8_0 + grammar | 59 ms | 118 ms |
|
| 59 |
+
| this adapter, direct PyTorch bf16 | 84 ms | 100 ms |
|
| 60 |
+
|
| 61 |
+
## Limitations
|
| 62 |
+
|
| 63 |
+
- Trained and validated **only on MAP01**. On **MAP02** nobody exits (0/3), **including
|
| 64 |
+
the rule-based teacher**: the chain stops at a **yellow-key door** (sector 37, linedef
|
| 65 |
+
special 27), which doomLaya offers as an openable door while the key is far away and
|
| 66 |
+
out of sight. Generalisation to new maps **cannot be measured** on this bench.
|
| 67 |
+
- The labels come from a **rule-based teacher**, not from human play: the adapter learns
|
| 68 |
+
to imitate those rules.
|
| 69 |
+
- The validation set is small (130 questions); calibration numbers carry noticeable noise.
|
| 70 |
+
|
| 71 |
+
## How it is used
|
| 72 |
+
|
| 73 |
+
Each option becomes a letter. A grammar allows a single token among the valid letters,
|
| 74 |
+
and the option probabilities are read from the logprobs of that token
|
| 75 |
+
(one prefill + one token, no free-form generation). The exact prompt:
|
| 76 |
+
|
| 77 |
+
```python
|
| 78 |
+
LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
| 79 |
+
SYSTEM = ("You control a DOOM player in real time. "
|
| 80 |
+
"Pick the best option for each question. Reply only with the letters.")
|
| 81 |
+
|
| 82 |
+
def build(state, name, question): # one question per request
|
| 83 |
+
keys = list(question["criteria"])
|
| 84 |
+
lines = [f"{LETTERS[i]}) {question['criteria'][k]}" for i, k in enumerate(keys)]
|
| 85 |
+
user = (state + "\n\n" + f"{name.upper()} — {question.get('instructions', '')}\n"
|
| 86 |
+
+ "\n".join(lines) + f"\n\nAnswer with 1 letter, in this order: {name.upper()}.")
|
| 87 |
+
return [{"role": "system", "content": SYSTEM}, {"role": "user", "content": user}], keys
|
| 88 |
+
```
|
| 89 |
+
|
| 90 |
+
The chat template is applied with `add_generation_prompt=True, enable_thinking=False`;
|
| 91 |
+
the answer is the next token.
|
| 92 |
+
|
| 93 |
+
## Training
|
| 94 |
+
|
| 95 |
+
- Data: `training/v3/train.json` (979) and `validation.json` (130) from azalio/doomLaya
|
| 96 |
+
at commit `b25edd3` (Apache-2.0). Game seeds 42/43 for training, 44 for validation, MAP01 only.
|
| 97 |
+
- LoRA rank 16, alpha 32, dropout 0.05 on `q,k,v,o,gate,up,down` of the language model;
|
| 98 |
+
AdamW, lr 1e-4, weight decay 0.01, gradient accumulation 8, clip 1.0, seed 771.
|
| 99 |
+
**Loss only on the answer letter.** Best epoch by validation accuracy (command + weapon):
|
| 100 |
+
**epoch 2 of 3**, 550 s per epoch on one RTX 4070 (history in `training_history.json`).
|
| 101 |
+
- Base weights: `google/gemma-4-E2B-it` (`model.safetensors` sha256 `2db5482b…`).
|
| 102 |
+
|
| 103 |
+
## Credits and licences
|
| 104 |
+
|
| 105 |
+
- Base model: Google **Gemma 4 E2B**. This adapter is a Gemma derivative and is
|
| 106 |
+
distributed under the [Gemma Terms of Use](https://ai.google.dev/gemma/terms).
|
| 107 |
+
- Training data and game harness: [azalio/doomLaya](https://github.com/azalio/doomLaya),
|
| 108 |
+
Apache-2.0 (see their NOTICE).
|
| 109 |
+
- Laya: [Convai Innovations](https://huggingface.co/convaiinnovations/laya), Apache-2.0.
|
| 110 |
+
- FreeDoom and ViZDoom under their respective licences.
|
adapter_config.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"alora_invocation_tokens": null,
|
| 3 |
+
"alpha_pattern": {},
|
| 4 |
+
"arrow_config": null,
|
| 5 |
+
"auto_mapping": {
|
| 6 |
+
"base_model_class": "Gemma4ForConditionalGeneration",
|
| 7 |
+
"parent_library": "transformers.models.gemma4.modeling_gemma4"
|
| 8 |
+
},
|
| 9 |
+
"base_model_name_or_path": "google/gemma-4-E2B-it",
|
| 10 |
+
"bias": "none",
|
| 11 |
+
"corda_config": null,
|
| 12 |
+
"ensure_weight_tying": false,
|
| 13 |
+
"eva_config": null,
|
| 14 |
+
"exclude_modules": null,
|
| 15 |
+
"fan_in_fan_out": false,
|
| 16 |
+
"inference_mode": true,
|
| 17 |
+
"init_lora_weights": true,
|
| 18 |
+
"kasa_config": null,
|
| 19 |
+
"layer_replication": null,
|
| 20 |
+
"layers_pattern": null,
|
| 21 |
+
"layers_to_transform": null,
|
| 22 |
+
"loftq_config": {},
|
| 23 |
+
"lora_alpha": 32,
|
| 24 |
+
"lora_bias": false,
|
| 25 |
+
"lora_dropout": 0.05,
|
| 26 |
+
"lora_ga_config": null,
|
| 27 |
+
"megatron_config": null,
|
| 28 |
+
"megatron_core": "megatron.core",
|
| 29 |
+
"modules_to_save": null,
|
| 30 |
+
"monteclora_config": null,
|
| 31 |
+
"peft_type": "LORA",
|
| 32 |
+
"peft_version": "0.21.0",
|
| 33 |
+
"qalora_group_size": 16,
|
| 34 |
+
"r": 16,
|
| 35 |
+
"rank_pattern": {},
|
| 36 |
+
"revision": null,
|
| 37 |
+
"target_modules": ".*language_model.*\\.(q_proj|k_proj|v_proj|o_proj|gate_proj|up_proj|down_proj)",
|
| 38 |
+
"target_parameters": null,
|
| 39 |
+
"task_type": null,
|
| 40 |
+
"trainable_token_indices": null,
|
| 41 |
+
"use_bdlora": null,
|
| 42 |
+
"use_dora": false,
|
| 43 |
+
"use_qalora": false,
|
| 44 |
+
"use_rslora": false,
|
| 45 |
+
"velora_config": null
|
| 46 |
+
}
|
adapter_model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e1ac4eb4853311b509d87b5cf33be663e81e8220f223858ff02489253e289a83
|
| 3 |
+
size 96693360
|
best_epoch.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"best_epoch": 2,
|
| 3 |
+
"validation_accuracy": {
|
| 4 |
+
"command": 0.95,
|
| 5 |
+
"weapon": 1.0
|
| 6 |
+
}
|
| 7 |
+
}
|
training_history.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"epoch": 0,
|
| 4 |
+
"validation_accuracy": {
|
| 5 |
+
"command": 0.5125,
|
| 6 |
+
"weapon": 0.76
|
| 7 |
+
}
|
| 8 |
+
},
|
| 9 |
+
{
|
| 10 |
+
"epoch": 1,
|
| 11 |
+
"validation_accuracy": {
|
| 12 |
+
"command": 0.7875,
|
| 13 |
+
"weapon": 1.0
|
| 14 |
+
},
|
| 15 |
+
"seconds": 550.1
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"epoch": 2,
|
| 19 |
+
"validation_accuracy": {
|
| 20 |
+
"command": 0.95,
|
| 21 |
+
"weapon": 1.0
|
| 22 |
+
},
|
| 23 |
+
"seconds": 549.8
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"epoch": 3,
|
| 27 |
+
"validation_accuracy": {
|
| 28 |
+
"command": 0.9375,
|
| 29 |
+
"weapon": 1.0
|
| 30 |
+
},
|
| 31 |
+
"seconds": 550.1
|
| 32 |
+
}
|
| 33 |
+
]
|