umar-sharif821 commited on
Commit
ca40719
·
verified ·
1 Parent(s): d4535f9

Update README.md

Browse files

So I built **CDN Cache Optimizer**.

It is an OpenEnv-compatible environment where an agent learns how to manage an edge CDN cache.
CDNs serve images, videos, scripts, documents, and application assets to users around the world.

A good cache policy can:

- reduce user latency
- reduce origin load
- save bandwidth
- improve reliability
- avoid unnecessary cache churn

A poor cache policy can do the opposite.

Files changed (1) hide show
  1. README.md +93 -187
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: CDN Cache Optimizer
3
  emoji: 🌐
4
  colorFrom: blue
5
  colorTo: green
@@ -13,237 +13,143 @@ tags:
13
  - hackathon
14
  ---
15
 
16
- # CDN Cache Optimizer - OpenEnv RL Agent
17
 
18
- Hackathon-ready OpenEnv project for **edge CDN cache admission and eviction**. It simulates the real production tradeoff between serving from a fast edge cache and falling back to slower origin fetches, while handling schema drift in CDN logs.
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  ---
21
 
22
- ## Why It Matters
 
 
23
 
24
- Content Delivery Networks serve billions of files daily. Edge servers have limited storage, so they must constantly decide: *which cached files to keep, and which to evict?* Standard algorithms like LRU aren't optimal — especially when traffic has **viral bursts** (a file suddenly gets 50x more requests for 20 minutes, then drops back to zero).
25
 
26
- A smarter agent can:
27
- - Predict viral spikes from queue previews
28
- - Avoid evicting high-frequency files
29
- - Prevent cache thrashing (evicting then immediately re-requesting)
30
- - Maximize bandwidth saved for users
 
 
 
 
 
 
31
 
32
  ---
33
 
34
- ## Live Demo
35
 
36
- This repo is Hugging Face Spaces-ready. The Docker Space runs `app.py`, a Gradio UI that compares:
37
 
38
- - **Baseline LRU**: always evicts the least recently used file.
39
- - **Fine-tuned Agent**: preserves viral/previewed objects, avoids bulky cold admissions, and evicts low-value content under cache pressure.
40
 
41
- Run locally:
 
 
 
 
42
 
43
- ```bash
44
- pip install -r requirements.txt
45
- python app.py
46
- ```
47
 
48
- Open `http://localhost:7860`.
49
 
50
- ## Google Colab Submission
51
 
52
- For judges who want a single reproducible run:
53
 
54
- ```python
55
- !python /content/colab_submission_script.py
56
- ```
57
 
58
- The script installs dependencies, mounts Drive when available, trains/evaluates the agent, verifies schema drift normalization, and saves:
59
 
60
- - `training_results.png`
61
- - `policy.pt`
62
- - `drift_report.json`
63
- - `metrics.json`
64
 
65
- ## Environment Description
66
 
67
- At each step, a file is requested from the network. If it is already in cache, the user is served from the edge. If not, the request goes to origin and the agent decides whether to admit the file and what to evict.
68
 
69
- ### Traffic Model
70
- - **Steady files**: consistent, cyclical demand.
71
- - **Viral files**: bell-curve spikes that fade back to baseline.
72
- - **Queue preview**: short lookahead signal similar to CDN prefetch telemetry.
73
 
74
- ### Reward Grounding
75
 
76
- The Colab RL environment uses a multi-component reward:
77
 
78
- ```text
79
- R = w1 * Perf - w2 * Cost
80
- ```
81
 
82
- `Perf` captures edge-latency savings versus origin fetch, while `Cost` penalizes cache churn and write/admission cost.
 
 
 
83
 
84
- ### Schema Drift
85
 
86
- `SchemaDriftGuard` in `colab_submission_script.py` normalizes CDN logs across renamed, missing, extra, and type-shifted fields, for example:
87
 
