This project implements GRPO (Group Relative Policy Optimization) training for an email search agent using unsloth for fast LoRA fine-tuning and TRL for the GRPO algorithm.
The email agent is trained to search through a database of emails (Enron dataset) and answer questions about email content using a tool-calling interface. The agent learns through reinforcement learning, receiving rewards based on whether it correctly answers queries.
email_agent/
├── data/
│ ├── types.py # Data models (Email, SyntheticQuery)
│ ├── query_loader.py # Load queries from HuggingFace
│ └── local_email_db.py # Generate SQLite database
├── tools.py # Email search and read tools
├── config.py # Training and policy configuration
└── rollout.py # Agent rollout and reward calculation
train_grpo.py # Main training script
train_grpo_advanced.py # Advanced training with custom rollout
scripts/
├── setup.sh # Initial setup
├── generate_database.sh # Generate email database
└── run_training.sh # Run training
./scripts/setup.sh
This will:
requirements.txt.env file for configurationEdit .env and add your OpenAI API key (required for judge model):
OPENAI_API_KEY=your_key_here
If not done during setup:
./scripts/generate_database.sh
This downloads the Enron email dataset and creates a local SQLite database (~10-15 minutes).
./scripts/run_training.sh
Or directly with Python:
python train_grpo.py
For multi-GPU training with accelerate:
accelerate launch train_grpo.py
To save comprehensive JSON logs for debugging and analysis:
python train_grpo.py --enable-detailed-logging
This creates detailed logs in outputs/rollout_logs/ for every rollout, including:
See ROLLOUT_LOGGING.md for detailed documentation and examples/rollout_logging_example.md for usage examples.
Analyze logs with:
# View latest step summary
python scripts/analyze_rollout_logs.py
# Compare multiple steps
python scripts/analyze_rollout_logs.py --compare "0,10,20"
# Show failure cases
python scripts/analyze_rollout_logs.py --step 10 --failures
Key parameters in .env:
# Training
TRAIN_DATASET_SIZE=1000
EVAL_DATASET_SIZE=100
MAX_STEPS=1000
LEARNING_RATE=1e-5
PER_DEVICE_TRAIN_BATCH_SIZE=1
GRADIENT_ACCUMULATION_STEPS=4
# Agent
MAX_TURNS=10
MAX_TOKENS=2048
# Output
OUTPUT_DIR=outputs/grpo
RUN_NAME=email_agent_grpo
Queries are loaded from the corbt/enron_emails_sample_questions dataset. Each query contains:
Dataset Splits (to prevent overfitting):
See DATASET_SPLIT_USAGE.md for detailed information.
For each query, the agent:
MAX_TURNS turnsRewards range from -2 to +2:
Partial credit awarded for:
GRPO generates multiple completions per prompt and uses group-relative advantage:
advantage_i = (reward_i - mean(rewards)) / std(rewards)
This makes rewards more comparable across different queries.
Evaluate a trained model on the test split:
python eval.py --model-path outputs/grpo/final --num-queries 100
Or run a comprehensive benchmark:
python benchmark.py --model-path outputs/grpo/final --limit 100
To test the dataset splits:
python test_dataset_splits.py
The model is evaluated using GPT-4o as a judge to determine if answers are semantically correct. Metrics tracked:
Important: All evaluation and benchmarking use the test split to ensure unbiased results and prevent overfitting.
Edit email_agent/rollout.py and modify calculate_reward():
def calculate_reward(policy_config: PolicyConfig, rubric: EvaluationRubric) -> float:
# Your custom reward logic here
return reward
Use train_grpo_advanced.py for more control over the rollout process:
python train_grpo_advanced.py
Modify dataset size in code or .env:
train_queries = load_synthetic_queries(
split="train",
limit=100, # Smaller for testing
shuffle=True,
)
Build and run with Docker:
# Build
docker build -t email-agent-grpo -f Dockerfile .
# Run training
docker run --gpus all -v $(pwd)/outputs:/workspace/outputs email-agent-grpo
accelerate for distributed training across multiple GPUsGRADIENT_ACCUMULATION_STEPS if memory is limitedMAX_TURNS to speed up rollouts during developmentMake sure the database is generated:
./scripts/generate_database.sh
Reduce batch size or increase gradient accumulation:
export PER_DEVICE_TRAIN_BATCH_SIZE=1
export GRADIENT_ACCUMULATION_STEPS=8
Check your OpenAI API key in .env:
echo $OPENAI_API_KEY
Apache 2.0
If you use this code in your research, please cite:
@misc{email-agent-grpo,
title={Email Agent GRPO Training with Unsloth},
year={2025},
publisher={GitHub},
url={https://github.com/your-repo/rl-unsloth}
}
20 commits
Python
89.8%
Shell
9.8%
This project implements GRPO (Group Relative Policy Optimization) training for an email search agent using unsloth for fast LoRA fine-tuning and TRL for the GRPO algorithm.
The email agent is trained to search through a database of emails (Enron dataset) and answer questions about email content using a tool-calling interface. The agent learns through reinforcement learning, receiving rewards based on whether it correctly answers queries.
email_agent/
├── data/
│ ├── types.py # Data models (Email, SyntheticQuery)
│ ├── query_loader.py # Load queries from HuggingFace
│ └── local_email_db.py # Generate SQLite database
├── tools.py # Email search and read tools
├── config.py # Training and policy configuration
└── rollout.py # Agent rollout and reward calculation
train_grpo.py # Main training script
train_grpo_advanced.py # Advanced training with custom rollout
scripts/
├── setup.sh # Initial setup
├── generate_database.sh # Generate email database
└── run_training.sh # Run training
./scripts/setup.sh
This will:
requirements.txt.env file for configurationEdit .env and add your OpenAI API key (required for judge model):
OPENAI_API_KEY=your_key_here
If not done during setup:
./scripts/generate_database.sh
This downloads the Enron email dataset and creates a local SQLite database (~10-15 minutes).
./scripts/run_training.sh
Or directly with Python:
python train_grpo.py
For multi-GPU training with accelerate:
accelerate launch train_grpo.py
To save comprehensive JSON logs for debugging and analysis:
python train_grpo.py --enable-detailed-logging
This creates detailed logs in outputs/rollout_logs/ for every rollout, including:
See ROLLOUT_LOGGING.md for detailed documentation and examples/rollout_logging_example.md for usage examples.
Analyze logs with:
# View latest step summary
python scripts/analyze_rollout_logs.py
# Compare multiple steps
python scripts/analyze_rollout_logs.py --compare "0,10,20"
# Show failure cases
python scripts/analyze_rollout_logs.py --step 10 --failures
Key parameters in .env:
# Training
TRAIN_DATASET_SIZE=1000
EVAL_DATASET_SIZE=100
MAX_STEPS=1000
LEARNING_RATE=1e-5
PER_DEVICE_TRAIN_BATCH_SIZE=1
GRADIENT_ACCUMULATION_STEPS=4
# Agent
MAX_TURNS=10
MAX_TOKENS=2048
# Output
OUTPUT_DIR=outputs/grpo
RUN_NAME=email_agent_grpo
Queries are loaded from the corbt/enron_emails_sample_questions dataset. Each query contains:
Dataset Splits (to prevent overfitting):
See DATASET_SPLIT_USAGE.md for detailed information.
For each query, the agent:
MAX_TURNS turnsRewards range from -2 to +2:
Partial credit awarded for:
GRPO generates multiple completions per prompt and uses group-relative advantage:
advantage_i = (reward_i - mean(rewards)) / std(rewards)
This makes rewards more comparable across different queries.
Evaluate a trained model on the test split:
python eval.py --model-path outputs/grpo/final --num-queries 100
Or run a comprehensive benchmark:
python benchmark.py --model-path outputs/grpo/final --limit 100
To test the dataset splits:
python test_dataset_splits.py
The model is evaluated using GPT-4o as a judge to determine if answers are semantically correct. Metrics tracked:
Important: All evaluation and benchmarking use the test split to ensure unbiased results and prevent overfitting.
Edit email_agent/rollout.py and modify calculate_reward():
def calculate_reward(policy_config: PolicyConfig, rubric: EvaluationRubric) -> float:
# Your custom reward logic here
return reward
Use train_grpo_advanced.py for more control over the rollout process:
python train_grpo_advanced.py
Modify dataset size in code or .env:
train_queries = load_synthetic_queries(
split="train",
limit=100, # Smaller for testing
shuffle=True,
)
Build and run with Docker:
# Build
docker build -t email-agent-grpo -f Dockerfile .
# Run training
docker run --gpus all -v $(pwd)/outputs:/workspace/outputs email-agent-grpo
accelerate for distributed training across multiple GPUsGRADIENT_ACCUMULATION_STEPS if memory is limitedMAX_TURNS to speed up rollouts during developmentMake sure the database is generated:
./scripts/generate_database.sh
Reduce batch size or increase gradient accumulation:
export PER_DEVICE_TRAIN_BATCH_SIZE=1
export GRADIENT_ACCUMULATION_STEPS=8
Check your OpenAI API key in .env:
echo $OPENAI_API_KEY
Apache 2.0
If you use this code in your research, please cite:
@misc{email-agent-grpo,
title={Email Agent GRPO Training with Unsloth},
year={2025},
publisher={GitHub},
url={https://github.com/your-repo/rl-unsloth}
}
20 commits
Python
89.8%
Shell
9.8%