A very simple GRPO implement for reproducing r1-like LLM thinking. This is a simple open source implementation that utilizes the core loss calculation formula referenced from Hugging Face's trl. We make the simplest codebase to support:
The project code is simple, with only about 200 lines of code spread across 2 files. It only depends on standard libraries such as deepspeed and torch, without requiring dependencies like ray. It is designed to allow for more complex interventions.
The reference model part is decoupled, which allows it to be run on different GPUs (even on a different machine with 4090). This avoids having the reference model and the training model on the same GPU, preventing multiple copies created by torch’s multiprocessing, and enabling training of a 7B model on 80G A800.
Training completed in under 1 hour on 1*A800 GPUs. Both Qwen2.5-7B and Qwen2.5-3B exhibited an "Aha moment" within the first 30 optimization steps.
The loss calculation formula is based on Hugging Face's trl. We extend our gratitude to Hugging Face for their contribution.
The runtime environment is in the requirements.txt so you can
pip install -r requirements.txt
At least two GPUs are needed.
Warning: You may need to install datasets and add a http proxy (maybe) to run the example script that simply use GSM8K.
pip install datasets
This package is only used for simply loading GSM8K. For real usage, users should prepare their own data, so datasets is not a strict requirement.
BTW:if datasets is not installed and you do not load dataset in file, the generate process has no data, so the training process (as well as ref process) is always waiting for batch.
Run the following command:
CUDA_VISIBLE_DEVICES=7 python ref_server.py
This just uses one GPU to collect and run the reference model.
In grpo_vllm_one.py, set the generation device index relative to the visible devices in next step:
gen_device = 1
Then, open another bash:
CUDA_VISIBLE_DEVICES=2,3,4,5,6 deepspeed grpo_vllm_one.py
| Model | Steps | Time |
|---|---|---|
| Qwen2.5-3B | 60 | 12m 34s |
| Qwen2.5-7B | 60 | 16m 40s |
2.1 Qwen2.5-3B
2.2 Qwen2.5-7B
<think>... To find out how many more eggs Camden painted than Arnold, we subtract the number of eggs painted by Arnold from the number of eggs painted by Camden. So, 21 - 28 = -7. However, this result doesn't make sense in the context of the problem, as Camden cannot have painted fewer eggs than Arnold. Let's reconsider the initial solution steps: we should verify if the initial assumption about the relationship between Camden and Sarah's eggs is correct. ...</think><answer>-7</answer>
<think>... Therefore, Joanne gathered 350 apples from the average trees. However, this doesn't seem right because the total should be 500 and we've already accounted for 150, leaving room only for 350 from the average trees, which contradicts the total. Let's reassess. ...</think><answer>350</answer>
We have implemented and are testing these features. They will be available soon.
This project is led by Dr. Jiaqing Liang and Professor Yanghua Xiao from KnowledgeWorks Lab, Fudan University. The core development team includes Ph.D. candidate Jinyi Han, Master's student Xinyi Wang, and other contributors. We gratefully acknowledge their dedication to this work.
If you find the code in our project useful, please consider citing our work as follows:
@misc{KW-R1,
author = {Jiaqing Liang, Jinyi Han, Xinyi Wang, Zishang Jiang, Chengyuan Xiong, Boyu Zhu, Jie Shi, Weijia Li, Tingyun Li, Yanghua Xiao},
title = {KW-R1: A Simple Implementation of the GRPO Algorithm},
year = {2025},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/lsdefine/simple_GRPO}},
}
Python
100.0%
A very simple GRPO implement for reproducing r1-like LLM thinking. This is a simple open source implementation that utilizes the core loss calculation formula referenced from Hugging Face's trl. We make the simplest codebase to support:
The project code is simple, with only about 200 lines of code spread across 2 files. It only depends on standard libraries such as deepspeed and torch, without requiring dependencies like ray. It is designed to allow for more complex interventions.
The reference model part is decoupled, which allows it to be run on different GPUs (even on a different machine with 4090). This avoids having the reference model and the training model on the same GPU, preventing multiple copies created by torch’s multiprocessing, and enabling training of a 7B model on 80G A800.
Training completed in under 1 hour on 1*A800 GPUs. Both Qwen2.5-7B and Qwen2.5-3B exhibited an "Aha moment" within the first 30 optimization steps.
The loss calculation formula is based on Hugging Face's trl. We extend our gratitude to Hugging Face for their contribution.
The runtime environment is in the requirements.txt so you can
pip install -r requirements.txt
At least two GPUs are needed.
Warning: You may need to install datasets and add a http proxy (maybe) to run the example script that simply use GSM8K.
pip install datasets
This package is only used for simply loading GSM8K. For real usage, users should prepare their own data, so datasets is not a strict requirement.
BTW:if datasets is not installed and you do not load dataset in file, the generate process has no data, so the training process (as well as ref process) is always waiting for batch.
Run the following command:
CUDA_VISIBLE_DEVICES=7 python ref_server.py
This just uses one GPU to collect and run the reference model.
In grpo_vllm_one.py, set the generation device index relative to the visible devices in next step:
gen_device = 1
Then, open another bash:
CUDA_VISIBLE_DEVICES=2,3,4,5,6 deepspeed grpo_vllm_one.py
| Model | Steps | Time |
|---|---|---|
| Qwen2.5-3B | 60 | 12m 34s |
| Qwen2.5-7B | 60 | 16m 40s |
2.1 Qwen2.5-3B
2.2 Qwen2.5-7B
<think>... To find out how many more eggs Camden painted than Arnold, we subtract the number of eggs painted by Arnold from the number of eggs painted by Camden. So, 21 - 28 = -7. However, this result doesn't make sense in the context of the problem, as Camden cannot have painted fewer eggs than Arnold. Let's reconsider the initial solution steps: we should verify if the initial assumption about the relationship between Camden and Sarah's eggs is correct. ...</think><answer>-7</answer>
<think>... Therefore, Joanne gathered 350 apples from the average trees. However, this doesn't seem right because the total should be 500 and we've already accounted for 150, leaving room only for 350 from the average trees, which contradicts the total. Let's reassess. ...</think><answer>350</answer>
We have implemented and are testing these features. They will be available soon.
This project is led by Dr. Jiaqing Liang and Professor Yanghua Xiao from KnowledgeWorks Lab, Fudan University. The core development team includes Ph.D. candidate Jinyi Han, Master's student Xinyi Wang, and other contributors. We gratefully acknowledge their dedication to this work.
If you find the code in our project useful, please consider citing our work as follows:
@misc{KW-R1,
author = {Jiaqing Liang, Jinyi Han, Xinyi Wang, Zishang Jiang, Chengyuan Xiong, Boyu Zhu, Jie Shi, Weijia Li, Tingyun Li, Yanghua Xiao},
title = {KW-R1: A Simple Implementation of the GRPO Algorithm},
year = {2025},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/lsdefine/simple_GRPO}},
}
Python
100.0%