supplymind / README.md
rishavutk's picture
Embed evidence plots in README
82d40c1 verified
|
Raw
History Blame Contribute Delete
8.17 kB
---
title: SupplyMind OpenEnv
sdk: docker
app_port: 7860
---
# SupplyMind
SupplyMind is an OpenEnv environment for training LLM agents to coordinate a regional supply network. A central coordinator allocates depot stock, buys replenishment, and brokers transfers; local warehouses accept customer orders, manage inventory, and expose offers or requests. The task is multi-agent because local and central incentives are related but not identical, and the center acts under partial observability.
Demo / HF Space: [rishavutk/supplymind](https://huggingface.co/spaces/rishavutk/supplymind)
The demo is playable in the browser with the built-in heuristic strategy, so reviewers can step through a full episode without running training first.
Key links:
- Demo Space: [https://huggingface.co/spaces/rishavutk/supplymind](https://huggingface.co/spaces/rishavutk/supplymind)
- Training notebook: [SupplyMind_Training_Run.ipynb](SupplyMind_Training_Run.ipynb)
- Mini-blog: [blog.md](blog.md)
## Why It Matters
Real supply-chain operations are not single-turn question answering. They require repeated decisions under scarcity:
- demand arrives over time
- inventory spoils or sits idle
- deliveries and transfers cost money
- local warehouses know more about local orders than the center
- helping one warehouse can hurt another later
SupplyMind turns this into a verifiable RL environment with structured observations, JSON actions, and programmatic rewards.
## Theme Fit
Primary hackathon theme: **Theme #1 - Multi-Agent Interactions**.
The environment includes cooperation, competition, negotiation, partial observability, and coalition-like inventory sharing. The center can improve global outcomes only by reasoning about warehouse needs, costs, and incentives.
## Environment
The world models a quick-commerce supply network:
```text
supplier -> central depot -> regional warehouses -> customers
```
Tracked SKUs:
- `fresh_milk`
- `rice_bag_5kg`
- `insulin_pack`
- `usb_c_charger`
Public tasks:
| Task | Warehouses | Rounds |
|---|---:|---:|
| `easy` | 3 | 18 |
| `medium` | 4 | 26 |
| `hard` | 5 | 34 |
Training aliases are also available as `v2_train_easy`, `v2_train_medium`, and `v2_train_hard`.
## Agent Interfaces
The joint action has two role surfaces:
```json
{
"warehouse_actions": {
"north": {
"order_decisions": [{"order_id": "o1", "decision": "accept"}],
"inventory_offers": [{"sku": "fresh_milk", "units": 2, "ask_price": 6.0}],
"inventory_requests": [{"sku": "insulin_pack", "units": 2, "max_price": 12.0}],
"transfer_responses": [{"proposal_id": "p1", "decision": "accept"}],
"local_priority": [{"sku": "insulin_pack", "priority": 3}]
}
},
"central_action": {
"central_procurements": [{"sku": "fresh_milk", "units": 4, "max_unit_cost": 4.0}],
"central_liquidations": [{"sku": "fresh_milk", "units": 2}],
"central_replenishments": [{"to_warehouse": "north", "sku": "insulin_pack", "units": 2, "unit_price": 12.0}],
"inventory_transfer_proposals": [{"from_warehouse": "west", "to_warehouse": "north", "sku": "rice_bag_5kg", "units": 2, "compensation": 10.0}],
"offer_matches": [{"offer_signal_id": "west:offer:rice_bag_5kg", "request_signal_id": "north:request:rice_bag_5kg", "units": 2, "compensation": 10.0}]
}
}
```
The repo also exposes role-specific training endpoints:
- `/v2/center/*`: train the center while warehouses are frozen to a heuristic
- `/v2/warehouse/*`: train warehouse behavior while the center is frozen
- `/v2/step`: evaluate both roles together in the same world
## Reward And Grading
The official score uses **global welfare**:
```text
global_welfare =
fulfilled_customer_value
- procurement_cost
- center_shipment_cost
- transfer_cost
- warehouse_delivery_cost
- holding_cost
- spoilage_cost
- stockout_penalty
- terminal_leftover_penalty
- fairness_penalty
- invalid_action_penalty
```
Role-specific rewards are also tracked:
- center reward: wholesale margin, useful service share, broker fees, depot costs, stockout share
- warehouse reward: customer fulfillment revenue, local costs, missed-order penalties, transfer economics
These role rewards are used for role training evidence. The official benchmark score remains global welfare.
Final score is normalized against a naive baseline and a privileged bounded planner:
```text
progress = (raw_reward - baseline_reward) / (target_reward - baseline_reward)
if progress <= 1:
score = 0.05 + progress * 0.90
else:
score = 0.95 + min(progress - 1, 1.0) * 0.0499
```
The target planner is a strong reference policy, not a claimed mathematical optimum.
## Training Evidence
Our final training evidence is:
```text
Base Qwen -> SFT warm start -> GRPO improvement
```
Held-out role-eval results on seeds `131, 149, 163`:
| Role | Variant | Global score | Role score | Raw reward | Invalid payloads | Invalid actions |
|---|---|---:|---:|---:|---:|---:|
| warehouse | Base Qwen 0.5B | 0.0001 | 0.0001 | -864.40 | 36 | 0 |
| warehouse | SFT parent | 0.2343 | 0.2166 | 26.05 | 0 | 69 |
| warehouse | GRPO child | 0.2801 | 0.2881 | 58.73 | 1 | 58 |
| center | Base Qwen 0.5B | 0.5172 | 0.6336 | 176.12 | 36 | 0 |
| center | SFT parent | 0.5327 | 0.5977 | 186.56 | 0 | 22 |
| center | GRPO child | 0.6469 | 0.7626 | 239.21 | 0 | 0 |
![Center role score improves after GRPO](assets/blog/center_role_score_improvement.png)
![Warehouse role score improves modestly after GRPO](assets/blog/warehouse_role_score_improvement.png)
Joint validation with the promoted trained policies:
```text
global score 0.4941
raw global reward 151.91
center role score 0.7206
warehouse role score 0.5254
center reward 52.59
average warehouse reward 28.04
```
![Joint validation: trained policies playing together](assets/blog/joint_trained_agents_reward.png)
The center GRPO run also shows the expected noisy-but-useful RL signal, so we track reward and invalid actions alongside loss.
![Center SFT and GRPO training curves](assets/blog/center_training_loss_curves.png)
Curated text evidence lives in [results/submission/summary.md](results/submission/summary.md).
## Run Locally
Install:
```bash
pip install -r requirements.txt
```
Start the Space/API:
```bash
uvicorn app:app --host 0.0.0.0 --port 7860
```
Open:
```text
http://127.0.0.1:7860/
```
Useful endpoints:
```text
POST /reset
GET /state
POST /step
GET /v2/rules
GET /v2/ui
GET /v2/dashboard
```
## Reproduce
Environment validation:
```bash
python validate_submission.py
```
Policy baselines:
```bash
python scripts/evaluate_v2_policies.py
```
Role training and evaluation scripts:
```bash
python scripts/hf_sft_supplymind_roles.py --help
python scripts/hf_train_supplymind_roles.py --help
python scripts/hf_eval_supplymind_adapters.py --help
```
Runnable training notebook:
```text
SupplyMind_Training_Run.ipynb
```
The notebook is intended to reproduce the training method end-to-end: environment smoke test, SFT warm-start, GRPO from the SFT adapter, and held-out evaluation. Its default step counts are intentionally short so judges can rerun it quickly. The promoted adapters in the table above were produced by longer HF runs with the same role-specific training scripts and fixed seed protocol, so exact scores may differ in a short notebook rerun.
## Project Structure
```text
src/supplymind_env_v2/ environment, models, rewards, generator, planner
src/supplymind_env/api.py FastAPI app mounting V2 routes
static/v2.html interactive episode UI
inference.py deterministic benchmark inference path
scripts/ training, evaluation, and preflight scripts
configs/ documented reward configuration
results/submission/ curated judge-facing text evidence
```
## Notes
We also experimented with same-rollout multi-agent adapter updates. Those scripts are kept as experimental scaffolding, but the final submission evidence focuses on the stable and reproducible role-training path: SFT for action format, then GRPO for reward improvement.