CloudFinOpsEnv / README.md
jacklachan's picture
Upload folder using huggingface_hub
daace4d verified
|
Raw
History Blame Contribute Delete
11.5 kB
---
title: CloudFinOpsEnv
emoji: πŸ’°
colorFrom: blue
colorTo: green
sdk: docker
app_port: 7860
tags:
- openenv
---
# CloudFinOpsEnv
**An OpenEnv environment where LLM agents learn to optimize cloud infrastructure costs by identifying waste, right-sizing resources, and safely pruning orphaned assets -- without breaking production.**
> **Meta PyTorch OpenEnv Hackathon** | Team: **Three Musketeers** (Utkarsh, Mohit, Tanush)
---
## Motivation
Cloud waste is a **$100B+ annual problem**. Every DevOps and FinOps team spends hours manually identifying orphaned EBS volumes, over-provisioned instances, idle NAT gateways, and resources that drain budgets without serving any purpose.
CloudFinOpsEnv tests whether LLM agents can learn to do this automatically -- navigating realistic cloud infrastructure with production constraints, resource dependencies, cluster quorum requirements, and budget targets. An agent that masters this environment represents a genuine step toward autonomous cloud cost optimization.
---
## Quick Start
### Docker (Recommended)
```bash
docker build -t cloudfinopsenv .
docker run -p 7860:7860 cloudfinopsenv
```
### Local Development
```bash
pip install -r requirements.txt
uvicorn app:app --host 0.0.0.0 --port 7860
```
### Verify It Works
```bash
# Health check
curl http://localhost:7860/health
# Run all tests (89 tests)
python -m pytest tests/ -v
# Run oracle validation (no LLM needed, proves all 3 tasks work)
python test_oracle_e2e.py
```
---
## Environment Variables
| Variable | Description | Example |
|----------|-------------|---------|
| `API_BASE_URL` | LLM API endpoint | `https://router.huggingface.co/v1` |
| `HF_TOKEN` | HuggingFace API token | `hf_xxxxx` |
| `MODEL_NAME` | Model identifier | `meta-llama/Meta-Llama-3-8B-Instruct` |
| `ENV_URL` | CloudFinOpsEnv server URL | `http://localhost:7860` |
### Running Inference
```bash
export API_BASE_URL="https://router.huggingface.co/v1"
export HF_TOKEN="your-token"
export MODEL_NAME="meta-llama/Meta-Llama-3-8B-Instruct"
export ENV_URL="http://localhost:7860"
python inference.py
```
---
## API Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/health` | GET | Health check -- returns `{"status": "healthy"}` |
| `/reset` | POST | Start new episode: `{"task_id": "easy_orphan_cleanup"}` |
| `/step` | POST | Take action: `{"action": {"action_type": "delete", "resource_id": "vol-xxx"}}` |
| `/state` | GET | Full internal state (oracle/debug) |
| `/schema` | GET | Action, observation, and state JSON schemas |
| `/metadata` | GET | Environment metadata |
| `/ws` | WebSocket | Persistent session endpoint (used by `inference.py`) |
---
## Environment Description
CloudFinOpsEnv simulates a realistic AWS cloud infrastructure account containing:
- **Wasteful resources** -- detached EBS volumes, unused Elastic IPs, stopped instances
- **Over-provisioned resources** -- EC2/RDS instances running at 2-5% CPU utilization
- **Critical production resources** -- must NOT be touched (deleting = instant score zero)
- **Dependency-linked resources** -- Kafka clusters with quorum, RDS primary/replica pairs, circular dependencies
The agent interacts through a **query -> investigate -> analyze -> act -> commit** loop, using metrics, tags, and dependency checks to make safe optimization decisions.
### Resource Types (7)
`ec2_instance`, `ebs_volume`, `rds_instance`, `s3_bucket`, `elastic_ip`, `nat_gateway`, `load_balancer`
---
## Action Space (8 Actions)
| Action | Description | Reward |
|--------|-------------|--------|
| `query_metrics(resource_id)` | Get 7-day CPU/memory/network usage | -0.015 |
| `check_deps(resource_id)` | Check resource dependencies and cluster info | -0.013 |
| `delete(resource_id, reason)` | Permanently remove a resource | +0.10 per $10/mo saved |
| `stop(resource_id, reason)` | Stop a running instance (reversible) | +0.05 per $10/mo saved |
| `resize(resource_id, new_size, reason)` | Change instance/DB tier | +0.08 per $10/mo saved |
| `detach(resource_id)` | Detach a volume from instance | -0.01 |
| `list_resources()` | Refresh resource list | -0.012 |
| `commit_changes()` | Finalize and end episode | bonus if >50% optimal |
**Safety penalties:**
- Delete production/critical resource: **-1.01** (catastrophic, zeroes final score)
- Delete resource with active dependencies: **-0.51**
- Bad resize (CPU >80% after downsize): **-0.21**
---
## Observation Space
Each observation includes:
| Field | Type | Description |
|-------|------|-------------|
| `task_description` | string | Natural language task brief |
| `resources` | List[Resource] | Cloud resources with ID, type, name, status, cost/hour, tags, age, attachments, dependencies |
| `total_monthly_cost` | float | Current total monthly cost (USD) |
| `budget_target` | float | Target monthly cost (medium/hard tasks) |
| `maintenance_window` | string | Allowed modification window (hard task) |
| `step_number` / `max_steps` | int | Current step and episode limit |
| `message` | string | Environment feedback from last action |
| `cost_saved_so_far` | float | Total savings achieved |
| `actions_taken` | List[str] | History of agent actions this episode |
Resource metrics (CPU, memory, network, IOPS) are **hidden** until explicitly queried via `query_metrics`.
---
## Tasks (3 Difficulty Levels)
### Task 1: Easy -- Orphan Cleanup
- **Resources:** 10 (6 wasteful, 4 production)
- **Max steps:** 15
- **Objective:** Delete orphaned/detached resources with clear signals (`status: "detached"`, `attached_to: null`)
- **Optimal savings:** $63.22/month
- **Expected LLM score:** 0.7 -- 0.9
### Task 2: Medium -- Right-Size & Prune
- **Resources:** 20 (6 wasteful + 3 over-provisioned, 11 production)
- **Max steps:** 25
- **Budget target:** $3,800/month
- **Objective:** Right-size over-provisioned instances AND clean waste. Requires querying metrics and understanding instance tiers.
- **Optimal savings:** $1,037.84/month
- **Expected LLM score:** 0.4 -- 0.6
### Task 3: Hard -- Dependency-Aware Migration
- **Resources:** 35 (7 wasteful + 6 resizable, 22 production/critical)
- **Max steps:** 40
- **Maintenance window:** 02:00--06:00 UTC
- **Objective:** Optimize costs with Kafka cluster quorum constraints, RDS primary/replica pairs, circular dependencies, maintenance windows, and decoy resources.
- **Optimal savings:** $2,513.54/month
- **Expected LLM score:** 0.1 -- 0.3
---
## Reward Function
**Per-step rewards** provide continuous signal throughout the episode:
- Correct optimizations: **positive** reward proportional to dollar savings
- Investigation actions (query, check_deps): **tiny negative** cost (encourages efficiency)
- Deleting production resources: **-1.01** (catastrophic, zeroes entire episode)
- Each step has a small time pressure cost
**Final grading** uses a deterministic oracle formula (no LLM-as-judge):
```
Easy: score = (savings / optimal) * safety_mult
Medium: score = (savings / optimal) * safety_mult - (steps * 0.005)
Hard: score = ((savings - cascade) / optimal) * safety_mult - (steps * 0.003)
```
`safety_multiplier = 0.0` if any production resource is deleted/stopped. All scores clamped to [0.0, 1.0].
---
## Baseline Scores
### Oracle Solution (Deterministic, No LLM)
| Task | Score | Savings |
|------|-------|---------|
| Easy: Orphan Cleanup | **1.000** | $63.22 / $63.22 (100%) |
| Medium: Right-Size & Prune | **0.987** | $1,024.41 / $1,037.84 (99%) |
| Hard: Dependency Migration | **1.000** | $2,582.96 / $2,513.54 (103%) |
### Expected LLM Agent (Meta-Llama-3-8B-Instruct)
| Task | Expected Score | Notes |
|------|---------------|-------|
| Easy | 0.7 -- 0.9 | Clear signals, most LLMs handle well |
| Medium | 0.4 -- 0.6 | Requires metrics analysis and tier knowledge |
| Hard | 0.1 -- 0.3 | Dependency reasoning is genuinely hard for LLMs |
---
## Project Architecture
```
CloudFinOpsEnv/
β”œβ”€β”€ app.py # FastAPI server entry point
β”œβ”€β”€ inference.py # Baseline LLM agent (OpenAI client)
β”œβ”€β”€ test_oracle_e2e.py # Oracle validation script (no LLM needed)
β”œβ”€β”€ openenv.yaml # OpenEnv metadata
β”œβ”€β”€ Dockerfile # Docker container config (port 7860)
β”œβ”€β”€ requirements.txt # Python dependencies
β”œβ”€β”€ pyproject.toml # Package configuration
β”œβ”€β”€ client.py # OpenEnv WebSocket client
β”‚
β”œβ”€β”€ models/ # Pydantic data models
β”‚ β”œβ”€β”€ observation.py # Observation, Resource, UsageMetrics
β”‚ β”œβ”€β”€ action.py # Action, ActionType (8 actions)
β”‚ β”œβ”€β”€ reward.py # Reward decomposition
β”‚ └── state.py # EnvironmentState (oracle/god-mode)
β”‚
β”œβ”€β”€ engine/ # Core environment logic
β”‚ β”œβ”€β”€ environment.py # reset(), step(), state() implementation
β”‚ β”œβ”€β”€ grader.py # Deterministic oracle scoring formulas
β”‚ β”œβ”€β”€ reward_calculator.py # Per-step reward computation
β”‚ └── dependency_graph.py # Resource dependency and quorum management
β”‚
β”œβ”€β”€ data/ # Deterministic scenario data
β”‚ β”œβ”€β”€ generator.py # Data loader
β”‚ β”œβ”€β”€ scenarios/ # 3 curated task JSONs (10, 20, 35 resources)
β”‚ β”œβ”€β”€ solutions/ # Oracle optimal action sequences
β”‚ └── pricing/ # Real AWS us-east-1 on-demand pricing
β”‚
β”œβ”€β”€ server/ # Server entry point (openenv multi-mode)
β”‚ └── app.py # main() for uv run / openenv serve
β”‚
└── tests/ # Test suite (89 tests)
β”œβ”€β”€ test_environment.py # Core environment logic tests
β”œβ”€β”€ test_grader.py # Oracle scoring formula tests
└── test_generator.py # Data loader and model tests
```
---
## Validation
```bash
# Local structure validation
openenv validate
# Output: [OK] Three-Musketeers: Ready for multi-mode deployment
# Runtime validation against live server
openenv validate --url http://localhost:7860
# Output: 6/6 criteria passed
# Unit tests
python -m pytest tests/ -v
# Output: 89 passed
# Oracle end-to-end (proves all tasks work, no LLM needed)
python test_oracle_e2e.py
# Output: Average Score 0.996, ALL TASKS PASSED
```
---
## Design Decisions
1. **Deterministic oracle grader** -- Mathematical formula, no LLM-as-judge, fully reproducible
2. **Curated JSON scenarios** -- Hand-crafted with real AWS pricing, not randomly generated
3. **Hidden metrics** -- Agents must explicitly query usage data before acting (mirrors real FinOps)
4. **Safety-first penalties** -- Deleting production resources is catastrophic (-1.01), encouraging investigation before action
5. **Scalable difficulty** -- Easy has clear signals, medium requires metric analysis, hard involves graph reasoning with quorum and cascading constraints
6. **Runs offline** -- Zero external API dependencies, all synthetic data, fits in Docker with <100MB
---
## Team
**Three Musketeers**
- Utkarsh Singh Yadav (Team Lead)
- Mohit Jain
- Tanush Deepak