88
- - `ts`, `time`, `event_time` -> `timestamp`
89
- - `fid`, `object_id`, `oid` -> `file_id`
90
- - `bytes`, `size_bytes` -> `size_mb`
91
- - `cache_hit`, `is_hit` -> `hit`
92
 
93
- ---
94
 
95
- ## 📐 Action & Observation Space
96
-
97
- ### Observation Space
98
- | Field | Type | Description |
99
- |-------|------|-------------|
100
- | `step` | int | Current episode step |
101
- | `cache_used_mb` | float | MB currently used |
102
- | `cache_capacity_mb` | float | Total cache size |
103
- | `cache_fill_ratio` | float | 0.0–1.0 fill level |
104
- | `cached_files` | List[FileEntry] | All files in cache with metadata |
105
- | `incoming_file_id` | str | File being requested |
106
- | `incoming_file_size_mb` | float | Size of incoming file |
107
- | `incoming_file_is_viral` | bool | Is this file currently viral? |
108
- | `cache_hit` | bool | Is incoming file already cached? |
109
- | `recent_hit_rate` | float | Rolling hit rate (last 20 steps) |
110
- | `time_of_day` | float | Normalized 0.0–1.0 daily cycle |
111
- | `queue_preview` | List[str] | Next 3 file IDs (prefetch hint) |
112
-
113
- ### FileEntry Fields
114
- | Field | Type | Description |
115
- |-------|------|-------------|
116
- | `file_id` | str | Unique identifier |
117
- | `size_mb` | float | File size in MB |
118
- | `request_frequency` | float | Requests since cached |
119
- | `is_viral` | bool | Currently viral |
120
- | `last_accessed` | int | Step number of last access |
121
-
122
- ### Action Space
123
- | Field | Type | Description |
124
- |-------|------|-------------|
125
- | `evict_file_id` | str \| null | File to evict (null = no eviction) |
126
-
127
- ### Reward Function
128
- | Component | Range | Description |
129
- |-----------|-------|-------------|
130
- | `cache_hit_bonus` | +1.0 to +1.5 | Hit reward (viral hits = +1.5) |
131
- | `bandwidth_saved` | +0.0 to +0.2 | Reward for bandwidth efficiency |
132
- | `eviction_penalty` | -0.0 to -0.5 | Penalty for evicting popular files |
133
- | `thrash_penalty` | 0.0 or -0.5 | Penalty for evicting same file twice |
134
- | `wasted_capacity_penalty` | -0.0 to -0.3 | Penalty for leaving cache empty |
135
 
136
  ---
137
 
138
- ## 📋 Tasks
139
-
140
- ### Task 1: Steady Traffic Cache (Easy)
141
- - **Cache**: 100MB | **Files**: 30 | **Steps**: 100
142
- - No viral files — steady demand only
143
- - Agent learns basic LRU-style eviction
144
- - **Target hit rate**: ≥ 0.60 → score 1.0
145
- - **Baseline score**: ~0.75
146
-
147
- ### Task 2: Mixed Traffic Cache (Medium)
148
- - **Cache**: 80MB | **Files**: 50 | **Steps**: 150
149
- - 20% viral files mixed with steady demand
150
- - Agent must handle spikes and prioritize popular content
151
- - **Score**: 70% hit rate + 30% bandwidth
152
- - **Baseline score**: ~0.60
153
-
154
- ### Task 3: Constrained Cache with Viral Bursts (Hard)
155
- - **Cache**: 50MB | **Files**: 80 | **Steps**: 200
156
- - 35% viral files, tight capacity, large file sizes
157
- - Agent must predict spikes, avoid thrashing
158
- - **Score**: 50% hit rate + 25% bandwidth + 25% reward quality
159
- - **Baseline score**: ~0.45
160
 
161
- ---
162
 
