Ben commited on
Commit
69f399c
·
1 Parent(s): a665bbe

Add application file

Browse files
Files changed (2) hide show
  1. app.py +135 -0
  2. requirements.txt +8 -0
app.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ if os.getenv("SPACE_ID") is not None:
3
+ os.environ["SDL_VIDEODRIVER"] = "dummy"
4
+ os.environ["SDL_AUDIODRIVER"] = "dummy"
5
+
6
+ import torch
7
+ import torch.nn as nn
8
+ import numpy as np
9
+ import gymnasium as gym
10
+ import imageio
11
+ import gradio as gr
12
+ from huggingface_hub import hf_hub_download
13
+
14
+ # 1. Policy Network Architecture
15
+ def layer_init(layer, std=np.sqrt(2), bias_const=0.0):
16
+ nn.init.orthogonal_(layer.weight, std)
17
+ nn.init.constant_(layer.bias, bias_const)
18
+ return layer
19
+
20
+ # Reconstruct pure Sequential actor
21
+ def get_actor_network(state_dim=8, action_dim=4):
22
+ actor = nn.Sequential(
23
+ layer_init(nn.Linear(state_dim, 64)),
24
+ nn.Tanh(),
25
+ layer_init(nn.Linear(64, 64)),
26
+ nn.Tanh(),
27
+ layer_init(nn.Linear(64, action_dim), std=0.01),
28
+ )
29
+ return actor
30
+
31
+ # 2. Inference & Rendering
32
+ def simulate_agent(stage_selection):
33
+ weight_mapping = {
34
+ "Stage 1: Baseline": "1_baseline.pth",
35
+ "Stage 2: Surrogate Hacking": "2_surrogate_hacking_attention.pth",
36
+ "Stage 3: Temporal Paradox ": "3_temporal_paradox_variance.pth",
37
+ "Stage 4: Target Decoupling": "4_target_decoupling_final.pth"
38
+ }
39
+ filename = weight_mapping.get(stage_selection)
40
+ repo_id = "ben-dlwlrma/Representation-Over-Routing"
41
+
42
+ # Download weights from HF Hub
43
+ try:
44
+ weights_path = hf_hub_download(repo_id=repo_id, filename=filename)
45
+ except Exception as e:
46
+ return None, f"Weight download failed. Error: {str(e)}"
47
+
48
+ # Initialize env
49
+ env = gym.make("LunarLander-v2", render_mode="rgb_array")
50
+
51
+ # Initialize model on CPU
52
+ device = torch.device("cpu")
53
+ actor = get_actor_network(state_dim=8, action_dim=4).to(device)
54
+
55
+ # Load weights
56
+ try:
57
+ actor.load_state_dict(torch.load(weights_path, map_location=device, weights_only=True))
58
+ actor.eval()
59
+ except Exception as e:
60
+ env.close()
61
+ return None, f"Architecture mismatch. Error: {str(e)}"
62
+
63
+ state, _ = env.reset(seed=32)
64
+ done = False
65
+ frames = []
66
+ total_reward = 0.0
67
+ step_count = 0
68
+
69
+ while not done and step_count < 600:
70
+ try:
71
+ frame = env.render()
72
+ if frame is not None:
73
+ frames.append(frame)
74
+ except Exception as e:
75
+ env.close()
76
+ return None, f"Render failed: {str(e)}"
77
+
78
+ state_tensor = torch.FloatTensor(state).unsqueeze(0).to(device)
79
+ with torch.no_grad():
80
+ action_logits = actor(state_tensor)
81
+ action = torch.argmax(action_logits, dim=1).item()
82
+
83
+ state, reward, terminated, truncated, _ = env.step(action)
84
+ total_reward += reward
85
+ step_count += 1
86
+ done = terminated or truncated
87
+
88
+ env.close()
89
+
90
+ # Export to MP4
91
+ video_filename = "eval_output.mp4"
92
+ fps = 30
93
+ try:
94
+ imageio.mimsave(video_filename, frames, fps=fps, codec='libx264', pixelformat='yuv420p')
95
+ except Exception as e:
96
+ return None, f"Video encoding failed: {str(e)}"
97
+
98
+ logs = (f"Status: Inference complete\n"
99
+ f"Stage: {stage_selection}\n"
100
+ f"Total Reward: {total_reward:.2f}\n"
101
+ f"Steps: {step_count}")
102
+
103
+ return video_filename, logs
104
+
105
+ # 3. Gradio Web UI
106
+ with gr.Blocks(title="Representation over Routing", theme=gr.themes.Base()) as demo:
107
+ gr.Markdown("## Representation over Routing")
108
+ gr.Markdown("Multi-timescale RL evaluation environment. Select an ablation stage to visualize policy behavior.")
109
+
110
+ with gr.Row():
111
+ with gr.Column(scale=1):
112
+ model_dropdown = gr.Dropdown(
113
+ choices=[
114
+ "Stage 1: Baseline",
115
+ "Stage 2: Surrogate Hacking",
116
+ "Stage 3: Temporal Paradox ",
117
+ "Stage 4: Target Decoupling"
118
+ ],
119
+ value="Stage 4: Target Decoupling",
120
+ label="Model Stage"
121
+ )
122
+ run_button = gr.Button("Run Inference", variant="primary")
123
+
124
+ with gr.Column(scale=2):
125
+ video_output = gr.Video(label="Environment Render")
126
+ text_output = gr.Textbox(label="Execution Logs", lines=4)
127
+
128
+ run_button.click(
129
+ fn=simulate_agent,
130
+ inputs=[model_dropdown],
131
+ outputs=[video_output, text_output]
132
+ )
133
+
134
+ if __name__ == "__main__":
135
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ torch>=2.0.0
2
+ numpy
3
+ gymnasium[box2d]
4
+ imageio
5
+ imageio-ffmpeg
6
+ huggingface_hub
7
+ gradio
8
+ spaces