|
1 | | -SWE-bench (Remote) - Local (non-Docker) Setup and Usage |
| 1 | +# SWE-bench Evaluation Example |
2 | 2 |
|
3 | | -Prerequisites |
4 | | -- Python 3.12 environment (same one you use for this repo) |
5 | | -- Fireworks API key |
6 | | -- mini-swe-agent and datasets (for patch generation) |
7 | | -- SWE-bench harness installed (for evaluation) |
| 3 | +This example shows how to evaluate LLM models on the SWE-bench software engineering benchmark using eval-protocol. |
8 | 4 |
|
9 | | -Setup mini-swe-agent (non-Docker) |
10 | | -1) Install dependencies |
11 | | -```bash |
12 | | -pip install mini-swe-agent datasets |
13 | | -``` |
| 5 | +## Quick Start |
| 6 | + |
| 7 | +### 1. Install Dependencies |
14 | 8 |
|
15 | | -2) Configure API key for mini-swe-agent |
16 | 9 | ```bash |
17 | | -mini-extra config set FIREWORKS_API_KEY <your_fireworks_key> |
| 10 | +# From the python-sdk repository root |
| 11 | +cd python-sdk |
| 12 | + |
| 13 | +# Install eval-protocol with swebench support |
| 14 | +pip install -e ".[swebench]" |
18 | 15 | ``` |
19 | 16 |
|
20 | | -3) (Optional) Test connectivity |
| 17 | +### 2. Set up mini-swe-agent |
| 18 | + |
| 19 | +mini-swe-agent requires a Fireworks API key to function: |
| 20 | + |
21 | 21 | ```bash |
22 | | -python3 examples/swebench/run_swe_agent_fw.py fireworks_ai/accounts/fireworks/models/kimi-k2-instruct-0905 --test |
| 22 | +# Configure API key for mini-swe-agent |
| 23 | +mini-extra config set FIREWORKS_API_KEY your_fireworks_api_key |
| 24 | + |
| 25 | +# Verify it's set |
| 26 | +mini-extra config get FIREWORKS_API_KEY |
23 | 27 | ``` |
24 | 28 |
|
25 | | -Install SWE-bench evaluation harness |
| 29 | +### 3. Install SWE-bench Harness |
| 30 | + |
26 | 31 | ```bash |
| 32 | +# Navigate to the swebench example directory |
| 33 | +cd examples/swebench |
| 34 | + |
| 35 | +# Clone and install SWE-bench |
27 | 36 | git clone https://github.com/princeton-nlp/SWE-bench |
28 | 37 | pip install -e SWE-bench |
29 | 38 | ``` |
30 | 39 |
|
31 | | -Environment |
| 40 | +### 4. Set Environment Variables |
| 41 | + |
| 42 | +```bash |
| 43 | +export FIREWORKS_API_KEY="your_fireworks_api_key" |
| 44 | +``` |
| 45 | + |
| 46 | +## Running the Evaluation |
| 47 | + |
| 48 | +**IMPORTANT:** Always run both the server and tests from the `examples/swebench/` directory. |
| 49 | + |
| 50 | +### Step 1: Start the Server |
| 51 | + |
| 52 | +Open a terminal and run: |
| 53 | + |
| 54 | +```bash |
| 55 | +cd examples/swebench |
| 56 | +python server.py |
| 57 | +``` |
| 58 | + |
| 59 | +You should see: |
| 60 | +``` |
| 61 | +INFO: Uvicorn running on http://127.0.0.1:3000 (Press CTRL+C to quit) |
| 62 | +``` |
| 63 | + |
| 64 | +### Step 2: Configure Your Test |
| 65 | + |
| 66 | +Edit `tests/test_swebench.py` to set your model and parameters: |
| 67 | + |
| 68 | +```python |
| 69 | +completion_params=[{ |
| 70 | + "model": "accounts/fireworks/models/your-model-name", # Edit this |
| 71 | + "model_kwargs": { |
| 72 | + "temperature": 0.2, # Optional |
| 73 | + # "max_tokens": 2048, # Optional |
| 74 | + # "reasoning": "high", # Optional |
| 75 | + } |
| 76 | +}], |
| 77 | +max_concurrent_rollouts=3, # How many instances to run in parallel |
| 78 | +``` |
| 79 | + |
| 80 | +To test different numbers of instances, edit line 26: |
| 81 | +```python |
| 82 | +def rows() -> List[EvaluationRow]: |
| 83 | + return rows_from_indices(2) # Change 2 to desired number (max 500) |
| 84 | +``` |
| 85 | + |
| 86 | +### Step 3: Run the Test |
| 87 | + |
| 88 | +Open a second terminal: |
| 89 | + |
| 90 | +```bash |
| 91 | +cd examples/swebench |
| 92 | +pytest tests/test_swebench.py -v -s |
| 93 | +``` |
| 94 | + |
| 95 | +## What Happens During a Run |
| 96 | + |
| 97 | +For each instance (row): |
| 98 | + |
| 99 | +1. **Server receives request** from pytest |
| 100 | +2. **Wrapper script** (`run_swe_agent_fw.py`) is called with the instance index |
| 101 | +3. **mini-swe-agent** runs in a Docker container for that specific repository |
| 102 | +4. **Agent attempts to solve** the issue by editing code |
| 103 | +5. **Patch is generated** and saved to `preds.json` |
| 104 | +6. **SWE-bench harness** applies the patch and runs tests |
| 105 | +7. **Results** are written to the row directory |
| 106 | +8. **Test fetches results** and displays pass/fail in the UI |
| 107 | + |
| 108 | +## Understanding the Output |
| 109 | + |
| 110 | +### Directory Structure |
| 111 | + |
| 112 | +Each instance creates its own `row_N/` directory: |
| 113 | + |
| 114 | +``` |
| 115 | +examples/swebench/ |
| 116 | +├── row_0/ # First instance |
| 117 | +│ ├── preds.json # ← Model's generated patch |
| 118 | +│ ├── astropy__astropy-12907/ # Instance-specific folder |
| 119 | +│ │ └── astropy__astropy-12907.traj.json # Agent's execution trace |
| 120 | +│ ├── logs/ # Harness execution logs |
| 121 | +│ │ └── run_evaluation/ |
| 122 | +│ │ └── eval-run/ |
| 123 | +│ │ └── <safe_model_name>/ |
| 124 | +│ │ └── astropy__astropy-12907/ |
| 125 | +│ │ ├── report.json # ← Test results (pass/fail) |
| 126 | +│ │ ├── test_output.txt # Test execution output |
| 127 | +│ │ ├── patch.diff # Applied patch |
| 128 | +│ │ └── eval.sh # Evaluation script |
| 129 | +│ ├── agent_0.log # Agent console output |
| 130 | +│ ├── exit_statuses_*.yaml # Exit status if failed |
| 131 | +│ └── <model_name>.eval-run.json # Overall run summary |
| 132 | +├── row_1/ # Second instance |
| 133 | +│ └── ... |
| 134 | +└── ... |
| 135 | +``` |
| 136 | + |
| 137 | +### Key Files Explained |
| 138 | + |
| 139 | +#### `preds.json` - Model Predictions |
| 140 | +Location: `row_N/preds.json` |
| 141 | + |
| 142 | +Contains the patch generated by the model: |
| 143 | +```json |
| 144 | +{ |
| 145 | + "astropy__astropy-12907": { |
| 146 | + "model_name_or_path": "accounts/fireworks/models/...", |
| 147 | + "instance_id": "astropy__astropy-12907", |
| 148 | + "model_patch": "diff --git a/... (the actual patch)" |
| 149 | + } |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +**If missing:** Agent failed before generating a patch (check `exit_statuses_*.yaml`) |
| 154 | + |
| 155 | +#### `report.json` - Test Results |
| 156 | +Location: `row_N/logs/run_evaluation/eval-run/<model_name>/<instance_id>/report.json` |
| 157 | + |
| 158 | +Contains pass/fail status after running tests: |
| 159 | +```json |
| 160 | +{ |
| 161 | + "astropy__astropy-12907": { |
| 162 | + "patch_is_None": false, |
| 163 | + "patch_exists": true, |
| 164 | + "patch_successfully_applied": true, |
| 165 | + "resolved": true, // ← Was the issue fixed? |
| 166 | + "tests_status": { |
| 167 | + "FAIL_TO_PASS": {"success": [...], "failure": []}, |
| 168 | + "PASS_TO_PASS": {"success": [...], "failure": []} |
| 169 | + } |
| 170 | + } |
| 171 | +} |
| 172 | +``` |
| 173 | + |
| 174 | +- `resolved: true` = Instance solved! All required tests pass. |
| 175 | +- `resolved: false` = Instance not solved (tests still failing) |
| 176 | + |
| 177 | +**If missing:** Agent didn't generate a patch or harness didn't run |
| 178 | + |
| 179 | +#### `exit_statuses_*.yaml` - Why Runs Failed |
| 180 | +Location: `row_N/exit_statuses_*.yaml` |
| 181 | + |
| 182 | +```yaml |
| 183 | +instances_by_exit_status: |
| 184 | + Submitted: [] |
| 185 | + LimitsExceeded: ["astropy__astropy-12907"] # Hit step/cost limits |
| 186 | + Error: [] |
| 187 | +``` |
| 188 | +
|
| 189 | +Common statuses: |
| 190 | +- `Submitted`: Completed normally |
| 191 | +- `LimitsExceeded`: Agent hit max steps or cost limit |
| 192 | +- `Error`: Unexpected error during execution |
| 193 | + |
| 194 | +#### `agent_N.log` - Agent Execution |
| 195 | +Location: `row_N/agent_N.log` |
| 196 | + |
| 197 | +Full console output from the agent run, including: |
| 198 | +- Docker container startup |
| 199 | +- Model API calls |
| 200 | +- Commands executed |
| 201 | +- Errors (if any) |
| 202 | + |
| 203 | +#### `*.traj.json` - Agent Trajectory |
| 204 | +Location: `row_N/<instance_id>/<instance_id>.traj.json` |
| 205 | + |
| 206 | +Complete record of the agent's execution: |
| 207 | +```json |
| 208 | +{ |
| 209 | + "instance_id": "astropy__astropy-12907", |
| 210 | + "info": { |
| 211 | + "submission": "...", // The patch |
| 212 | + "exit_status": "Submitted", |
| 213 | + "model_stats": { |
| 214 | + "instance_cost": 0.05, |
| 215 | + "api_calls": 15 |
| 216 | + } |
| 217 | + }, |
| 218 | + "messages": [...] // All agent messages |
| 219 | +} |
| 220 | +``` |
| 221 | + |
| 222 | +## Viewing Results |
| 223 | + |
| 224 | +### In the Terminal |
| 225 | + |
| 226 | +The test output shows: |
| 227 | +``` |
| 228 | +INFO:test_swebench:[Row 0] Found instance_id: astropy__astropy-12907 |
| 229 | +INFO:test_swebench:[Row 0] Report says resolved=True |
| 230 | +INFO:test_swebench:[Row 0] Final: resolved=True, reason=harness_resolved=True |
| 231 | +``` |
| 232 | + |
| 233 | +### In the Eval Protocol UI |
| 234 | + |
| 235 | +If Elasticsearch is running, visit: `http://localhost:8000` |
| 236 | +- View aggregate scores |
| 237 | +- Inspect individual trajectories |
| 238 | +- Filter by resolved/unresolved |
| 239 | +- See cost and token usage |
| 240 | + |
| 241 | +### Check Individual Files |
| 242 | + |
32 | 243 | ```bash |
33 | | -export FIREWORKS_API_KEY="<your_fireworks_key>" |
| 244 | +# Check if instance was solved |
| 245 | +cat row_0/logs/run_evaluation/eval-run/<model>/astropy__astropy-12907/report.json | jq '.["astropy__astropy-12907"].resolved' |
| 246 | +
|
| 247 | +# View the generated patch |
| 248 | +cat row_0/preds.json | jq '.["astropy__astropy-12907"].model_patch' |
| 249 | +
|
| 250 | +# Check exit status |
| 251 | +cat row_0/exit_statuses_*.yaml |
34 | 252 | ``` |
35 | 253 |
|
36 | | -Run the server |
| 254 | +## Performance Notes |
| 255 | + |
| 256 | +- **Small test (2 instances):** ~10-30 minutes |
| 257 | +- **Full dataset (500 instances):** 24-48 hours on a 16-core machine |
| 258 | +- **Concurrent runs:** Recommended 3-5 based on CPU/memory |
| 259 | +- **Docker space:** ~100GB for all images (downloads happen automatically) |
| 260 | + |
| 261 | +## Troubleshooting |
| 262 | + |
| 263 | +### Docker container fails to start |
37 | 264 | ```bash |
38 | | -python examples/swebench/server.py |
| 265 | +# Check Docker is running |
| 266 | +docker ps |
| 267 | +
|
| 268 | +# Check disk space |
| 269 | +df -h |
39 | 270 | ``` |
40 | 271 |
|
41 | | -What the server does |
42 | | -- Invokes `run_swe_agent_fw.py` in batch mode with a single-slice per request |
43 | | -- Writes outputs to a per-row directory: `./row_{index}/` |
44 | | - - `row_{index}/preds.json` |
45 | | - - `row_{index}/<instance_id>/<instance_id>.traj.json` |
46 | | -- Runs the SWE-bench harness on `row_{index}/preds.json` |
| 272 | +### Agent hits step limits |
| 273 | +Instances that consistently hit limits may need: |
| 274 | +- Higher step limit (edit mini-swe-agent config) |
| 275 | +- Different prompting strategy |
| 276 | +- More capable model |
47 | 277 |
|
48 | | -Run pytest to evaluate a model on SWE-bench |
| 278 | +### Server not responding |
49 | 279 | ```bash |
50 | | -cd /Users/shrey/Documents/python-sdk |
51 | | -pytest examples/swebench/tests/test_swebench.py -v -s |
| 280 | +# Check server is running |
| 281 | +curl http://127.0.0.1:3000/status?rollout_id=test |
| 282 | +
|
| 283 | +# Check server logs for errors |
| 284 | +# (shown in terminal where server.py is running) |
52 | 285 | ``` |
53 | 286 |
|
54 | | -Notes |
55 | | -- The test currently generates 10 rows by numeric index (0–9) |
56 | | -- Each request triggers the server to run one SWE-bench instance and write to its own `row_{index}` |
57 | | -- Control harness workers via: `export SWEBENCH_EVAL_WORKERS=5` |
| 287 | +## Next Steps |
| 288 | + |
| 289 | +- Review results in `row_*/logs/.../report.json` |
| 290 | +- Analyze failed instances to improve your model |
| 291 | +- Run on larger subsets to get statistical significance |
| 292 | +- Export results for further analysis |
| 293 | + |
| 294 | +## Support |
| 295 | + |
| 296 | +For issues: |
| 297 | +- Check agent logs: `row_N/agent_N.log` |
| 298 | +- Check exit statuses: `row_N/exit_statuses_*.yaml` |
| 299 | +- Verify Docker has sufficient resources |
| 300 | +- Ensure API key is valid and has credits |
0 commit comments