163
- ## Hugging Face Deployment
164
-
165
- 1. Create a new Hugging Face Space.
166
- 2. Choose **Docker** as the SDK.
167
- 3. Push this repository to the Space remote.
168
- 4. The Space starts automatically from `Dockerfile` and serves `app.py` on port `7860`.
169
-
170
- ```bash
171
- git remote add space https://huggingface.co/spaces/<username>/cdn-cache-optimizer
172
- git push space main
173
- ```
174
-
175
- ## GitHub Deployment
176
-
177
- ```bash
178
- git add .
179
- git commit -m "Prepare CDN Cache Optimizer hackathon submission"
180
- git branch -M main
181
- git remote add origin https://github.com/<username>/cdn-cache-optimizer.git
182
- git push -u origin main
183
- ```
184
-
185
- ## 🚀 Setup & Usage
186
-
187
- ### Local Setup
188
- ```bash
189
- git clone <repo>
190
- cd cdn-cache-env
191
- pip install -r requirements.txt
192
- ```
193
-
194
- ### Run API Server
195
- ```bash
196
- uvicorn api.main:app --host 0.0.0.0 --port 7860
197
- ```
198
-
199
- ### Run Inference (Baseline Agent)
200
- ```bash
201
- export API_BASE_URL="https://api.openai.com/v1"
202
- export MODEL_NAME="gpt-4o-mini"
203
- export HF_TOKEN="your_token_here"
204
-
205
- python inference.py
206
- ```
207
-
208
- ### Docker
209
- ```bash
210
- docker build -t cdn-cache-env .
211
- docker run -p 7860:7860 cdn-cache-env
212
- ```
213
 
214
  ---
215
 
216
- ## 🌐 API Endpoints
217
 
218
- | Method | Endpoint | Description |
219
- |--------|----------|-------------|
220
- | GET | `/health` | Health check (returns 200) |
221
- | GET | `/tasks` | List all tasks |
222
- | POST | `/reset` | Start episode `{"task_id": "task_easy", "seed": 42}` |
223
- | POST | `/step` | Take action `{"evict_file_id": "file_001" or null}` |
224
- | GET | `/state` | Full environment state |
225
 
226
- ---
227
 
228
- ## 📊 Baseline Scores
229
 
230
- Using the built-in `smart_policy` (non-LLM baseline):
 
231
 
232
- | Task | Hit Rate | Score |
233
- |------|----------|-------|
234
- | Easy | ~0.72 | ~1.00 |
235
- | Medium | ~0.61 | ~0.82 |
236
- | Hard | ~0.48 | ~0.78 |
237
- | **Overall** | | **~0.87** |
238
 
239
- ---
 
 
 
 
 
 
240
 
241
- ## 📝 Log Format
 
 
242
 
243
- `inference.py` emits structured JSON logs:
244
 
245
- ```
246
- {"type": "START", "task_id": "task_easy", ...}
247
- {"type": "STEP", "step": 0, "action": {...}, "reward": 1.0, ...}
248
- {"type": "END", "total_reward": 87.3, "final_hit_rate": 0.72, "score": 1.0}
249
- ```
 
1
  ---
2
+ title: Building a CDN Cache Optimizer with OpenEnv and RL
3
  emoji: 🌐
4
  colorFrom: blue
5
  colorTo: green
 
13
  - hackathon
14
  ---
15
 
16
+ # Building a CDN Cache Optimizer with OpenEnv and RL
17
 
18
+ For this hackathon, I wanted to build something that felt close to a real infrastructure problem.
19
+
20
+ A lot of reinforcement learning demos are fun, but they often feel disconnected from systems that engineers actually run in production. I wanted my project to sit closer to that world: networking, latency, logs, cost, traffic spikes, and reliability.
21
+
22
+ So I built **CDN Cache Optimizer**.
23
+
24
+ It is an OpenEnv-compatible environment where an agent learns how to manage an edge CDN cache.
25
+
26
+ The project is live here:
27
+
28
+ - GitHub: https://github.com/umar-sharif821/cdn-cache-env-improvedone
29
+ - Hugging Face Space: https://huggingface.co/spaces/umar-sharif821/cdn-cache-env-improvedone
30
 
