Views
No views yet
train_grpo_minimal.py — the smallest run that works, from the
TRL quickstart: reward = be close to
20 characters long. No task, no labels. GRPO optimizes whatever number you return, and
the completions/mean_length curve shows it converging within a few steps.train_grpo.py — a verifiable reward: the model writes a Python function for an
MBPP problem, the reward
executes the problem's own asserts, reward = fraction that pass. The knob to play with is
--num_generations (the group size).train_grpo_pathological.py — reward hacking on purpose: trains on a deliberately
gameable reward (count the code blocks, run nothing) while logging the real tests reward
with weight 0. The trained reward saturates, the tests reward collapses, completion length
pins at the maximum: reward hacking, length gaming and collapse on one dashboard.burtenshaw/gemma4-pi-mono-youtube-livestream-1-scripts ·
Class 2 (distillation) scripts: sergiopaniego/pi-mono-youtube-livestream-2-scriptsQwen/Qwen3-0.6B (thinking mode disabled: the completion is just the code)full (374 train problems, each with 3 asserts) for 2 and 3; trl-lib/tldr
prompts for 1. GRPO only needs prompts: the reward function replaces the labels.a100-large), ~20 minutes per run.1# 1. Minimal: reward = be close to 20 characters
2hf jobs uv run --flavor a100-large --secrets HF_TOKEN -d --timeout 1h train_grpo_minimal.py \
3 --model_name_or_path Qwen/Qwen3-0.6B --dataset_name trl-lib/tldr \
4 --dtype bfloat16 --bf16 True \
5 --use_vllm --vllm_mode colocate --vllm_gpu_memory_utilization 0.3 \
6 --num_generations 8 --per_device_train_batch_size 16 \
7 --max_completion_length 256 --temperature 0.7 --learning_rate 2e-6 \
8 --max_steps 300 --logging_steps 1 --log_completions \
9 --report_to trackio --project minimal --run_name reward-len \
10 --trackio_space_id sergiopaniego/trackio-training-agents-3 \
11 --output_dir qwen3-0.6b-tldr-lenreward
12
13# 2. Verifiable: sweep the group size
14for k in 2 8 16; do
15hf jobs uv run --flavor a100-large --secrets HF_TOKEN -d --timeout 2h train_grpo.py \
16 --model_name_or_path Qwen/Qwen3-0.6B \
17 --dataset_name google-research-datasets/mbpp --dataset_config full \
18 --dtype bfloat16 --bf16 True \
19 --use_vllm --vllm_mode colocate --vllm_gpu_memory_utilization 0.3 \
20 --num_generations $k --per_device_train_batch_size 16 \
21 --max_completion_length 512 --temperature 0.7 --learning_rate 2e-6 \
22 --max_steps 300 --logging_steps 1 --log_completions \
23 --report_to trackio --project grpo-sweep --run_name grpo-k$k \
24 --trackio_space_id sergiopaniego/trackio-training-agents-3 \
25 --output_dir qwen3-0.6b-mbpp-grpo-k$k --push_to_hub \
26 --hub_model_id sergiopaniego/qwen3-0.6b-mbpp-grpo-k$k
27done
28
29# 3. Pathological: reward hacking on purpose
30hf jobs uv run --flavor a100-large --secrets HF_TOKEN -d --timeout 2h train_grpo_pathological.py \
31 --model_name_or_path Qwen/Qwen3-0.6B \
32 --dataset_name google-research-datasets/mbpp --dataset_config full \
33 --dtype bfloat16 --bf16 True \
34 --use_vllm --vllm_mode colocate --vllm_gpu_memory_utilization 0.3 \
35 --num_generations 8 --per_device_train_batch_size 16 \
36 --max_completion_length 512 --temperature 0.7 --learning_rate 2e-6 \
37 --max_steps 300 --logging_steps 1 --log_completions \
38 --report_to trackio --project pathological --run_name hacked-reward \
39 --trackio_space_id sergiopaniego/trackio-training-agents-3 \
40 --output_dir qwen3-0.6b-mbpp-grpo-hackedhf jobs uv run --flavor ... --secrets HF_TOKEN -d --timeout ... and
calling uv run <script> ....minimal — the 20-characters rewardgrpo-sweep — the verifiable reward, k = 2 / 8 / 16pathological — the gameable reward| num_generations | reward (start → end) | groups with no variance |
|---|---|---|
| 2 | 0.41 → 0.58 | ~75% |
| 8 | 0.41 → 0.67 | ~40% |
| 16 | 0.39 → 0.61 | ~30% |
tests_reward runs model-generated code in a plain subprocess with a timeout, with no
sandbox. Inside a disposable job container this is acceptable for a demo, but the container
still holds your HF_TOKEN: beyond a demo, run rewards in a real sandbox. The natural fit is
Hugging Face Sandboxes, isolated
machines built on the same Jobs infrastructure, made for exactly this ("running untrusted or
AI-generated code"), with SandboxPool for fanning out RL rollouts:1from huggingface_hub import Sandbox
2
3with Sandbox.create() as sbx:
4 result = sbx.run(["python", test_file], timeout=10)