Instructions to use YeMoKoo/AF_RL with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use YeMoKoo/AF_RL with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
Add first_error GRPO LoRA adapters (scalar / discrete), 2026-08-17
Browse files- README.md +33 -0
- discrete-firsterror-20260817/README.md +81 -0
- discrete-firsterror-20260817/adapter_config.json +40 -0
- discrete-firsterror-20260817/adapter_model.safetensors +3 -0
- scalar-firsterror-20260817/README.md +81 -0
- scalar-firsterror-20260817/adapter_config.json +40 -0
- scalar-firsterror-20260817/adapter_model.safetensors +3 -0
README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
base_model: Qwen/Qwen3-VL-2B-Instruct
|
| 3 |
+
library_name: peft
|
| 4 |
+
pipeline_tag: image-text-to-text
|
| 5 |
+
tags: [lora, grpo, rlhf, gui-agent, android, androidflux]
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
# AF_RL — AndroidFlux GRPO LoRA adapters
|
| 9 |
+
|
| 10 |
+
GRPO-trained LoRA adapters for **Qwen3-VL-2B-Instruct** on Android GUI error
|
| 11 |
+
recovery. Each adapter lives in its own subfolder.
|
| 12 |
+
|
| 13 |
+
| subfolder | reward model | final reward |
|
| 14 |
+
|---|---|---|
|
| 15 |
+
| `scalar-firsterror-20260817` | Bradley-Terry scalar head | +4.608 |
|
| 16 |
+
| `discrete-firsterror-20260817` | judge-token `<\|+\|>` / `<\|-\|>` margin | −2.273 |
|
| 17 |
+
|
| 18 |
+
Reward scales are **not comparable across the two** — they come from different
|
| 19 |
+
reward models. Compare policies by downstream task performance, not by these numbers.
|
| 20 |
+
|
| 21 |
+
```python
|
| 22 |
+
from peft import AutoPeftModelForCausalLM
|
| 23 |
+
model = AutoPeftModelForCausalLM.from_pretrained(
|
| 24 |
+
"YeMoKoo/AF_RL", subfolder="scalar-firsterror-20260817", torch_dtype="bfloat16")
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
Both were trained on the `first_error` split (2,662 samples) of
|
| 28 |
+
`Gyubeum/AndroidFlux_RL_Train_Test` @ `4545695c26951a4884e8f18e6468d69cbdf9d174`,
|
| 29 |
+
for 1 epoch with identical hyperparameters — the reward model is the only
|
| 30 |
+
difference. See each subfolder's `README.md` for full details.
|
| 31 |
+
|
| 32 |
+
Intended comparison (run elsewhere, on held-out data):
|
| 33 |
+
base `Qwen/Qwen3-VL-2B-Instruct` vs. scalar-GRPO vs. discrete-GRPO.
|
discrete-firsterror-20260817/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# discrete-firsterror-20260817
|
| 2 |
+
|
| 3 |
+
GRPO-trained LoRA adapter for **Qwen3-VL-2B-Instruct**, optimised for GUI error
|
| 4 |
+
recovery on Android. The policy sees the screen *immediately after the first
|
| 5 |
+
erroneous action* of a trajectory and must produce the next recovery action.
|
| 6 |
+
|
| 7 |
+
Reward model: **discrete** — judge-token `<|+|>` / `<|-|>` log-probability margin.
|
| 8 |
+
|
| 9 |
+
## Load
|
| 10 |
+
|
| 11 |
+
```python
|
| 12 |
+
from peft import AutoPeftModelForCausalLM
|
| 13 |
+
model = AutoPeftModelForCausalLM.from_pretrained(
|
| 14 |
+
"YeMoKoo/AF_RL", subfolder="discrete-firsterror-20260817", torch_dtype="bfloat16")
|
| 15 |
+
```
|
| 16 |
+
|
| 17 |
+
Or with the base model loaded explicitly:
|
| 18 |
+
|
| 19 |
+
```python
|
| 20 |
+
from transformers import AutoModelForCausalLM
|
| 21 |
+
from peft import PeftModel
|
| 22 |
+
base = AutoModelForCausalLM.from_pretrained(
|
| 23 |
+
"Qwen/Qwen3-VL-2B-Instruct",
|
| 24 |
+
revision="89644892e4d85e24eaac8bacfd4f463576704203",
|
| 25 |
+
torch_dtype="bfloat16")
|
| 26 |
+
model = PeftModel.from_pretrained(base, "YeMoKoo/AF_RL", subfolder="discrete-firsterror-20260817")
|
| 27 |
+
```
|
| 28 |
+
|
| 29 |
+
The base checkpoint is pinned in `adapter_config.json`
|
| 30 |
+
(`Qwen/Qwen3-VL-2B-Instruct` @ `89644892e4d85e24eaac8bacfd4f463576704203`) and is
|
| 31 |
+
downloaded automatically.
|
| 32 |
+
|
| 33 |
+
> `target_modules` is a **regex** over `model.language_model.*`. Verify the adapter
|
| 34 |
+
> actually attached (`sum("lora" in n for n, _ in model.named_parameters()) > 0`);
|
| 35 |
+
> a different `transformers` version can silently match zero modules.
|
| 36 |
+
> Trained with `transformers==4.57.6`, `peft==0.19.1`, `torch==2.8.0`.
|
| 37 |
+
|
| 38 |
+
## Training data
|
| 39 |
+
|
| 40 |
+
`Gyubeum/AndroidFlux_RL_Train_Test` @ `4545695c26951a4884e8f18e6468d69cbdf9d174`,
|
| 41 |
+
directory `data_rl_v0_from_error_only`, filtered to `sampling_category == "first_error"`.
|
| 42 |
+
|
| 43 |
+
| | |
|
| 44 |
+
|---|---|
|
| 45 |
+
| samples | 2,662 (unique 2,662) |
|
| 46 |
+
| images | 12,648 |
|
| 47 |
+
| policy / reward history window | 10 / 5 |
|
| 48 |
+
| hidden labels exported | false |
|
| 49 |
+
| dataset SHA-256 | `d6a7463520feb40403f806640622435e4abacad7dcfacc119bc399a5edd8c6e7` |
|
| 50 |
+
|
| 51 |
+
Prompts are label-free: no sampling category, error location, or recorded next
|
| 52 |
+
action is present at runtime.
|
| 53 |
+
|
| 54 |
+
## Training
|
| 55 |
+
|
| 56 |
+
LoRA r=8, alpha=32, dropout=0.05, `target_modules=all-linear` (ViT and aligner
|
| 57 |
+
frozen, LLM trainable). GRPO with `num_generations=8`, `generation_batch_size=8`,
|
| 58 |
+
temperature 0.9, top_p 0.95, lr 1e-6, 1 epoch, warmup_ratio 0.03, weight_decay 0,
|
| 59 |
+
beta 0.001, `scale_rewards=group`, max_length 8192, max_completion_length 256,
|
| 60 |
+
seed 42, bf16. vLLM colocate rollout. 2×H100 DDP
|
| 61 |
+
(`per_device_train_batch_size=1`, `gradient_accumulation_steps=4`) + 1×H100 for
|
| 62 |
+
the reward model. 2,662 optimizer steps.
|
| 63 |
+
|
| 64 |
+
Reward model: `Gyubeum/Qwen3-VL-8B-Instruct-UI-Genie` @ `05bf461bed27a18ee18cf9eacc6706f424a53d5e`, invalid-action penalty −5.0.
|
| 65 |
+
|
| 66 |
+
ms-swift `23e06ccd93ea00533c0e14d579095f45ac7976bc` (4.5.0.dev0), Python 3.11.15.
|
| 67 |
+
|
| 68 |
+
## Final metrics
|
| 69 |
+
|
| 70 |
+
| metric | value |
|
| 71 |
+
|---|---|
|
| 72 |
+
| reward (final) | -2.2728 |
|
| 73 |
+
| reward, first 10 logs -> last 10 logs | -4.7019 -> -3.1675 |
|
| 74 |
+
| reward_std (final) | 1.5304 |
|
| 75 |
+
| frac_reward_zero_std (final) | 0.0000 |
|
| 76 |
+
| train_loss | 0.00109 |
|
| 77 |
+
| completion length min/mean/max | 128.0 / 166.9 / 217.0 |
|
| 78 |
+
| clipped_ratio | 0.000 |
|
| 79 |
+
| train_runtime | 32083 s |
|
| 80 |
+
|
| 81 |
+
Trained 2026-08-17. Checkpoint `checkpoint-2662` (final, 1 full epoch).
|
discrete-firsterror-20260817/adapter_config.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"alora_invocation_tokens": null,
|
| 3 |
+
"alpha_pattern": {},
|
| 4 |
+
"arrow_config": null,
|
| 5 |
+
"auto_mapping": null,
|
| 6 |
+
"base_model_name_or_path": "Qwen/Qwen3-VL-2B-Instruct",
|
| 7 |
+
"bias": "none",
|
| 8 |
+
"corda_config": null,
|
| 9 |
+
"ensure_weight_tying": false,
|
| 10 |
+
"eva_config": null,
|
| 11 |
+
"exclude_modules": null,
|
| 12 |
+
"fan_in_fan_out": false,
|
| 13 |
+
"inference_mode": true,
|
| 14 |
+
"init_lora_weights": true,
|
| 15 |
+
"layer_replication": null,
|
| 16 |
+
"layers_pattern": null,
|
| 17 |
+
"layers_to_transform": null,
|
| 18 |
+
"loftq_config": {},
|
| 19 |
+
"lora_alpha": 32,
|
| 20 |
+
"lora_bias": false,
|
| 21 |
+
"lora_dropout": 0.05,
|
| 22 |
+
"lora_ga_config": null,
|
| 23 |
+
"megatron_config": null,
|
| 24 |
+
"megatron_core": "megatron.core",
|
| 25 |
+
"modules_to_save": [],
|
| 26 |
+
"peft_type": "LORA",
|
| 27 |
+
"peft_version": "0.19.1",
|
| 28 |
+
"qalora_group_size": 16,
|
| 29 |
+
"r": 8,
|
| 30 |
+
"rank_pattern": {},
|
| 31 |
+
"revision": "89644892e4d85e24eaac8bacfd4f463576704203",
|
| 32 |
+
"target_modules": "^(model\\.language_model(?=\\.).*\\.(up_proj|down_proj|v_proj|k_proj|gate_proj|q_proj|o_proj))$",
|
| 33 |
+
"target_parameters": null,
|
| 34 |
+
"task_type": "CAUSAL_LM",
|
| 35 |
+
"trainable_token_indices": null,
|
| 36 |
+
"use_bdlora": null,
|
| 37 |
+
"use_dora": false,
|
| 38 |
+
"use_qalora": false,
|
| 39 |
+
"use_rslora": false
|
| 40 |
+
}
|
discrete-firsterror-20260817/adapter_model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:498340cf3048290a1db48dcd3552246218831697fe35b136f4a76e2b9863c043
|
| 3 |
+
size 17490168
|
scalar-firsterror-20260817/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# scalar-firsterror-20260817
|
| 2 |
+
|
| 3 |
+
GRPO-trained LoRA adapter for **Qwen3-VL-2B-Instruct**, optimised for GUI error
|
| 4 |
+
recovery on Android. The policy sees the screen *immediately after the first
|
| 5 |
+
erroneous action* of a trajectory and must produce the next recovery action.
|
| 6 |
+
|
| 7 |
+
Reward model: **scalar** — Bradley-Terry scalar head; raw scalar reward.
|
| 8 |
+
|
| 9 |
+
## Load
|
| 10 |
+
|
| 11 |
+
```python
|
| 12 |
+
from peft import AutoPeftModelForCausalLM
|
| 13 |
+
model = AutoPeftModelForCausalLM.from_pretrained(
|
| 14 |
+
"YeMoKoo/AF_RL", subfolder="scalar-firsterror-20260817", torch_dtype="bfloat16")
|
| 15 |
+
```
|
| 16 |
+
|
| 17 |
+
Or with the base model loaded explicitly:
|
| 18 |
+
|
| 19 |
+
```python
|
| 20 |
+
from transformers import AutoModelForCausalLM
|
| 21 |
+
from peft import PeftModel
|
| 22 |
+
base = AutoModelForCausalLM.from_pretrained(
|
| 23 |
+
"Qwen/Qwen3-VL-2B-Instruct",
|
| 24 |
+
revision="89644892e4d85e24eaac8bacfd4f463576704203",
|
| 25 |
+
torch_dtype="bfloat16")
|
| 26 |
+
model = PeftModel.from_pretrained(base, "YeMoKoo/AF_RL", subfolder="scalar-firsterror-20260817")
|
| 27 |
+
```
|
| 28 |
+
|
| 29 |
+
The base checkpoint is pinned in `adapter_config.json`
|
| 30 |
+
(`Qwen/Qwen3-VL-2B-Instruct` @ `89644892e4d85e24eaac8bacfd4f463576704203`) and is
|
| 31 |
+
downloaded automatically.
|
| 32 |
+
|
| 33 |
+
> `target_modules` is a **regex** over `model.language_model.*`. Verify the adapter
|
| 34 |
+
> actually attached (`sum("lora" in n for n, _ in model.named_parameters()) > 0`);
|
| 35 |
+
> a different `transformers` version can silently match zero modules.
|
| 36 |
+
> Trained with `transformers==4.57.6`, `peft==0.19.1`, `torch==2.8.0`.
|
| 37 |
+
|
| 38 |
+
## Training data
|
| 39 |
+
|
| 40 |
+
`Gyubeum/AndroidFlux_RL_Train_Test` @ `4545695c26951a4884e8f18e6468d69cbdf9d174`,
|
| 41 |
+
directory `data_rl_v0_from_error_only`, filtered to `sampling_category == "first_error"`.
|
| 42 |
+
|
| 43 |
+
| | |
|
| 44 |
+
|---|---|
|
| 45 |
+
| samples | 2,662 (unique 2,662) |
|
| 46 |
+
| images | 12,648 |
|
| 47 |
+
| policy / reward history window | 10 / 5 |
|
| 48 |
+
| hidden labels exported | false |
|
| 49 |
+
| dataset SHA-256 | `d6a7463520feb40403f806640622435e4abacad7dcfacc119bc399a5edd8c6e7` |
|
| 50 |
+
|
| 51 |
+
Prompts are label-free: no sampling category, error location, or recorded next
|
| 52 |
+
action is present at runtime.
|
| 53 |
+
|
| 54 |
+
## Training
|
| 55 |
+
|
| 56 |
+
LoRA r=8, alpha=32, dropout=0.05, `target_modules=all-linear` (ViT and aligner
|
| 57 |
+
frozen, LLM trainable). GRPO with `num_generations=8`, `generation_batch_size=8`,
|
| 58 |
+
temperature 0.9, top_p 0.95, lr 1e-6, 1 epoch, warmup_ratio 0.03, weight_decay 0,
|
| 59 |
+
beta 0.001, `scale_rewards=group`, max_length 8192, max_completion_length 256,
|
| 60 |
+
seed 42, bf16. vLLM colocate rollout. 2×H100 DDP
|
| 61 |
+
(`per_device_train_batch_size=1`, `gradient_accumulation_steps=4`) + 1×H100 for
|
| 62 |
+
the reward model. 2,662 optimizer steps.
|
| 63 |
+
|
| 64 |
+
Reward model: `Gyubeum/Qwen3-VL-8B-Instruct-UI-Genie-scoring` @ `b7d953e59c49a3108416f860d430712d8b81094f`, invalid-action penalty −5.0.
|
| 65 |
+
|
| 66 |
+
ms-swift `23e06ccd93ea00533c0e14d579095f45ac7976bc` (4.5.0.dev0), Python 3.11.15.
|
| 67 |
+
|
| 68 |
+
## Final metrics
|
| 69 |
+
|
| 70 |
+
| metric | value |
|
| 71 |
+
|---|---|
|
| 72 |
+
| reward (final) | +4.6084 |
|
| 73 |
+
| reward, first 10 logs -> last 10 logs | +4.3925 -> +5.0904 |
|
| 74 |
+
| reward_std (final) | 2.6275 |
|
| 75 |
+
| frac_reward_zero_std (final) | 0.0000 |
|
| 76 |
+
| train_loss | 0.00098 |
|
| 77 |
+
| completion length min/mean/max | 103.5 / 139.0 / 189.0 |
|
| 78 |
+
| clipped_ratio | 0.000 |
|
| 79 |
+
| train_runtime | 31523 s |
|
| 80 |
+
|
| 81 |
+
Trained 2026-08-17. Checkpoint `checkpoint-2662` (final, 1 full epoch).
|
scalar-firsterror-20260817/adapter_config.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"alora_invocation_tokens": null,
|
| 3 |
+
"alpha_pattern": {},
|
| 4 |
+
"arrow_config": null,
|
| 5 |
+
"auto_mapping": null,
|
| 6 |
+
"base_model_name_or_path": "Qwen/Qwen3-VL-2B-Instruct",
|
| 7 |
+
"bias": "none",
|
| 8 |
+
"corda_config": null,
|
| 9 |
+
"ensure_weight_tying": false,
|
| 10 |
+
"eva_config": null,
|
| 11 |
+
"exclude_modules": null,
|
| 12 |
+
"fan_in_fan_out": false,
|
| 13 |
+
"inference_mode": true,
|
| 14 |
+
"init_lora_weights": true,
|
| 15 |
+
"layer_replication": null,
|
| 16 |
+
"layers_pattern": null,
|
| 17 |
+
"layers_to_transform": null,
|
| 18 |
+
"loftq_config": {},
|
| 19 |
+
"lora_alpha": 32,
|
| 20 |
+
"lora_bias": false,
|
| 21 |
+
"lora_dropout": 0.05,
|
| 22 |
+
"lora_ga_config": null,
|
| 23 |
+
"megatron_config": null,
|
| 24 |
+
"megatron_core": "megatron.core",
|
| 25 |
+
"modules_to_save": [],
|
| 26 |
+
"peft_type": "LORA",
|
| 27 |
+
"peft_version": "0.19.1",
|
| 28 |
+
"qalora_group_size": 16,
|
| 29 |
+
"r": 8,
|
| 30 |
+
"rank_pattern": {},
|
| 31 |
+
"revision": "89644892e4d85e24eaac8bacfd4f463576704203",
|
| 32 |
+
"target_modules": "^(model\\.language_model(?=\\.).*\\.(q_proj|gate_proj|o_proj|k_proj|up_proj|v_proj|down_proj))$",
|
| 33 |
+
"target_parameters": null,
|
| 34 |
+
"task_type": "CAUSAL_LM",
|
| 35 |
+
"trainable_token_indices": null,
|
| 36 |
+
"use_bdlora": null,
|
| 37 |
+
"use_dora": false,
|
| 38 |
+
"use_qalora": false,
|
| 39 |
+
"use_rslora": false
|
| 40 |
+
}
|
scalar-firsterror-20260817/adapter_model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7a3fff83b0171d0cfcf87ce20c87c534baa707438033094caf8aa5aeef6955dd
|
| 3 |
+
size 17490168
|