31
  ---
32
 
33
+ ## The Problem
34
+
35
+ A CDN edge server has limited storage.
36
 
37
+ Every time a file is requested, the system has to make a decision:
38
 
39
+ > Should this object stay in cache, should we ignore it, or should we evict something else to make room?
40
+
41
+ If the file is already cached, the user gets a fast edge response.
42
+
43
+ If the file is not cached, the request goes back to origin.
44
+
45
+ That is slower and more expensive.
46
+
47
+ At small scale, this looks simple.
48
+
49
+ At internet scale, it becomes a hard optimization problem.
50
 
51
  ---
52
 
53
+ ## Why This Matters
54
 
55
+ CDNs serve images, videos, scripts, documents, and application assets to users around the world.
56
 
57
+ A good cache policy can:
 
58
 
59
+ - reduce user latency
60
+ - reduce origin load
61
+ - save bandwidth
62
+ - improve reliability
63
+ - avoid unnecessary cache churn
64
 
65
+ A poor cache policy can do the opposite.
 
 
 
66
 
67
+ It may evict useful files.
68
 
69
+ It may cache large files that are rarely requested.
70
 
71
+ It may miss viral traffic bursts.
72
 
73
+ It may keep sending users back to origin even when the edge cache could have served them.
 
 
74
 
75
+ This is why cache optimization is an interesting RL problem.
76
 
77
+ ---
 
 
 
78
 
79
+ ## Why Not Just Use LRU?
80
 
81
+ LRU is simple:
82
 
83
+ > Evict the least recently used file.
 
 
 
84
 
85
+ That is a strong baseline, and it works well in many cases.
86
 
87
+ But it has blind spots.
88
 
89
+ For example:
 
 
90
 
91
+ - A file may be old but about to become popular again.
92
+ - A file may be recently used once but not worth storing.
93
+ - A viral object may deserve protection even if it has not been in cache for long.
94
+ - A large file may consume too much cache space compared to its value.
95
 
96
+ That is where an agent can do better.
97
 
98
+ The agent does not just ask:
99
 
100
+ > What was used least recently?
 
 
 
101
 
102
+ It can ask:
103
 
104
+ > What is most valuable to keep right now?
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  ---
107
 
108
+ ## Project Goal
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
+ The goal of this project is not just to train a model.
111
 
112
+ The goal is to build a complete benchmarkable environment around a realistic CDN caching problem.
113
+
114
+ That includes:
115
+
116
+ - an OpenEnv-style environment
117
+ - a baseline policy
118
+ - a fine-tuned agent policy
119
+ - a reward function grounded in latency and cost
120
+ - schema drift handling for CDN logs
121
+ - Colab reproducibility
122
+ - a live Hugging Face demo
123
+ - visual comparison between baseline and agent behavior
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
  ---
126
 
127
+ ## Live Demo
128
 
129
+ The Hugging Face Space runs a Gradio app.
 
 
 
 
 
 
130
 
131
+ The UI lets the judge choose a CDN task and run a benchmark.
132
 
133
+ It compares:
134
 
135
+ - **Baseline LRU**
136
+ - **Fine-tuned CDN agent**
137
 
138
+ The output shows:
 
 
 
 
 
139
 
140
+ - total reward
141
+ - cache hit rate
142
+ - bandwidth saved
143
+ - hit-rate curve
144
+ - baseline-vs-agent comparison chart
145
+
146
+ Space:
147
 
148
+ https://huggingface.co/spaces/umar-sharif821/cdn-cache-env-improvedone
149
+
150
+ ---
151
 
152
+ ![image](https://cdn-uploads.huggingface.co/production/uploads/69d35c9026493c5725de5708/HVE2u5rvJs9TLonlKuNUH.png)
153
 
154
+ ```markdown
155
+ ![Live Gradio demo](https://huggingface.co/spaces/umar-sharif821/cdn-cache-env-improvedone/resolve/main/demo_screenshot.png)