ojaffe commited on
Commit
613565a
·
verified ·
1 Parent(s): c5c1e99

Upload folder using huggingface_hub

Browse files
__pycache__/predict.cpython-311.pyc CHANGED
Binary files a/__pycache__/predict.cpython-311.pyc and b/__pycache__/predict.cpython-311.pyc differ
 
model_pole_position.pt CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d648d5626123d26b5967aa52f0580914728b1aaab67905dd5b647786a017337e
3
  size 1580934
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:62d218b9859acd4d19cfcfe6b3aa93ae129485a872175632ed32d6441ae9c7f6
3
  size 1580934
predict.py CHANGED
@@ -1,4 +1,4 @@
1
- """Compact PP ensemble: full Pong AR, Sonic AR+direct ensemble, compact PP direct. Under 16MB."""
2
  import sys
3
  import os
4
  import numpy as np
@@ -72,7 +72,7 @@ def load_model(model_dir: str):
72
  sonic_direct.eval()
73
  ens.sonic_direct = sonic_direct
74
 
75
- # PP: compact direct 8-frame model (24 outputs, smaller architecture)
76
  pp = UNet(in_channels=24, out_channels=24,
77
  enc_channels=(24, 48, 96), bottleneck_channels=128,
78
  upsample_mode="bilinear").to(DEVICE)
@@ -115,17 +115,46 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
115
  last_frame_t = np.transpose(last_frame, (2, 0, 1))[np.newaxis]
116
 
117
  if game == "pong":
 
 
 
 
 
 
 
 
 
 
118
  with torch.no_grad():
119
  context_tensor = torch.from_numpy(context).to(DEVICE)
120
  last_tensor = torch.from_numpy(last_frame_t).to(DEVICE)
121
- predicted = _predict_ar_frame(ens.models["pong"], context_tensor, last_tensor)
122
 
123
- predicted_np = predicted[0].cpu().numpy()
124
- predicted_np = np.transpose(predicted_np, (1, 2, 0))
125
- predicted_np = (predicted_np * 255).clip(0, 255).astype(np.uint8)
126
- return predicted_np
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
  elif game == "sonic":
 
129
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
130
  result = ens.direct_cache[ens.cache_step]
131
  ens.cache_step += 1
@@ -144,7 +173,7 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
144
  last_flipped = torch.flip(last_tensor, dims=[3])
145
  direct_flipped = _predict_8frames_direct(ens.sonic_direct, context_flipped, last_flipped)
146
  direct_flipped = torch.flip(direct_flipped, dims=[4])
147
- direct_pred = (direct_orig + direct_flipped) / 2.0
148
 
149
  # AR prediction with TTA
150
  ar_preds = []
@@ -167,8 +196,15 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
167
  ctx_flip = ctx_flip_frames.reshape(1, -1, 64, 64)
168
  last_f = ar_flip
169
 
170
- ar_pred = torch.stack(ar_preds, dim=1)
171
- predicted = (ar_pred + direct_pred) / 2.0
 
 
 
 
 
 
 
172
 
173
  predicted_np = predicted[0].cpu().numpy()
174
  ens.direct_cache = []
 
1
+ """Inference tricks: Pong AR caching, Sonic step-dependent blending."""
2
  import sys
3
  import os
4
  import numpy as np
 
72
  sonic_direct.eval()
73
  ens.sonic_direct = sonic_direct
74
 
75
+ # PP: compact direct 8-frame model (24 outputs)
76
  pp = UNet(in_channels=24, out_channels=24,
77
  enc_channels=(24, 48, 96), bottleneck_channels=128,
78
  upsample_mode="bilinear").to(DEVICE)
 
115
  last_frame_t = np.transpose(last_frame, (2, 0, 1))[np.newaxis]
116
 
117
  if game == "pong":
118
+ # Pong: AR with internal caching (all 8 steps in float32)
119
+ if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
120
+ result = ens.direct_cache[ens.cache_step]
121
+ ens.cache_step += 1
122
+ if ens.cache_step >= PRED_FRAMES:
123
+ ens.reset_cache()
124
+ return result
125
+
126
+ ens.reset_cache()
127
+ model = ens.models["pong"]
128
  with torch.no_grad():
129
  context_tensor = torch.from_numpy(context).to(DEVICE)
130
  last_tensor = torch.from_numpy(last_frame_t).to(DEVICE)
 
131
 
132
+ # Run all 8 AR steps in float32 (no uint8 quantization between steps)
133
+ preds = []
134
+ ctx = context_tensor.clone()
135
+ last_t = last_tensor.clone()
136
+ for step in range(PRED_FRAMES):
137
+ predicted = _predict_ar_frame(model, ctx, last_t)
138
+ preds.append(predicted)
139
+ # Shift context with float32 prediction (no quantization)
140
+ ctx_frames = ctx.reshape(1, CONTEXT_FRAMES, 3, 64, 64)
141
+ ctx_frames = torch.cat([ctx_frames[:, 1:], predicted.unsqueeze(1)], dim=1)
142
+ ctx = ctx_frames.reshape(1, -1, 64, 64)
143
+ last_t = predicted
144
+
145
+ ens.direct_cache = []
146
+ for i in range(PRED_FRAMES):
147
+ frame = preds[i][0].cpu().numpy()
148
+ frame = np.transpose(frame, (1, 2, 0))
149
+ frame = (frame * 255).clip(0, 255).astype(np.uint8)
150
+ ens.direct_cache.append(frame)
151
+
152
+ result = ens.direct_cache[ens.cache_step]
153
+ ens.cache_step += 1
154
+ return result
155
 
156
  elif game == "sonic":
157
+ # Sonic: step-dependent AR/direct blending with caching
158
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
159
  result = ens.direct_cache[ens.cache_step]
160
  ens.cache_step += 1
 
173
  last_flipped = torch.flip(last_tensor, dims=[3])
174
  direct_flipped = _predict_8frames_direct(ens.sonic_direct, context_flipped, last_flipped)
175
  direct_flipped = torch.flip(direct_flipped, dims=[4])
176
+ direct_pred = (direct_orig + direct_flipped) / 2.0 # (1, 8, 3, 64, 64)
177
 
178
  # AR prediction with TTA
179
  ar_preds = []
 
196
  ctx_flip = ctx_flip_frames.reshape(1, -1, 64, 64)
197
  last_f = ar_flip
198
 
199
+ ar_pred = torch.stack(ar_preds, dim=1) # (1, 8, 3, 64, 64)
200
+
201
+ # Step-dependent blending: AR weight goes from 0.7 (step 0) to 0.3 (step 7)
202
+ # Direct weight goes from 0.3 (step 0) to 0.7 (step 7)
203
+ predicted = torch.zeros_like(direct_pred)
204
+ for step in range(PRED_FRAMES):
205
+ ar_weight = 0.7 - (step / (PRED_FRAMES - 1)) * 0.4 # 0.7 -> 0.3
206
+ direct_weight = 1.0 - ar_weight # 0.3 -> 0.7
207
+ predicted[:, step] = ar_weight * ar_pred[:, step] + direct_weight * direct_pred[:, step]
208
 
209
  predicted_np = predicted[0].cpu().numpy()
210
  ens.direct_cache = []